C++ 變量也許和其餘語言的變量沒有什麼差異.就是用來存儲一些可能會變值的容器.
固然 C++ 變量裏又分爲 原子類型 的(int , char ,bool 等等),複合類型 的(struct ,class ,union).
這篇內容會比較側重與於記錄些原子類型的變量的使用和注意事項.其實我想不少都記錄在原文中,可是無奈怕篇幅太長.並且讓人生厭.因此給出了一些連接讓有興趣的同窗方便查看.html
咱們能夠按照變量的實際保存數據的類型分割爲一下幾個類別 程序員
int
(4字節) short
(2字節) long
(在 32 位系統下是 4 字節,64 位系統則是 8 字節)float
(4字節) double
(8字節)char
(1字節) wchar_t
(這個在內存中的所佔的大小,可能根據使用的 字符集 不一樣而不一樣,好比你在 VS 上用默認是 utf16le 那麼它大體是佔 2 個字節,gcc 上默認是 utf8 ,其寬度是 4 字節) bool
(1字節)函數指針
(例如 int (*pFunc) (void),這裏定義了一個 pFunc 函數指針,指向返回值爲 int ,參數列表爲 void 的函數指針.這個是屬於 c 範疇的內容啦.因此這裏不詳細介紹了有興趣的能夠點這個 連接(函數指針) 或這個 連接( C++ 成員函數指針) 參考看看.我在一開始時候學習到這個特性的時候,仍是很痛苦的.常常和返回值爲指針的函數原型弄混) 指針變量
(用於記錄某些變量地址)
這裏簡單的列舉出來變量的定義形式(引用必須在聲明時候顯示賦值):數組
int i; // 定義整型變量 int *p; // p 爲指向整型數據的指針變量 int a[n]; // 定義整型數組 a 有 n 個元素 int *p[n]; // 定義指針數組 p,有 n 個指向整型指針 int f(); // f 爲返回整型函數值的函數 int *p(); // p 爲返回一個指針的函數,該指針指向整型數據 int (*p)(); // p 爲指向函數指針,該函數返回一個整型值 int **p; // p 爲一個指針變量,它指向一個整型的指針變量 int &p = a; // p 爲整形變量 a 的引用 int *& p2 = p; // p2 爲整形變量指針 p 的引用(能夠查看這裏的例子)
那在實際的開發中在定義變量時候最好給變量顯示賦予一個初始值.爲何這麼作呢,若你在定義變量的時候並未顯示賦值,那麼你的變量一開始裏面保存的數據是不肯定的.好比定義一個整形 int a; 這句話僅僅只是爲 a 這個變量分配了一個內存空間,而 a 的內容取決於你當前分配那塊內存的值,那這個就是很不肯定的了.因此假設你不當心使用了一個爲經初始話的變量,可能就會致使程序崩潰等等.數據結構
整形變量就是用來存放整數的地方.那麼整數又是如何被存儲在內存當中的呢?答案是以 補碼 (這裏是有關 [原碼] ,[反碼] ,[補碼] 的相關說明,若想知道的更深刻能夠 [點這裏])的形式存放在內存中.若瞭解了這個的話,那麼算術異常你也就大體知道是什麼緣由了,爲什麼兩個很大的數相加會獲得一個負數.
還須要注意的是 C++ 對於 1000 0000 表示的數變不在是 0 而是 -128(即 -127-1).由於在有符號數中表示 -0 的這個數實際意義上是最小負數在減一. 固然實際是應爲 -128 剛恰好對應的二進制補碼爲 1000 0000 除符號位外也.
在計算機當中其實它只識別二進制的形式,即 0101 這種的形式(由於沒有什麼電路的專業知識因此這裏也很少作解釋,以避免誤導到你.個人理解是電路中存在兩種狀態即,有電,沒電.對應的便是 1, 0).
由於計算機的整形存儲是以二進制的形式.因此有個細節能夠注意,對於整數進行 2 的次冪乘除的時候,能夠用移位來實現.這樣效率會更高函數
下面來擴展下思路.既然計算機存儲的數據格式是二進制,那麼咱們就簡單下如何用布爾運算來實現有符號整數加法與乘法的方式.這裏只是作個擴展思路,實際計算機的操做可能有被優化過.學習
-- 加法 --優化
一個加法能夠拆分紅布爾運算的 *與* 與 *異或* 的組合的屢次迭代 兩個數相與後再左移 1 位能夠獲得這兩個數相加的 *進位*, 而兩個數的異或能夠獲得兩個書相加的 *本位* 若 *進位* 爲 0 那麼,當前的 *本位* 及是加法的運算結果,若不爲 0 重複將 *進位* 與 *本位* 繼續進行 *與* 與 *異或* 直至 *進位* 爲 0. 舉個例子吧 第一輪: 本位: 101001 ^ 001001 = 100000 進位: 101001 & 001001 = 001001 << 1 = 010010 第二輪: 本位: 100000 ^ 010010 = 110010 進位: 100000 & 010010 = 000000(爲 0 結束) 因此的到 101001 與 001001 的相加結果 110010
-- 乘法 --編碼
乘法的本質就是加法的迭代,那麼咱們能夠用更貼近計算機處理的思路來想問題.若 n * m,能夠講 m * n 拆分紅 m*(2^x + 2^y + 2^w + ...) 舉個例子: 好比 6 * 5 , 而後我按照 m*(2^x + 2^y + 2^w + ...) 的拆分能夠獲得 6(2^2 + 2^0),那下面我就用二進制的表達式列出下運算公式. 110 * 101 = (110 << 000) + (110 << 010) = 110 + 11000 = 11110 這裏看似正常,可是若 n,m 中出現了負數的話運算結果卻會使人瞪目結舌.正像上面說的負數也是以補碼形式存放在內存中的.那麼咱們可能要在運算前對 m,n 進行一步處理,即把 m,n 還原成源碼再而後在進行運算.固然在運算時候切記不要把符號位帶入運算當中.並且得到運算結果後記得把結果轉換爲補碼的形式.
既然瞭解了整形變量是如何存儲在內存當中的,那麼咱們也瞭解下浮點型是如何存儲在內存中的吧.浮點型是遵守 [IEEE 754] 標準.也能夠點 [這裏] 簡單地瞭解下什麼是浮點數.也正由於它存儲數據的方式.致使它所表達的具體值可能存在精度不夠準確.指針
既然計算機只能識別些 1010 的二進制那麼字符又是如何被存儲的呢?固然你不可能 'a' 這個字符直接寫入內存中,那麼就找個折中辦法吧.咱們用一個數值來對應一個字符.而後把這個記錄在內存中,接着咱們就能夠經過這個數值找個這個字符.下面咱們就簡單的瞭解一些相關的專業名詞和對於的解釋吧.code
這裏可能要補充一點 當你在使用 char 時候,若第一個字符大於 0x80,那麼就必須檢查下一個字節,才能判斷一個完整的字符.
在使用變量的時候應該注意變量的生存週期(即變量的做用域),以避免引用了已經脫離做用域的變量,好比返回了一個指向函數局部變量的指針.可參看下表:
變量存儲類別 函數內 函數外 做用域 存在性 做用域 存在性 auto 與 register √ √ × × static(局部) √ √ × √ static(外部) √ √ √(只限本文件) √ extern √ √ √ √
在初步瞭解變量的做用域,順帶這裏也能夠初略解下 C++ 在編譯的程序時候會把程序內存分爲的幾個部分: