1.函数的返回类型不能是数组类型或函数类型,但可以是指向数组或函数的指针
返回数组的指针:
1)使用类型别名
typedef int arrT[10];
using arrT = int[10]; //与上面的声明等价
arrT* func(int i);
2)直接声明
int (*func(int i))[10];
3)使用尾置返回类型
auto func(int i) -> int(*)[10];
4)使用decltype
int odd[]={1,3,5,7,9};
decltype(odd) *arrPtr(int i);
因为decltypde并不把数组类型转换成对应的指针,所以decltype的结果只是个数组,要想表示arrPtr返回指针还必须在函数声明时加一个*
2.指针作为形参,当执行指针拷贝操作时,拷贝的是指针的值。拷贝之后,两个指针是不同的指针,即进行了值传递
3.当形参有顶层const时,传给他常量对象或非常量对象都可以。也就是说,仅仅根据有无顶层const无法实现两个相互重载的函数
void func(int i)
void func(const int i) //错误,重复定义了func
4.由于不允许拷贝数组,且使用数组时通常会将其转换成指针,所以当我们为函数传递一个数组时,实际上传递的是指向数组首元素的指针
以下三个定义是等价的
void print(const int*);
void print(const int[]);
void print(const int[10]); //这里的维度10并无效果,传递的仍只是一个指向const int的指针
所以,如果想指定数组的大小,就需要传递一个表示数组大小的形参,或者使用两个指针,分别指向数组的首和尾
5.数组引用形参
以下声明,形参是一个指向数组的引用
void print(int (&arr)[10]); //arr是一个有10个元素的整型数组的引用
与以下声明区别
void print(int &arr[10]); //声明成了引用的数组,而并不存在引用的数组
经过以上声明的函数,只能作用于大小为10的数组
6.传递多维数组
以二维数组为例,要传递的应该是一个指向一维数组的指针,这个一维数组是二维数组的首元素(数组传递的都是指向首元素的指针)
void print(int (*matrix)[10] , int rowSize); //传递一个大小为[rowSize][10]的二维数组
同样区分 int *matrix[10] 与 int (*matrix)[10] ,与上面引用类似
以下声明亦可
void print(int matrix[][10] , int rowSize);
7.含有可变数量形参的函数
如果函数的实参数量未知但全部实参类型相同,则可以使用initializer_list类型的形参
void error_msg(initializer_list<string> il);
initializer_list中的值都是常量值,无法改变其中元素的值
传递参数时,需要将参数序列放在一对花括号内
error_msg({"yes","no"});
8.引用返回左值
调用一个返回引用的函数返回左值,其他返回类型得到右值
char &get_val(string &str, string::size_type ix){
return str[ix];
}
int main()
{
string s("a value");
cout<<s<<endl; //输出a value
get_val(s,0)='A';
cout<<s<<endl; //输出A value
return 0;
}
9.默认实参
一旦某个形参被赋予了默认值,它后面的所有形参都必须有默认值
而且省略时只能省略尾部的实参,以下调用错误
window = screen( , , '?');
10.constexpr函数
函数的返回类型及所有形参的类型都得是字面值类型(算术类型,引用和指针),且constexpr函数被隐式地指定为内联函数
11.实参类型转换
排序:
1)精确匹配
- 实参类型和形参类型相同
- 实参从数组类型或函数类型转换成对应的指针类型
- 向实参添加顶层const或者从实参中删除顶层const
bool (*pf)(const string &, const string &);
bool b1 = pf("hello","goodbye");
bool b2 = (*pf)("hello","goodbye"); //与上面等价的调用
void useBigger(const string &s1 , const string &s2, bool pf(const string &,const string &)); //形参看起来是函数类型,实际上是当成指针使用的
void useBigger(const string &s1 , const string &s2, bool (*pf)(const string &,const string &)); //与上面声明等价
返回指向函数的指针
using F = int(int*,int); //F是函数类型
using PF = int(*)(int*,int); //PF是函数指针类型
PF f1(int);
F *f1(int); //与上面声明相同
int (*f1(int i))(int*,int); //直接声明
auto f1(int i) -> int(*)(int*,int); //尾置返回类型
使用decltype,与返回数组类型相似