《C++ Primer》第6章函数

mac2024-08-10  53

6.1 函数基础

我们通过调用运算符来执行函数。调用运算符的形式是一对圆括号,它作用于一个表达式,改表达式是一个函数或者指向函数的指针。

形参和实参 实参是形参的初始值。第一个实参初始化第一个形参,第二个实参初始化第二个形参,以此类推。尽管实参与形参存在对应关系,但是没有规定实参的求值顺序。编译器能以任意可行的顺序对实参求值。

局部对象 自动对象:我们把只存在于块执行期间的对象称为自动对象。当块执行结束后,块中创建的自 动对象的值就变成未定义的了。 局部静态对象:局部静态对象在程序的执行路径第一次经过对象定义语句时初始化,并且直到程序结束终止才被销毁,在此期间即使对象所在的函数结束执行也不会对它有影响。

函数声明 函数的三要素(返回类型、函数名、形参类型)描述了函数的接口,说明了调用该函数所需的全部信息。函数声明也称作为函数原型。 在头文件中进行函数声明

6.2 参数传递

当形参是引用类型时,我们说它对应的实参被引用传递或者函数被传引用调用。 当实参的值被拷贝给形参时,形参和实参是两个相互独立的对象。我们说这样的实仓被值传递或者函数被传值调用。 使用引用避免拷贝,如果函数无需改变引用形参的值,最好将其声明为常量引用。

尽量使用常量引用 把函数不会改变的形参定义成引用是一种比较常见的错误,这么做带给函数的调用者一种误导,即函数可以修改它的实参的值。此外,使用引用而非常量引用也会极大地限制函数所能接受的实参类型。我们不能把const对象、字面对象或者需要类型转换的对象给普通的引用形参。 数组形参 不允许拷贝数组以及使用数组时会将其转换成指针,我们通常需要显式传递一个表示数组大小的形参。 传递多维数组 C++语言实际上没有多维数组,所谓多维数组其实是数组的数组。因为我们处理的是数组的数组,所以首元素本身就是一个数组,指针就是一个指向数组的指针。数组第二维的大小都是数组类型的指针,不能省略。

void print(int (*matrix)[10], int rowsize); void pirnt(int maxtrix[][10], int rowsize);

main:处理命令行选项

int main(int argc, char *argv[])

第二个形参是一个数组,它的元素是指向C风格字符串的指针;第一个形参表示数组中字符串的数量。当实参传给main函数之后,argv的第一个元素指向程序的名字或者一个空字符串,接下来的元素依次传递命令行提供的实参。最后一个指针之后的元素值保证为0

含可变形参的函数 为编写能处理不同数量实参的函数,C++11新标准提供了两种主要的方法:如果所有的实参类型相同,可以传递一个名为Initializer_list的标准库类型。

initializer_list<T> lst; initializer_list<T> lst{a,b,c}; lst2(lst); lst.size(); lst.begin(); lst.end();

和vector不一样的是,initializer_list对象中的元素永远是常量值,我们无法改变initializer_list对象中元素的值。

6.3 返回类型和return语句

引用返回左值 调用一个返回引用的函数得到左值,其他返回类型得到右值,和其他左值一样它也能出现在赋值运算符的左侧。 列表初始化返回值 C++11新标准规定,函数可以返回花括号包围的值列表。例如一个vector对象。

返回数组的指针 typedef int arr[10]; arr* func(int i);//func返回一个指向含有10个整数的数组的指针 int (*func(int i))[10];//同上

使用尾置返回类型 C++11中新增尾置返回类型,尾置返回类型跟在形参列表后面并以一个->符号开头。为了表示函数真正的返回类型跟在形参列表之后,我们在本应该出现返回类型的地方放置一个auto。

auto func(int i) -> int(*) [10];//返回一个指针,指向含有10个整数数组 auto func(int i) -> string(&) [10];//返回数组的引用,数组包含10个string对象

6.4 函数重载

重载和const形参 顶层const不影响传入函数的对象。一个拥有顶层const的形参无法和另一个没有顶层const的形参区分开来。 调用重载函数 函数匹配也叫重载确定。编译器首先将调用的实参与重载集合中每一个函数的形参进行比较,然后根据比较结果决定到底调用哪个函数。

6.5 特殊用途语言特性

默认实参 一旦某个形参被赋予了默认值,它后面的所有形参都必须有默认值,防止出现二义性。通常,应该在函数声明中指定默认值,并将该声明放在合适的头文件中。

constexpr函数 constexpr函数指能用于常量表达式的函数。要遵循几项约定:函数的返回类型及函数的所有形参必须是字面值类型,而且函数体中必须有且只有一条return语句。 执行初始化任务时,编译器把对constexpr函数的调用替换成其结果值。为了能在编译过程中随时展开,constexpr函数被隐式地指定为内联函数。如果我们用一个非常量表达式调用constexpr函数,它将返回一个非常量表达式。 把内联函数和constexpr函数放在头文件中。

调试帮助 程序可以包含一些用于调试的代码,但是这些代码只在开发程序时使用。当应用程序编写完成准备发布时,要先屏蔽掉调试代码。这种方法用到两项预处理功能:assert和NDEBUG。

assert预处理宏 所谓预处理宏其实是一个预处理变量,它的行为有点类似于内联函数。 assert(expr);

首先对expr求值,如果表达式为假(即0),assert输出信息并终止程序的执行。 assert宏常用于检查“不能发生“的条件。 assert的行为依赖于一个名为NDEBUG的预处理变量的状态。如果定义了NDEBUG,则assert什么也不做。

6.6 函数匹配

确定候选函数和可行函数 第一步是选定本次调用对应的重载函数集,集合中的函数称为候选函数。候选函数具备两个特征:一是与被调用的函数同名,二是其声明在调用点可见。 第二步考察本次调用提供的形参,然后从候选函数中选出能被这组实参调用的函数,这些新选出的函数称为可行函数。可行函数也具有两个特征:一是其形参数量与本次调用提供的形参数量相等。二是每个实参的类型和对应的形参类型相同,或者能转换成形参的类型。 第三步是从可行函数中选择本次调用最匹配的函数。

6.7 函数指针

https://blog.csdn.net/zj1131190425/article/details/92065897

https://www.cnblogs.com/lvchaoshun/p/7806248.html

最新回复(0)