函数相关
函数基础
-
形参与实参
实参类型要与形参类型匹配
实参可以发生隐式转换
引用传递和值传递 -
函数的返回类型
函数的返回类型不能是数组或函数,但可以返回指向数组或函数的指针 -
局部静态对象
定义在函数内部的局部静态对象,函数执行结束也不会销毁int test() { static int i = 10; //调用结束后依然有效 return i++; } int main() { for (int i = 0; i < 10; i++) { cout << test() << endl; //由于静态对象一直有效,结果为 11-19 } return 0; }
传参
-
传引用参数
-
可以避免拷贝
-
利用引用传递返回额外信息
-
const
形参
由于传参的时候会忽略顶层const
,所以函数重载可能会受到影响
形参尽量使用常量引用
常见错误func(string &s);//非常量引用无法接收字面值,除非加const func("hello");
-
-
数组形参
数组两个特性:不允许拷贝数组;使用数组时会转换为首元素的指针
实参会自动转换为指向数组首元素的指针,形参定义为底层const
指针void print(const int *); void print(const int[]); void print(const int[10]);//10并不是真实维度,相当于注释
由于数组是以指针形式传递给函数的,所以不知道数组的维度,必须由调用者提供额外信息
解决方法:- 使用标记指定数组长度
C 风格的字符串(字符数组),空字符结尾 - 使用标准库规范
传递指向数组首元素和尾后元素的指针(迭代器的做法) - 显式传递一个表示数组大小的形参
- 使用标记指定数组长度
-
数组引用形参
数组虽然不能拷贝,但是可以传递引用,f(int (&arr)[10])
-
多维数组传参
形参传递指向数组的指针,f(int (*arr)[10])
返回
-
值返回细节
- 返回的值用于初始化调用点的临时量
- 不要返回局部对象的引用或指针
- 引用返回可以成为左值,返回非常量引用的函数可以进行赋值操作
-
返回数组指针
由于数组不能拷贝,所以函数不能返回数组-
定义返回数组指针的函数
int (*f(int i))[10]
(*f(int i))
表示函数返回指针int [10]
表示函数返回的指针指向含有10整型对象的数组 -
尾置返回类型
auto func(int i) -> int(*)[10]
-
重载
-
重载与
const
形参
拥有顶层的const
形参无法与没有顶层const
的形参区分,因此不能作为重载条件void test(int i); void test(const int i);//重复声明
引用或指针的底层
const
可以作为重载条件int j = 0; void test(int &i) { cout << "int i" << endl; } void test(const int &i) { cout << "const int i" << endl; } test(j);//j是非常量,非常量可以初始化常量,因此两个版本都能调用,但优先调用非常量引用版本
-
重载与作用域
一旦在内层作用域声明函数,它将隐藏外层作用域所有版本的函数通常来说,在内层作用域声明函数是不好的习惯
-
函数匹配
- 候选函数
与被调用的函数同名;
声明在调用点可见 - 可行函数
形参数量与本次调用的实参数量相同;
形参与实参的类型相同,或者实参可以转换为形参的类型 - 最佳匹配
精确匹配比类型转换匹配更好
有且仅有一个最佳匹配,否则编译器因为二义性二拒绝请求
- 候选函数
-
函数指针
函数的类型:由其返回类型和其形参类型共同决定
举个例子:函数定义,
int func(int value)
函数类型,int (int value)
函数指针,int (*p)(int value)
,p 函数指针未初始化,只是定义了一个返回类型为int
,形参为一个int
类型参数的函数指针
当函数作为一个值使用时,该函数自动转换成指针,p = func;
等价于p = &func;
使用函数指针调用时可以不解引用,p(1)
等价于(*p)(1)
int func(int value) { return value; } int main() { int (*p)(int) = func;//定义一个函数指针并赋值为func cout << func(1) << endl; return 0; }
-
函数指针形参
- 形参可以是指向函数的指针,传递函数类型时,会自动转换成函数的指针
void test(int func(int value))
等价于void test(int (*p)(int value))
- 实参可以直接传递函数名,它会自动转换为指针
test(func)
- 形参可以是指向函数的指针,传递函数类型时,会自动转换成函数的指针
-
返回函数指针
int (*f1(int))(int *, int);
f1(int)
是函数类型
*f1(int)
表示返回指针
*f1
还包含后面的参数列表,说明返回的指针指向函数类型,类型为int (int *, int)
特殊语言特性
-
默认实参
默认实参作为形参的初始值
一旦某个形参被赋予了默认值,则它之后的所有形参都必须有默认值
函数调用时,只能省略尾部实参,因此要合理设计形参的顺序 -
内联函数
关键字:inline
作用:编译器将小函数在调用点展开,达到优化的效果但最终取决于编译器的处理,
inline
关键字只是给编译器一个建议