C++ 記事本: 變量

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 字節)
    [還有在使用 wchar_t , char 類型時候須要注意區分要使用與之對應的容器或函數.好比 char 對應的字符串容器是 string,而 wchar_t 對應的容器是 wstring,而在屏幕輸出上 char 對應的 cout,而 wchar_t 對於的是用 wcout]
  • 布爾類型
    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

  • 字符(Character)是指人類語言中最小的表義符號.例如 'A'、'B' 等;想知道更多點 [這裏]
  • 字符編碼(Encoding) 是指給定一系列字符,對應每一個字符賦予一個特殊的數值,並能夠用這數值來表明對應的字符.例如,咱們給字符 'A' 賦予數值 0,給字符 'B' 賦予數值 1,則 0 就是字符 'A' 的編碼;想知道更多點 [這裏] 一幫咱們使用比較多的編碼集是 ASCII , Unicode(utf-8,utf-16), GBK.
  • 字符集(Character Set) 是指給定一系列字符並賦予對應的編碼後,全部這些字符和編碼對組成的集合就.例如,給定字符列表爲{'A','B'}時,{'A' => 0, 'B' => 1}就是一個字符集;
  • 字符序(Collation) 是指在同一字符集內字符之間的比較規則;肯定字符序後,才能在一個字符集上定義什麼是等價的字符,以及字符之間的大小關係;每一個字符序惟一對應一種字符集,但一個字符集能夠對應多種字符序,其中有一個是默認字符序(Default Collation);

這裏可能要補充一點 當你在使用 char 時候,若第一個字符大於 0x80,那麼就必須檢查下一個字節,才能判斷一個完整的字符.

 

-- 變量做用域 --

在使用變量的時候應該注意變量的生存週期(即變量的做用域),以避免引用了已經脫離做用域的變量,好比返回了一個指向函數局部變量的指針.可參看下表:

變量存儲類別       函數內                 函數外
                 做用域    存在性        做用域      存在性
auto 與 register  √        √           ×           ×
static(局部)     √        √           ×           √
static(外部)     √        √           √(只限本文件) √
extern            √        √           √           √

在初步瞭解變量的做用域,順帶這裏也能夠初略解下 C++ 在編譯的程序時候會把程序內存分爲的幾個部分:

  • 棧區: 由編譯器自動分配釋放的,存放着函數的參數值,局部變量的值,其操做方式相似於數據結構中的棧(申請)速度快,但程序員沒法控制.
  • 堆區: 由程序員分配釋放,程序員不釋放程序結束時可能回收,分配方式相似鏈表(申請速度慢,易產生內存碎片).
  • 全局區/靜態區: 全局變量與靜態變量的存儲是放一塊的,初始化全局變量在一塊區域內,未初始化的靜態變量在相鄰的另外一塊區域內,程序結束後由系統釋放,內存在整個運行期間都存在.
  • 字符常量區: 常量字符串就是放在這裏,程序結束後由系統釋放.
  • 程序代碼區: 存放函數體的二進制代碼,在這裏存放的變量又稱字面常量
相關文章
相關標籤/搜索