【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.pswp.cn/news/377832.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/377832.shtml
英文地址,請注明出處:http://en.pswp.cn/news/377832.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

一些又用的國內著名期刊

記&#xff1a; 電子學報、電子與信息學報、圖像圖形學報、自動化學報、計算機學報、軟件學報、計算機研究與發展。轉載于:https://www.cnblogs.com/nanyangzp/p/3322244.html

一、Arduino UNO R3將數據上傳至云平臺

一、準備工作 ①ESP12E Shield ②Arduino UNO R3開發板 ③把ESP12E Shield安裝到Arduino UNO R3開發板上 ④登錄物聯網平臺注冊個賬號&#xff0c;到時候需要使用。 ⑤記錄下來你的Uid和key到時候會用到 ⑥創建個設備&#xff0c;用于測試 ⑦beyondyanyu為設備名&…

怎樣做一個快樂的ASP.NET程序員

首先我想解釋一下標題中兩個關鍵字: "快樂", "ASP.NET程序員". 有的人想成為一個"杰出"的程序員, 或者"資深"的程序員, 簡單來說就是"大牛"級的人物 -- 但是本文不是針對此種發展方向不是說我不鼓勵大家朝這方向走, 而是對我…

__eq___C ++'and_eq'關鍵字和示例

__eq__"and_eq" is an inbuilt keyword that has been around since at least C98. It is an alternative to & (Bitwise AND Assignment) operator and it mostly uses for bit manipulations. “ and_eq”是一個內置關鍵字&#xff0c;至少從C 98起就存在。 它…

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開發板上下載下面的代碼 這段代碼進行測試要點&…

使用MSBuild編譯FsLex項目

FsLex FsYacc微軟本身也提供了一個項目模板。但是這個項目模板是lex和yacc文件均包含。我想只適用lex&#xff0c;但是如果每次使用命令行也覺得不夠方便&#xff0c;于是還是研究了一番MsBuild的使用。 使用msbuild hellp.fsproj /v:d 可以查看整個msbuild的流程&#xff0c;非…

Python字符串格式:%vs.format

Often the string formatters in python are referred to as old style and new style. The old-style is % and .format is known as the new style. python中的字符串格式化程序通常被稱為舊樣式和新樣式。 舊樣式為&#xff05; &#xff0c;. format被稱為新樣式。 Simple…

【C++grammar】代理構造、不可變對象、靜態成員

目錄1、Delegation Constructor&#xff08;代理構造&#xff09;1. What is delegating constructor? (什么是代理構造/委托構造)2. Avoiding recursive calls of target constructors (避免遞歸調用目標ctor)3. 委托構造的好處2、不可變對象和類1、如何讓類成為“不可變類”…

paip.最新的c++ qt5.1.1環境搭建跟hello world

paip.最新的c qt5.1.1環境搭建跟hello world 作者Attilax &#xff0c; EMAIL:1466519819qq.com 來源&#xff1a;attilax的專欄 地址&#xff1a;http://blog.csdn.net/attilax 有一段時間沒接觸c了...今天下載新的qt下來研究一番.. qt的環境搭建有eclipseqtdtmingwqtl…

RFID模塊+WIFI模塊+振動傳感器+有源蜂鳴器+舵機+Arduino UNO R3所構成的門禁系統模塊

該系統模塊主要由RFID模塊WIFI模塊振動傳感器有源蜂鳴器舵機Arduino UNO R3組成的門禁系統模塊。這里使用舵機充當門鎖&#xff0c;用戶可以刷卡開門&#xff0c;也可以通過APP控制舵機狀態達到開門的效果。若有不法分子想要強行進入室內&#xff0c;對門進行撞擊或者人為的破壞…

PushManager

http://suchandalex.googlecode.com/svn/trunk/beOui/beWe/client/Classes/PushNotificationManager.m轉載于:https://www.cnblogs.com/vincent-lu/archive/2012/01/18/2325740.html

krsort_PHP krsort()函數與示例

krsortPHP krsort()函數 (PHP krsort() function) krsort() function is used to sort an associative array in descending order based on the keys, as we know that an associative array contains keys and values, this method sorts an array according to the keys. kr…

ESP12E Shield+Arduino UNO R3開發板+DHT11溫濕度模塊+雙色LED燈+有源蜂鳴器+光敏電阻模塊+I2CLCD1602液晶顯示器所構成的室內檢測系統

室內檢測系統由ESP12E ShieldArduino UNO R3開發板DHT11溫濕度模塊雙色LED燈有源蜂鳴器光敏電阻模塊I2CLCD1602液晶顯示器所構成。DHT11溫濕度模塊獲取室內溫濕度數據通過I2CLCD1602液晶顯示器進行顯示&#xff0c;另一方面通過ESP12E Shield將數據上傳至云平臺。光敏電阻進行捕…

輸入輸出函數:

一、printf函數&#xff1a;     printf("Hello World!\n");     printf("My age is %d\n",26);     int age 17;     printf("My age is %d\n",age);  %d 或 %i: 帶符號 十進制整數。   %o:不帶符號 八進制整數。   %x:…

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…

JavaScript中的地圖與對象

JavaScript對象與地圖 (JavaScript Objects vs Maps) Objects are super popular in JavaScript so its not a term you are hearing for the first time even if youre a novice JS developer. Objects, in general, are a very common data structure that is used very ofte…

深發展銀行編碼器(解剖)

電池拆下來&#xff0c;再裝上&#xff0c;還能繼續用下&#xff0c;不會被重置 轉載于:https://www.cnblogs.com/ahuo/archive/2012/01/25/2329485.html

關于$.getJson

這是一個Ajax函數的縮寫&#xff0c;這相當于: 123456$.ajax({dataType: "json",url: url,data: data,success: success});數據會被附加到一個查詢字符串的URL中&#xff0c;發送到服務器。如果該值的data參數是一個普通的對象&#xff0c;它會轉換為一個字符串并使用…