C++--primer-第二章

C++中變量以及基本類型

內置類型包括:字符,整型,浮點型等;同時C+還支持更加復雜的數(shù)據(jù)類型,首先來看看基本的內置類型;
C++定義的內置類型

  • 算數(shù)類型
    • 整形:
      • bool:布爾類型,用于表示真和假;
      • char:字符型,最小尺寸為8位;
      • wchar_t:表示寬字符,最小尺寸為16位;
      • char16_t:表示最小尺寸為16位,Unicode字符;
      • char32_t:表示最下尺寸為32位,Unicode字符;
      • short:表示短整型,最小長度為16位;
      • int:表示整型,最小尺寸為16位;
      • long:表示長整型,最小尺寸為32位;
      • long long:長整型,最小尺寸為64位;
      • float:單精度浮點數(shù),6位有效數(shù)字;
      • double:雙精度浮點型,10為有效數(shù)字;
      • long double:擴展精度浮點型,10位有效數(shù)字;
    • C++中對于長度的規(guī)定:一個int至少和一個short一樣大,一個long至少
      和一個int一樣大,一個long long至少和一個long一樣大,其中long long類型是C++11標準中定
      義的;
    • 整型按照不同的標準還可以劃分成為帶符號整型(用于表示正數(shù),負數(shù),0),無符號類型(只能用于表示正數(shù)),
      默認的都是帶符號的,可以通過unsigned來表示無符號類型;
    • 類型轉換
      • 類型所能表示的范圍決定了轉換的過程

      • 非布爾類型的算數(shù)值賦值給布爾類型時,初始值為0,賦值結果為false,否則結果為true;

      • 如果講上面的過程反過來進行賦值,初始值為false結果為0,初始值為true結果為1;

      • 如果將一個浮點數(shù)據(jù)賦值給整數(shù)類型時,結果僅僅保留浮點數(shù)據(jù)的整數(shù)部分;

      • 整數(shù)賦值為浮點數(shù)據(jù)類型時,小數(shù)部分為0,,如果整數(shù)的類型超過了浮點類型,精度就會有所損失;

      • 如果將一個大范圍的數(shù),賦值給一個小范圍的類型,賦值后的結果是進行取余操作;

#include <iostream>

using namespace std;

int main(){
    bool bi = 10;
    bool by = 0;
    cout << "one is "<< bi << " Next one is  " <<  by << endl;

    int i ;
    i = 3.14;
    cout << "The i(int) is "<< i << endl;

    double dx ;
    dx = 1;
    cout << "The dx(double) is " << dx << endl;

    unsigned char cx = -1;
    cout << "Unsigned char(cx) is " << (int)cx << endl;

    unsigned char cy = 256;
    cout << "Unsigned char(cy) is " << (int)cy << endl;
}

字面值常量

每個字面值常量都對應一種數(shù)據(jù)類型,字面值常量的形式和值決定了它的數(shù)據(jù)類型;

  • 整型和浮點型
    字面值包括十進制,八進制,十六進制等形式,用0開始代表八進制,使用0x或者0X開頭代表十六進制;對
    于整型字面值常量的具體數(shù)據(jù)類型由它的值和符號來決定;
  • 字符和字符串型
    使用''包含的單個字符稱為char字面值,使用""包含的0個或者多個字符稱為字符串字面值;字符串字面值
    通常表示的是由常量字符構成的數(shù)組,編譯器會在每個字符串的結尾使用\0,字符'A'表示的是單個字符
    但是"A"表示的是兩個字符'A'和\0;對于編譯器來說,如果存在兩個字符串字面值之間僅僅由空格,縮進,
    和換行符分離,name本質上就是一個整體;
  • 常用的轉移序列
    • 程序員不能夠直接使用的字符包含以下兩種:
      • 1 不可打印字符,比如退格符號,換行符號;
      • 2 在C++語言中由特殊定義的符號:單引號,雙引號,問號,反斜線等,這就需要使用轉義序列;
符號 含義
\n 換行符,可以用于結束本行輸入,進入下一行,也用來刷新緩存
\t 橫向制表符號,每次縮進有限個單位
\v 表示縱向指標符號,垂直制表符號
\b 表示退格符號,每次回退一格
" 用于打印""
\ 用于轉義\
? 用于轉義?
' 用于轉義''
\r 表示回車符號
\f 表示進紙符號
以上字符都是被當做一個字符來進行使用的;
  • 指定字面值類型
    通過添加前綴或者后綴的方法可以用來改變整形,浮點型和字符型字面值的默認類型;
前綴 含義 類型
u Unicode 16字符 char16_t
U Unicode 32字符 char32_t
L 寬字符 wchar_t
u8 UTF-8(僅僅用于字符串字面值常量) char
    • 整數(shù)型字面值
后綴 最小匹配類型
u or U unsigned
l or L long
ll or LL long long
  • *浮點型字符類型
后綴 類型
f or F float
l or L long double
  • 布爾字面值
    truefalse都是布爾類型的字面值;
變量

變量提供一個具名的,可供程序操作的存儲空間,數(shù)據(jù)類型決定著變量所占內存空間的大小和布局方式該空間能
存儲值的范圍,以及變量能夠參與的運算;

  • 定義變量
    int sum1,sum2;:首先是類型名,然后是變量列表,最后是;結尾;

    • 對象:對象表示的是一塊能夠存儲數(shù)據(jù)并且具有某種類型的內存空間;
      • 對象可以表示類中;
      • 通常已經(jīng)命名的對象成為變量;
      • 對象還用于表示能夠被程序修改的數(shù)據(jù),值通常用來表示只讀的數(shù)據(jù);
    • 還是將對象理解為某種數(shù)據(jù)類型的內存空間;
  • 初始化和賦值操作

    • 初始化:對象在創(chuàng)建時獲得的某個特定的值;在變量的初始化過程中,在一條語句中可以用一個已經(jīng)初始化
      的變量去為另一個要定義的變量進行初始化操作;
    • 賦值操作:表示的是將對象的當前值擦除,用一個新的值來進行代替;
      初始化的四種方式
    int i1 = 0;
    int i2 = {0};
    int i3(0);
    int i4{0};
    
    
    • 默認初始化操作:如果定義變量時,沒有指定初始值,變量會執(zhí)行默認初始化,默認值由變量類型來決定;如果
      內置類型的變量未被初始化,定義于任何函數(shù)值外的變量會被初始化為0,定義域函數(shù)體內部的內置類型的變
      量將不會被初始化,如果訪問此類未被初始化的內置類型數(shù)據(jù)會發(fā)生錯誤;
      在類里面可以各自決定其初始化對象的方式,并且是否允許不初始化就定義對象,也有類本身決定;
    • 當時用列表數(shù)初始化時枪眉,初始數(shù)值存在丟失的風險,編譯器回進行報錯;
  • 聲明和定義的關系:

    • C++語言中為了支持分離式編譯帖努,通常將聲明和函數(shù)的定義分開帮碰;
    • 聲明使得名字為人所知,聲明使用extern比如extern int i笨使,表示的含義是僅僅是聲明了這個變量美澳,但是不能夠顯式的初始化這個變量;
    • 定義負責創(chuàng)建和名字關聯(lián)的實體眠饮;
    • 變量只能夠被定義一次奥帘,但是可以被聲明很多次;
    • 如果extern包含初始值就變成了定義;
      總結:
    • 也就是當變量的定義前面有關鍵字extern時,并且沒有進行變量的初始化賦值,就是變量的聲明;
    • C++語言是一種靜態(tài)類型的語言,也就是說,在編譯階段段進行類型檢查;
  • 標識符
    組成:C++語言的標識符,必須由字母.數(shù)字和下劃線組成,并且必須由字母或者下劃線開頭,標識付沒有長度限制;

    注意:
    * 用戶自定義的標識符不能夠出現(xiàn)兩個連續(xù)的下劃線;
    * 同時也不能夠使用下劃線緊跟大寫字母開頭;

    • 變量的命名規(guī)范
      • 標識符需要體現(xiàn)特定的意義
      • 變量名稱一般使用小寫;
      • 用戶自定義的類名一般使用大寫字母開頭;
      • 如果標識符有多個單詞組成,單詞之間應該又明顯的區(qū)分;
        C++關鍵字一共有:5*13+8=73關鍵字;
  • 作用域
    作用域表示的是大部分是使用{}進行分割的,并且作用域是可以進行嵌套的,當某個作用域中定義了變量,那么在其嵌套的的作用
    域中都是可以訪問該變量的;

    • 一個建議就是局部變量盡量不要和全局變量沖突;
  • 復合類型

    • 引用
      引用可以分為左值引用和右值引用;
      • 左值引用:引用就是個對象起了另外一個名字.并且引用必須被初始化,且不能夠修改引用的值,也就是說引用無法綁定一個
        新的對象;對于引用的操作等價于對于引用對象的操作;
    • 指針
      和引用的不同:
      * 指針本身就是一個對象,允許對于指針進行賦值和拷貝,在指針的生命周期內,可以指向幾個不同對象;
      * 指針不需要在定義時,就進行賦值;
      指針存放的是某個單元的地址,引用只是一個別名,并沒有地址,所以不能夠定義指向引用的指針
      int ival = 1024;
      int *p = &ival;
      
      如果這樣定義
      int inval = 1024;
      int &rival = ival;
      int *p = rival;
      
      但是這樣其實也是可行,書里面說的不能夠定義指向引用的指針,上面的代碼都是沒有任何錯誤的的;
      指針是一個地址,獲取地址使用&運算符;
    • 當存在指針時,指針的四種指向:
      • 指針指向一個對象;
      • 指向緊鄰對象所占空間的的下一個位置;
      • 空指針,也就是指向NULL;
      • 無效指針,也就是指向其他情況;
    • 解引用
      如果需要利用指針來訪問對象,就需要使用解引用符號*;
      需要說明的是借用操作僅僅適合于那些真正指向某個對象的有效地址的指針;
    • 空指針的初始化
    int *pival1 = nullptr;
    int *pival2 = 0;
    int *pival3 = NULL; //這里需要#include<cstdlib>
    

    nullptr:是字面值,這個是C++11引用的新標準,是一種特殊的字面值,可以被轉換成任意的指針類型;
    建議使用這種方式進行控制真的初始化;書里面給出的一點建議:初始化所有定義的指針;

    • void *指針
      void *類型的指針可以用于存放任意對象的地址,所以不確定是什么類型的時候,建議聲明成這種類型;
    • 指針與引用的區(qū)別
    • 引用本身不是一個對象,但是指針是一個對象,所以引用是可以指向指針的;
    int i = 42;
    int *p;
    int *&r = p;
    
  • const 限定符

    • 當定義某一個值,并且希望這個值不被改變時.可以使用const限定符;
    • 需要注意的是const定義時,就需要進行初始化,如果執(zhí)行了默認初始化,之后值就不能夠進行更改;
    • 如果利用一個對象來初始化另一個對象,那么兩個對象是不是const并沒有太多的要求;
    • 在默認情況下,const對象僅僅在文件內部有效;如果多個文件之間需要共享const文件,那么需要使用關鍵字extern;
  • const與引用

    • 當引用和const進行綁定時,對常量的引用不能夠用來修改所綁定的對象;
    • 當對象是一個const常量時,那么引用也必須是一個const常量;
    const int ci = 1024;
    const int &rci = ci;
    int &r2 = ci;  //因為`ci`是一個`const`常量,所以引用必須是`const`常量,所以這里會出錯;
    
    • const引用通常稱為"常量引用";
    • 引用的類型必須和所引用對象的類型一致,但是例外的情況有兩種:
      • 初始化常量引用時,允許用任意表達式作為初始值;
      int i = 42;
      const int &r1 = i;
      const int &r2 = 42;
      int &r4 = r1; //這個操作就是錯誤的,`r4`是一個非常量的引用;
      
    • const的引用可能引用一個非const的值;
      • const int& i2 = i,其中i不一定是一個常量值;因為const引用并不要求i為常量,但是反過來,當i為常量,對i
        的引用必須是const常量引用;
  • const和指針

    • pi是一個常量時,pi的指針也必須是一個常量
    const double pi = 3.14;
    const double* cptr = π
    
  • 一點小總結:

    • 指向常量的指針或者引用,只不過是指針或者常量以為自己指向了常量,而不去修改常量的值,但是實際上,這些值往往
      是可以改變;
    • 指針允許定義為常量,但是常量指針必須進行初始化;int *const ptr=&tr;
  • 頂層const與底層const

    • 這里涉及兩個問題,首先:指針是常量還是指針所指向的對象是個常量,頂層const表示的是指針本身是一個常量,爾底層const用于表示指針所指向的對象是一個常量;
    • 另一方面來說頂層const用于表示任意的對象是常量,但是底層的const用于表示指針和引用某些部分是常量;
    • 指針類型可以表示頂層也可以表示底層;
    • const int *const pintq = &intq:對于這個來說最左邊的const表示底層,右邊的const表示頂層;
    • 用于聲明引用的都是底層const;
    • 這些區(qū)別在進行對象拷貝是區(qū)別明顯;
  • 常量表達式

    • 用于表示在程序的便以階段就得到結果的表達式,常見的包括const初始化的對象,字面值常量;
    • 所以const int size = get_size(),這個就不是常量表達式;size的值只有等到程序運行時才可以的得到;
    • C++11允許將一個可能是常量表達式生命為constexpr,讓編譯器進行檢查;
  • 字面值常量

    • 算數(shù)類型,引用和指針都屬于字面值類型,其中指針被定義為constexpr時,初始值必須是nullptr或者是0,或者是某個固定
      地址里面的對象;
    • 函數(shù)體里面的變量一般存放于非固定的位置,所以不能夠使用constexpr,但是所有函數(shù)體外的變量則例外;
    • 如果再consexpr聲明時,定義了一個指針,那么該限定符僅對指針有效和指針所指向的對象無關;
  • 類型處理
    兩種辦法:

      *  `typedef oldname newname` 
      *  `using newname = oldname`;
      *  定以后的別名和原來的名稱完全等價,但是在理解替換后的別名時,是不能夠替換回去的,這樣產(chǎn)生的理解是錯誤的;
      * 例如:`typedef char* pstring;  const pstring cstr = 0; const pstring *ps;` 
      * 對于替換之后的解釋,首先應該解釋變量本身的類型,`cstr`是一個沒有類型的,其次解釋`pstring`的含義,是一個常量指
      針,所以`cstr`是一個指向`char`的常量指針;對于`ps`,首先是一個指針類型,其次它的對象是一個指向`char`的常量指針;
      * 如果進行替換就會影響`const`和`*`的相對位置,從而理解含義就會發(fā)生變換;
    
  • auto類型說明符

    • auto通過初始值來推斷變量的類型.所以使用auto時,必須包含初始值,如果連續(xù)進行賦值操作,那么類型必須是匹配的;
    • 對于引用來說,編譯器使用應用對象的類型作為auto的類型;
    • auto會忽略頂層的const,但是會保留底層const;但是可以通過添加const來保留頂層const;這是對于指針來說;
    • 當設置為一個引用的auto時,初始值中頂層的const仍然有效;
    • 在一條語句中定義多個變量時,符號&*不屬于基本數(shù)據(jù)類型;
  • decltype類型指示符

    • 需要通過表達式的類型來定義自己需要的類型,但是有不對表達式進行變量的初始化;

    • decltype(f()) sum = x;編譯器可以通過分析返回值f的類型得到sum的類型,而不需要對x進行類型的判定;

    • decltype,如果使用的表達式是一個變量,那么decltype返回該變量的類型(包括頂層的const和引用);

    • 引用一直是引用對象的同義詞,但是在decltype是一個例外;

    • const int& cj = 0;decltype(cj) = ci;在這里cj是一個const int&的引用,但是和引用本身的對象沒有關系,只和類
      型有關;

    • 如果decltype(*p),如果進行解引用操作,那么得到的就是一個引用類型,并且引用類型必須有初始值;

    • int i; decltype((i));decltype(i);,前者得到是int& 類型,后者得到的是int類型;(()):表示的一定是引用;

    • 類里面的數(shù)據(jù)成員,在定義對象之后,每個對象都有數(shù)據(jù)的一份拷貝,數(shù)據(jù)之間是不會相互影響的;

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末仪召,一起剝皮案震驚了整個濱河市寨蹋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌扔茅,老刑警劉巖已旧,帶你破解...
    沈念sama閱讀 223,002評論 6 519
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異召娜,居然都是意外死亡运褪,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,357評論 3 400
  • 文/潘曉璐 我一進店門玖瘸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來秸讹,“玉大人,你說我怎么就攤上這事雅倒×Ь鳎” “怎么了?”我有些...
    開封第一講書人閱讀 169,787評論 0 365
  • 文/不壞的土叔 我叫張陵蔑匣,是天一觀的道長劣欢。 經(jīng)常有香客問我,道長殖演,這世上最難降的妖魔是什么氧秘? 我笑而不...
    開封第一講書人閱讀 60,237評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮趴久,結果婚禮上丸相,老公的妹妹穿的比我還像新娘。我一直安慰自己彼棍,他們只是感情好灭忠,可當我...
    茶點故事閱讀 69,237評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著座硕,像睡著了一般弛作。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上华匾,一...
    開封第一講書人閱讀 52,821評論 1 314
  • 那天映琳,我揣著相機與錄音,去河邊找鬼。 笑死萨西,一個胖子當著我的面吹牛有鹿,可吹牛的內容都是我干的。 我是一名探鬼主播谎脯,決...
    沈念sama閱讀 41,236評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼葱跋,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了源梭?” 一聲冷哼從身側響起娱俺,我...
    開封第一講書人閱讀 40,196評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎废麻,沒想到半個月后荠卷,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,716評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡脑溢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,794評論 3 343
  • 正文 我和宋清朗相戀三年僵朗,在試婚紗的時候發(fā)現(xiàn)自己被綠了赖欣。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片屑彻。...
    茶點故事閱讀 40,928評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖顶吮,靈堂內的尸體忽然破棺而出社牲,到底是詐尸還是另有隱情,我是刑警寧澤悴了,帶...
    沈念sama閱讀 36,583評論 5 351
  • 正文 年R本政府宣布搏恤,位于F島的核電站,受9級特大地震影響湃交,放射性物質發(fā)生泄漏熟空。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,264評論 3 336
  • 文/蒙蒙 一搞莺、第九天 我趴在偏房一處隱蔽的房頂上張望息罗。 院中可真熱鬧,春花似錦才沧、人聲如沸迈喉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,755評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挨摸。三九已至,卻和暖如春岁歉,著一層夾襖步出監(jiān)牢的瞬間得运,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,869評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留熔掺,地道東北人彬檀。 一個月前我還...
    沈念sama閱讀 49,378評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像瞬女,于是被迫代替她去往敵國和親窍帝。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,937評論 2 361

推薦閱讀更多精彩內容