函数
参数传递
数组形参
void print(const int*);
void print(const int[]);
void print(const *int[10]);
//等价
数组引用形参
void print(int (&arr)[10]){
for(auto elem : arr)
cout<<elem<<endl;
}
int i=0,j[2]={0,1};
int k[10]={0,1,2,3,4,5,6,7,8,9};
//printf(&i);实参不是含由10个整数的数组
//printf(j);实参不是含由10个整数的数组
printf(k);//实参时含有10个整数的数组
含有可变形参的函数
initializer_list形参
函数的实参数量未知但是全部实参的类型都相同 一种标准库类型,用于表示某种特定类型的值的数组
//initializer_lisr提供的操作
initoalizer_list<T> lst;
//默认初始化:T类型元素的空列表
initializer_list<T>lst{a,b,c...};
//lst的元素数量和初始值一样多,lst的元素时对应初始值的副本,列表中的元素是const
lst2(lst);
lst2=lst;
//拷贝或赋值一个initializer_list对象不会拷贝列表中的元素,拷贝后原始列表和副本共享元素
lst.size();
//列表中的元素数量
lst.begin();
//返回指向lst中首元素的指针
lst.end();
//返回指向lst中尾元素下一位置的指针
initializer_list对象中的元素永远是常量值
void error_msg(initializer_list<string> il){
for(auto beg = il.begin();beg != il.end();++beg)
cout<<*beg<<" ";
cout<<endl;
}
if (expected != actual)
error_msg({"functionX",expected,acutual});
else
error_msg({"functionX","okay"});
省略符形参
void foo(parm_list,...);
//指定了foo函数的部分形参类型
void foo(...);
返回类型
返回数组指针
typedef int attT[10];//arrT是一个类型别名,表示含有10个整数的数组
using arrT = int[10];
arrT* func (int i);
//func返回一个指向含有10个整数的数组的指针
声明一个返回数组指针的函数
数组的维度必须跟在函数名字之后,函数的形参列表也跟在函数名字后面且形参列表优先于数组维度
type(*function(parameter_list))[dimension];
int (*func(int i))[10];
使用尾置返回类型
auto func(int i)->int(*)[10];
//func接受一个int类型的实参,返回一个指针,该指针指向含有10个整数的数组
使用decltype
int odd[]={1,3,5,7,9};
int even[]={0,2,4,6,8};
decltype(odd)*arrPtr(int i){
return (i%2)?&odd:&even;
}
函数重载
重载和const形参
顶层const不影响传入函数的对象 一个拥有顶层const的形参无法和另一个没有顶层const的形参区分开
Record lookup(Phone);
//Record lookup(const Phone);
Record lookup(Phone*);
//Record lookup(Phone* const)
如果形参是某种类型的指针或引用,则通过区分其指向的是常量对象还是非常量对象可以实现函数重载,此时的const是底层的
Record lookup(Account&);
Record lookup(const Account&);
Record lookup(Account*);
Record lookup(const Account*);
特殊用途语言特性
默认实参
一旦某个形参被赋予默认值,则其后面的所有形参都必须有默认值
typedef string::size_type sz;
string screen(sz hr = 24,sz wid = 80,char backgend = ' ');
使用默认实参调用函数
string window;
window = screen();
window = screen(66); //66,80,' '
window = screen(66,256);
window = screen(66,256,'#');
默认实参声明
string screen(sz,sz,char = ' ');
//不能修改一个以及存在的默认值
//string screen(sz,sz,char='*');
//可以添加默认实参
string screen(sz=24,sz=80,char);
内联函数和constexpr函数
将函数指定为内联函数,就是将它在每个调用点上内联地展开 在函数的返回类型前加上关键字inline
constexpr函数
能用于常量表达式的函数 函数的返回类型即所有形参的类型都是字面值类型 函数体中必须有且只有一条return语句
函数指针
想要声明一个可以指向函数的指针,只需要用指针替换含函数名
bool lengthCompare(const string &,const string &);
bool (*pf)(const string &,const string &);
//pf指向一个函数,该函数的参数是两个const string的引用,返回值是bool
使用函数指针
pf = lengthCompare;
pf = lengthCompare;
//pf指向名为lengthCompare的函数
//可以直接使用指向函数的指针调用该函数,无须提前解引用指针
bool b1 = pf("hellp","goodbye");
bool b2 = (*pf)("hello","goodbye");
bool b3 = lengthCompare("hellp","goodbye");
函数指针形参
void useBigger(const string &s1,const string &s2,bool pf(const string &,const string &));
void userBigger(const string &s1,const string &s2,bool (*pf)(const string &,const string &));
useBigger(s1,s2,lengthCompare);
返回指向函数的指针
使用类型别名
using F = int(int*,int);
//F是函数类型不是指针
using PF = int(*)(int*,int);
//PF是指针类型
//函数返回裂隙不会自动地转换成指针,必须显式将返回类型指定为指针
PF f1(int);
//F f1(int);F为函数类型,f1不能返回一个函数
F *f1(int);
将auto和decltype用于函数指针类型
string::size_type sumLength(const string&,const string&);
string::size_type largerLength(const string&,const string&);
decltype(sumLength)*getFcn(const string &);