温馨提示×

温馨提示×

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

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

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