說明
看《C++ Primer Plus》時整理的學習筆記,部分內容完全摘抄自《C++ Primer Plus》(第6版)中文版,Stephen Prata 著,張海龍 袁國忠譯,人民郵電出版社,只做學習記錄用途,
目錄- 說明
- 3.1 簡單變數
- 3.1.1 變數名
- 3.1.2 整型
- 3.1.3 符號整型
- 3.1.4 無符號整型
- 3.1.5 選擇整型型別
- 3.1.6 整型字面值
- 3.1.7 C++ 如何確定常量的型別
- 3.1.8 char 型別:字符和小整數
- 3.1.9 bool 型別
- 3.2 const 限定符
- 3.3 浮點數
- 3.3.1 書寫浮點數
- 3.3.2 浮點型別
- 3.3.3 浮點常量
- 3.3.4 浮點數的優缺點
- 3.4 C++ 算術運算子
- 3.4.1 運算子優先級和結合性
- 3.4.2 除法分支
- 3.4.3 求模運算子
- 3.4.4 型別轉換
- 3.4.5 C++11 中的 auto 宣告
3.1 簡單變數
內置的 C++ 型別分兩組:基本型別和復合型別,本章主要介紹基本型別,
3.1.1 變數名
變數命名時,需遵循以下規則:
- 名稱只能使用字母、數字或下劃線,
- 名稱第一個字符不能是數字,
- 區分大寫字母與小寫字母,
- 名稱不能是 C++ 關鍵字,
- 以兩個下劃線或下劃線和大寫字母打頭的名稱被保留給實作(編譯器及其使用的資源)使用,以一個下劃線開頭的名稱被保留給實作,用作全域識別符號,
- C++ 對名稱沒有長度限制,但有些平臺有長度限制,
倒數第二點原因:使用像 _time_stop 或 _Donut 這樣的名稱不會導致編譯錯誤,但會導致行為的不確定性,不知道結果將是什么,最后一點需注意:ANSI C (C99標準) 只保證名稱中的前 63 個字符有意義(前 63 個字符相同的名稱被認為是相同的,即使第 64 個字符不同),目前比較流行的有 4 種命名習慣:
- 小駝峰命名法:第一個單詞首字母小寫,后面單詞首字母大寫,如
myVariableName, - 大駝峰命名法:又稱帕斯卡命名法(Pascal),所有單詞的首字母都大寫,如
MyVariableName, - 匈牙利命名法:變數名 = 屬性 + 型別 + 物件描述,如
m_lpctstrStudentName表示類中一個成員變數(屬性m_),型別為指向字串常量的長指標(型別lpctstr),所指字串常量用來表示學生姓名(物件描述StudentName), - 下劃線命名法:用下劃線分隔單詞,如
my_variable_name,
3.1.2 整型
計算機語言只能表示所有整數的一個子集,存盤時使用的記憶體量越大,可表示的整數值范圍也越大,C++ 的基本整型按記憶體量寬度排序有 char、short、int、long和 C++11 新增的long long,其中每種型別都有符號版本和無符號版本,因此總共有 10 種型別可供選擇(實際上short是short int的簡稱,long是long int的簡稱,long long是long long int的簡稱,但一般不使用長名稱),最好在宣告變數時就對它的值進行初始化,即將宣告陳述句與賦值陳述句合并在一起,以防出現未初始化就使用變數的情況,這時變數的值是不確定的,C++ 變數初始化有以下幾種方式:
//傳統C語言方式
int uncles = 5;
//C++支持的方式
int uncles(5);
//C++98支持的方式
int uncles = {5};
//C++11支持的方式
int uncles = {5};
int uncles{5};
//C++11將變數初始化為0
int uncles = {};
int uncles{};
3.1.3 符號整型
不是在所有的系統中,每種型別的寬度都相同,例如int不總是 32 位,在早期的 16 位作業系統中,int是 16 位,但在后來的 32 位作業系統以及 64 位作業系統中,int是 32 位,C++ 標準只確保了最小寬度:
short至少 16 位,int至少和short一樣寬,long至少 32 位,且至少和int一樣寬,long long至少 64 位,且至少和long一樣寬,
想知道某種整型的記憶體量大小,可以使用sizeof運算子回傳型別或變數的記憶體量寬度,單位為位元組(位元組的含義也依賴于實作,在一個系統中一個位元組可能是 8 位,而在另一個系統中可能是 16 位),對型別名(如int)使用sizeof運算子時,應將名稱放在括號里面,但對變數名(如n_short)使用該運算子,括號是可選的,
//對型別名使用sizeof運算子(必要括號)
cout << "int is " << sizeof(int) << " bytes.\n";
//對變數名使用sizeof運算子(括號可選)
cout << "short is " << sizeof(n_short) << " bytes.\n";
cout << "short is " << sizeof n_short << " bytes.\n";
想知道某種整型所能表示的整數范圍,一種方式是根據該整型的記憶體量寬度進行計算,例如:若short為 16 位,則其符號版本可表示的整數范圍為 \([-2^{15}, 2^{15}-1]\) 即 \([-32768, 32767]\),無符號版本可表示的整數范圍為 \([0, 2^{16}-1]\) 即 \([0, 65535]\),這樣計算的原因可參考原碼補碼反碼的相關資料,另一種方式是#include <climits>,這個庫檔案里面包含了關于整型限制的資訊,使用示例如下:
//獲得int所能表示的最小整數值
cout << "Minimum int value = "https://www.cnblogs.com/young520/archive/2022/07/22/<< INT_MIN << endl;
//獲得當前系統一個位元組占多少位
cout <<"Bits per byte = " << CHAR_BIT << endl;
climits檔案中將上述限制資訊定義為宏:
#define INT_MIN -2147483648
編譯指令#define的作業方式與文本編輯器的全域搜索并替換的命令相似,它告訴前處理器:查找獨立的標記INT_MIN并將其替換為-2147483648,但它會跳過嵌入的INT_MIN,不會將PINT_MINTM替換為-2147483648,C++ 有一種更好的創建符號常量的方法,就是使用const關鍵字,這將在后續章節學習,
3.1.4 無符號整型
前面介紹的 4 種符號整型都有對應的無符號版本,僅當數值不會為負時才使用無符號版本:unsigned short、unsigned int、unsigned long和 unsigned long long,整型變數的取值如果超過了取值限制,其值將成為另一端點的值,依然以 16 位short為例,其符號版本的最大值加 1 后,值會變成 -32768,最小值減 1 后,值會變成 32767,其無符號版本的最大值加 1 后,值會變成 0,最小值減 1 后,值會變成 65535,這種現象分別稱為整型的上溢與下溢,
3.1.5 選擇整型型別
int被設定為計算機處理起來效率最高的長度,若沒有非常有說服力的理由選擇其他型別,則應首選int,若變數取值不可能為負數,則應首選無符號版本,若變數取值可能超過 16 位整數的最大值,則應首選long型別,這樣可確保程式移植到 16 位系統時不會出現問題,若變數取值超過 20 億(\(2^{31}=2147483648\)),則可選擇long long,若存在大型陣列且節省記憶體很重要,可考慮使用short,
3.1.6 整型字面值
整型字面值是顯式地書寫的常量,C++ 能夠以三種不同的計數方式來書寫整數:基數為 10、基數為 8(老式UNIX版本)、基數為 16(硬體黑客的最愛),C++ 使用前一(兩)位來標識數字常量的基數,如果第一位為 1~9,則基數為10(十進制),例如 93,如果第一位為 0,第二位為 1~7,則基數為8(八進制),例如 042(等于十進制數 34),如果前兩位為 0x 或者 0X,則基數為16(十六進制),例如 0x42(等于十進制數 66),
//十進制
int chest = 42;
//八進制
int waist = 042;
//十六進制
int inseam = 0x42;
3.1.7 C++ 如何確定常量的型別
數字常量后面可以添加后綴以指明型別:
| 后綴 | 常量型別 |
|---|---|
| l , L | long |
| u , U | unsigned int |
| UL , LU , ul , lu , Ul , Lu , uL , lU | unsigned long |
| LL , ll | long long |
| ULL , ull , Ull , uLL | unsigned long long |
對于不帶后綴的十進制整數,使用下面幾種型別中能夠存盤該數的最小型別做默認值:int 、long 、long long,
對于不帶后綴的十六進制和八進制整數,使用下面幾種型別中能夠存盤該數的最小型別做默認值:int 、unsigned int、long、unsigned long、long long、unsigned long long,
3.1.8 char 型別:字符和小整數
char 型別是專為存盤字符(如字母和數字)而設計的,通常為 8 位,也用來表示比 short 更小的整型,常用的符號集有 ASCII字符集 、國際Unicode字符集,例如字符 A 的 ASCII 碼是 65,字符 a 的 ASCII 碼是 97,另外還有一種特殊的字符:轉義字符,常用的轉義字符有:
| 字符名稱 | ASCII符號 | C++代碼 | 十進制ASCII碼 | 十六進制ASCII碼 |
|---|---|---|---|---|
| 換行符 | NL(LF) | \n |
10 | 0xA |
| 水平制表符 | HT | \t |
9 | 0x9 |
| 垂直制表符 | VT | \v |
11 | 0xB |
| 回車 | CR | \r |
13 | 0xD |
| 反斜杠 | \ | \\ |
92 | 0x5C |
| 單引號 | ' | \' |
39 | 0x27 |
| 雙引號 | " | \" |
34 | 0x22 |
可以使用數字轉義序列(只支持八進制、十六進制)或符號轉義序列來表示轉義字符,但數字轉義序列與特定的編碼方式(如ASCII)相關,而符號轉義序列適用于任何編碼方式,可讀性也更強,比如\n 、\012 與\0xA 都表示換行符,C++ 標準還允許實作提供擴展源字符集和擴展執行字符集,這種機制獨立于任何特定的鍵盤,使用的是通用字符名,通用字符名以 \u 或者 \U 打頭,\u 后接 8 個十六進制位,\U 后則是 16 個十六進制位,這些位表示的是字符的 ISO 10646 碼點,
將 char 用于表示整型時,其默認情況下既不是沒有符號,也不是有符號,這由具體的 C++ 實作來決定,可以顯式地對其進行設定:
//默認可能是無符號,也可能是有符號
char fodo;
//顯式宣告為無符號
unsigned char bar;
//顯式宣告為有符號
signed char snark;
寬字符型別 wchar_t 可以表示擴展字符集,它的記憶體量寬度由 C++ 實作來決定,可能是 16 位,也可能是 32 位,可能是有符號的,也可能是無符號的,其底層型別可能是 int 也可能是 unsigned short ,前綴 L 可以用來指明寬字符常量與寬字串:
//右邊為寬字符常量
wchar_t bob = L'P';
//輸出寬字串
std::wcout << L"tall" << endl;
C++11 新增了型別 char16_t 和 char32_t ,這兩者都是無符號的,分別長 16 位、32 位,其底層型別也是一種內置整型,具體底層型別隨系統而變化,前綴 u 用來指明 char16_t 字符常量和字串常量,前綴 U 用來指明 char132_t 字符常量和字串常量,可使用通用字符名來對它們進行初始化,
3.1.9 bool 型別
ANSI/ISO C++ 標準添加了一種名叫 bool 的新型別,它只有兩種取值 true 或者 false,常用于判斷陳述句,記憶體量寬度一般為 8 位,過去,C++ 和 C 一樣,是沒有布爾型別的,布爾型別支持隱式轉換,任何數字值或指標值都可以轉換為 bool 值,轉換時任何非零值都被轉為 true ,零值轉換為 false ,布林值也可以隱式提升為 int 型別,true被轉換為 1,false被轉換為 0,
//布林值隱式提升為1
int ans = true;
//布林值隱式提升為0
int ans = false;
//非零被轉換為true
bool ans = -100;
//零值被轉換為false
bool ans = 0;
3.2 const 限定符
創建常量的通用格式如下:
const type name = value;
應該在宣告常量時就對其進行初始化,如果在宣告常量時沒有初始化,則該常量的值是不確定的,且無法修改,常量被初始化后,其值就被固定了,編譯器將不允許再修改該常量的值,const 常量相比于 #define 常量的好處有三點:明確指定型別、作用域限制、可用于復雜型別,
C++ 的 const 與 ANSI C 的 const 有兩點主要區別:C++ 版本有作用域限制、可在C++ 中用來宣告陣列長度,
3.3 浮點數
浮點型別是 C++ 的第二組基本型別,它能夠表示帶小數部分的數字,
3.3.1 書寫浮點數
C++ 有兩種方式書寫浮點數,一種是常用的標準小數點表示法,另一種是 E 表示法,
//標準小數點表示法
12.34;
//E表示法(中間不能有空格)
2.52e+8;
2.52e8;
2.52E+8;
2.52E8;
2.52e-8;
2.52E-8;
3.3.2 浮點型別
和 ANSI C 一樣,C++ 也有 3 種浮點型別:float、double和long double,C 和 C++ 對浮點數記憶體量寬度的要求是:
float至少 32 位,double至少 48 位,且至少和float一樣寬,long double至少和double一樣寬,
通常,float為 32 位,double為 64 位,long double為 80、96 或128 位,可以通過 #include <cfloat>獲取各型別浮點數所能表示的數值范圍,各浮點型別所能表示的精度(有效位數)一般為:float至少 6 位,double至少 15 位,long double至少 18 位,
3.3.3 浮點常量
浮點常量后面可以添加后綴以指明型別(部分老式編譯器可能不支持浮點常量后綴):
| 后綴 | 常量型別 |
|---|---|
| f , F | float |
| l , L | long double |
對于不帶后綴的浮點常量,默認型別為 double,
3.3.4 浮點數的優缺點
與整數相比,浮點數有兩大優點:可表示整數之間的值、可表示的數值范圍更大,
與整數相比,浮點數也有兩大缺點:運算更慢、精度將降低,
3.4 C++ 算術運算子
C++ 提供了 5 種運算子來完成基本算術計算:
- 加法運算子 + 執行加法運算,例如 \(4+20=24\),
- 減法運算子 - 執行減法運算,例如 \(12-3=9\),
- 乘法運算子 * 執行乘法運算,例如 \(12*4=112\),
- 除法運算子 / 執行除法運算,例如 \(1000/5=200\),
- 求模運算子 % 執行取余運算,兩個運算元必須都為整數,它生成第一個整數除以第二個整數后的余數,計算結果滿足等式 \(a\%b=a-(a/b)*b\),
3.4.1 運算子優先級和結合性
當多個運算子可用于同一運算元時,C++ 使用優先級規則來決定首先使用哪個運算子,也可用括號來執行自己定義的優先級,乘法、除法和求模運算子的優先級相同,加法和減法運算子的優先級相同,但比其他三個要低,當兩個運算子的優先級相同且作用于同一個運算元時,C++ 使用結合性規則來決定首先使用哪個運算子,上述 5 種運算子的結合性規則都是從左到右,
3.4.2 除法分支
除法運算子 / 的行為取決于運算元的型別,如果兩個運算元都是整數,則 C++ 將執行整數除法,結果的小數部分將被丟棄,即向零取整,若其中有一個(或兩個)運算元是浮點值,則結果的小數部分將保留,結果為浮點數,
3.4.3 求模運算子
求模運算子 % 回傳整數除法的余數,尤其適用于解決要求將一個量分成不同的整數單元的問題,例如單位轉換,
3.4.4 型別轉換
整型和浮點型統稱為算術型別,在以下情況下 C++ 將自動執行型別轉換:
- 將一種算術型別的值賦給另一種算術型別的變數時,
- 運算式中包含不同算術型別時,
- 將引數傳遞給函式時,
自動型別轉換時的規則如下:
-
賦值以及普通初始化:將一種算術型別的值賦給另一種算術型別的變數時,值將被轉換為接收變數的型別,有些轉換是安全的,但轉換時也可能出現以下問題:
轉換 潛在問題 大浮點數轉小浮點數(如 double轉float)精度(有效位數)降低,超過取值范圍的結果是不確定的 浮點數轉整型(如 double轉int)小數部分丟失(向零取整),超過取值范圍的結果是不確定的 大整型轉小整型(如 long轉short)超過取值范圍的結果會出問題,此時只復制右邊的位元組 -
串列初始化:C++11 將使用大括號\(\{\}\)的初始化稱為串列初始化,這種初始化方式對型別轉換的要求更嚴格,它不允許縮窄轉換,上面表格中浮點數轉整型在這是不被允許的,當大浮點數轉小浮點數、大整型轉小整型時,若超過了目標型別的取值范圍,也是不被允許的,
-
運算式中的轉換:編譯器通過校驗表以及整型級別來確定算術運算式中的型別轉換,有符號整型按級別從高到低依次為
long long、long、int、short和signed char,無符號整型的排列順序與有符號整型相同,型別char、signed char和unsigned char的級別相同,型別bool的級別最低,wchar_t、char16_t和char32_t的級別與其底層型別相同,校驗表的規則較復雜,這里只舉一個簡單的例子:兩個short整型進行算術運算時將先做整型提升至int,然后再運算,最后再轉回short, -
傳遞引數時的轉換:傳遞引數時的型別轉換通常由 C++ 原型控制,也可取消原型對引數傳遞的控制,這將在第 7 章介紹,
-
強制型別轉換:C++ 允許通過強制型別轉換機制顯式地進行型別轉換,強制轉換的格式有兩種:
//C語言風格 (typeName) value; //純粹的C++風格 typeName (value);強制型別轉換不會修改變數本身,而是創建一個新的、指定型別的值,可以在運算式中使用這個值,C++ 還引入了 4 個強制型別轉換運算子,這將在第 15 章介紹,其中
static_cast<>可用于將數值從一種數字型別轉換為另一種數值型別://使用運算子強制轉換為typeName型別 static_cast<typeName> (value);
3.4.5 C++11 中的 auto 宣告
C++ 重新定義了 C 語言中的 auto 關鍵字,在初始化宣告中,如果使用關鍵字auto ,而不指定變數的型別,編譯器將把變數的型別設定成與初始值相同(自動型別推斷):
//自動推斷為int型別
auto n = 100;
//自動推斷為double型別
auto x = 1.5;
//自動推斷為long double型別
auto y = 1.3e12L;
本文來自博客園,作者:木三百川,轉載請注明原文鏈接:https://www.cnblogs.com/young520/p/16504130.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/499979.html
標籤:其他
上一篇:HTTPClient示例分享
下一篇:Java 如何終止執行緒呢?
