C++ primer讀書筆記(1-3章)

  • 使用istream對象作爲條件時,其效果是檢測流的狀態.如果流是有效的,即流未遇到錯誤,那麼檢測成功,返回true ,如果遇到文件結束符(end of file ),或遇到一個無效輸入時(例如輸入的值不是一個整數),istream對象的狀態會變爲無效.處於無效狀態的istream對象使條件變爲假

  • windows操作系統中,輸入文件結束符的方法是ctrl+z ,然後回車.UNIX系統中包括mac osx系統,輸入ctrl+D

  • 標準庫頭文件通常不帶後綴,自定義的頭文件根據其中定義的類的名字命名,自定義類首字母大寫,用下劃線連接

  • C語言中的庫,在C++中都可以導入,格式爲c+原庫名 ,如cstdio

  • 類類型的變量如果未指定初值,則按類定義指定的方式進行初始化.定義在函數內部的內置類型變量默認是不初始化的,除非有顯式的初始化語句.全局變量默認初始化.

  • 基本數據類型的尺寸(即所佔的比特數)在不同的機器上有所差別,C++標準規定尺寸的最小值,同時允許編譯器賦予這些類型更大的尺寸.

  • 類型所能表示的值的範圍決定了類型轉換的過程

    • 非布爾類型算術值賦給布爾類型時,初始值爲0結果爲false,否則結果爲true
    • 布爾值賦給非布爾類型,初始值爲false,結果爲0,否則爲1
    • 浮點數賦給整數類型,小數部分記爲0,整數所佔空間超出浮點類型的容量,精度可能丟失,保留低位,高位截去
    • 賦給無符號類型一個超出它表示範圍的值時,結果是初始值對無符號類型表示數值總數取模後的餘數.
    • 賦給帶符號類型一個超出它表示範圍的值時,結果是未定義的(undefined)
    • 有符號<<==>>無符號(均是補碼錶示):對原數據內容不變,解釋方式改變(即第一位是否爲符號位,正負數有不同的解釋方式)
    • 長整數<<==>>短整數:短變長,符號擴展,長變短,高位截斷,低位保留
  • 編譯器在每個字符串的結尾處添加一個空字符('\0'),因此字符串字面值的實際長度要比他的內容多1.

  • nullptr是指針字面值

  • C++中的每個變量都有其數據類型,數據類型決定變量所佔內存空間的大小和佈局方式,該空間能存儲的值的範圍,以及變量能參與的運算.

  • 在C++語言中,初始化和賦值是兩個完全不同的操作,初始化不是賦值,初始化的含義是創建變量時賦予其一個初始值,賦值的含義是把對象的當前值擦除,而以一個新值來替代.

  • 如果定義變量時沒有指定初值,則變量被默認初始化,此時變量被賦予默認值,默認值到底是什麼由變量類型決定,同時定義變量的位置也會對此有影響.如果是內置類型的變量未被顯式初始化,它的值由定義的位置決定.定義於任何函數體之外的變量被初始化爲0,定義在函數體內部的內置類型變量將不被初始化.一個未被初始化的內置類型變量的值是未定義的,如果試圖拷貝或以其他形式訪問此類值將引發錯誤.每個類各自決定其初始化對象的方式.

  • 爲了支持分離式編譯,C++語言將聲明和定義區分開.聲明(declaration)使得名字爲程序所知,一個文件如果想使用別處定義的名字則必須包含對那個名字的聲明.而定義(definition)負責創建與名字關聯的實體.變量聲明規定了變量的類型和名字,在這一點上定義與之相同,但是除此之外,定義還申請存儲空間,也可能會爲變量賦一個初始值.如果想聲明一個變量而非定義它,就在變量名前添加關鍵字extern,而且不要顯式初始化變量:

    extern int i;//聲明i而非定義i
    int j;//聲明並定義j
    

    任何包含了顯式初始化的聲明即成爲定義,可以給extern關鍵字標記的變量賦一個初始值,但是這麼做抵消了extern的作用.extern語句如果包含初始值就不再是聲明,而是定義:

    extern double pi = 3.1415;//定義
    

    變量能且只能被定義一次,但是可以被多次聲明.

  • 引用爲對象起了另外一個名字,引用類型引用另外一種類型.通過將聲明符寫成&d的形式來定義引用類型.一般在初始化變量時,初始值會被拷貝到新建的對象中,然而定義引用時,程序把引用和它的初始值綁定(bind)在一起,而不是將初始值拷貝給引用.一旦初始化完成,引用將和它的初始值對象一直綁定在一起.因爲無法令引用重新綁定到另外一個對象,因此引用必須初始化.

  • 引用並非對象,他只是一個已經存在的對象所起的另外一個名字.定義了一個引用之後,對其進行的所有操作都是在與之綁定的對象上進行的.引用只能綁定到對象上,而不能與字面值或某個表達式的計算結果綁定在一起

  • 指針本身就是一個對象,允許對指針賦值和拷貝,而且在指針的生命週期內它可以先後指向幾個不同的對象.指針無需在定義時賦初值.和其他內置類型一樣,在塊作用域內定義的指針如果沒有被初始化,也將擁有一個不確定的值.

  • 任何非0指針對應的條件值都是true

  • void*是一種特殊的指針類型,可用於存放任意對象的地址.一個void*指針存放着一個地址,我們對該地址中到底是個什麼類型的對象並不瞭解.利用void*指針能做的事比較有限,拿它和別的指針比較,作爲函數的輸入或輸出,賦給另外一個void*指針,不能直接操作void* 指針所指的對象,因爲我們並不知道這個對象到底是什麼類型,也就無法確定能在這個對象上做哪些操作.概括說來,以void*的視角來看內存空間也就僅僅是內存空間,沒辦法訪問內存空間中所存的對象.

  • 理解複合類型的聲明

    //i是一個int型的數,p是一個int型指針,r是一個int型引用(要理解類型修飾符只是聲明符的一部分)
    int i = 1024 , *p = &i, &r = i;
    
    //定義多個變量
    //p1是指向int的指針,p2是int類型
    int* p1,p2;
    
  • 面對一條比較複雜的指針或者引用的聲明語句時,從右向左閱讀有助於弄清楚它的真實含義.

  • 因爲const對象一經創建後其值就不能再改變,所以const對象必須初始化.

  • 有兩種方法可以用於定義類型別名

    typedef double wages;	//wages是double的同義詞
    typedef wages base,*p;	//base是double的同義詞,p是double*的同義詞
    using SI = Sales_item;	//SI是Sales_item的同義詞
    
  • auto讓編譯器通過初始值來推算變量的類型.顯然auto定義的變量必須有初始值,使用auto也能在一條語句中聲明多個變量,因爲一條聲明語句只能有一個基本數據類型,所以該語句中所有變量的初始基本數據類型都必須一樣.

  • c++11新標準規定,可以爲結構體的數據成員提供一個類內初始值,創建對象時,類內初始值將用於初始化數據成員,沒有初始值的成員將被默認初始化.

  • 預處理器是在編譯之前執行的一段程序,可以部分的改變我們所寫的程序,如當預處理器看到#include標記時就會用指定的頭文件的內容代替#include

  • 一個標準的自定義頭文件結構

    #ifndef SALES_DATA_H
    #define SALES_DATA_H
    #include<string>
    
    struct Sales_data{
        std::string bookNo;
        unsigned units_sold = 0;
        double revenue = 0.0;
    };
    #endif
    

    使用這些功能可以有效地防止重複包含頭文件

    發表評論
    所有評論
    還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
    相關文章