C语言语法教程:函数

函数

C++同样也有函数,函数同样也需要声明,声明格式为

    函数返回值类型 函数名称(参数列表){}

声明时我们写在参数列表里的参数叫做形参,调用时传入的参数叫做实参。

如果你的函数设置了返回值,则必须返回一个值,在函数里面用

return 返回值;

的格式返回,注意:返回值的类型必须和先前声明的一致。如果你的函数没有返回值,则可以在声明的返回值类型的位置填void,表示无类型,可以不用返回值,那么请思考下面一段代码:

int a=0;

int add(int a,int b){return a+b;}

int function(){}

在这段代码中,在function中是否可以访问add函数中的b,这时候就要引出一个新概念:变量的生命周期——作用域,那么什么是作用域呢?比如a不在任何函数里,它属于这个文件,在在这个文件内的所有位置都可以访问它,它从程序开始被创建程序结束被销毁,文件就是它的作用域,叫文件作用域,而声明在函数内的变量则不同,它从函数开始被创建,函数结束就被销毁,所以在除了它所在的函数外是访问不到的,这样的变量叫局部变量,那么如果我想让这个局部变量不被外面访问,但是它函数结束后又不会被销毁,还能继续保存数据呢?这时候可以用静态变量,静态变量的声明和普通变量区别不大,只要在普通变量声明前加static即可,例如:

int function(){

    static int sum;

}

函数有第二个机制:函数原型,指先声明函数而不告诉编译器函数的内容,后面再对函数进行实现,请读者思考如果存在两个函数a和b,我想要让a调用b,b调用a该怎么编写代码,这个问题的一大难处就在于声明因为如果将a放在b前面,那么a就不能调用b因为编译器会报错未声明函数,反之则会报错未声明a函数,这时候就可以使用函数原型,函数原型的作用只是告诉编译器有这么一个函数,至于实现到下面的代码中去寻找,一般地,在C/C++中的项目编写规范就是在头文件中写出函数原型而不实现,在源文件中包含头文件并对函数原型进行实现,或者在源文件中有声明和实现,这样的项目规范在下面的OOP中还会提及,请读者注意。函数原型的声明格式为:

返回值类型 函数名称(参数列表);

参数列表中的参数不必指明参数名称(当然也可以写)而实现函数原型的格式与声明一致。

函数的第三个机制:函数重载,函数重载可以理解为一个函数有多种不同的实现,就像我们做数学题,证明一个命题我们可以用多种不同的方式,试想我们现在写了一个函数add可以计算两个参数传入的值,那么我们不难想到我们要写出add_int,add_float,add_long等等多个不同名称的函数版本来实现加法,而C/C++允许函数重名,这种机制叫函数重载,当存在多个重载时,你调用这个函数,编译器会自动根据传入的实参匹配相应的重载,如果你写的代码中存在两个重载的函数名称,参数类型,数量都一致,编译器会报错,因为编译器找不到该调用哪个版本的重载,这种问题被称作“二义性问题”,注意:是根据参数来判断是否存在二义性问题,不包括返回值。即使你的返回值不一致,只要你的参数类型一致,就会被判定为二义性问题。

函数还有“内联函数”,内联函数的运行比普通函数稍微快一点,因为在C/C++的底层中,当你调用一个函数,它的原理是先跳到那个函数,执行完再跳出来,那么就多出了跳到和跳出这两个额外的开支,而内联函数则是直接把函数复制到调用的地方,虽加快了程序运行,但是可能会让程序的体量变大,内联函数的声明就只是在普通函数声明前面加上inline,同样内联函数也支持函数重载、函数原型,内联函数的声明格式如下:

inline 返回值类型 函数名称(参数列表){}

下面会讲解函数的第5个机制:参数默认值,一个参数可能会存在默认值,比如0,这就意味着在调用这个函数时即使我们不传0,编译器也会知道这个参数是0,例如:

int set(int Value,int offset=0){return Value+offset;}

当我们调用时,如果我写set(3,0);它会返回3,我写set(3);也会返回3,如果我写set(3,2);会返回5,当你不传实参时,这个默认参数值就是我们给的默认值,传入时则会选取我们传入的实参为准,注意:默认参数值必须放在参数列表的最后而不能放在参数列表的中间位置或者前面比如int set(int offset=0,int Value){return Value+offset;}这么写是错误的。对函数的进一步探究会在讲解指针与泛型编程中进一步探讨。

点点赞赏,手留余香

0

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
善语结善缘,恶语伤人心
提交
头像

昵称

取消
昵称表情代码图片快捷回复

    暂无评论内容