2019.04.27第二遍
特别注意的地方
- 與其他整型不同,字元型被分成了三種:char、unsigned char、signed char。char是哪種是由編譯器決定的。
- 當我們賦給帶符号類型一個超出它表示範圍的值時,結果是未定義的。此時,程式可能繼續工作、可能崩潰、也可能産生垃圾資料。
- 類型short沒有對應的字面值。
- 十進制字面值不可能是負值,如有有個帶負号的字面值,那麼那個負号作用僅僅是對字面值取負值。
- 字元串字面值的實際長度要比它的内容多1 。
- 對象是指一塊能存儲資料并具有某種類型的記憶體空間。
- 初始化和指派是兩個完全不同的操作。
- 定義于任何函數體之外的變量被初始化為0,定于在函數體内部的内置類型變量将不被初始化。
- 用花括号來初始化變量被稱為清單初始化,這種初始化有一個重要特點:如果我們使用清單初始化且初始值存在丢失資訊的風險,則編譯器會報錯。
- 如果想聲明一個變量而非定義它,就在變量名前添加關鍵字extern,而且不要顯式地初始化變量。任何包含了顯示初始化的聲明即成為定義。
- 在函數體内部,如果試圖初始化一個由extern關鍵字标記的變量,将引發錯誤。
- 使用者自定義的辨別符中不能連續出現兩個下劃線,也不能以下劃線緊連大寫字母開頭。定義在函數體外的辨別符不能以下劃線開頭。
- 右值引用主要用于内置類。引用必須被初始化。引用類型的初始值必須是一個對象。
- 指針是對象且無須在定義時指派。不能定義指向引用的指針。
- 使用未經初始化的指針是引發運作時錯誤的一大原因。
- 如果利用一個對象去初始化另外一個對象,則它們是不是const都無關緊要。
- auto定義的變量必須有初始值;會忽略掉頂層const。
- decltype((variable))的結果永遠是引用。
2.1
1.一個int至少和一個short一樣大,一個long至少個一個int一樣大,一個long long 至少和一個long一樣大。
2.帶符号類型可以表示正數、負數或0,無符号類型則僅能表示大于等于0的值。
3.一般來說,float類型有7個有效位,double類型有16個有效位。
(float至少有6個有效位,double至少有10個有效位)
2.2
利率:double(float和double的計算代價相差不大,對于某些機器,double更快)
本金:long long (不清楚你是不是想買豪宅)
付款:long long (同上)
2.3
unsigned u = 10, u2 = 42;
std::cout << u2 - u << std::endl; // 32
std::cout << u - u2 << std::endl; // 2^32 - 32
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.4
#include<iostream>
int main()
{
unsigned u = 10, u2 = 42;
int i = 10, i2 = 42;
std::cout << u2 - u << std::endl;
std::cout << u - u2 << std::endl;
std::cout << i2 - i << std::endl;
std::cout << i - i2 << std::endl;
std::cout << i - u << std::endl;
std::cout << u - i << std::endl;
return 0;
}
運作結果如下
2.5
(a) 'a', L'a', "a", L"a" //
字元字面值:char ;寬字元型字面值: wchar_t; 字元串字面值 ; 寬字元串字面值
(b) 10, 10u, 10L, 10uL, 012, 0xC
int , unsigned int , long , unsigned long, 八進制,16進制
(c) 3.14, 3.14f, 3.14L
double, float, long double
(d) 10, 10u, 10., 10e-2
int , unsigned int, 浮點型字面值, 科學計數法
2.6
int month = 9, day = 7;
int month = 09, day = 07;
有差別,上面的day為10進制,下面的day為8進制。
2.7
(a) 隻知道/145和/012構成轉義字元
(b)long double型加科學計數法 31.4
(c) float型1024.0
(d) long double型3.14
2.8
#include<iostream>
int main()
{
std::cout << "2\x4d\n" << std::endl;
std::cout << "2\t\x4d\n" << std::endl;
return 0;
}
2.9
(a) 錯誤。未定義的input_value,改為 int input_value; std::cin >> input_value;
(b) 錯誤。從double到int 需要收縮變換
(c) =從右向左結合,wage未定義類型
(d) 可以運作。
2.10
std::string global_str;
int global_int;
int main()
{
int local_int;
std::string local_str;
}
定義于任何函數體之外的變量被初始化為0,故global_str = "0", global_int = 0。
定義在函數體内部的内置類型變量不被初始化,故local_int, local_str值未定義。
2.11
(a)定義
(b)聲明并定義
(c)聲明
2.12
(a)非法
(b)合法
(c)非法
(d)非法
(e)合法
2.13
2.14
合法
輸出:100 45
for循環定義的i到結束循環就不能使用了,故i輸出為100
2.15
(a)不太好,但是可以。
(b)不合法,引用類型的初始值必須是一個對象
(c)合法
(d)不合法,引用必須被初始化
2.16
(a)給d指派為3.14159
(b)可以,不太好。把int類型的i的值賦給double類型d
(c)不合法,
(d)不合法,r1的初始值必須為int型對象
2.17
2.18
#include<iostream>
int main()
{
int i = 12;
int *p = &i;
// 修改指針的值
std::cout << p << std::endl;
p++;
std::cout << p << std::endl;
/* 修改指針所指對象的值
std::cout << *p << std::endl;
(*p)++;
std::cout << *p << std::endl;
*/
return 0;
}
2.19
指針:允許指派和拷貝;在生命周期内可以指向不同對象;不需要在定義時賦初值。
引用: 不能定義引用的引用;定義引用時程式是把引用和它的初始值綁定在一起,不是拷貝;引用必須被初始化。
2.20
2.21
(a)非法,試圖把int型對象的位址賦給double型指針
(b)非法,不能把int變量直接賦給指針
(c)合法,把i的位址賦給指針ip
2.22
if(p) // ... 如果指針不為空,則進行下面的語句
if(*p) //... 如果指針指向的值不為空,則進行下面的語句
2.23
先用*p将指針所指對象的值輸出,如果報錯,則說明指針指向無效的對象,然後用if(p == NULL)進行判斷。
2.24
void*指針可用于存放任意對象的位址;而lp指針為long型,不能存在int類型的對象的位址。
2.25
(a)ip為int型指針,i為int型變量,r為對int型變量i的引用
(b)i為int型變量,ip為所指對象的值為0的int型指針
(c)ip為int型指針,ip2為int型變量
2.26
(a)不合法,const對象必須初始化
(b)合法
(c)合法
(d)++sz不合法 const對象不能改變值
2.27
(a)不合法,不能為非常量引用綁定字面值
(b)合法
(c)合法
(d)合法
(e)合法
(f)不合法,引用必須初始化
(g)不合法,這樣可通過修改r的值來修改i2的值
2.28
(a)i為int類型的變量,cp為int類型的常量指針
(b)p1為int類型指針,p2為int類型常量指針
(c)ic為int類型常量,r為整形常量引用
(d)p3為指向int類型常量的常量指針
(e)p為指向int類型常量的指針
2.29
(a)不合法,不能把常量賦給變量
(b)不合法,同上
(c)不合法,同上
(d)合法
(e)合法
(f)不合法,左邊應是變量,不能為常量
2.30
const int v2 = 0; // 頂層const
int v1 = v2; // 不合法
int *p1 = &v1, &r1 = v1; // 沒有
const int *p2 = &v2, *const p3 = &i, &r2 = v2; // p2為底層const
//p3靠右的為頂層const,靠左的為底層const
2.31
r1 = v2; // 不合法
p1 = p2; // 不合法
p2 = p1; // 合法
p1 = p3; // 不合法
p2 = p3; // 不合法
2.32
不合法
int null = 0, *p = &null;
2.33
a = 42; // 合法
b = 42; // 合法
c = 42; // 合法
d = 42; // 不合法
e = 42; // 不合法
g = 42; // 不合法
2.34
17、18、19行出現問題,說明我上一個習題推斷正确
2.35
const int i = 42;
auto j = i; const auto &k = i; auto *p = &i;
const auto j2 = i, &k2 = i;
(1)j是一個整數(i的頂層const特性被忽略掉了)
(2)k是一個整形常量引用
(3)p是一個指向int類型指針的指針
(4)j2是一個int類型的常量,k2是常量引用
程式如下:
#include<iostream>
int main()
{
const int i = 42;
auto j = i;
const auto &k = i;
auto *p = &i;
const auto j2 = i, &k2 = i;
std::cout << j << " " << k << " " << p << " "
<< j2 << " " << k2 << std::endl;
return 0;
}
2.36
int a = 3, b = 4;
decltype(a) c = a;
decltype ((b)) d = a;
++c; // c為int類型,值為4
++d; // d為int&, 值為4
2.37
int a = 3, b = 4;
decltype(a) c = a; // c為int類型,值為3
decltype(a = b) d = a; // d為int&,值為4
2.38
差別:
decltype:如果decltype使用的表達式是一個變量,則decltype傳回該變量的類型(包括頂層const和引用在内)
auto:auto一般會忽略頂層const
例子:
一樣:int a = 3; decltype (a) b = a; auto b = a;
不一樣:const int a = 3; decltype(a) b = a; auto b = a;
2.39
2.40
struct Sales_data
{
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
// 書上把想的寫出來了,“最好”兩字說明可以和書上一樣~