第一周筆記 - 第二章和第三章

使用初始化列表初始化內(nèi)置類型的時候,編譯器會做更加嚴(yán)格的檢查。

按書上的說法jk都會有編譯錯誤。而i可能不會有編譯錯誤,雖然現(xiàn)在大多數(shù)的編譯器在i的時候都會報錯。所以個人覺得對于內(nèi)置類型也使用初始化列表來初始化不是個強(qiáng)制要求,因為代碼看起來不舒服,還要多打幾個字母。

    int i = 1.1;
    int j{ 1.1 };
    int k = { 1.1 };

任何顯式的初始化都會把聲明變成定義。

extern int g_i = 0;這是個定義。

聲明其實(shí)也可以寫在函數(shù)內(nèi)。

比如在調(diào)試程序的時候,我喜歡寫下面這樣的代碼。目的在于懶得跳到函數(shù)的最前面寫上extern int g_i,跳來跳去麻煩,回頭要刪除代碼的時候,也要刪兩處。而直接在用的地方這么寫就方便多了。當(dāng)然在正式的產(chǎn)品代碼中,不推薦這么寫。

int foo(){
    extern int g_i;
    g_i = 10;
}

P33 如何表示類型的最大最小值。

如果想知道各個類型的最大最小值,在C下應(yīng)該查看三個頭文件:limits.hfloat.h,stdint.h。其中規(guī)定了諸如INT_MAX,ULONG_MAX的宏。
在C語言出生的那個年代,處理器各種各樣,為了保證C語言的可移植性,C語言的標(biāo)準(zhǔn)甚至連char bit都是用宏來定義的。

define CHAR_BIT 8 /* number of bits in a char */

在C++語言下使用頭文件limits(沒有.h的版本)里面的std::numeric_limits。

std::numeric_limits<int>::lowest()
std::numeric_limits<int>::max()

不太熟悉和用的不多的C++關(guān)鍵字 P43

  • alignas
  • alignof
  • noexcept
  • constexpr
  • thread_local

操作符替代名 P43

其實(shí)挺喜歡用not代替!,因為!有時候太小了,常常忘記沒看到。用not就可讀多了,不過似乎沒人這么用,那就算了吧。

#include <iso646.h>
int foo(int *p){
    if (!p){}

    if (not p){}
}

內(nèi)置類 P45

沒聽過這個詞,

constexpr

這個東西后面的章節(jié)還要提,暫時這里就不去深究了。constexpr指的是一種在編譯階段就能計算出值的表達(dá)式,在某些特定場合,比如說聲明數(shù)組的時候,都必須使用編譯期常量,因為編譯器必須知道數(shù)組的長度。比如說下面的代碼是可行的。

const int a = 10;
int b[a + 20] = { 0 };

但是在C++03的時代,一個常量是否被當(dāng)成編譯期常量完全是編譯器自己憑感覺。比如說下面size()明顯就是個常量,但是編譯器并不會把它當(dāng)成一個常量。

int size(){ return 10; }
int c[size()] = { 0 }; //error here

所以直覺上c++11引入這個新的東西的目的就是告訴編譯器這里需要一個編譯期常量,請試圖去計算這個表達(dá)式。比如說下面這段代碼是正確的,編譯器是會在編譯階段來計算sum(10)的值。PS: VS2013還沒有很好的支持constexpr,所以要嘗試下面的代碼,可以試試GCC或者Clang

constexpr int sum(int n) {
    return n <= 1 ? 1 : n + sum(n - 1); 
};
int d[sum(10)] = { 0 };

constexpr指針

如果嚴(yán)謹(jǐn)?shù)恼f,consexpr不一定都是編譯期就能及計算出來的值,比如說constexpr指針。從下面這段代碼為例,p1的值必須等到運(yùn)行階段才能知道,所以p2 - p1就不可能是一個constexpr

//global
int i, j;
constexpr int * p1 = &i;
constexpr int * p2 = &j;
constexpr int c1 = p2 - p1; // wrong here

某些情況下編譯器也能比較聰明的處理下面這種情況。

int a[10];
constexpr int *p = &a[1];
constexpr int *pp = &a[5];
constexpr int c = pp - p; // correct

類型別名 P60

初略的查了一下資料,using和typedef是等價的,所以應(yīng)該用using來替代掉typedef。主要目的是可讀性比較好。

指針,常量和類型別名 P61

書上提到了把pstring展開后來理解類型是不對的,cstrcstr1其實(shí)是不一樣的類型。

typedef char* pstring;
const pstring cstr = 0; // cstr is const pointer to char type
const char* cstr2 = 0; // cstr2 is pointer to const char type

這里想了個小技巧,沒有特別細(xì)究,但估計是正確的方法。當(dāng)遇到const T的情況,把前置的const寫到類型后面,如T const。這樣在做展開就沒錯了。

pstring const cstr = 0; // const pointer to char type;
char * const cstr2 = 0; // const pointer to char type;

當(dāng)把const放到后面以后,解讀類型就可以方便的從右到左的讀出來。
&替換成reference to,把*替換成pointer to;那就是很自然的話了。

char *p;
char const * const & k = p; // K is reference to const pointer to const char;

top-level const和low-level const

如果把const放到了類型的右邊,那么top-level const就是直接靠近變量的標(biāo)識符的const,這個const限制的是變量本身不能改變。為什么會用top-level和low-level這兩個詞呢,估計是從編譯原理里面的語法樹分析借鑒來的。

auto關(guān)鍵字。

auto關(guān)鍵字有兩個特點(diǎn),頂層的引用屬性和const屬性會被去掉。

const int ci = 10;
const int &r = 10;
auto a = &ci;
const auto &b = r;

&c的類型是int const *,所以沒有top-level const。那么a的類型就是int const *
&r的類型是int const &,去掉頂層的引用變成int const,那么b的類型就是(int const) const & b; 兩個const都修飾左邊的int。也就是int const & b

decltype就沒有講透,需要進(jìn)一步的細(xì)化。

這個東西在寫模板的時候很有用處,所以需要仔細(xì)的了解。

關(guān)于表達(dá)式i=10的類型

在練習(xí)2.37 P64也提到了i=x的類型是int&,所以下面這段代碼是可行的。但只是在C++下可行,在C下是不可行的。

int i, *p;
(i = 10) = 20;
p = &(i = 1);

當(dāng)使用字符串初始化std::string時,如果字符串中間包含了'\0'字符,如何繞過去。

如例子s2,可以使用另外一個構(gòu)造函數(shù)Constructs the string with the contents of the range [first, last).

int main(){
    char s[] = "first\0second";
    string s1(s); // only get "first "
    cout << s1.length() << " : " << s1 << endl;
    string s2(s, s + sizeof(s));
    cout << s2.length() << " : " << s2 << endl;
}

輸出是

5 : first
13 : first second

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容