使用初始化列表初始化內(nèi)置類型的時(shí)候骏掀,編譯器會(huì)做更加嚴(yán)格的檢查。
按書上的說(shuō)法j
和k
都會(huì)有編譯錯(cuò)誤卸夕。而i
可能不會(huì)有編譯錯(cuò)誤层释,雖然現(xiàn)在大多數(shù)的編譯器在i
的時(shí)候都會(huì)報(bào)錯(cuò)。所以個(gè)人覺得對(duì)于內(nèi)置類型也使用初始化列表來(lái)初始化不是個(gè)強(qiáng)制要求娇哆,因?yàn)榇a看起來(lái)不舒服,還要多打幾個(gè)字母。
int i = 1.1;
int j{ 1.1 };
int k = { 1.1 };
任何顯式的初始化都會(huì)把聲明變成定義碍讨。
extern int g_i = 0;
這是個(gè)定義治力。
聲明其實(shí)也可以寫在函數(shù)內(nèi)。
比如在調(diào)試程序的時(shí)候勃黍,我喜歡寫下面這樣的代碼宵统。目的在于懶得跳到函數(shù)的最前面寫上extern int g_i
,跳來(lái)跳去麻煩覆获,回頭要?jiǎng)h除代碼的時(shí)候马澈,也要?jiǎng)h兩處。而直接在用的地方這么寫就方便多了弄息。當(dāng)然在正式的產(chǎn)品代碼中痊班,不推薦這么寫。
int foo(){
extern int g_i;
g_i = 10;
}
P33 如何表示類型的最大最小值摹量。
如果想知道各個(gè)類型的最大最小值涤伐,在C下應(yīng)該查看三個(gè)頭文件:limits.h
,float.h
缨称,stdint.h
凝果。其中規(guī)定了諸如INT_MAX
,ULONG_MAX
的宏睦尽。
在C語(yǔ)言出生的那個(gè)年代器净,處理器各種各樣,為了保證C語(yǔ)言的可移植性当凡,C語(yǔ)言的標(biāo)準(zhǔn)甚至連char bit都是用宏來(lái)定義的山害。
define CHAR_BIT 8 /* number of bits in a char */
在C++語(yǔ)言下使用頭文件limits
(沒(méi)有.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
代替!
宁玫,因?yàn)?code>!有時(shí)候太小了粗恢,常常忘記沒(méi)看到。用not
就可讀多了欧瘪,不過(guò)似乎沒(méi)人這么用眷射,那就算了吧。
#include <iso646.h>
int foo(int *p){
if (!p){}
if (not p){}
}
內(nèi)置類 P45
沒(méi)聽過(guò)這個(gè)詞佛掖,
constexpr
這個(gè)東西后面的章節(jié)還要提妖碉,暫時(shí)這里就不去深究了。constexpr
指的是一種在編譯階段就能計(jì)算出值的表達(dá)式芥被,在某些特定場(chǎng)合欧宜,比如說(shuō)聲明數(shù)組的時(shí)候,都必須使用編譯期常量拴魄,因?yàn)榫幾g器必須知道數(shù)組的長(zhǎng)度冗茸。比如說(shuō)下面的代碼是可行的席镀。
const int a = 10;
int b[a + 20] = { 0 };
但是在C++03
的時(shí)代,一個(gè)常量是否被當(dāng)成編譯期常量完全是編譯器自己憑感覺夏漱。比如說(shuō)下面size()
明顯就是個(gè)常量豪诲,但是編譯器并不會(huì)把它當(dāng)成一個(gè)常量。
int size(){ return 10; }
int c[size()] = { 0 }; //error here
所以直覺上c++11引入這個(gè)新的東西的目的就是告訴編譯器這里需要一個(gè)編譯期常量挂绰,請(qǐng)?jiān)噲D去計(jì)算這個(gè)表達(dá)式屎篱。比如說(shuō)下面這段代碼是正確的,編譯器是會(huì)在編譯階段來(lái)計(jì)算sum(10)
的值葵蒂。PS: VS2013還沒(méi)有很好的支持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(shuō)践付,consexpr
不一定都是編譯期就能及計(jì)算出來(lái)的值秦士,比如說(shuō)constexpr指針
。從下面這段代碼為例荔仁,p1
的值必須等到運(yùn)行階段才能知道伍宦,所以p2 - p1
就不可能是一個(gè)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是等價(jià)的次洼,所以應(yīng)該用using來(lái)替代掉typedef。主要目的是可讀性比較好遇骑。
指針卖毁,常量和類型別名 P61
書上提到了把pstring
展開后來(lái)理解類型是不對(duì)的,cstr
和cstr1
其實(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
這里想了個(gè)小技巧亥啦,沒(méi)有特別細(xì)究,但估計(jì)是正確的方法练链。當(dāng)遇到const T
的情況翔脱,把前置的const
寫到類型后面,如T const
媒鼓。這樣在做展開就沒(méi)錯(cuò)了届吁。
pstring const cstr = 0; // const pointer to char type;
char * const cstr2 = 0; // const pointer to char type;
當(dāng)把const
放到后面以后,解讀類型就可以方便的從右到左的讀出來(lái)绿鸣。
把&
替換成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)識(shí)符的const
,這個(gè)const
限制的是變量本身不能改變擎厢。為什么會(huì)用top-level和low-level這兩個(gè)詞呢究流,估計(jì)是從編譯原理里面的語(yǔ)法樹分析借鑒來(lái)的辣吃。
auto關(guān)鍵字。
auto關(guān)鍵字有兩個(gè)特點(diǎn)芬探,頂層的引用屬性和const屬性會(huì)被去掉齿尽。
const int ci = 10;
const int &r = 10;
auto a = &ci;
const auto &b = r;
&c
的類型是int const *
,所以沒(méi)有top-level const灯节。那么a
的類型就是int const *
&r
的類型是int const &
,去掉頂層的引用變成int const
绵估,那么b
的類型就是(int const) const & b
; 兩個(gè)const都修飾左邊的int
炎疆。也就是int const & b
decltype就沒(méi)有講透,需要進(jìn)一步的細(xì)化国裳。
這個(gè)東西在寫模板的時(shí)候很有用處形入,所以需要仔細(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時(shí)蛇数,如果字符串中間包含了'\0'字符,如何繞過(guò)去是越。
如例子s2耳舅,可以使用另外一個(gè)構(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