中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++的函數概念

發布時間:2021-08-24 09:12:54 來源:億速云 閱讀:136 作者:chen 欄目:大數據

本篇內容主要講解“C++的函數概念”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“C++的函數概念”吧!


C++的函數

今天我們開始了解C++中的函數的概念。

說到函數,我們應該比較清楚了,不論哪一門語言都有這個概念的,其實本質上就是講我們之前介紹的語句,表達式等封裝起來,形成一個功能單元。在C/C++中它也是程序執行的最小單元,我們新建一個工程,如果想要編譯通過的話,必須要有一個主函數main。

但是在一個解釋型語言,就不必要了,想js, shell,python等。以后,我們介紹的Go語言,也是編譯型語言,也是需要main函數的,只不過形式不同而已。

函數的定義

首先,我們先說一下函數的定義方法,函數包括返回值,函數名,以及參數列表,返回值可以具有實際意義,也可以為void,參數列表呢,可以有,也可以沒有。這個C/C++中沒什么區別。下面舉個例子怎么定義一個函數:

static BrewFunction GetBrewFunction(const caffe::string& name) {
 if (g_brew_map.count(name)) {
   return g_brew_map[name];
 } else {
   LOG(ERROR) << "Available caffe actions:";
   for (BrewMap::iterator it = g_brew_map.begin();
        it != g_brew_map.end(); ++it) {
     LOG(ERROR) << "\t" << it->first;
   }
   LOG(FATAL) << "Unknown action: " << name;
   return NULL;  // not reachable, just to suppress old compiler warnings.
 }
}

上面就是一個函數的例子,BrewFunction是返回值,GetBrewFunction是函數名,const caffe::string& name 是函數的參數列表。其實這部分代碼是我從深度學習框架caffe中截取的一點。

我決定以后文章中的示例代碼,我就從一些經典的開源項目中尋找吧,這樣的話如果我們以后用到的話,可以更快熟悉,如果不用,也沒太大關系,建議大家在學習完基礎教程后,多去閱讀一下開源代碼,這樣,我們的技能可以提升得更快。

參數列表的使用

我們在定義函數時,經常需要往一個函數里面傳遞參數。比如下面的代碼:

void Blob<Dtype>::Reshape(const BlobShape& shape) {
 CHECK_LE(shape.dim_size(), kMaxBlobAxes);
 vector<int> shape_vec(shape.dim_size());
 for (int i = 0; i < shape.dim_size(); ++i) {
   shape_vec[i] = shape.dim(i);
 }
 Reshape(shape_vec);
}

我要實現一個改變數據形狀的函數,我就要傳遞一個BlobShape類型的參數, 可以看到上面這個參數shape也是一個BlobShape引用。我們把這成為傳引用調用。如果是下面這樣的,僅僅傳一個值的話,我們稱為“傳值調用”。

void Blob<Dtype>::Reshape(const BlobShape shape) {
 CHECK_LE(shape.dim_size(), kMaxBlobAxes);
 vector<int> shape_vec(shape.dim_size());
 for (int i = 0; i < shape.dim_size(); ++i) {
   shape_vec[i] = shape.dim(i);
 }
 Reshape(shape_vec);
}

除了傳引用,傳值以外,我們的參數列表還可以傳遞指針,就是把一個對象或變量的地址傳進去,傳遞指針可以實現和傳遞引用同樣的功能,就是希望通過函數改變參數的值,然后能把這個值傳出。這種用法很多很多。

void DataTransformer<Dtype>::Transform(const vector<cv::Mat> & mat_vector,
                                      Blob<Dtype>* transformed_blob) {
 const int mat_num = mat_vector.size();
 const int num = transformed_blob->num();
 const int channels = transformed_blob->channels();
 const int height = transformed_blob->height();
 const int width = transformed_blob->width();

 CHECK_GT(mat_num, 0) << "There is no MAT to add";
 CHECK_EQ(mat_num, num) <<
   "The size of mat_vector must be equals to transformed_blob->num()";
 Blob<Dtype> uni_blob(1, channels, height, width);
 for (int item_id = 0; item_id < mat_num; ++item_id) {
   int offset = transformed_blob->offset(item_id);
   uni_blob.set_cpu_data(transformed_blob->mutable_cpu_data() + offset);
   Transform(mat_vector[item_id], &uni_blob);
 }
}

看上面的transformed_blob,就是Blob<Dtype>類型的指針,我們可以在函數外面定義一個這個類型的變量,然后把它作為參數傳入Transform函數,然后,我們就可以在函數中改變參數的值,最后把它傳出去。

那么,從上面的例子中我們看到,函數中出現了const這個限定符,這里有什么用呢?這里const就是我們之前講的,限定,不可更改。

就是說如果我們不打算在函數中修改傳入的變量的話,最好把它用const加以限定,當然這不是必須的,這只是一個C++程序員的基本修養,一種編程習慣。當然,這也是非常有益處的。

比如,你要開發一個庫給第三方調用,你不希望某個輸入參數在代碼運行時被更改,那么就應該使用const,強制限定。

除此以外,如果我們的參數比較大的話,也建議使用引用形參傳遞給參數,因為引用沒有實體,是原輸入數據的別名,不對數據進行拷貝,因此有更高的效率。

main函數獲取命令行參數

很多情況下,我們會用到main函數獲取命令行參數,那么這是怎么實現的呢?

我們先來看一下main函數的完整定義:

int main(int argc, char * argv[])
{
   ...
}

上面的代碼中,argc就是表示參數列表的個數,argv就是參數列表數組,假設我有一個test_func可執行文件,我在命令行執行下面的命令:

test_func arg1 arg2 arg3 arg4 arg5

那么我們就可以在函數中讀到argc的值為5,參數列表中的值分別為:

argv[0] = arg1
argv[1] = arg2
argv[2] = arg3
argv[3] = arg4
argv[4] = arg5

到此,相信大家對“C++的函數概念”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

c++
AI

通州市| 阳城县| 禹州市| 湘西| 应城市| 抚州市| 瓦房店市| 饶阳县| 清原| 唐河县| 寿阳县| 保靖县| 闽清县| 阜康市| 辽宁省| 寻乌县| 兰州市| 凌云县| 林周县| 苍南县| 丹江口市| 崇文区| 临泽县| 麻阳| 宝坻区| 渑池县| 高清| 称多县| 五常市| 万山特区| 宜昌市| 海城市| 东明县| 海晏县| 庐江县| 连山| 玉田县| 榆树市| 凤凰县| 大竹县| 宁阳县|