1.返回指向数组/函数的指针
顾名思义,就是函数返回值为指向数组/函数的指针。
数组的性质:不能被拷贝,函数也不能返回数组。但可以返回数组指针/引用,声明一个返回数组指针的函数,有四种方式,一种是直接声明,格式为:
int (*func(int i) [10]; //函数声明
第二种是使用using/typedef类型别名来简化:
typedef int arr[10]; /using arr=int[10]; //定义类型别名和数组等效
arr *func(int i); //函数声明
第三种是采用C++11提供的尾后返回类型的方式来声明数组指针,具体格式如下:
auto func(int i) -> int(*)[10];
第四种是知道数组指针指向那种类型的数组情况下,可以采用decltype获得数组类型(decltype,sizeof,typeid不会让数组退化为指针),具体格式如下:
int array[10] = { 0 };
decltype(array) *func(int i);
函数指针是采用需要声明的指针名替换函数名来完成函数指针的声明,函数指针由函数的返回值和参数列表类型共同决定。其声明、赋值和调用如下所示:
bool LengthCompare(const string & , const string &); //函数声明
bool(*pf)(const string & , const string &); //函数指针声明
pf=LengthCompare; //函数指针赋值
pf=&LengthCompare; //函数指针赋值
bool b1 = pf("hello”,“good”); //直接调用,等价于bool b3=LengthCompare("hello”,“good”);
bool b2 = (*pf)("hello”,“good”); //解引用调用
函数指针作为C语言的半壁江山,其可以作为函数的形参,来实现一类函数的功能,从来增加代码的鲁棒性。具体代码如下:
void usebigger(const string &s1,const string&s2, bool pf(const string &,const string &));//函数指针做形参,pf替换为(*pf)一样
使用using/typedef可以简化上述的过程,具体代码如下:
typedef bool func(const string &,const string&)/typedef decltype(LengthCompare) funcz;//声明func/funcz为函数类型;
typedef bool (*funcp)(const string &,const string&)/typedef decltype(LengthCompare) *funcp2;//声明funcp/funcp2函数指针类型
void usebigger(const string&,const string&,func/funcp2);//函数形参为函数指针,函数名做形参时可做函数指针用
另外函数指针也可以作为返回值使用,具体形式为:
int (* f1(int) )(int * , int); //声明一个函数指针,数指针指向的是一个参数列表为int*和int,返回值为int的函数。
使用尾置返回类型的方式声明一个返回函数指针的函数,格式为:
auto f1(int) -> int (*)(int * , int);
2.函数重载
函数重载的条件:相同作用域,同名函数,不同参数列表。其中返回类型和参数列表中的顶层const不能作为函数重载的依据。如果同名函数不在同一作用域内,但在同一个文件中,则属于函数覆盖。
重载函数调用时,如有多个函数满足,则优先考虑不用隐式转换的版本。
const_cast可以用于改变运算对象的底层const属性,可以用于增加const属性或者去除const属性,这里很容易理解错说const_cast只能用于去除原因对象的const属性,《C++ Primer 第五版》p209的例子可以看出const_cast的另外一种用法。
在查找const_cast相关博客介绍过程中,无意之间发现了一个程序中的专业名词“常量折叠”,具体意思在编译期间简化常量表达式的一个过程,简单来说就是将常量表达式计算求值,并对求得的值来替换表达式,放入常量表中,具体详细的情况可参考博客:https://blog.csdn.net/it_wjw/article/details/86668302
3.默认形参、inline函数和constexpr函数
函数的默认形参就是在调用时函数可以不给实参,此时函数的形参采用默认参数值,多用于某些函数参数值固定的情况。默认形参之后就不能再出现需要初始化的形参。
内联函数(inline函数)用于优化规模较小、流程直接、使用频繁的函数,使用内联函数能够省去函数的出入栈过程和参数的拷贝过程,但是inline只是对编译器的一个请求,编译器可以忽略这个请求。inline函数的实质是在调用函数的地方直接把函数替换调用函数。
constexpr函数:通常用于常量表达式的函数(通常会被隐式inline化)。要求:返回类型和形参类型(应该是实参的带入值)都是字面值常量;函数体有且仅有一条return语句;函数体中的语句在运行时不执行任何操作。
由于inline和constexpr函数都属于函数调用时直接将函数体和调用函数替换的情形,因此inline和constexpr函数应该讲定义放在头文件中,另外这两种函数可以在多个文件中重复定义,但必须保证多个定义完全相同。**新知识点
4.调试代码工具
assert(断言,头文件在cassert中);用于辅助验证不可能发生的事情。assert括号中的条件为真,则对程序无影响,否则程序停止运行。
NDENUG 预处理变量,如果定义了这个预处理变量,不执行assert,没有定义这个预处理变量,则执行assert(默认)。
预处理器提供5个预处理器定义的程序调试名字:
_ _ func _ _:输出当前调试函数的名字
_ _ FILE _ _:输出当前文件名的字符串字面值
_ _ LINE _ _:输出当前行号的整型字面值
_ _ TIME _ _:输出当前文件编译时间的字符串字面值
_ _ DATE _ _:输出当前文件编译日期的字符串字面值