C 常量和字面值常量

2022-09-19 06:45:10 字數 4335 閱讀 4829

在c++中,常量(constant)即新增了const的定義的量。字面常量(literal constant)即無需定義可以直接寫出來的量。字面常量的值一望便知,但是他的資料型別往往不能被準確分辨。而const作為常量關鍵字,則有著豐富的應用,同時可能導致的錯誤也讓人備受折磨。

我們直接寫出來的有確定值的量就是字面常量,如1145143.12'a'1e30等,那麼42的型別是什麼?3.12是單精度還是雙精度?這些都有明確的規定,乙個字面常量的型別是由他的形式完全決定的。

整數的字面值

即使沒有了解過,也很容易想到114514肯定是int型別。那1145141919呢?超過了int當然就是乙個long long型別了。c++裡整數常量的型別就是int->long->long long裡能表示出它的尺寸最小的型別(顯然都是有符號(signed)型)。比如:

不過八進位制和十六進製制的規則有些不一樣。八進位制和十六進製制常量可以不用負號而表示負數(如0x80000000),這個時候他的型別會被判定為unsigned而不是負值。也就是說,此時按照int->unsigned int->.....->long long->unsigned long long取能表示為正數的最小型別。

浮點數的字面值

shortint的關係類似,雖然float更小,但是double才是我們最常用的浮點數型別。3.14。在c++裡無論時小數表示還是指數表示,無論有幾位有效數字,所有的浮點型別預設都是double(如0.1.098786756451e203e-15)。

手動指定字面值

如果我們需要1個long long型別的0,或者double存不下超長的浮點數,就可以在值的後面加上修飾符,手動指定字面值的型別。

當然你也可以使用型別轉換,但是略顯繁瑣。

c++中char型別一般以\([0, 128)\)的整數與ascii字元相對應。單個ascii字元的型別當然是char(如'a'表示char大小的字元a,即97)。

字面字串則是乙個常量字元陣列const charconst char*(並不是string)。在傳參時,如果將常量字串傳入f(char *s)中,並修改字串的值,將引發錯誤。

手動指定字面值

' '的型別都是char,不能使用漢字等其他字元,如果要指定寬字元(wide char)的字面量。可以在前面加上u(表示16位字元char16_t)、u(表示32位字元char32_t)或l(表示寬字元wchar_t,在不同環境下為16位或32位),比如u'天'

(當然這只是啟用中文字串的乙個步驟,還需要一系列寬字元的工具才能實現中文操作)

布林字面值只有兩種:truefalse

指標字面值只有乙個,那就是空指標nullptr

我們知道nullptrnull0都可以初始化空指標,其中nullptr是類似truefalse的字面值關鍵字,而null僅僅是定義在標頭檔案裡巨集,其含義就是「0」,也就是說與0沒有區別。

那為什麼要專門弄乙個nullptr呢。因為nullptr是「指標」,而單獨存在的0是「int」。類似之前提到的max問題。如果有兩個同名函式f(int x)f(int *x),如果傳入f(null),由於null的值為0,就會呼叫前者,要呼叫後者,則只能使用f(nullptr)

const關鍵字定義的量叫常量,const有很多方面的應用,這裡介紹其在定義變數時的一些擴充套件知識。

const int a = 5; //編譯時初始化

const int b = read(); //執行時初始化

const int c = sqrt(4)+a; //編譯時初始化

其中5sqrt(4)被叫做常量表示式(const expression),他們是定製,並且可以在編譯時就直接得出答案,以此提公升效率。

但是在乙個複雜的程式裡,分辨乙個表示式能否作為常量表示式提前計算是一件困難的事,因此c++11裡出現了constexpr。加上constexpr表示我們希望它在編譯階段就初始化,編譯器將驗證表示式是否可以提前計算。

常量表示式的一般只由字面常量和字面常量初始化的常量組成。如果需要使用自定義函式,那麼必須是由constexpr宣告的,足夠簡單的常函式,以便在編譯時就計算出值。

對於一般的資料來講,const修飾即代表這個值不能被修改,這叫做頂層const(toplevel const)

然而對於指標來說,指標的值能否被修改和指標指向的值能否被修改是兩個獨立的問題。

const int a = 5;

const int *p = &a;//底層const

int* const p = &a;//頂層const

const int *const p = &a;//雙重

constexpr int* p = &a;//頂層const

const的位置不同時,其意義也不同。如果const*的左側(與「int」的先後無所謂),代表*p是常量,即p的值可以修改到其他變數,但無論指向哪個變數都不能修改該變數,這叫做底層const(lowlevelconst)。p是乙個「指向常量的指標」

const*的右側時,可以理解為p是常量,因此p只能指向a不能更改,但是可以通過p修改a的值。p是乙個「常量指標」。如果兩個同時使用,就變成了「指向常量的常量指標」。

不過使用constexpr時的語法稍有不同,雖然這個關鍵字在*左邊,但他代表的還是通常意義下的頂層const,即不能修改p的值。

對於乙個非常量,既可以用普通指標指向,也可以用「指向常量的指標」指向,此時不能通過指標修改變數值。

而引用的規則與指標相同。既可以使用普通引用,也可以使用常量引用,但是不能通過常量引用來修改值。

int a = 5;

const int &b = a;

int &c = a;

c = 3;

b = 3;// 錯誤

但是常量只能被「指向常量的指標」指向,也只能被常量引用繫結,當然也就不允許修改值了。

const int a = 5;

int &b = a;// 錯誤

int *p = &a;// 錯誤

當然你可以使用強制型別轉換來強制指向。

const int a = 5;

int *p = (const int*)&a;//或者使用const_cast

此時你甚至可以通過指標來修改變數值,不過這屬於未定義行為,取決於編譯器如何處理a

c 字面值常量

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

C 字面值常量

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

字面值常量

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