本篇內容主要講解“C++的函數(shù)概念”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“C++的函數(shù)概念”吧!
創(chuàng)新互聯(lián)公司-專業(yè)網站定制、快速模板網站建設、高性價比澄城網站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式澄城網站制作公司更省心,省錢,快速模板網站建設找我們,業(yè)務覆蓋澄城地區(qū)。費用合理售后完善,10余年實體公司更值得信賴。
C++的函數(shù)
今天我們開始了解C++中的函數(shù)的概念。
說到函數(shù),我們應該比較清楚了,不論哪一門語言都有這個概念的,其實本質上就是講我們之前介紹的語句,表達式等封裝起來,形成一個功能單元。在C/C++中它也是程序執(zhí)行的最小單元,我們新建一個工程,如果想要編譯通過的話,必須要有一個主函數(shù)main。
但是在一個解釋型語言,就不必要了,想js, shell,python等。以后,我們介紹的Go語言,也是編譯型語言,也是需要main函數(shù)的,只不過形式不同而已。
函數(shù)的定義
首先,我們先說一下函數(shù)的定義方法,函數(shù)包括返回值,函數(shù)名,以及參數(shù)列表,返回值可以具有實際意義,也可以為void,參數(shù)列表呢,可以有,也可以沒有。這個C/C++中沒什么區(qū)別。下面舉個例子怎么定義一個函數(shù):
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.
}
}
上面就是一個函數(shù)的例子,BrewFunction是返回值,GetBrewFunction是函數(shù)名,const caffe::string& name 是函數(shù)的參數(shù)列表。其實這部分代碼是我從深度學習框架caffe中截取的一點。
我決定以后文章中的示例代碼,我就從一些經典的開源項目中尋找吧,這樣的話如果我們以后用到的話,可以更快熟悉,如果不用,也沒太大關系,建議大家在學習完基礎教程后,多去閱讀一下開源代碼,這樣,我們的技能可以提升得更快。
參數(shù)列表的使用
我們在定義函數(shù)時,經常需要往一個函數(shù)里面?zhèn)鬟f參數(shù)。比如下面的代碼:
void Blob::Reshape(const BlobShape& shape) {
CHECK_LE(shape.dim_size(), kMaxBlobAxes);
vector shape_vec(shape.dim_size());
for (int i = 0; i < shape.dim_size(); ++i) {
shape_vec[i] = shape.dim(i);
}
Reshape(shape_vec);
}
我要實現(xiàn)一個改變數(shù)據(jù)形狀的函數(shù),我就要傳遞一個BlobShape類型的參數(shù), 可以看到上面這個參數(shù)shape也是一個BlobShape引用。我們把這成為傳引用調用。如果是下面這樣的,僅僅傳一個值的話,我們稱為“傳值調用”。
void Blob::Reshape(const BlobShape shape) {
CHECK_LE(shape.dim_size(), kMaxBlobAxes);
vector shape_vec(shape.dim_size());
for (int i = 0; i < shape.dim_size(); ++i) {
shape_vec[i] = shape.dim(i);
}
Reshape(shape_vec);
}
除了傳引用,傳值以外,我們的參數(shù)列表還可以傳遞指針,就是把一個對象或變量的地址傳進去,傳遞指針可以實現(xiàn)和傳遞引用同樣的功能,就是希望通過函數(shù)改變參數(shù)的值,然后能把這個值傳出。這種用法很多很多。
void DataTransformer::Transform(const vector & mat_vector,
Blob* 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 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
那么,從上面的例子中我們看到,函數(shù)中出現(xiàn)了const這個限定符,這里有什么用呢?這里const就是我們之前講的,限定,不可更改。
就是說如果我們不打算在函數(shù)中修改傳入的變量的話,最好把它用const加以限定,當然這不是必須的,這只是一個C++程序員的基本修養(yǎng),一種編程習慣。當然,這也是非常有益處的。
比如,你要開發(fā)一個庫給第三方調用,你不希望某個輸入參數(shù)在代碼運行時被更改,那么就應該使用const,強制限定。
除此以外,如果我們的參數(shù)比較大的話,也建議使用引用形參傳遞給參數(shù),因為引用沒有實體,是原輸入數(shù)據(jù)的別名,不對數(shù)據(jù)進行拷貝,因此有更高的效率。
main函數(shù)獲取命令行參數(shù)
很多情況下,我們會用到main函數(shù)獲取命令行參數(shù),那么這是怎么實現(xiàn)的呢?
我們先來看一下main函數(shù)的完整定義:
int main(int argc, char * argv[])
{
...
}
上面的代碼中,argc就是表示參數(shù)列表的個數(shù),argv就是參數(shù)列表數(shù)組,假設我有一個test_func可執(zhí)行文件,我在命令行執(zhí)行下面的命令:
test_func arg1 arg2 arg3 arg4 arg5
那么我們就可以在函數(shù)中讀到argc的值為5,參數(shù)列表中的值分別為:
argv[0] = arg1
argv[1] = arg2
argv[2] = arg3
argv[3] = arg4
argv[4] = arg5
到此,相信大家對“C++的函數(shù)概念”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續(xù)學習!