您好,登錄后才能下訂單哦!
本篇內容主要講解“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++的函數概念”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。