C++ 字面值常量的類型


在C++中,字面常量(literal constant)即無需定義可以直接寫出來的量。字面常量的值一望便知,但是他的數據類型往往不能被准確分辨(尤其是使用auto時)。

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

1. 整數和浮點數的字面值

整數的字面值

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

  • 2147483547int,而2147483648就是long long類型了,而不是unsigned int
  • 42即使在short范圍內,類型也為int而不是short
  • -2147483648int范圍內,但是仍然是long long(前面沒有提到過負號,實際上-不在字面值之內,先判定了2147483648的類型再取了符號)
  • 1000000000000000000000000如果這個數連long long都裝不下怎么辦?某些編譯器可以繼續擴展到128位整數(__int128_t,范圍\([-2^{127}, 2^{127})\)),如果更大的話,就不能通過編譯了。

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

浮點數的字面值

shortint的關系類似,雖然float更小,但是double才是我們最常用的浮點數類型。在C++里無論時小數表示還是指數表示,無論有幾位有效數字,所有的浮點類型默認都是double(如0.1.098786756451e203E-15)。

手動指定字面值

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

  • uU指定該值為無符號類型,比如2147483648u是一個unsigned int-1U也是一個“無符號的-1”(即4294967295),

  • lL指定類型為longllLL指定類型為long long

    long long a = 3, b = max(a, 0)會出錯,因為along long0int導致參數不匹配,修改為b = max(a, 0ll)即可。

    ull可以混用,即ullul表示無符號長整形。

  • fF指定類型為float,指數類型和小數類型都可以(如1e3f0.12F)。

  • lL也可以用於浮點,表示指定long double類型。

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

2. 字符和字符串的字面值

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

字面字符串則是一個常量字符數組const char[]const char*(並不是string)。在傳參時,如果將常量字符串傳入f(char *s)中,並修改字符串的值,將引發錯誤。

手動指定字面值

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

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

3. 布爾字面值

布爾字面值只有兩種:truefalse

  • true轉化為任意數時值為1,false轉化為任意數時值為0
  • 任意非0數轉化為bool時,只有原數等於0時變為false,否則都為true(不過浮點數的判定方法有點特殊,由於浮點數的等於是“近似相等”,如果double x=0.1+0.2-0.3,在某些環境下x==0true,但x的實際值由於浮點誤差並不為0(非常接近0的一個數),如果有循環if (x) {}將仍然執行,除非x的實際值真的是0(正0或負0),才不會執行)

4. 指針字面值

指針字面值只有一個,那就是空指針nullptr

我們知道nullptrNULL0都可以初始化空指針,其中nullptr是類似truefalse的字面值關鍵字,而NULL僅僅是定義在頭文件里宏,其含義就是“0”,也就是說與0沒有區別。

那為什么要專門在C++11里弄一個nullptr呢。因為nullptr是“指針”,而單獨存在的0是“int”。類似之前提到的max問題。如果有兩個同名函數f(int x)f(int *x),如果傳入f(NULL),由於NULL的值為0,就會調用前者,要調用后者,則只能使用f(nullptr)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM