温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

C++的函数概念

发布时间:2021-08-24 09:12:54 阅读:145 作者:chen 栏目:大数据
C++开发者专用服务器限时活动,0元免费领,库存有限,领完即止! 点击查看>>

本篇内容主要讲解“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] = arg1argv[1] = arg2argv[2] = arg3argv[3] = arg4argv[4] = arg5

到此,相信大家对“C++的函数概念”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

原文链接:https://my.oschina.net/u/4436209/blog/4353638

c++
AI

开发者交流群×