2.4 const限定符
練習26:下面的哪些句子是合法的?如果有不合法的句子,請說明為什麼?
(a) const int buf; (b) int cnt = 0;
(c) const int sz = cnt; (d) ++cnt; ++sz;
【解答】
本題的所有語句應該看作是順序執行的,即形如:
const int buf;
int cnt = 0;
const int sz = cnt;
++cnt;
++sz;
(a)是非法的,const 物件一旦建立後其值不不能改變,所以const物件必須初始化。
該句應修改為const int buf = 10。
(b)和(c)是合法的。
(d)是非法的,sz是乙個const物件,其值不能被改變,當然不能執行自增操作。
練習27:下面的哪些初始化是合法的?請說明原因。
(a) int i = -1, &r = 0; (b) int *const p2 = &i2;
(c) const int i = -1, &r = 0; (d) const int *const p3 = &i2;
(e) const int *p1 = &i2; (f) const int &const r2;
(g) const int i2 = i, &r = i;
【解答】
(a)是非法的,非常量引用r不能引用字面值常0。
(b)是合法的,p2是乙個常量指標,p2的值永不改變,即p2永遠指向變數i2。
(c)是合法的,p3是乙個常量,r是乙個常量引用,此時r可以繫結到字面值常量0。
(d)是合法的,p3是乙個常量指標,p3的值永不改變,即p3永元指向變數i2;同時p3指向的是常量,即我們不能通過p3心變所指物件的值。
(e)是合法的,p1指向乙個常量,即我們不能通過p1改變所指物件的值。
(f)是非法的,引用本身不是物件,因此不能讓引用恆定不變。
(g)是合法的,i2是乙個常量,r是乙個常量引用。
練習28:說明下面的這些定義是什麼意思,挑出其中不合法的。
(a) int i, *const cp; (b) int *p1, *const p2;
(c) const int ic, &r = ic; (d) const int *const p3;
(e) const int *p;
【解答】
(a)是非法的,cp是乙個常量指標,因其值不能被改變,所以必須初始化。
(b)是非法的,cp2是乙個常量指標,因其值不能被改變,所以必須初始化。
(c)是非法的,ic是乙個常量,因其值不能被改變,所以必須初始化。
(d)是非法的,p3是乙個常量指標,因其值不能被改變,所以必須初始化;同時p3指向的是常量,即我們不能通過p3改變所指物件的值。
(e)是合法的,但是p沒有指向任何實際的物件。
練習29:假設已有上乙個練習中定義的那些變數,則下面的哪些語名是合法的?請說明原因。
(a) i = ic; (b) p1 = p3;
(c) p1 = (d) p3 =
(e) p2 = p1; (f) ic = *p3
【解答】
(a)是合法的,常量ic的值賦給了非常量i。
(b)是非法的,普通指標p1指向了乙個常量,從語法上說,p1的值可以隨意改變,顯然是不合理的。
(c)是非法的,普通指標p1指向了乙個常量,錯誤情況與上一條類似。
(d)是非法的,p3是乙個常量指標,不能被賦值。
(e)是非法的,p2是乙個常量指標,不能被賦值。
(f)是非法的,ic是乙個常量,不能被賦值。
練習30:對於下面的這些語句,請說明物件被宣告成了頂層const還是底層const?。
const int v2 = 0; int v1 = v2;
int *p1 = &v1, &r1 = v1;
const int *p2 = &v2, *const p3 = &i, &r2 = v2;
【解答】
v2和p3是頂層const,分別表示乙個整型常量和乙個整型常量指標;p2和r2是底層const,分別表示它們所指(所引用)的物件是常量。
練習31:假設已有上乙個練習所做的那些宣告,則下面的哪些語句是合法的?請說明頂層const和底層const在每個例子有何體現。
r1 = v2;
p1 = p2; p2 = p1;
p1 = p3; p2 = p3;
【解答】
在執行拷貝操作時,頂層const和底層const區別明顯。其中,頂層const不受影響,
這是因為拷貝操作並不會改變被拷貝物件的值。底層const的限制則不容忽視,拷入和拷出的物件必須具有相同的底層const資格,
或者兩個物件的資料型別必須能夠轉換。一般來說,非常量可以轉換成常量,反之則不行。
r1 = v2;是合法的,r1是乙個非常量引用,v2是乙個常量(頂層const),把v2的值拷貝給r1不會對v2有任何影響。
p1 = p2;是非法的,p1是普通指標,指向的物件可以是任意值,p2是指向常量的指標(底層const),令p1指向p2所指的內容,有可能錯誤地改變常的值。
p2 = p1;是合法的,與上一條語句相反,p2可以指向乙個非常量,只不過我們不會通過p2更改它所指的值。
p1 = p3;是非法的,p3包含底層const定義(p3所指的物件是常量),不能把p3的值賦給普通指標。
p2 = p3;是合法的,p2和p3包含相同的底層const, p3的頂層const則可以忽略不計。
練習32:下面的**是否合法?如果非法,請設法將其修改正確。
int null = 0, *p = null;
【解答】
上述**是非法的,null是乙個int變數,p是乙個int指標,二者不能直接繫結。公從語法角度來說,可以將**修改為:
int null = 0, *p = &null;
顯然,這種改法與**的原意不一定相符。另一種改變是使用nullptr:
int null = 0, *p = nullptr;
《C Primer》第2章 2 6節習題答案
2.5 自定義資料結構 練習39 編譯下面的程式觀察其執行結果,注意,如果忘記寫類定義體後面的分號會發生什麼情況?記錄下相關資訊,以後可能會有用。struct foo 注意 沒有分號 int main 解答 該程式無法編譯通過,原因是缺少乙個分號。因為類體後面可以緊跟變數名以示對該型別物件的定義,所...
C primer習題 第3章
習題 2.11 編寫程式,要求使用者輸入兩個數 底數 base 和指數 exponent 輸出底數的指數次方的結果。include include include using namespace std intmain for int i 1 i exp i result base cout 的 次...
C primer習題 第4章
習題 4.7 編寫必要的 將乙個陣列賦給另乙個陣列,然後把這段 改用 vector 實現。考慮如何將乙個 vector 賦給另乙個 vector。用陣列實現 include using namespace std intmain inta2 size for size t i 0 ii a2 i a...