查漏补缺——函数(C++ Primer)

来源:互联网 发布:系统备份软件 编辑:程序博客网 时间:2024/05/16 12:00

1、const形参和实参

(1)当用实参初始化形参时会忽略掉顶层const(作用于对象本身),换句话说,形参的顶层const被忽略掉了。当形参有顶层const时,传给它常量对象或非常量对象都是可以的:

void fcn(const int i){/*fcn能够读取i,但是不能向i写值*/}//忽略掉形参的顶层const可能会产生意想不到的结果:void fun(const int i);void fun(int i);   //错误:重复定义了fun(int)

(2)我们可以使用一个非常量初始化一个底层const对象,但是反过来不行;同时一个普通的引用必须用同类型的对象初始化(不能用字面值初始化一个非常量引用)。形参的初始化方式和变量的初始化方式是一样的。

我们不能把const对象、字面值或者需要类型转换的对象传递给普通的引用形参。



2、数组形参

(1)数组有两个特殊的性质:不允许拷贝数组;使用数组时(通常)会将其转换成指针

因为不能拷贝数组,所以我们不能以值传递的方式使用数组参数。因为数组会被转换成指针,所以当我们为函数传递一个数组时,实际上传递的是指向数组首元素的指针。


尽管不能使用以值传递的方式传递数组,但是我们可以把形参写成类似数组的形式:

//尽管形式不同,但是这三个print函数是等价的,每个函数都有一个const int*的形参void print(const int*);void print(const int[]);void print(const int[10]);  //数组的大小对函数的调用没有影响//当编译器处理对print函数的调用时,只检查传入的参数是否是const int*类型

因为数组是以指针形式传递给函数的,所以函数并不知道数组的确切尺寸,调用者应该为此提供额外的信息。有三种常用的技术:数组本身包含一个结束标记(比如C风格的字符串以空字符结尾);传递指定数组尾元素和尾后元素的指针;专门定义一个表示数组大小的形参。

(2)只有当函数确实要改变元素值得时候,才把形参定义成指向非常量的指针,否则数组的形参应该设置成指向const的指针。

(3)将变量定义成数组的引用,注意维度是类型的一部分

void print(int (&arr)[10]) //&arr两端的括号必不可少{    for(auto elem : arr)          cout<<elem<<endl;}

//再一次强调int *matrix[10];  //10个指针构成的数组int (*matrix)[10];  //指向含有10个整数的数组的指针


3、引用返回左值

调用一个返回引用的函数得到左值,其他返回类型得到右值。可以像使用左值那样来使用返回引用的函数的调用,特别的,我们能为返回类型是非常量引用的函数的结果赋值。



4、主函数main的返回值

我们允许main函数没有return语句直接结束,这时候编译器将隐式插入一条返回0的return语句。

main函数的返回值可以看做是状态指示器,返回0表示执行成功,返回其他值表示执行失败。

cstdlib头文件中定义了两个预处理变量,我们可以用这两个变量分别表示成功或失败。使用return EXIT_FAILURE 或return EXIT_SUCCESS


5、函数的重载

我们知道,使得被修饰的变量本身无法改变的const是顶层const,其他的通过指针或引用等间接途径来限制目标内容不可变的const是底层const。

函数重载中的函数匹配,区分底层const,不区分顶层const


重载与作用域的关系:如果我们在内层作用域中声明名字,它将隐藏外层作用域中声明的同名实体,在不同作用域中无法重载函数名。

一旦在当前的作用域中找到了所需的名字,编译器就会忽略掉外层作用域中的同名实体,剩下的工作就是检查函数调用是否有效了。所以在不同的作用域中对函数的重载是失效的。



6、内联函数和constexpr函数

(1)内联函数可避免函数调用的开销:内联函数在它的每个调用点上“内联的”展开。而一般的函数调用包含一系列的工作:调用前要先保存寄存器,并在返回时恢复,可能需要拷贝实参,程序要转向一个新位置执行等。

在函数的返回类型前加上关键字inline即可声明为内联函数。内联机制用于优化规模较小、流程直接、频繁调用的函数。

(2)constexpr函数指能用于常量表达式的函数:定义constexpr函数要遵循几个约定:函数的返回类型及所有的形参的类型都是字面值类型,不过该函数不一定返回常量表达式;函数体中必须有且只有一条return语句

执行constexpr函数初始化任务时,编译器把对constexpr函数的调用替换成其结果值。为了能在编译过程随时展开,constexpr函数被隐式地指定为内联函数。


内联函数和constexpr函数通常定义在头文件中。和其他函数不一样,他们可以在程序中多次定义,但要保证多个定义必须完全一致。


7、调试帮助

(1)assert预处理宏

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

assert(expr);

首先对expr求值,表达式为假(0)时,assert输出信息并终止程序的执行,如果表达式为真(非0),assert什么也不做

(2)assert的行为依赖于一个名为NDEBUG的预处理变量的状态,如果定义了NDEBUG则assert什么也不做,默认状态下没有定义NDEBUG,assert将执行运行时检查。

#define NDEBUG

我们把assert和NDEBUG当成是一种调试程序的辅助手段,不能代替真正的运行时的逻辑检查,也不能代替程序本身应该包含的错误检查。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 驾驶证被注销后超过两年怎么办 a2照驾驶证年审过期一个月怎么办 车被别人追尾行驶证过期怎么办 骑魔头车没驾照车祸保险拒赔怎么办 行驶证过了两个多月没年检怎么办 驾照没满一年扣了3分怎么办 6年免检但是行驶证到期怎么办 驾驶证和行驶证一起丢了怎么办 身份证驾驶证行驶证一起丢了怎么办 在银行柜圆机取款时忘了取卡怎么办 中国建设银银行取款密码忘了怎么办 买到证件不全的二手电动车怎么办 光大乐惠金卡信用卡还了怎么办 增驾期间被扣3分怎么办 a2驾驶证被扣12分后怎么办 我手机换号码了驾驶证档案怎么办 手机号码换了查不到驾照分了怎么办 金牛区源泉幼儿园摇不到号怎么办 b2驾驶证被扣12分后怎么办 福建省超过一年驾照未年审要怎么办 为缓解交通拥堵现状人们应该怎么办 告对方不知道对方出身日期怎么办 上海业余围棋4进3老不过怎么办 孩子想上学但又怕同学议论怎么办 在菲律宾黑了博彩老板的钱怎么办 九阴真经3d先遣服更新失败怎么办 公司核名通过不想用了怎么办 公司核名下来了不想注册了怎么办 家人受到小贷公司催款威胁怎么办 商标抽签资料提交上去有问题怎么办 花椒直播助手苹果版下载不了怎么办 在香港酒店住把床单弄上血了怎么办 综英美我能怎么办我也很绝望百度云 护照的名字中间有个空格怎么办 开车不小心压死黄鼠狼了怎么办 三户联保贷款一方不还怎么办 因为隔断中介违约…我该怎么办 上海居住证没下来换住址了怎么办 工商注册后大股东不注资怎么办 公司不给去办理变更股东信息怎么办 滴滴车主注册没有自己的车型怎么办