第七章 函数
第1节 函数基础
栈帧结构
函数的外部链接
第2节 函数详解
传值、传址、传引用
传参数时的类型退化,传数组时函数形参退化成指针,所以形参不要写数组个数
多维数组作为函数参数时
void fun(int (*par)[4])
int a[3][4] = {0};
fun(a);
避免退化的写法
void fun(int (&par)[3])
int a[3];
fun(a);
变长参数
-
initializer_list
,变量类型必须相同
#include <initializer_list>
void fun(std::initializer_list<int> par)
fun({1,2,3,4,5});
-
可变长度模板参数 (不限制类型相同,复杂一些)
-
使用省略号表示形参(不建议使用)
函数缺省实参
void fun (int x = 0){} fun();
缺省实参右侧的参数都必须有缺省实参
传入实参时从左到右与形参匹配
在一个翻译单元中,每个参数的缺省实参只能定义一次
缺省实参为对象时,实参的缺省值会随对象的值变化而变化 (不建议,阅读困难)
推荐方法:源文件中定义函数,头文件中声明函数同时定义缺省实参,main函数中调用函数,最安全。
main函数的两个版本
- 无形参
int main(){}
- 带两个形参的
int main(int argc,char* argv[]){}
argc
为非负数,程序运行环境传递给程序的实参个数
argv
为指针,指针指向argc+1
个指针的数组
函数体
函数体形成域
函数体的返回值
返回值优化(RVO)
返回类型
表示函数计算结果类型,可以为void
返回类型的几种书写方式
17引入返回类型的结构化绑定
第3节 函数重载与重载解析
(重载的函数,参数类型不相同)
int fun(int x){
return x+1;
}
double fun(double x){
return x+1;
}
fun(3);
fun(3.5);
使用相同的函数名定义多个函数,每个函数具有不同的参数列表
- 不能基于不同的返回类型进行重载
- 函数重载与mangling
编译器如何选择正确的版本完成调用
名称查找
限定查找(限定查找域)与非限定查找
非限定查找会进行逐级域查找——名称隐藏(同一域的函数在域内会隐藏其他域的同名函数)
查找通常会在已声明集合中进行
实参依赖查找
namespace MyNS{
struct Str{};
void g(Str s){
}
}
MyNS::Str obj;
g(obj);
重载解析
在名称查找基础上进一步选择合适的调用函数
第4节 函数相关的其他内容
递归函数
在函数体内调用其自身的函数
通常用于描述复杂的迭代过程(注意避免无线递归)
内联函数
调用函数时,函数体运算较简单,则较多资源用于构建和释放栈帧,针对这一问题编译期可以展开函数,避免构建栈帧。
inline
内联标识符,向编译器发出请求,将函数编译时展开
inline
内联标识符,将程序级的一次定义原则改为翻译单元级别的一次定义原则
向编译器发出请求,将函数编译时展开
constexpr函数与consteval函数
为了让**某些函数在编译期计算**,引入constexpr函数
(内联函数和constexpr函数都应该定义在头文件中,翻译单元级不重复)
constexpr int fun(int x){
return x + 1;
}
constexpr int y = 3;
int z = fun(y);
实参也需要是字面值或常量编译表达式
函数指针
函数类型与函数指针类型
int fun(int x){}
函数类型为int(int)
using K = int(int);
K fun; //相当于函数声明,不可用于定义
或者配合std::function
使用
(函数指针多数跟高阶函数配合使用)
函数指针与重载
函数指针作为参数
using K = int(int);
void pla(K* input) {
std::cout << (*input)(2) << std::endl;
}
int inc(int x) {
return x + 1;
}
int main(int argc, char *argv[]) {
pla(inc);
}
函数指针作为返回值
int inc(int x){
return x+1;
}
int dec(int x){
renturn x-1;
}
auto fun(bool input){
if(input)
return inc; //返回函数指针
else
return dec;
}
std::cout<<(*fun(true))(100)<<std::endl;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)