C 中字面值常量和字面值型別

2021-08-31 03:14:36 字數 1984 閱讀 6528

乙個形如42的值被稱為字面值常量。字面值常量的形式和值決定了常量的型別。例如0x42是16進製表示的整型常量。『a'是char型字面值。字面值常量顧名思義由字面意思表示,是常量。字面值常量在程式中是直接表示的,整型直接寫出大小,字元直接寫出字元。乙個字面值常量在編譯時被直接解析為立即數,編譯器內部維護字面值常量的型別。

常量表示式是指在編譯和執行過程中,該表示式的值不會改變,且編譯過程中可以立即得到其值的表示式。一部分const物件是常量表示式,由常量表示式初始化的const物件也是常量表示式。常量表示式在程式執行時不會改變,即使乙個程式多次啟動或外部引數發生變化,該值也不會改變。編譯器在編譯優化時可能把常量表示式直接替換為立即數,具體要看編譯環境。一般來講,字面值常量屬於常量表示式。

並非所有const物件都是常量表示式,const僅標記物件為唯讀屬性,該物件在初始化後無法再改變。如果const物件所賦初值在編譯階段就可確定,那麼此const物件才是常量表示式。const物件和儲存位置也沒有必然聯絡,常量可以分布在棧、堆、靜態儲存區中。對於宣告在函式體內的const常量,如果沒有被編譯優化掉,該常量儲存在棧中。全域性的const常量儲存在全域性儲存區。

c++中允許將變數宣告為constexpr型別以使編譯器在編譯時檢查該變數是否是常量表示式。宣告為constexpr的物件一定是常量表示式。且初始化必須用常量表示式。

例如:const int a = 12;    //a是常量表示式

const int b = a+1;  //b也是常量表示式

constexpr int c = a+b; //編譯器可以在編譯時期可以確定其值

const int d = getsize();   //c不是常量表示式,編譯器編譯時無法確知getsize()的執行結果。

constexpr int e = getsize();  //error! 將會報錯

字面值的型別根據字面值表達形式不同而不同,編譯器根據字面值形式推斷字面值的型別。字面值多數為算術型別。自定義類、io類不屬於該型別。

對於指標字面值,其只有nullptr和null。指標也可以是constexpr的常量表示式,表示該指標為const且指向在編譯時確定。不是所有的頂層const指標都是constexpr的。只有那些在編譯時就確定位址指向的const指標才是constexpr。因此nullptr、null、指向固定位址的指標是constexpr的。

對於顯式指出的字串常量,其儲存在常量儲存區中,例如:

const char *const str1 = "hello"; //

const char *const str2 = "hello"; //「hello"儲存在常量儲存區

constexpr const char *str = str1; //constexpr,編譯時確定的指標str

assert(str1 == str2); //str1和str2指向相同位址

此時的str1和str2指標都是constexpr的。那麼,如何判斷指標是否指向固定位址呢? 

程式在記憶體中的組織形式是段,有堆疊段、資料段和**段。對於資料指標指向資料,函式指標則指向某個**。

對於定義在函式體外的變數,其指標是constexpr的;此類變數要占用資料段,而程式執行時,**段和資料段大小位置均不會改變,因此編譯器可以確定位址指向,是constexpr的。此外,函式內部定義的static靜態變數,也會在資料區使用固定位址,因此指標也是constexpr的。對於定義在函式內部的變數,由於要在棧中開闢記憶體空間,而棧的情況要看程式執行狀態,因此這類變數沒有確定的位址,其指標不是constexpr的。**段不會改變,函式指標也是constexpr的。

const/constexpr常量表示式可能在編譯時直接替換為立即數;但也可能被編譯為const物件,程式執行時占用記憶體空間。const/constexpr是否被替換為立即數或生成物件取決於編譯環境和語**析,語義不允許替換的地方便生成const物件,就如inline函式一樣,不是所有inline函式都被替換。

C 中字面值常量和字面值型別

乙個形如42的值被稱為字面值常量。字面值常量的形式和值決定了常量的型別。例如0x42是16進製表示的整型常量。a 是char型字面值。字面值常量顧名思義由字面意思表示,是常量。字面值常量在程式中是直接表示的,整型直接寫出大小,字元直接寫出字元。乙個字面值常量在編譯時被直接解析為立即數,編譯器內部維護...

字面值常量

乙個形如 39 的值被稱作字面值常量 literal 每個字面值常量都對應一種資料型別,字面值常量的形式和值決定了它的資料型別。整型字面值寫作十進位制數 八進位制數或十六進製制數的形式。以0開頭的整數代表八進位制數,以0x或0x開頭的代表十六進製制數。下面的任意一種形式都表示數值 20 20 十進位...

c 字面值常量

字面值常量 literal constant 字面值 是指只能用它的值稱呼它,常量 是指其值不能修改。每個字面值都有相應的型別,3.14是double型,2是int型。只有內建型別存在字面值。1.整形字面值規則 整形字面值常量可以用十進位制 八進位制 十六進製制表示。20 dec 024 oct 以...