目录

  • 1、常量表达式和constexpr关键字
  • 2、断言与C++11的静态断言
    • 1.1. assert : C语言的宏(Macro),运行时检测。
    • 1.2. assert()依赖于NDEBUG 宏
    • 1.3. assert 帮助调试解决逻辑bug (部分替代“断点/单步调试”)
    • 2.1static_assert (C++11的静态断言 )
    • 2.2. 作用:编译时断言检查
    • 2.3. static_assert的用途
    • 3. 1When to use assertions (何时使用断言)
  • 3、声明与定义
    • 1. What is "Declare/Declaration" (什么是声明)
    • 2. What is "define/definition" (什么是定义)
    • 3. Differences between a declaration and a definition (定义与声明的区别)

1、常量表达式和constexpr关键字

常量表达式是编译期间就能计算其结果的表达式。
const修饰的对象既可能是编译期常量,也可能是运行期常量。
constexpr说明符声明可在编译时计算函数或变量的值

constexpr int max(int a , int b) { // c++11 引入 constexprif (a > b) return a;   // c++14才允许constexpr函数中有分支循环等else       return b;
}
int main() {int m = 1;const int rcm = m++;   // rcm是运行期常量const int cm = 4;      // 编译期常量,等价于: constexpr int cm = 4;int a1[ max(m , rcm)]; // 错误:m & rcm 不是编译期常量std::array<char , max(cm , 5)> a2; // OK: cm 和 5 是编译期常量
}

const用来告知程序员const指向的内容不可被修改,主要目的是为了避免写出bug。
constexpr在所有编译期常量的地方做限定。使得constexpr修饰的语句在编译期即可计算得到值。让编译期优化代码性能。
constexpr修饰的函数,要满足什么条件才能成为编译期常量表达式?
constexpr 函数的返回值必须在编译时就能被确定。

2、断言与C++11的静态断言

断言是一条检测假设成立与否的语句。
断言assert是一个宏,而非一个函数。
static_assert 是一个关键字,而非一个函数。

1.1. assert : C语言的宏(Macro),运行时检测。

用法:包含头文件 以调试模式编译程序

//assert( bool_expr ); // bool_expr 为假则中断程序
std::array a{ 1, 2, 3 };  //C++17 类型参数推导
for (size_t i = 0; i <= a.size(); i++) {assert(i < 3);  //断言:i必须小于3,否则失败std::cout << a[ i ];std::cout << (i == a.size() ? "" : " ");

1.2. assert()依赖于NDEBUG 宏

NDEBUG这个宏是C/C++标准规定的,所有编译器都有对它的支持。
(1) 调试(Debug)模式编译时,编译器不会定义NDEBUG,所以assert()宏起作用。
(2) 发行(Release)模式编译时,编译器自动定义宏NDEBUG,使assert不起作用
如果要强制使得assert()生效或者使得assert()不生效,只要手动 #define NDEBUG 或者 #undef NDEBUG即可。

1.3. assert 帮助调试解决逻辑bug (部分替代“断点/单步调试”)

#undef NDEBUG   // 强制以debug模式使用<cassert>
int main() {int i;std::cout << "Enter an int: ";std::cin >> i;assert((i > 0) && "i must be positive"); return 0;
}

上面示例的第6行代码中,若assert中断了程序则表明程序出bug了!程序员要重编代码解决这个bug,而不是把assert()放在那里当成正常程序的一部分
assert断言中所用的表达式可以不是是编译期常量表达式。

2.1static_assert (C++11的静态断言 )

2.1. static_assert ( bool_constexpr, message)

其中两个参数解释如下:
(1)      bool_constexpr:   编译期常量表达式,可转换为bool 类型
(2)      message: 字符串字面量 ,是断言失败时显示的警告信息。自C++17起,message是可选的

2.2. 作用:编译时断言检查

// 下面的语句能够确保该程序在32位的平台上编译进行。
// 如果该程序在64位平台上编译,就会报错 (例子来自MSDN)

static_assert(sizeof(void *) == 4, "64-bit code generation is not supported.");

2.3. static_assert的用途

常用在模版编程中 ,对写库的作者用处大
在static_assert的第一个参数 bool_constexpr 中不能有变量表达式

3. 1When to use assertions (何时使用断言)

这里我们指的是assert,运行期的断言。
若某些状况是你预期中的,那么用错误处理;若某些状况永不该发生,用断言)

int n{ 1 } , m{ 0 };
std::cin >> n;
assert((n != 0) && "Divisor cannot be zero!"); // 不合适
int q = m / n;
int n{ 1 } , m{ 0 };
do {                // 这是修补bug的代码std::cin >> n;    // 断言失败后,要解决这个bug
} while (n == 0);   // 在这里编写修复bug的代码
assert((n != 0) && "Divisor cannot be zero!");
int q = m / n;

下面的例子说明了在编译期,静态断言就已经执行了,因为array<int,nums>的nums在编译期就应该知道它的值。

3、声明与定义

1. What is “Declare/Declaration” (什么是声明)

“声明”是引入标识符并描述其类型,无论是类型,对象还是函数。编译器需要该“声明”,以便识别在它处使用该标识符。

extern int bar;extern int g(int, int);double f(int, double); // extern can be omitted for function declarationsclass foo; // no extern allowed for type declarations

2. What is “define/definition” (什么是定义)

“定义”实例化/实现这个标识符。链接器需要“定义”,以便将对标识符的引用链接到标识符所表示的实体。

int bar;int g(int lhs, int rhs) {return lhs*rhs;}double f(int i, double d) {return i+d;}class foo {};

3. Differences between a declaration and a definition (定义与声明的区别)

1、定义有时可取代声明,反之则不行
2、标识符可被声明多次,但只能定义一次
3、 定义通常伴随着编译器为标识符分配内存

【C++grammar】断言与表达式常量相关推荐

  1. 第 2 章 常量、变量和表达式

    <一>继续Hello World 深入了解C语言的注释,注释可以跨行,也可以穿插在程序中.注释的定界符/*和*/,注释需要注意两点:注释不能够嵌套使用,如:/*test1 /* test2 ...

  2. 常量表达式(constexpr)

    首先,常量表达式的概念:在编译期就可以计算出结果的表达式 那么为什么要用常量表达式呢,用常量表达式会有什么好处: 1.允许一些计算只在编译时进行一次,而不是每次程序运行时: 2.编译器可以进行尺度更大 ...

  3. C++知识整理系列(三)—— constexpr常量表达式

    const修饰常量,但是const并未区分编译时常量和运行时常量,而constexpr则只能是编译时常量,在C++11中提出. 这篇文章,将详细讲解constexpr. 目录 一.常量表达式 二.co ...

  4. C++11 nullptr与常量表达式constexpr记录

    1.nullptr (1) nullptr是一个关键字,而nullptr_t是一个类型 typedef decltype(nullptr) nullptr_t 使用nullptr_t类型必须包含#in ...

  5. Go编程基础 - 常量与运算符

    为什么80%的码农都做不了架构师?>>>    常量的定义 常量的值在编译时就已经确定 常量的定义格式与变量基本相同 等号右侧必须是常量或者常量表达式 常量表达式中的函数必须是内置函 ...

  6. Linq之Expression高级篇(常用表达式类型)

    目录 写在前面 系列文章 变量表达式 常量表达式 条件表达式 赋值表达式 二元运算符表达式 一元运算符表达式 循环表达式 块表达式 总结 写在前面 首先回顾一下上篇文章的内容,上篇文章介绍了表达式树的 ...

  7. golang 常量简介

    目录 1.单个常量声明 2.多个常量声明 3.常量表达式 1.单个常量声明 常量可以是全局常量,也可以是函数内部的局部常量.常量的值不可修改,常量表达式的值在编译期计算,而不是在运行期.存储在常量中的 ...

  8. grep零宽断言正则表达式

    一.grep零宽断言: (匹配宽度为零,满足一定的条件/断言) 零宽断言用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像 \b ^ $ \< \> 这样的锚定作用, ...

  9. CH2-1 类型 操作 表达式

    2.1 变量名 (1) 大小写敏感,小写一般做变量,大写做符号常量(symbolic constant) (2) 以字母和_开头,有些类库用了"_" 2.2 数据类型和长度 (1) ...

最新文章

  1. Html一修改就会自动刷新,web 前端修改 自动刷新 插件使用 liveReload
  2. OSMboxPost()
  3. 第二期阿里巴巴 Java Meetup 来北京了。你来么?
  4. SQL增删改查,基础
  5. 字体单独设置样式_Glyphs 官方教程 | 字体命名
  6. 荣耀系列到底算不算华为手机
  7. 体系结构分析与设计语言AADL基础
  8. BS7799、ISO/IEC 17799、ISO/IEC 27001的联系与区别
  9. ab压力 failed_Apache ab压力测试时出现大量的错误原因分析
  10. webscraper多页爬取_webscraper的常见爬取问题
  11. 使用xshell登陆腾讯云主机
  12. 迅雷下载GitHub文件提示需要授权或登录等
  13. 用PayPal在eBay上撸货加哪种卡可以长期用?
  14. android开发中论坛帖子图片的排版
  15. ROS1学习笔记--xacro
  16. 买卖时机APP 开启股票交易大数据时代!
  17. 【题解】吉首大学第九届"新星杯"大学生程序设计大赛(重现赛)
  18. Spring boot实现代理服务器
  19. mysql 1168_mysql merge报错ERROR 1168
  20. cocos 《吃星星》---运用Vec2和mag()判断位置和距离

热门文章

  1. php boolean 全大写还是全小写,【PHP培训】PHP为什么大小写规则是如此不规则?
  2. android读取excel文件_python里读写excel等数据文件的几种常用方式
  3. activiti mysql 版本_Mysql8.0.17版本不能自动创建activiti表的坑
  4. 微信小程序 request请求封装
  5. Odyssey.js – 使用现成模板在线创建互动的故事
  6. 【工具相关】web-HTML/CSS/JS Prettify的使用
  7. CCS3的过渡、变换、动画以及响应式布局、弹性布局
  8. Laravel 不同环境加载不同的.env文件
  9. java.lang.IllegalStateException: Connection pool shut down
  10. Brackets (区间DP)