文章目录

  • 默认实参
    • 使用默认实参调用函数
    • 默认实参声明
    • 默认实参初始值
  • 内联函数和constexpr函数
    • 内联函数
    • constexpr 函数
    • 把内联函数和constexpr函数声明在头文件内
  • 调试帮助
    • assert预处理宏
    • NDEBUG预处理变量

默认实参

某些函数有这样一种形参,在函数的很多次调用中它们都被赋予一个相同的值,此时,我们把这个反复出现的值称为函数的默认实参。调用含有默认实参的函数时,可以包含该实参,也可以省略该实参。

//函数
void function(int i = 0)
{cout<<i<<endl;
}
//调用
function();//正确,不用传入参数默认参数为0.
function(1);//正确,传入参数即使用传入的参数进行赋值。

其中我们为每一个形参都提供了默认实参,默认实参作为形参的初始值出现在形参列表中。我们可以为一个或多个形参定义默认值,不过需要注意的是,一旦某个形参被赋予了默认值,它后面的所有形参都必须有默认值。

PS:还有便是在函数的形式参数列表中,默认实参应该放在所有的非默认实参的后面。

使用默认实参调用函数

如果我们想使用默认实参,只要在调用函数的时候省略该实参就可以了。

但值得注意的是:

//函数
void function(int i1=1,float i2=0.0)
{}
//调用
function()//正确,调用的是function(1,0.0)
function(1.0)//调用的是function(1,0.0)

从上述可得,函数仅能省略尾部的实参,传入参数按照顺序进行赋值,然后后面的值再进行默认赋值。

所以:当设计含有默认实参的函数时,其中一项任务是合理设置形参的顺序,尽量让不怎么使用默认值的形参出现在前面,而让那些经常使用默认值的形参出现在后面。

默认实参声明

一般也将其放在合适的头文件中。声明方式即原本函数的定义去掉内部的函数块。

默认实参初始值

局部变量不能作为默认实参(也即如果作为函数默认参数的变量应当命名于函数之外)。除此之外,只要表达式的类型能转换成形参所需的类型,该表达式就能作为默认实参:

#include<iostream>using namespace std;
//只可以将函数之外定义的变量,作为默认实参。
int p = 1;
double j = 0.0;void function(int i1 = p,double i2=j)
{cout << i1 << "  " << i2<<endl;
}int main()
{function();int p = 0;//此时虽然将p改成了0,但是是重新声明的内部的p将外层的p隐藏了。默认不发生改变。j = 1.0;//此时默认发生了改变。function();return 0;
}

输出结果:

内联函数和constexpr函数

内联函数

将一个函数声明为内联函数,通常就是将其在每一个调用的位置处进行内联的展开,加快程序运行的速度。

比如一个简单的函数:

inline int max(int num1,int num2)
{   return num1>num2?num1:num2;
}

在调用时:

cout<<max(3,4)<<endl;
//实际上是调用:
cout<<return 3>4?3:4<<endl;

如此从而加快程序运行的速度,但仅局限于函数内部数据很少的时候才可以这么使用。

constexpr 函数

constexpr函数是指能用于常量表达式的函数。定义constexpr函数的方法与其他函数类似,不过要遵循几项约定:函数的返回类型及所有形参的类型都得是字面值类型,而且函数体中必须有且只有一条return语句。

constexpr函数体内也可以包含其他语句,只要这些语句在运行时不执行任何操作就行。例如,constexpr函数中可以有空语句、类型别名以及using声明。

也就是说constexpr函数的return的值仅仅只能是两种:

  1. return 字面值
  2. return constexpr函数*字面值(但这种套娃不易过多,一两个就可以)

实际上constexpr也是一个内联函数,他将函数隐形的申明为内联函数,在调用的时候直接返回其对应的常量表达式。

把内联函数和constexpr函数声明在头文件内

和其他函数不一样,内联函数和constexpr函数可以在程序中多次定义。毕竟,编译器要想展开函数仅有函数声明是不够的,还需要函数的定义。不过,对于某个给定的内联函数或者constexpr函数来说,它的多个定义必须完全一致。基于这个原因,内联函数和constexpr函数通常定义在头文件中。

调试帮助

C++程序员有时会用到一一种类似于头文件保护的技术,以便有选择地执行调试代码。基本思想是,程序可以包含一些用于调试的代码,但是这些代码只在开发程序时使用。当应用程序编写完成准备发布时,要先屏蔽掉调试代码。这种方法用到两项预处理功能: assert和NDEBUG。

assert预处理宏

assert是一种预处理宏。所谓预处理宏其实是一个预处理变量,它的行为有点类似于内联函数。assert宏使用一个表达式作为它的条件:

assert (expr) ;

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

assert宏定义在cassert头文件中。如我们所知,预处理名字由预处理器而非编译器管理,因此我们可以直接使用预处理名字而无须提供using声明。也就是说,我们应该使用assert而不是std: :assert,也不需要为assert提供using声明。

NDEBUG预处理变量

assert的行为依赖于一个名为NDEBUG的预处理变量的状态。如果定义了NDEBUG,则assert什么也不做。默认状态下没有定义NDEBUG,此时assert将执行运行时检查。我们可以使用一个#define语句定义NDEBUG(DEBUG就是调试的意思),从而关闭调试状态。

而我们也可以通过这个来自行设计出相关仅在调试状态下运行的代码块。

最后给几个比较有用的错误提醒:

__FILE__存放文件名的字符串字面值。

__LINE__存放当前行号的整型字面值。

__TIME__存放文件编译时间的字符串字面值。

__DATE__存放文件编译日期的字符串字面值。

给一段相关的代码辅助理解:

#define NDEBUG  //整个程序最开头写
#include<iostream>
#include<cassert>using namespace std;
int new_sz(int i) {assert(i<100);if (i > 9)return 42;elsereturn 10;
}
int main() {int n = new_sz(101);return n;  //返回42
}

6.5 特殊用途语言特性相关推荐

  1. 【C++学习笔记】特殊用途语言特性

    一.默认实参   如果在多次调用函数时,其形参都被赋予同一值,可以把反复出现的值成为函数的默认实参(default argument),需要注意的是,在形参列表中,一旦某个形参被赋予默认值,那么后面多 ...

  2. c++ 函数 -函数重载 -特殊用途的语言特性(默认实参,内联函数 ,constexpr ,assert,NDEBUG)

    c++ 函数 -函数重载 -特殊用途的语言特性 文章目录 c++ 函数 -函数重载 -特殊用途的语言特性 函数重载 定义: 重载和const形参 const_cast 和重载 const_cast 重 ...

  3. C++应用程序性能优化(三)——C++语言特性性能分析

    C++应用程序性能优化(三)--C++语言特性性能分析 一.C++语言特性性能分析简介 通常大多数开发人员认为,汇编语言和C语言比较适合编写对性能要求非常高的程序,C++语言主要适用于编写复杂度非常高 ...

  4. python 特性和方法同名_Python语言特性的梳理

    对python的语言特性,多线程机制,以及性能局限的梳理 运行环境 由于Python不同版本,尤其是Python2与Pyhton3之间差异明显,所以运行不同项目时往往需要不同版本的运行环境,这种情况下 ...

  5. 雷卷 java,阿里巴巴资深技术专家雷卷:值得开发者关注的 Java 8 后时代的语言特性...

    阿里巴巴资深技术专家雷卷:值得开发者关注的 Java 8 后时代的语言特性 发布时间:2020-07-04 08:25:36 来源:51CTO 阅读:315 作者:阿里系统软件技术 栏目:云计算 作者 ...

  6. ABAP和Java里关于DEFAULT(默认)机制的一些语言特性

    ABAP 740的新语法: 上图的代码相当于: DATA: ls_data LIKE LINE OF it_data. READ TABLE it_data INTO ls_data WITH KEY ...

  7. “主要的编程范型”及其语言特性关系(多图)

    "主要的编程范型"(The principal programming paradigms)这幅图,其实出现得不算早,作者在2007年完成了该图的1.0版,到2008年更新至v1. ...

  8. 阿里巴巴资深技术专家雷卷:值得开发者关注的 Java 8 后时代的语言特性

    作者 | 阿里巴巴资深技术专家  雷卷,GitHub ID @linux-china 导读:在 Python.JavaScript 等一众编程语言崛起风靡之际,一代霸主 Java 风采虽不及当年,但仍 ...

  9. python 3 5的值_python3 语言特性5

    一天一个语言特性更新 Number [数字] String [字符串] List [列表] Tuple [元组] Set [集合] Dictionary [字典] 不可变数据类型 Number [数字 ...

最新文章

  1. java io 缓冲流_记忆系列-Java IO的缓存输入输出流(高效流)
  2. Apache的管理及优化web
  3. 一些算法入门应该明白的东西
  4. linux 指令tftp传输文件_Linux tftp 命令用法详解-Linux命令大全(手册)
  5. 10 分钟使用 Spring Boot + Vue + Antd + US3 搭建自己的图床
  6. [ZOJ 3203] 灯泡
  7. 抽象工厂模式设计模式_抽象工厂设计模式解释
  8. 面试官 | 说一下数据库如何分库分表?
  9. html pre标签增加行号,vue使用highlight.js 添加行号
  10. java graphics dispose_Graphics.Dispose 方法 (System.Drawing) | Microsoft Docs
  11. android高仿微信视频编辑页-视频多张图片提取
  12. windows上怎么用libnfc的库函数编程
  13. php那好,php那好【货币问答】- php那好所有答案 - 联合货币
  14. 02142数据结构导论
  15. 三体中的思想实验二:黑暗森林(上)
  16. 京东、闲鱼、转转的二手战场
  17. 差分与反差分计算(MATLAB)
  18. Vue(1706E)
  19. 房产管理系统系统与数据中心对接要遵循的标准和规范
  20. matlab计算矩阵的相关系数矩阵,计算二维矩阵的相关系数

热门文章

  1. 网易云音乐用户信息爬取以及可视化
  2. [转载]windows搭建cloudreve对接OneDrive教程
  3. 简单的小程序——可操作的表白神器
  4. 局域网共享文件夹/共享文件夹无法访问解决办法
  5. 如何录制真人出镜?别急,一篇教会你:真人出镜的ppt怎么录制
  6. mysql的连接名和用户名_MySQL登陆认证用户名先后顺序
  7. 《择天记》--一个关于改命的故事
  8. 涉密计算机不得接入互联网等公共信息网络,在涉密场所使用的与国际互联网或者其他公共网络连接的计算机不得安装视频、音频等输入装置 - 作业在线问答...
  9. tcp checksum 0xffff instead of 0x0000 see rfc 1624
  10. 瑞昱rtl8168网卡支持Linux吗,我的集成网卡RTL8111/8168B终于搞定(非常感谢ubuntu中文论坛)...