標籤:結束 指定 利用 day 也會 err 答案 計算 貸款
練習2.1
Q: 類型int、long、long long和short的區別是什麼,無符號和帶符號類型的區別是什嗎?float和double的區別是什嗎?
A:int、 long、 long long和short尺寸不同,表示的資料範圍不同。無符號只能表示0和正數,無符號還可以表示負數。float為單精確度浮點數,double為雙精確度,一般來說,float佔4位元組,double佔8位元組。
練習2.2
Q: 計算按揭貸款時,對於利率、本金和付款分別應選擇何種資料類型?說明你的理由。
A: 利率應該用unsigned double表示,本金和付款應使用unsigned float表示。因為利率一般小數位元較多,且沒有負數,本金和付款小數位元少,也沒有負數。
練習2.3
Q: 讀程式,寫結果
unsigned u = 10, u2 = 42;
std::cout << u2 - u << std::endl; //32
std::cout << u - u2 << std::endl; // -32的補碼 4294967264
int i = 10, i2 = 42;
std::cout << i2 - i << std::endl; // 32
std::cout << i - i2 << std::endl; // -32
std::cout << i - u << std::endl; // 0
std::cout << u - i << std::endl; // 0
練習2.5
Q:指出下面字面值的資料類型
A:(1)‘a‘<字元字面值>, L‘a‘<寬字元字面值,類型是wchar_t>, "a"<字串字面值>, L"a"<寬字元字串字面值>
(2)10<十進位>, 10u<無符號整型>, 10L<長整型>, 10uL<無符號長整型>, 012<八進位>, 0xC<十六進位>
(3)3.14,<浮點數> 3.14f<單精確度浮點型字面值,類型是float>, 3.14L<擴充精度浮點型字面值,類型是long double>
(4)10<十進位>, 10u<無符號整型>, 10.<浮點型>, 10e-2<浮點型字面值>
練習2.6
Q:下面兩組定義是否有區別?
A:
int month = 9, day = 7; //定義的month和day均為10進位
int month = 09, day = 07; // 定義的month和day為八進位,month會報錯,因為09超出範圍了。error: invalid digit ‘9‘ in octal constant
練習2.7
Q:下述字面值表示什麼含義?各自的資料類型是什嗎?
A:(1)"who goes with F\145rgus?\012" --- \145表示小寫字母“e”, \012表示分行符號。 輸出:who goes with Fergus?
(2) 3.14e1L --- 表示擴充的浮點型,類型是long double
(3) 1024f --- 單精確度浮點型字面值,類型是float
(4) 3.14L --- 表示擴充的浮點型,類型是long double
練習2.8
Q:使用轉義寫一段程式,先輸出2M,然後轉到新的一行,修改程式使其先輸出2, 然後輸出定位字元,再輸出M,最後轉到新的一行。
A: cout << "\62\115\012" ;
cout << "\62\t\115\012" ;
練習2.9
Q:解釋下列定義的含義。對於非法的定義,說明錯在何處
A:(1)std::cin >> int input_value --- 錯誤,不能在輸入輸出語句中定義變數。
(2)int i = { 3.14 }; --- 錯誤,在初始化列表中使用浮點型初始化int變數可能會遺失資料,編譯器會拒絕執行
(3)double salary = wage = 9999.99; --- wage未定義,如果wage定義了,則該語句可以正常執行,最終wage和salary相等
(4)int i = 3.14; --- 警告,有隱式轉化,i值為3。
練習2.10
Q:下列變數的初始值是什嗎?
A:std::string g_str; //初始化為一個空串
int g_int; // 初始化為0
void test210 ()
{
int local_int; //按標準局部變數不初始化,g++編譯器下可能也會初始化為空白
std::string local_str;
}
練習2.11
Q:指出下面的語句是被聲明還是定義。
A: (1)extern int ix = 1024; // 定義 (任何包含了顯式初始化的聲明即成為定義)
(2)int iy; // 聲明並定義 (想聲明而不定義,就在變數名前家extern)
(3)extern int iz; // 聲明
練習2.12
Q:請指出下面的名字中哪些是非法的?
A: (1)int doube = 3.14; //非法,double為關鍵字,不能作為變數名
(2)int _; //合法
(3)int catch-22; //非法,變數名只能包含字母、數字、底線
(4)int 1_or_2 = 1; //非法,不能以數字開頭
(5)double Double = 3.14; //合法
練習2.13
Q:下面程式中j的值是多少?
A:int i =42;
void test213 ()
{
int i = 100;
int j = i;
cout << "j = " << j << endl; //j =100 ,使用局部變數j。
}
練習2.14
Q:下面的程式合法嗎?輸出什嗎?
A:int i =100, sum =0;
for (int i =0; i != 10; ++i) {
sum += i;
}
cout << i << " " << sum << endl; // i = 100, sum = 45,for迴圈中的i,只在迴圈體內起作用,因此輸出的是全域變數i= 100, 局部變數sum依舊在範圍內,因此輸出局部變數sum=45。
練習2.15
Q:下面哪個定義是不合法的,為什嗎?
A: (1)int ival = 1.01; //用float初始化int,不合法,會有警告
(2)int &rval1 = 1.01; //非法,引用的初始值必須是一個對象
(3)int &rval2 = ival; //合法
(4)int &rval3; //非法,引用必須被初始化。
練習2.16
Q:下面哪些賦值不合法,為什嗎?
A: int i = 0, &rl = i;
double d = 0, &r2 = d;
(1)r2 = 3.14159; //合法,d的值也變為3.14159
(2)r2 = r1; //合法,但隱式轉化
(3)i = r2; //合法,但隱式轉化
(4)r1 = d; //合法,但隱式轉化
練習2.17
Q:下面的代碼會輸出什麼結果?
A: int i, &ri = i;
i = 5;
ri = 10;
cout << "i = " << i << " ri = " << ri << endl; //i = 10, ri = 10 --- 改變ri的值也會改變i的值。
練習2.18
Q:編寫代碼分別更改指標的值以及指標所指對象的值。
A:int i =20;
int j = 10;
int* p = &i;
cout << "p = " << p << endl; // p = 0x7ffee3a3ea3c
p = &j;
cout << "p = " << p << endl; // p = 0x7ffee3a3ea38
*p = 5;
cout << "*p = " << *p << " i = " << i << " j = " << j << endl; // *p = 5 i = 20 j = 5
練習2.19
Q:說明指標和引用的主要區別。
A:(1) 引用在定義時必須初始化,而指標可不初始化
(2)引用在其生命週期內,只能指向一個對象,而指標可以先後指向不同的對象
(3)指標本身就是一個對象,允許對指標進行賦值和拷貝。
練習2.20
Q:敘述下面代碼的作用
A:int i = 42;
int * p = &i;
*p = *p * *p; // 42*42, 求i的平方。
練習2.21
Q: 解釋下述定義是否非法。
A: int i = 0;
(1)double* dp = &i; //非法,不能用int型的變數初始化doube指標
(2)int* ip = i; //非法, 不能用int值初始化指標
(3)int* p = &i; //合法
練習2.22
Q: 假設p是一個int型指標,說明下面代碼的含義
A: if (p) //如果地址不為0
if (*p) //如果所指的值為真
練習2.23
Q: 給定指標p,能否知道它指向了一個合法的對象?
A: 不行,如果你把指標理解為一個信封上的地址,那麼沒有任何手段能保證你填寫的地址必然有人住。(別人的回答)
我的理解,給定一個指標,首先要判斷這個指標是否有效(不為NULL,地址合法等),好像沒什麼辦法判斷指向了合法對象,有可能在使用過程中發現。
練習2.24
Q: 下面的代碼中,為什麼p合法而lp非法?
A: int i = 42;
void *p = &i; //因為void指標類型可以存放任意對象的地址
long *lp = &i; //但是long指標,就只能存放long對象的地址
練習2.25
Q: 說明下列變數的類型和值。
A: (1) int* ip, i, &r = i; // ip 為int指標類型,i為int型,r為參考型別,初始化為i。
(2) int i, *p =0; // i為int型, p為int指標類型,初始化為0,並未指向任何對象
(3) int* ip, ip2; // ip為int指標類型,ip2為int型
練習2.26
Q: 下面哪些句子是合法的,說明原因。
A: (1)const int buf; // 不合法,聲明一個const常量的同時必須初始化
(2)int cnt = 0; // 合法,聲明並初始化一個int變數
(3)const int sz = cnt; // 合法,聲明一個int const常量,並初始化。
(4)++ cnt; ++sz; // 不合法,sz為常量,不能進行++操作。
練習2.27
Q: 下面哪些初始化是合法的,說明原因。
A: (1)int i = -1, &r = 0; // 不合法, r為引用,初始化只能指向一個對象。
(2)int *const p2 = &i2; // 合法,定義一個int型的常量指標,初始化為i2的地址,之後指標的值不能再改變
(3)const int i = -1, &r = 0; // 不合法, r為引用。但const int &r = 0; 是合法的。
(4)const int* const p3 = &i2; // 合法,p3的值不能改變,*p3也不能改變
(5)const int* p1 = &i2; // 合法,指標常量,p1指向的值不能被改變
(6)const int& const r2; // 不合法,引用不能是const
(7)const int i2 = i, &r = i; // 合法
練習2.28
Q: 下面哪些是合法的,請說明。
A: (1) int i, *const cp; // 不合法,定義const類型指標要初始化,cp
(2) int *p1, *const p2; // 不合法,同上,p2應該初始化。
(3) const int ic, &r = ic; // 不合法,ic為const類型,必須要初始化
(4) const int *const p3; // 不合法,p3需要初始化
(5) const int *p; // 合法,指向是常量,但指標的值可變。
練習2.29
Q: 假設已有上題中所定義的變數,則下面哪些是合法的?
A: (1) i = ic; // 合法
(2) p1 = p3; // 不合法,int* 不能用const int* 初始化
(3) p1 = ⁣ // 合法
(4) p3 = ⁣ // 不合法,p3的值和p3指向的值都不能改變
(5) p2 = p1; // 不合法,p2的值不能被改變
(6) ic = *p3; // 不合法,ic是常量,不能被改變
練習2.30
Q: 對於下面的語句,請說明對象被聲明為頂層const還是底層const。
A: (1) const int v2 = 0; int v1 = v2; // v2是頂層const
(2) int *p1 = &v1, &r1 = v1; // 非const
(3) const int *p2 = &v2, *const p3 = &i, &r2 = v2; // p2是底層const,p3最左是底層,p3前面是頂層const, r2是底層const。
練習2.31
Q: 假設上題中的變數已定義,判斷下面語句哪些合法。
A: (1) r1 = v2; // 合法,引用改變值
(2) p1 = p2; p2 = p1; // 不合法,p2是底層const,賦值對象必須同樣有底層const才行,p2 = p1合法
(3) p1 = p3; p2 = p3; // 不合法,p3是底層const, p2 = p3合法。
總結:頂層const可以進行賦值操作。但底層const有限制,拷入拷出的對象也必須具有相同的底層const。
練習2.32
Q: 下面的代碼是否合法?說明原因。
A: int null = 0, *p = null; // int *p不能用int型來初始化。 應為 int null = 0, *p = &null / int *p = nullptr
練習2.33
Q: 利用本節已定義的變數,判斷下列語句的運行結果。
A: (1) a = 42; b = 42; c = 42; // a, b, c的值均為42
(2) d = 42; e = 42; g = 42; // d:error, d為int *類型
// e:error, e為int*類型
// g:error, g為const int類型,不能再賦值
練習2.34
Q: 證明上述推斷是否正確,寫一段程式。
A: int i = 0, &r = i;
auto a = r;
const int ci = i, &cr = ci;
auto b = ci;
auto c = cr;
auto d = &i;
auto e = &ci;
auto &g = ci;
a = 42;
b = 42;
c = 42;
std::cout << a << b << c << std::endl;
>> d = 42;
>> e = 42;
>> g = 42;
練習2.35
Q: 判斷下面定義的類型,編寫程式驗證。
A: const int i = 42; // i為const int類型
auto j = i; // j為int類型
auto &k = i; // k為const int& 類型
auto *p = &i; // p為const int* 類型
const auto j2 = i, &k2 = i; // j2為const int類型,k2為const int& 類型。
練習2.36
Q: 關於下列代碼,指出每個變數的值及程式結束後的值。
A: int a = 3, b = 4; //
decltype(a) c = a; // c為int類型,a為c的初值
decltype((b)) d = a; // d為int& 類型,是a的引用
++c; // ++c之後的值為4;
++d; // ++d之後的值為4
練習2.37
Q: 賦值是會產生引用的一類典型運算式,引用的類型就是左值的類型。也就是說,如果i是int,則運算式i=x的類型是int&。根據該特點指出下面變數的類型。
A: int a = 3, b = 4; // a, b均為int
decltype (a) c = a; // c為int
decltype (a = b) d = a; // d為int&,是a的引用。
練習2.38
Q: 舉例說明decltype指定類型和auto有何區別。
A: 相同點:都通過已知變數或運算式的類型來指定類型。如:int i = 2; auto j = i; decltype(i) j = i; 兩者相同。
不同點:(1)auto會忽略頂層const,但decltype不會。
(2)auto定義變數必須有初始值,但decltyple不一定
練習2.39
Q:
A:
練習2.40
Q:
A:
練習2.41
Q:
A:
練習2.42
Q:
A:
c++ Primer 第五版習題答案第二章