【C++grammar】断言与表达式常量

目录

  • 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、 定义通常伴随着编译器为标识符分配内存

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/377832.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一、Arduino UNO R3将数据上传至云平台

一、准备工作 ①ESP12E Shield ②Arduino UNO R3开发板 ③把ESP12E Shield安装到Arduino UNO R3开发板上 ④登录物联网平台注册个账号&#xff0c;到时候需要使用。 ⑤记录下来你的Uid和key到时候会用到 ⑥创建个设备&#xff0c;用于测试 ⑦beyondyanyu为设备名&…

leetcode 93. 复原IP地址 思考分析

题目 给定一个只包含数字的字符串&#xff0c;复原它并返回所有可能的 IP 地址格式。 有效的 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0c;整数之间用 ‘.’ 分隔。 例如&#xff1a;“0.1.2.201” …

二、通过云平台反向控制Arduino UNO R3

该篇博文是在第一篇博文(一、Arduino UNO R3将数据上传至云平台)的基础上进行的 一、云平台发送指令反向控制Arduino UNO R3 ESP12E Shield开关都推到OFF&#xff08;要不然下载会报错&#xff09;&#xff0c;往Arduino UNO R3开发板上下载下面的代码 这段代码进行测试要点&…

【C++grammar】代理构造、不可变对象、静态成员

目录1、Delegation Constructor&#xff08;代理构造&#xff09;1. What is delegating constructor? (什么是代理构造/委托构造)2. Avoiding recursive calls of target constructors (避免递归调用目标ctor)3. 委托构造的好处2、不可变对象和类1、如何让类成为“不可变类”…

RFID模块+WIFI模块+振动传感器+有源蜂鸣器+舵机+Arduino UNO R3所构成的门禁系统模块

该系统模块主要由RFID模块WIFI模块振动传感器有源蜂鸣器舵机Arduino UNO R3组成的门禁系统模块。这里使用舵机充当门锁&#xff0c;用户可以刷卡开门&#xff0c;也可以通过APP控制舵机状态达到开门的效果。若有不法分子想要强行进入室内&#xff0c;对门进行撞击或者人为的破坏…

ESP12E Shield+Arduino UNO R3开发板+DHT11温湿度模块+双色LED灯+有源蜂鸣器+光敏电阻模块+I2CLCD1602液晶显示器所构成的室内检测系统

室内检测系统由ESP12E ShieldArduino UNO R3开发板DHT11温湿度模块双色LED灯有源蜂鸣器光敏电阻模块I2CLCD1602液晶显示器所构成。DHT11温湿度模块获取室内温湿度数据通过I2CLCD1602液晶显示器进行显示&#xff0c;另一方面通过ESP12E Shield将数据上传至云平台。光敏电阻进行捕…

leetcode 202. 快乐数 思考分析(哈希集合与双指针解)

1、题目 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」定义为&#xff1a;对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和&#xff0c;然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到 1。如果 可以变为 1&am…

五、线性回归和多项式回归实现

官网API 一、线性回归 针对的是损失函数loss faction Ⅰ、Lasso Regression 采用L1正则&#xff0c;会使得w值整体偏小&#xff1b;w会变小从而达到降维的目的 import numpy as np from sklearn.linear_model import Lasso from sklearn.linear_model import SGDRegresso…

深发展银行编码器(解剖)

电池拆下来&#xff0c;再装上&#xff0c;还能继续用下&#xff0c;不会被重置 转载于:https://www.cnblogs.com/ahuo/archive/2012/01/25/2329485.html

leetcode 1. 两数之和 思考分析

1、题目 给定一个整数数组 nums 和一个目标值 target&#xff0c;请你在该数组中找出和为目标值的那 两个 整数&#xff0c;并返回他们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素不能使用两遍。 2、思考分析 双for循环的时间复杂度…

六、逻辑回归

一、何为逻辑回归 逻辑回归可以简单理解为是基于多元线性回归的一种缩放。 多元线性回归y的取值范围在(-∞&#xff0c;∞)&#xff0c;数据集中的x是准确的一个数值。 用这样的一个数据集代入线性回归算法当中会得到一个模型。 这个模型所具备的功能就是当有人给这个模型一个…

leetcode 383. 赎金信 思考分析

题目 给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串&#xff0c;判断第一个字符串 ransom 能不能由第二个字符串 magazines 里面的字符构成。如果可以构成&#xff0c;返回 true &#xff1b;否则返回 false。 (题目说明&#xff1a;为了不暴露赎金信字迹&#x…

Numpy(科学计算库)---讲解

本内容来自《跟着迪哥学Python数据分析与机器学习实战》&#xff0c;该篇博客将其内容进行了整理&#xff0c;加上了自己的理解&#xff0c;所做小笔记。若有侵权&#xff0c;联系立删。 迪哥说以下的许多函数方法都不用死记硬背&#xff0c;多查API多看文档&#xff0c;确实&a…

仿安居客好租网房产源码

网站设计简约&#xff0c;大方&#xff0c;清爽开发技术&#xff1a;ASP.NET3.5,SQL2005,VS2008功能简介1、小区&#xff0c;二手房&#xff0c;租房小区发布&#xff0c;编辑&#xff0c;修改功能&#xff0c;图片批量上传2、支持积分&#xff0c;发布房源、发布论坛帖子可获得…

LeetCode 454. 四数相加 II 思考分析

题目 给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) &#xff0c;使得 A[i] B[j] C[k] D[l] 0。 为了使问题简单化&#xff0c;所有的 A, B, C, D 具有相同的长度 N&#xff0c;且 0 ≤ N ≤ 500 。所有整数的范围在 -228 到 228 - 1 之间&am…

【转】Spark源码分析之-scheduler模块

原文地址&#xff1a;http://jerryshao.me/architecture/2013/04/21/Spark%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E4%B9%8B-scheduler%E6%A8%A1%E5%9D%97/ Background Spark在资源管理和调度方式上采用了类似于Hadoop YARN的方式&#xff0c;最上层是资源调度器&#xff0c;它负…

【C++grammar】析构、友元、拷贝构造函数、深浅拷贝

目录1、Destructor&#xff08;析构函数&#xff09;在堆和栈(函数作用域与内嵌作用域)上分别创建Employee对象&#xff0c;观察析构函数的行为2、Friend&#xff08;友元&#xff09;1、为何需要友元2、友元函数和友元类3、关于友元的一些问题3、Copy Constructor&#xff08;…

Android PreferenceActivity 使用

我想大家对于android的系统配置界面应该不会陌生吧&#xff0c;即便陌生&#xff0c;那么下面的界面应该似曾相识吧&#xff0c;假若还是不认识&#xff0c;那么也没有关系&#xff0c;我们这一节主要就是介绍并讲解android 中系统配置界面的使用&#xff0c;相信大家看完本节后…

Pandas(数据分析处理库)---讲解

本内容来自《跟着迪哥学Python数据分析与机器学习实战》&#xff0c;该篇博客将其内容进行了整理&#xff0c;加上了自己的理解&#xff0c;所做小笔记。若有侵权&#xff0c;联系立删。 迪哥说以下的许多函数方法都不用死记硬背&#xff0c;多查API多看文档&#xff0c;确实&a…

leetcode 78. 子集 思考分析

题目 给定一组不含重复元素的整数数组 nums&#xff0c;返回该数组所有可能的子集&#xff08;幂集&#xff09;。 说明&#xff1a;解集不能包含重复的子集。 思考分析 画出解空间树。 我们可以发现我们所需要的结果是解空间的所有结点。而我们之前组合问题和分割问题都是…