6.1.1 局部对象
- 如果局部静态变量没有显式的初始值,它将执行值初始化。内置类型的局部静态变量初始化为0
6.2.3 const形参和实参
- 形参的顶层const被忽略掉了,故
void fcn(const int i);void fcn(int i);
表示同一个函数,不会构成重载
6.2.4 数组形参
int (&arr)[10]
c++允许将变量定义成数组的引用,此时,引用形参绑定到对应的实参上,也就是绑定到数组上- 传递多维数组:当将多维数组传递给函数时,真正传递的是指向数组首元素的指针,因为我们处理的是数组的数组,所以首元素本身就是一个数组,指针就是一个指向数组的指针,数组第二维(以及后面的所有维度)的大小都是数组类型的一部分,不能省略
void print(int (*matrix)[10],int rowSize); void print(int matrix[][10],int rowSize;//等价定义)
6.2.6 含有可变形参的函数
- initializer_list:表示某种特定类型的值得数组,如果想向initializer_list形参中传递一个值得序列,则必须把序列放在一堆花括号内{。。。}
- 范围for语句使用条件:expression表示的必须是一个序列,这些类型的共同特点是拥有能返回迭代器的begin和end成员
6.3.2 有返回值函数
C++11 规定,函数可以返回花括号包围的值的列表
vector<string> process()
{
...
return {"a","b","c"};
}主函数main的返回值:返回0表示执行成功,其他值表示执行失败,非0值得具体含义依机器而定。为了使返回值与机器无关,cstdlib头文件定义了连个预处理变量
return EXIT_FAILURE; return EXIT_SUCCESS;//成功
6.3.3 返回数组的指针
- 尾置返回类型:
auto func(int i)->int(*)[10]
任何函数都能使用尾置返回,但这种形式对于返回类型比较复杂的函数最有效,比如返回类型是数组的指针或数组的引用 int odd[]={1,3,5,7,9};decltype(odd) *arrPtr(int i)
decltype并不负责吧数组类型转换成对应的指针,所以decltype的结果是个数组。要想表示arrPtr返回指针还必须在函数声明时加一个*符号
{...}
6.4 函数重载
- 参数为顶层const无法构成重载、底层const构成重载,当参数为常量对象的指针或引用,实参为非常量对象时,编译器会优先选用非常量版本的函数
6.4.1 重载与作用域
- 一旦在当前作用域中找到了所需的名字,编译器就会忽略掉外层作用域中的同名实体。剩下的工作就是检查函数调用是否有效了。名字查找发生在类型检查之前。
6.5.2 默认实参
- 用作默认实参的名字在函数声明所在的作用域内解析,而这些名字的求值过程发生在函数调用时
void f2()
{
def='*';
sz wd=100;
window=screen();
}
由于在函数f2内部改变了def的值,所以对screen的调用将会传递这个更新过的值,另一方面,虽然我们的函数还声明了一个局部变量用于隐藏外层的wd,但是该局部变量与传递给screen的默认实参没有任何关系
constexpr 函数
constexpr函数是指能用于常量表达式的函数:函数的返回类型及所有形参的类型都得是字面值类型,而且函数体中必须有且只有一条return语句。
constexpr size_t scale(size_t cnt) {return new_sz()/*new_sz()是一个constexpr函数*/*cnt}
当scale的实参是常量表达式时它的返回值也是常量表达式,反之则不然。
constexpr函数不一定返回常量表达式内联函数和constexpr函数通常定义在头文件中:因为内联函数和constexpr函数可以在程序中多次定义,每个调用该函数的原文件中都要有inline定义,故放在头文件中
6.7 函数指针
- decltype返回函数类型,此时不会将函数类型自动转换成指针类型
typedef decltype(lengthCompare) *FuncP;//FuncP为函数指针
using F=int(int*,int)//F是函数类型,不是指针
using PF=int(*)(int*,int)//PF是指针类型
必须时刻注意的而是,和函数类型的形参不一样,返回类型不会自动第转换成指针。我们必须显式地将返回类型指定为指针
F* f1(int)
还可以直接声明f1
int (*f1(int))(int* int);
还可以用尾置返回类型声明一个返回函数指针的函数
auto f1(int)->int(*)(int*,int);
还可以使用decltype,当我们将decltype作用于某个函数时,他返回函数类型而非指针类型,因此我们显示加上*以表明我们需要返回指针,而非函数本身
decltype(sumLength) *getFcn(const string&);