1、函数其实是一个命名的代码块,参数的个数可以是0个也可以是多个参数,通常会产生一个结果,可以重载。
2、调用函数是通过调用运算符进行函数调用。调用运算符作用于一个表达式,表达式是函数或者指向函数的指针。
3、调用表达式的类型就是函数返回的类型。实参是形参的初始值。函数返回类型不能是函数类型或数组类型,但是可以是指向数组或函数的指针。
4、主调函数的实参去初始化被调函数的形参是隐式地初始化。函数的return语句的作用有两方面:一方面是返回return语句后的值,二是从被调函数返回到主调函数。
5、main()和man(void)是等价的,只不过前者是隐式地定义空参数列表,而后者是显式地定义了空参数列表。
6、即使某个形参不被函数用到,也必须给它提供一个实参。
7、C++中,名字有作用域,而对象有生命周期,名字在作用域中可见,对象的生命周期则是指创建到销毁的这段时间。
8、形参和函数体内定义的变量称为局部变量,仅在函数的作用域内可见,也会隐藏在外层作用域的同名函数的其他所有声明。
9、只存在于块执行期间的对象称为自动变量。对于局部变量对应的自动对象来说,可以分成两种情况:一种是如果变量本身含有初始值,就用初始值进行初始化。另一种是如果变量没有初始值,那么执行默认初始化。
10、局部静态对象在程序执行路径第一次经过这个对象,会对其进行初始化,然后直到程序终止后才被销毁,此时就算对象所在函数结束,也不会销毁这个对象。若局部静态对象没有进行初始化,那么将会进行值初始化,内置类型会被初始化为0.
11、函数可以声明多次,但是只能定义一次,声明时可以省略形参,但是一般建议保留,便于理解函数功能。函数声明也叫作函数原型。
12、分离式编译,就是把程序分离成几个文件,分开编译。
13、有时因为我们无法预知应该向函数提供多少个实参,为了能编写能处理不同数量实参的函数,C++11提供了两种主要的方法:1)如果函数所有实参的类型相同,则可以传递一个initializer_list的标准库类型。2)若实参的类型不相同,那么可以编写可变形参函数模板。C++的特殊的形参类型(省略符)用来传递可变数量的实参。(一般只用于在与C函数交互的接口程序)
14、没有返回值的return,只能用在void类型的函数中,(有一个例外,主函数main的return语句也可以没有,这样编译器会隐式地添加return 0语句。)这类函数不一定要有return语句,它会在函数最后隐式地执行return。return语句表示函数到此终止,并返回到调用的它的位置。
15、void类型的函数的return语句后面也可以跟上值,但是这个值必须是另一个void类型函数。
16、函数返回值的类型必须与函数返回类型一致,或者能隐式地转换成函数返回类型。
17、在含有return语句的循环后面应该也有一条return语句,如果没有的话该程序就是错误的,很多编译器检测不出来。
18、返回的值用于初始化调用点的一个临时量。即将返回的值拷贝到调用点的临时量。若返回的是一个引用,那么就不会涉及到拷贝值,也就是返回的结果不会拷贝返回的值。
19、不要返回局部对象的引用或指针。函数的终止,将使局部对象的引用指向不再有效地内存区域。同样的道理,返回局部对象的指针也是错误的。使用引用作为返回值,在内存中不会产生返回的值的副本。
20、我们可以使用函数调用运算符和点运算符、箭头运算符一起使用,因为他们的优先级相同,并且满足左结合律。
21、调用一个返回引用的函数得到左值,其他返回类型得到右值。可以为一个返回类型为非常量引用的函数得到的左值进行赋值。
22、C++11标准规定,函数可以返回花括号包围的值的列表。若列表为空,则对调用点临时量的初始化执行值初始化,例如容器对象,则初始化为空的容器对象;否则返回的值,由函数返回类型决定。
若返回的类型是内置类型,则花括号中的列表最多包含一个值,且值所占空间大小不大于目标空间大小。若是类类型,则由类本身决定如何进行初始化。
23、主函数main的返回值可以看作是状态指示器,0表示执行成功,其他值根据机器而定,表示执行失败。在头文件cstdlib中定义了两个预处理变量(EXIT_FAILURE、EXIT_SUCESS),根据这两个变量可以分别表示成功与失败。它们是预处理变量不在std中。
24、递归函数拥有一个终结递归循环的条件,否则只有等到程序栈空间耗尽为止。
25、若引用引用的是在函数之前已经存在的对象,那么返回引用有效。若想给数组的引用赋值那么直接使用数组名即可。
26、函数不能返回数组类型,但是可以返回数组的指针或引用,虽然有些烦琐,但是可以使用类型别名。
27、若不想使用数组别名,那么定义的返回数组指针的函数,数组的维度要放在函数形参表的后面。即Type (*function(parameter_list)) [dimension] 注意,最外围的 圆括号必须存在,表示强调返回值是一个指针,否则返回的是指针数组。
28、C++11提供了尾置返回类型来简化上述函数声明,任何函数都可以使用位置返回类型,不过一般使用在返回类型复杂的函数,其在函数形参列表之后以->开头跟上尾置返回类型,并在原先函数返回值的位置添加auto。
29、若知道函数返回的数组指针类型指向哪个数组,那么可以使用decltype关键字声明返回类型。decltype后括号内的若是数组,则其结果为数组,不会像auto一样转换成指针,所以还需要加上*表示其返回数组指针。
30、若函数的名字相同形参列表(形参数量,和形参类型)不同,则称为重载函数。main函数不能重载。函数名字仅仅是告诉编译器它要调用哪个函数,重载函数根据调用点的实参类型推断编译器应该调用哪个函数。
31、不允许两个函数除了返回类型不同外其他都相同。函数形参列表中的参数名起到记忆的作用,可以省略。
32、传给形参的对象,忽略顶层const,因此不能用是否拥有顶层const的形参进行区分其类型不同,但是底层的const可以用来区分。const不能转换成其他类型,但是非常量可以转换成const。
33、当我们传递一个非常量对象或者指向常量的指针,那么若有这两个形参类型的重载函数,则编译器会优先选择非常量版本的函数。
34、重载函数应该使用在那些非常相似的操作,在某些情况下,使用不同的名字的函数,方便于理解。
35、函数匹配是一个过程,即在调用过程中将实参与一组重载函数的某一个函数关联起来,或者称为重载确定。当形参数量相同,类型可以相互转换,此时选择使用哪个函数就较为困难。
36、调用重载函数有三种情况:1)找到了最佳匹配的函数,调用该函数;2)找不到一个重载函数可以与实参匹配,此时编译器会发出无匹配的错误;3)有多个可以与实参进行匹配,但是没有一个是最佳匹配,这时候就会产生二义性。
37、函数声明不要放在局部作用域里。若在内层作用域声明了名字,那么将隐藏外层作用域的同名实体,注意:是在内层作用域声明了名字,若没有声明名字,则外层作用域的函数变量就不会被隐藏。C++中查找名字发生在类型检查之前。
38、函数匹配,就是用于当函数形参个数相同,并且形参类型可以由其他类型转换而来时。
39、函数匹配首先选定本次调用的候选函数的重载函数集合。作为候选函数有两个特征:1)与被调用函数名相同;2)其声明在调用点可见。
接着是检查本次调用的函数实参,从候选函数中选出能被实参调用的可行函数。作为可行函数有两个特征:1)形参数量与本次调用的实参数量相同;2)每个实参类型与对应形参类型相同或者能转换成形参类型。
最后是从可行函数中找到最佳的匹配的函数。实参与形参之间类型越接近,它们匹配的越好。在含有多个形参的函数匹配中,其匹配规则如下:1)该函数的每个实参的匹配都不劣于其他可行函数需要的匹配。
2)至少有一个实参的匹配优于其他可行函数提供的匹配。
40、若没有找到可行函数,那么编译器会报出无匹配函数的错误。调用重载函数时,应该尽量避免强制类型转换。
41、实参到形参的最佳匹配分为几个等级,具体排序如下:1)精确匹配。2)通过const转换实现的匹配。3)通过类型提升实现的匹配。4)通过算术类型转换或指针转换实现的匹配。5)通过类类型转换实现的匹配。
42、所有算术类型转换级别都是一样的。当重载函数通过是否是底层const来区分,这时候通过实参是否是常量来选择调用哪个函数。