c++ 的類型回顧

C++標準規定了每個算術類型的最小存儲空間,但它并不阻止編譯器使用更大的存儲空間。事實上,對于 int 類型,幾乎所有的編譯器使用的存儲空間都比所要求的(16字節)大。

c語言和c++的內存管理

c語言和c++的內存管理

  • c語言分四個區:堆,棧,全局區和常量區
  • c++分五個區: 堆、棧、全局區、常量區和自由存儲區
    c++的自由存取區類似于c語言的堆,存放的是malloc創建的內存,

基本類型

字符類型
字符類型有兩種:char 和 wchar_t。char 類型保證了有足夠的空間,能夠存儲機器基本字符集中任何字符相應的數值,因此,char 類型通常是單個機器字節(byte)。wchar_t 類型用于擴展字符集,比如漢字和日語,這些字符集中的一些字符不能用單個 char 表示。
整數型
short、int 和 long 類型都表示整型值,存儲空間的大小不同。一般, short類型為半個機器字長,int 類型為一個機器字長,而 long 類型為一個或兩個機器字長(在 32 位機器中 int 類型和 long 類型通常字長是相同的)。
浮點型
對于實際的程序來說,float 類型精度通常是不夠的——float 型只能保證 6 位有效數字,而 double 型至少可以保證 10 位有效數字,能滿足大多數計算的需要。

字面量

只有內置類型存在字面值,沒有類類型的字面值。因此,也沒有任何標準庫類型的字面值。
整型字面值
整型字面量可以有三種進制的表示:十進制、八進制和十六進制。以 0(零)開頭的字面值整數常量表示八進制,以 0x 或 0X 開頭的表示十六進制。

字面值整數常量的類型默認為 int 或 long 類型。其精度類型決定于字面值——其值適合 int 就是 int 類型,比 int 大的值就是 long 類型。通過增加后綴,能夠強制將字面值整數常量轉換,在數值后面加 L 或者 l(字母“l”大寫或小寫)指定常量為 long 類型。在數值后面加 U 或 u 定義 unsigned 類型。同時加 L 和 U就能夠得到 unsigned long 類型的字面值常量 。

用十進制或者科學計數法來表示浮點字面值常量。使用科學計數法時,指數用 E 或者 e 表示。默認的浮點字面值常量為 double 類型。在數值的后面加上 F 或 f 表示單精度。同樣加上 L 或者 l 表示擴展精度. 1e-3f 表示的是0.001.
字符型字面量
在字符字面值前加 L 就能夠得到 wchar_t類型的寬字符字面值。L'a'
字符串字面值
字符串字面值常量用雙引號括起來的零個或者多個字符表示。為了兼容 C 語言,C++ 中所有的字符串字面值都由編譯器自動在末尾添加一個空字符。"A" 表示包含字母 A 和空字符兩個字符的字符串。 也存在寬字符串字面值,一樣在前面加“L”,如 L"a wide string literal"寬字符串字面值是一串常量寬字符,同樣以一個寬空字符結束。

兩個相鄰的僅由空格、制表符或換行符分開的字符串字面值(或寬字符串字面值),可連接成一個新字符串字面值。這使得多行書寫長字符串字面值變得簡單:

string a = "123"
           "456";

變量

變量名規則
變量名必須以字母或下劃線開頭,并且區分大小寫字母。char _;
初始化多個變量
當一個定義中定義了兩個以上變量的時候,每個變量都可能有自己的初始化式。 對象的名字立即變成可見,所以可以用同一個定義中前面已定義變量的值初始化后面的變量。

double salary = 9999.99, wage(salary + 0.01); 

內置類型的變量只有在全局定義時才會被自動初始化為0, 而類的對象定義時如果沒有指定構造函數,不管是全局定義還是局部定義都會調用默認構造函數。

引用類型

引用(非const型)必須用與該引用同類型的對象初始化。
定義多個引用
在一行中定義多個引用時,每個名字簽名前都必須帶&,這一點與指針相似,因為它們都是復合類型

int i=1024, j=2048;
int &a=i, &b=j;

const引用
const引用是指向const對象的引用,不能用非const引用指向const對象,const引用當然也可以指向非const對象的引用。

非const引用只能綁定到與該引用同類型的對象。const引用則可以綁定到不同但相關類型的對象(多態或支持隱式類型轉換)或綁定到字面值常量上(這就是有限的兩個引用不同類型的例子)。

const int a = 1;
int b = 2;
int &c=a; //會報錯
const int &d=b ; //正確
const int &e = a; //正確
const int &f = 1; // 正確
int &g = 1; // 錯誤
auto &h=a; //正確 auto會保留底層const 
auto &i=b; // 正確
auto &j=1; //錯誤,字面值需要指明const
const auto &k=1; //正確

對比,最后兩個表達式,我們知道編譯器可以從右值的對象中推斷出底層const,卻無法從字面量中推出,所以字面量必須顯式指出const auto;

當指向不同類型的對象時,會臨時創建一個對象進行類型轉換。

指針類型

指針與引用的區別

  1. 指針是一個對象,所以可以有賦值、取地址等操作,所以可以有指向指針的引用。
  2. 不強制必須初始化

除了兩種例外情況外,其它所有指針的類型都要和它所指向的對象嚴格匹配
例外1. const對象的指針指向同類型的非const對象(比引用嚴格,引用可以不同類型)
例外2. 多態的場合

空指針
c++11建議 使用字面值常量nullptr來將一個指針初始化為空指針

int *a=nullptr;

等價于 int *a=0;
以前的程序用的NULL其實是一個預處理變量,這個變量定義在頭文件cstdlib中,
c++建議初始化所有的指針,而常量指針在定義的時候必須初始化。

class與 struct

用class和struct關鍵字定義類的唯一差別在于默認訪問級別:默認情況下,struct的成員為public,而class的成員為private——《c++ primer》

類的定義
類的定義可以放在頭文件里面。

頭文件一般不包含定義,只包含extern 變量的聲明和函數的聲明。有三個例外:類的定義、值在編譯時就知道的const對象和inline函數——《c++ primer》

當我們在頭文件中定義了const變量后,每個包含這個頭文件的源文件都有了自己的const變量,當該const變量是用常量表達式初始化時,編譯器在編譯時會用常量表達式替換這些const變量,所以不會為每個源文件創建const對象的存儲空間。而當是用函數返回值或其它內容對const變量進行初始化時,編譯期間并不知道其值,所以就必須為其分配存儲空間,同時該const變量也不能定義在頭文件中。

類型別名

typedef和using都能定義類型別名

typedef double wages;
using wages=double;

如果某個類型別名指代的是符合類型或常量,那么把它用到聲明語句中就會產生意想不到的后果。

char tmp='a';
typedef char *  pstring;
const pstring cstr=&tmp;
*cstr='b';
cstr=nullptr;
pstring const cstr2=&tmp;
*cstr2='b';
cstr2=nullptr;

其實cstr1和cstr2是同樣類型的對象。

auto

C++ 是靜態類型(statically typed)語言,在編譯時執行類型檢查。結果是程序中使用某個名字之前,必須先告知編譯器該名字的類型——《c++ primer》

auto的對象必須初始化,auto能在一條語句中,聲明多個變量。一條聲明語句只能由一個基本數據類型。auto可以推斷出指針,卻推不出引用,必須用auto &來定義一個引用。

auto i = 0, *p = &i;

auto的對象的類型有時候會和初始值的類型不完全一致
auto與引用
當用來為auto對象初始化的值是引用類型的時候,auto對象的類型是真正參與初始化的對象的值。
設置一個類型為auto的引用時,初始值終點頂層常量屬性仍然保留

const int a = 0;
int b = 0;
auto &b = a; // b是const int 類型的引用
auto c = a;   // c是int類型
auto *d = &a, &e = b; // 編譯出出錯,因為&a是const int的地址,而b是int

auto與const
auto一般會忽略掉頂層const,同時底層const會被保留,比如當初始值是一個指向常量的指針時。

const int ci = 0, &cr = ci; 
auto a = &ci; // 這時候a是const int * 類型的
auto b = cr; // b是int類型的 
auto &c = ci; // c是const int & 類型的,因為是底層const 

如果希望推斷出的auto類型是一個頂層const,則需要明確指出。

const auto f = ci;

decltype

c++11 引入了第二種類型說明符 decltype,它的作用是返回表達式返回值的類型,但是不會實際計算表達式的值。

decltype 遇到解引用操作將返回引用類型,引用類型的變量定義的時候必須初始化

int a;
int *p=&a;
decltype(*p) c=a; //注意這里必須初始化

decltype與變量,decltype((var))返回的是引用類型,decltype(var)返回的是正常類型。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,818評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,185評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,656評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,647評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,446評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,951評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,041評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,189評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,718評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,602評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,800評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,316評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,045評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,419評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,671評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,420評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,755評論 2 371

推薦閱讀更多精彩內容