【c++ primer 笔记】第六章 函数

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
2)通过const转换实现的匹配
3)通过类型提升实现的匹配
4)通过算术类型转换或指针转换实现的匹配
5)通过类类型转换实现的匹配

12.函数指针
声明一个函数指针
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,与返回数组类型相似

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值