菜狗的C++ primer读书笔记:第六章 函数

1.调用运算符:形式是一对圆括号,它作用于一个表达式,该表达式是函数或者指向函数的指针。调用表达式的类型就是函数的返回类型。调用运算符的优先级和点运算符及箭头运算符是相同的,并且也符合左结合律。
2.函数的调用完成两项工作:一是用实参初始化函数对应的形参,二是将控制权转移给被调用函数。此时,主调函数的执行被暂时中断,被调函数开始执行。
3.尽管实参与形参存在对应关系,但是并没有规定实参的求值顺序。编译器能一任何可行的顺序对实参求值。
4.函数的返回类型不能是数组类型或函数类型,但可以是指向数组或函数的指针。
5.形参和函数体内部定义的变量统称为局部变量,仅在函数的作用域内可见,同时局部变量还会隐藏在外层作用域中同名的其他所有声明中。
6.局部静态变量:用static定义,其直到程序终止才被销毁,在此期间即使对象所在函数结束执行也不会对它有影响。如果局部静态变量没有显式的初始值,它将执行值初始化。内置类型的局部静态变量初始化为0。
7.函数应该在头文件中声明,在源文件中定义,这样可以确保同一函数的所有声明保持一致。
8.参数传递中的传值调用包括指针形参,当执行指针拷贝操作时,拷贝的是指针的值。拷贝之后,两个指针是不同的指针。
9.C++语言中,建议使用引用类型的形参代替指针。
10.拷贝大的类类型对象或者容器对象比较低效,甚至有的类类型(包括IO类型在内)根本就不支持拷贝操作。在这些情况下,最好通过引用形参访问该类型的对象。
11.如果函数无须改变引用形参的值,最好将其声明为常量引用。使用引用而非常量引用也会极大限制函数所能接受的实参类型,不能把const对象、字面值或者需要类型转换的对象传递给普通的引用形参。
12.当形参有顶层const时,传给他常量对象或者非常量对象都是可以的,同其他初始化一样顶层const被忽略掉了。我们可以使用非常量初始化一个底层const对象,但是反过来不行。
13.因为数组是以指针的形式传递给函数的,调用者应该为此提供一些额外的信息。管理指针形参有三种常用的技术。
①.使用标记指定数组长度。适用于有明显结束标记且该标记不会与普通数据混淆的情况。
②.使用标准库规范。传递指向数组首元素和尾后元素的指针。
③.显示传递一个表示数组大小的形参。
14.使用数组引用形参时,因为数组的大小也是构成数组类型的一部分,所以只要不超过维度就可以在函数体内放心地使用数组。但这样也限制了函数的可用性,只能将函数作用于大小固定的数组。
15.传递多维数组时,因为我们处理的是数组的数组,所以首元素本身就是一个数组,指针就是一个指向数组的指针。数组第二维(及后面所有维度)的大小都是数组类型的一部分不能省略。
16.有时我们需要给main传递实参,一种常见的情况就是用户通过设置一组选项来确定函数所要执行的操作。
int main(int argc , char *argv[])第二个形参argv是一个数组,它的元素是指向C风格字符串的指针;第一个形参argc表示数组中字符串的数量。当使用argv中的实参时,可选的实参从argv[1]开始,argv[0]保存程序的名字而非用户输入。
17.如果函数的是参数两未知但是全部实参的类型都相同,我们可以使用initializer_list类型的形参。(标准库类型,用于表示某种特定类型的值的数组,定义在同名的头文件中)
18.和vector一样,initializer_ list也是一种模板类型,定义时说明列表中所含元素的类型,不一样的是initializer_list对象中的元素永远是常量值,无法改变。
19.一个返回类型为void的函数也能使用return语句,不过此时return语句的expression必须是另一个返回void的函数。
20.返回一个值的方式和初始化一个变量或形参的方式完全一样:返回的值用于初始化调用点的一个临时量,该临时量就是函数调用的结果。
21.不要返回局部对象的引用和指针。函数完成后,它们所占用的存储空间也被随之释放掉,不再指向有效的内存区域。
22.函数的返回类型决定函数调用是否是左值,调用一个返回引用的函数返回左值,其他返回类型得到右值。
23.C++11规定,函数可以返回花括号包围的值的列表。如果返回的是内置类型,则花括号列表最多包含一个值,而且该值所占空间不应该大于目标类型的空间。如果函数返回的是类类型,有类本身定义初始值如何使用。
24.
①.要想定义一个返回数组的指针或引用的函数比较麻烦,但有些方法可以简化这一任务,其中最直接的方法是使用类型别名。
typedef int arrT[10] ; using arrT = int[10] ;其中arrT 是含有10个整数的数组的别名。
②.要想在声明返回数组指针的函数时不使用类型别名,我们必须牢记被定义的名字后面的数组的维度。
Type (*function(parameter_list)) [dimension]
③.C++11中还有一种可以简化声明的方法,使用尾置返回类型。任何函数都能使用,但是这种形式对于返回类型比较复杂的函数最有效。
auto func(int i) -> int (*) [10];
④.如果我们知道函数返回的指针将要指向哪个数组,可以使用decltype关键字声明返回类型。
25.对于重载函数来说,它们应该在形参数量或形参类型上有所不同。不允许两个函数除了返回类型外其他所有的要素都相同。
26.如果形参是某种类型的指针或引用,则通过区分其指向的是常量对象还是非常量对象可以实现函数重载,此时的const是底层的。当我们传递一个费常量对象或指向非常量对象的指针时,编译器会优先选用非常量版本的函数。
27.函数匹配可能会产生三种结果
①.编译器找到一个与实参最佳匹配的函数
②.找不到任何一个参数与调用的实参匹配,此时编译器发出无匹配错误。
③.有多于一个函数可以匹配,但没一个都不是最佳匹配,此时将产生二义性调用错误。
28.重载对作用域的一般性质没有什么改变:如果我们在内层作用域中声明名字,它将隐藏外层作用域中声明的同名实体。在不同作用域中无法重载函数名。
29.如果某个形参被赋予了默认值,它后面所有形参都必须有默认值。函数调用时实参按其位置解析,默认实参负责填补函数调用缺少的尾部实参。当设计含有默认实参的函数时,其中一项任务是合理设置形参的顺序,尽量让不怎么使用默认值的形参出现在前面,而让那些经常使用默认值的形参出现在后面。
30.将函数指定为内联函数,通常就是将它在每个调用点上内联地展开。一般来说,内联机制用于优化规模较小、流程直接、频繁调用的函数。
31.constexpr函数的返回类型及所有形参的类型都得是字面值类型,而且函数体中必须有且只有一条return语句。为了能在编译过程中随时展开,constexpr函数被隐式定义为内联函数。
32.内联函数和constexpr函数通常定义在头文件中。
33.C++有时会用到一种类似于头文件保护的技术,以便有选择地执行调试代码。基本思想是,程序可以包含一些用于调试的代码,但是这些代码只在开发程序时使用。当应用程序编写完成时,要先屏蔽掉调试代码。这种方法用到两项预处理功能:
第一项是assert:assert是一种预处理宏,使用一个表达式作为条件,assert(expr),首先对expr求值,如果表达式为假,assert输出信息并终止程序的执行。assert宏定义在cassert头文件中。无需使用using声明且宏名字在程序内必须唯一。assert宏常用于检查“不能发生”的条件。assert应该仅用于验证那些确实不可能发生的事情,可以把assert当成调试程序的一种辅助手段,但是不能用它替代真正的运行时逻辑检查,也不能替代程序本身应该包含的错误检查。
第二项是NDEBUG预处理变量:assert的行为依赖于这个预处理变量的状态。若定义了NDEBUG则assert什么也不做,默认状态下没有定义NDEBUG此时assert将执行运行时检查。除此之外,也可以使用NDEBUG编写自己的条件调试代码。
34.函数匹配:
第一步:选定本次调用对应的重载函数集合,集合中的函数称为候选函数,候选函数有两个特征:一是与被调用的函数同名,二是其声明在调用点可见。
第二步:考察本次调用提供的实参,然后从候选函数中选出能被这组实参调用的函数,这些新选出的函数称为可行函数。可行函数也有两个特征:一是其形参数量与本次调用的提供的实参数量相等,二是每实参的类型与对应的形参类型相同,或者能够转换成形参的类型。
第三步:从可行函数中选择与本次调用最匹配的函数,基本思想是实参类型与形参类型越接近他们匹配得越好。
如果有且只有一个函数满足下列条件,则匹配成功:
①该函数每个实参的匹配都不劣于其他可行函数需要的匹配。
②至少有一个实参的匹配优于其他可行函数提供的匹配。
35.调用重载函数时应尽量避免强制类型转换。如果在实际应用中确实需要强制类型转换,则说明我们设计的形参集合不合理。
36.编译器将实参类型到形参类型的转换分成几个等级:
①精确匹配(实参和形参类型相同、实参从数组类型或函数类型转换成对应的指针类型、向实参添加顶层const或者从实参中删除顶层const)
②通过const转换实现的匹配
③通过类型提升实现的匹配
④通过算术类型转换或指针转换实现的匹配
⑤通过类类型转换实现的匹配
37.函数指针指向的是函数而非对象。和其他指针一样,函数指针指向某种特定类型。函数的类型由它的返回类型和形参类型共同决定,与函数名无关。例如 bool (*pf)( const string& , const string&);
38.当我们把函数名作为一个值使用时,该函数自动地转换成指针。(取地址符可选)。我们可以为函数指针赋一个nullptr或者值为0的整型常量表达式,表示该指针没有指向任何一个函数。
39.使用重载函数的指针时,指针类型必须与重载函数中的某一个精确匹配。
40.和数组类似,虽不能定义函数类型的形参,但是形参可以是指向函数的指针。此时形参看起来是函数类型,实际上确实当成指针使用。虽然不能返回一个函数,但是却能返回指向函数类型的指针。需要注意的是decltype返回函数类型,此时不会将函数类型自动转换成指针类型。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值