第三章:處理數據 簡單變量 整型 整型 short 、int 、long 和 long 無符號類型 選擇整型類型 整型字面值 C++如何確定常量的類型 char 類型:字符和小整型 bool類型 cosnt 限定符 浮點數 C++算術運算符 運算符優先級和結合性 除法分支 求模運算符 類型轉換 初始化和賦值進行轉換 以 { } 方式初始化時進行的轉換(C++11) 表達式中的轉換 傳參時轉換 強制類型轉換 C++11中的 auto 總結 C++基本類型
第三章:處理數據
面向對象的本質是設計并擴展自己的數據類型。 C++內置類型:
基本類型。 復合類型。
簡單變量
信息存儲在計算機中需要記錄三個基本屬性:
存儲的位置。 存儲的值。 存儲的類型。
變量的命名規范:
數字、字母、下劃線組成。 不以數字開頭。 區分大小寫。 不能使用關鍵字。
命名方案:
整型變量名前加 n 字符串前面加 str 布爾值前面加 b 指針前面加 p 單個字符前面加 c 類成員值前面 m_
整型
char、short、int、long和C++11新增 long long 每種類型都有符號版本和無符號版本共計10種類型。
整型 short 、int 、long 和 long
C++提供靈活標準:
short 至少16位。 int 至少和 short一樣長。 long 至少32位,且至少和 int 一樣長。 long long 至少64位,且至少和 long 一樣長。
short 是 short int 簡稱。 long 是 long int 簡稱。
程序清單3.1 limits.cpp 代碼演示:
#include <iostream>
#include <climits> int main ( )
{ using std
:: cin
; using std
:: cout
; using std
:: endl
; int n_int
= INT_MAX
; short n_short
= SHRT_MAX
; long n_long
= LONG_MAX
; long long n_llong
= LLONG_MAX
; cout
<< "int is " << sizeof ( int ) << " bytes." << endl
; cout
<< "short is " << sizeof ( short ) << " bytes." << endl
; cout
<< "long is " << sizeof ( long ) << " bytes." << endl
; cout
<< "long long is " << sizeof ( long long ) << " bytes." << endl
; cout
<< "Maximum values:" << endl
; cout
<< "int: " << n_int
<< endl
; cout
<< "short: " << n_short
<< endl
; cout
<< "long: " << n_long
<< endl
; cout
<< "long long: " << n_llong
<< endl
<< endl
; cout
<< "Maximum int value = " << INT_MAX
<< endl
; cout
<< "Bits per byte = " << CHAR_BIT
<< endl
; return 0 ;
}
運行結果:
C++編譯過程中,現將源代碼傳遞給預處理器,預處理完成替換之后被編譯。 預處理器只查找獨立的標記,跳過嵌入的標記。
初始化:將賦值和聲明合并。 如果不對函數內部的變量進行初始化,則改變量的值是不確定的。 在聲明變量時進行初始化,避免忘記賦值的情況發生。 C++11 使得可以將大括號初始化器用于任何類型,這是一種通用的初始化語法。
無符號類型
優點:增大變量能夠存儲的最大值。 使用關鍵字 usigned 修飾。 unsigned 本身是 unsigned int 的縮寫。
程序清單3.2 exceed.cpp 代碼演示:
#include <iostream>
#include <climits> #define ZERO 0 int main ( )
{ using std
:: cin
; using std
:: cout
; using std
:: endl
; short sam
= SHRT_MAX
; unsigned short sue
= sam
; cout
<< "Sam has " << sam
<< "dollars and Sue has " << sue
<< "dollars deposited." << endl
; cout
<< "Add $1 to each account." << endl
<< "Now " ; sam
= sam
+ 1 ; sue
= sue
+ 1 ; cout
<< "Sam has " << sam
<< " dollars and Sue has " << sue
<< " dollars deposited.\nPoor Sam!" << endl
; sam
= ZERO
; sue
= ZERO
; cout
<< "Sam has " << sam
<< " dollars and Sue has " << sue
<< " dollars deposited." << endl
; cout
<< "Take $1 from each account." << endl
<< "Now" ; sam
= sam
- 1 ; sue
= sue
- 1 ; cout
<< "Sam has " << sam
<< " dollars and Sue has " << sue
<< " dollars deposited." << endl
; cout
<< "Lucky Sue!" << endl
; return 0 ;
}
運行結果:
C++不保證符號整型超過限制是不出錯。
選擇整型類型
int 被設置為對目標計算機而言的自然長度。 自然長度:計算機處理起來效率最高的長度。
如果沒有非常有說服力的理由來選擇其他類型,則應該使用 int。 如果變量的值不可能為負,則可以使用無符號類型表示更大的值。 如果知道變量所表示的整數值大于16位整數的最大值,則使用 long,及時系統上 int 為32位,也應該這樣做。 (原因:移植到16位系統上程序可以正常工作。) 如果要存儲的值超過20億,使用 long long。 使用 short 可以節省內存,當有大型數組時,才有必要使用 shrot。 如果只需要一個字節,可使用char。
整型字面值
十進制:第一位為 1 ~ 9 基數為 10。 八進制:第一位為 0,第二位為 1~7 基數為 8。 十六進制:前兩位為 0x 或者 0X 基數為 16。
程序清單3.3 hexoct.cpp 代碼演示:
#include <iostream> int main ( )
{ using std
:: cin
; using std
:: cout
; using std
:: endl
; int chest
= 42 ; int waist
= 0x42 ; int inseam
= 042 ; cout
<< "Monsieur cuts a stricking figure!\n" ; cout
<< "chest = " << chest
<< " (42 in decimal)\n" ; cout
<< "waist = " << waist
<< " (0x42 in decimal)\n" ; cout
<< "inseam = " << inseam
<< " (042 in decimal)\n" ; return 0 ;
}
運行結果:
默認情況下 cout 以十進制顯示整數,不管整數在程序中如何書寫。 所有數都以相同的方式存儲在計算機中:二進制數存儲。
cout進制輸出控制符:
dec 十進制輸出。 hex 十六進制輸出。 oct 八進制輸出。
默認格式為十進制,修改格式之前,格式一直有效。
程序清單3.4 hexoct2.cpp 代碼演示:
#include <iostream> int main ( )
{ using namespace std
; int chest
= 42 ; int waist
= 42 ; int inseam
= 42 ; cout
<< "Monsieur cuts a stricking figure!\n" ; cout
<< "chest = " << chest
<< " (decimal for 42)\n" ; cout
<< hex
; cout
<< "waist = " << waist
<< " (hexadecimal for 42)\n" ; cout
<< oct
; cout
<< "inseam = " << inseam
<< " (octal for 42)\n" ; return 0 ;
}
運行結果: cout << hex; 等代碼不會在屏幕上顯示任何信息,只是修改 cout 顯示整數的方式。
C++如何確定常量的類型
除非有理由存儲為其他類型,否則將C++整型常量存儲為 int 類型。
數字常量后面的字母用于表示類型:
l 或 L 表示為 long 常量。 u 或 U 表示 unsigned int 常量 。 ul (采用任何順序,大小寫均可)表示 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 能夠能夠存儲該數的最小類型。
十六進制常用來表示內存地址,內存地址無符號。
char 類型:字符和小整型
char 類型:
比 short 更小的整型。 字符類型。
程序清單3.5 chartype.cpp 代碼演示:
#include <iostream> int main ( )
{ using namespace std
; char ch
; cout
<< "Enter a character: " << endl
; cin
>> ch
; cout
<< "Hola! " ; cout
<< "Thank you for the " << ch
<< " character." << endl
; return 0 ;
}
運行結果: cin 和 cout 的行為由變量類型引導。 C++對字符用單引號,字符串用雙引號。
程序清單3.6 morechar.cpp 代碼演示:
#include <iostream> int main ( )
{ using namespace std
; char ch
= 'M' ; int i
= ch
; cout
<< "The ASCII code for " << ch
<< " is " << i
<< endl
; cout
<< "Add one to the character code: " << endl
; ch
= ch
+ 1 ; i
= ch
; cout
<< "The ASCII code for " << ch
<< " is " << i
<< endl
; cout
<< "Displaying char ch using cout.push(ch): " ; cout
. put ( ch
) ; cout
. put ( '!' ) ; cout
<< endl
<< "Done" << endl
; return 0 ;
}
運行結果: C++將字符表示為整型,方便操縱。 char 字面量:將字符使用單引號括起來,表示字符的數值編碼。
轉義字符: 像處理常規字符一樣處理轉義字符。 作為字符常量時,用單引號括起來。 放在字符串中時,不要使用單引號。
換行操作:
cout<<endl; cout<<'\n'; cout<<"\n"
可以基于字符的八進制和十六進制編碼來使用轉義字符。
符號適用于任何編碼方式,可讀性更強,應使用符號序列,不要使用數字轉義序列。
程序清單3.7 bondini.cpp 代碼演示:
#include <iostream> int main ( )
{ using namespace std
; cout
<< "\aOperation \"HyperHype\" is noew activated!\n" ; cout
<< "Enter your agent code:_________\b\b\b\b\b\b\b\b" ; long code
; cin
>> code
; cout
<< "\aYou entered " << code
<< "……\n" ; cout
<< "\aCode verified! Proceed with PlanZ3!\n" ; return 0 ;
}
運行結果: char 默認情況下既不是沒有符號,也不是有符號。是否有符號由C++實現決定。 可以顯示將類型設置為 signed char 或 unsigned char。 用 char 存儲標準 ASCII 字符,char有沒有符號都沒關系。
C++處理無法用一個8位表示的字符集:
如果大型字符集實現是基本字符集,編譯器廠商可以將 char 定義為一個16位的字節或更長的字節。 同時支持一個小型基本字符集和一個較大的擴展字符集,8位char可以表示基本字符集,另一種類型 wchar_t 表示擴展字符集。
wchar_t :整數類型,有足夠的空間,可以表示系統使用的最大擴展字符集。
C++新增的類型:
char16_t:無符號,長16位,使用前綴 u 表示 char16_t 字符常量和字符串常量。例如:u'C' 和 u"be good" char32_t:無符號,長32位,使用前綴 U 表示 char32_t 字符常量和字符串常量。例如:U'R' 和 U"dirtyrat"
wchar_t、char16_t 和 char32_t 有底層內置數據類型——一種內置整型,底層類型隨系統。
bool類型
bool 變量的值可以是 true 或 false。 C++將非零解釋為true,將零解釋為false。 字面值 true 和 false 可以通過整型提升轉換為 int 類型,true轉換為 1,false轉換為0。 任何數值或指針都可以被隱式轉換為bool值,非零值轉換為true,零轉換為false。
cosnt 限定符
程序中多個地方使用同一個常量,需要修改該常量時,只需要修改一個符號定義即可。 C++處理常量的方法:使用 const 關鍵字來修改變量的聲明和初始化。 常量被初始化之后,編譯器不允許再修改該變量的值。 常見做法:將常量名稱首字符大寫或將整個名稱大寫。例如:Months,MONTHS。
在聲明中對于 const 進行初始化,否則該常量的值將是不確定的,且無法修改。
const 相對于 #define 的優勢:
const 能夠明確類型。 可以使用C++作用域規則將定義限制在特定的函數或文件中。 可以將 const 用于更復雜的類型。 C++中(而不是C)可以使用 cosnt 值來聲明數組長度。
浮點數
帶小數部分的數字。
浮點數能夠表示:
小數值。 非常大的值。 非常小的值。
書寫浮點數
標準小數表示。例如:123.456 E表示法(適合表示非常大或非常小的值)。例如:3.45E6 表示 3.45 * 10^6
E表示法規則:
可以使用 E 或 e。 指數可以是正數也可以是負數。 數字中間不能有空格。
浮點數類型
按照有效位數和允許的指數最小范圍劃分:
float。有效位數至少32位。通常為32位。至少6位有效位。 double。有效位數至少48位,且不少于 float。通常為64位。至少15位有效位。 long double。有效位數至少和 double 一樣多。通常為80、96 或 128位。 三種類型指數范圍至少 -37 到 37。
ostream 方法 setf():迫使輸出使用定點表示法,更好地了解精度,防止程序把較大值切換為E表示法,使程序顯示到小數點后六位。
程序清單3.8 floatnum.cpp 代碼演示:
#include <iostream> int main ( )
{ using namespace std
; cout
. setf ( ios_base
:: fixed
, ios_base
:: floatfield
) ; float tub
= 10.0 / 3.0 ; double mint
= 10.0 / 3.0 ; const float million
= 1.0e6 ; cout
<< "tub = " << tub
<< ", a million tubs = " << million
* tub
; cout
<< ",\nand ten million tubs =" << 10 * million
* tub
<< endl
; cout
<< "mint = " << mint
<< " and a million mints = " << million
* mint
<< endl
; return 0 ;
}
運行結果:
浮點常量
默認情況下浮點數常量都是 double 類型。 如果希望為 float 類型,使用 f 或者 F后綴。 long double 類型后綴使用 l 或 L。
浮點數的優缺點
優點:
可以表示正數之間的值。 可以表示的數值范圍大很多。
缺點:浮點運算速度比正數運算慢,且精度將降低。
程序清單3.9 fltadd.cpp 代碼演示:
#include <iostream> int main ( )
{ using namespace std
; float a
= 2.34E+22f ; float b
= a
+ 1.0f ; cout
<< "a = " << a
<< endl
; cout
<< "b - a = " << b
- a
<< endl
; return 0 ;
}
運行結果: 分析:float 只能表示數字中的前 6位 或者前 7位,因此修改第23位對于數值不影響。
C++算術運算符
基本算術計算:
加法。 減法。 乘法。 除法。 求模。(求余數)
每種運算符有兩個操作數。 表達式:操作數 + 運算符。
如果兩個操作數是整數,則結果為商的整數部分,小數部分被丟棄。例如:17 / 3 等于 5。
求模運算:
例如:19 % 6 為 1。 兩個操作數必須都是整型,將運算符用于浮點數將導致編譯錯誤。 如果其中一個操作數為負數,則結果的符號滿足如下規則: (a/b)*b + a%b = a。
變量和常量都可以用于操作數。
程序清單3.10 arith.cpp 代碼演示:
#include <iostream> int main ( )
{ using namespace std
; float hats
, heads
; cout
. setf ( ios
:: fixed
, ios_base
:: floatfield
) ; cout
<< "Enter a number: " ; cin
>> hats
; cout
<< "Enter another number: " ; cin
>> heads
; cout
<< "hats = " << hats
<< "heads = " << heads
<< endl
; cout
<< "hats + heads = " << hats
+ heads
<< endl
; cout
<< "hats - heads = " << hats
- heads
<< endl
; cout
<< "hats * heads = " << hats
* heads
<< endl
; cout
<< "hats / heads = " << hats
/ heads
<< endl
; return 0 ;
}
運行結果:
float只保證6位有效位。 如果需要更高的精度,請使用 double 或 long double。
運算符優先級和結合性
優先級:
算數運算符遵循先乘除,后加減。 可以用括號來執行自定義優先級。 / * % 由優先級相同。 減和加優先級相同,但比乘除低。
結合性:
優先級相同時看操作數結合性。 乘除都是從左向右結合。 僅當兩個運算符被用于同一個操作數時,優先級和結合性才有效。 例如:int num = 20 * 5 + 24 * 6 沒有指出應該先算那個乘法。C++讓實現決定在系統中最佳順序。
除法分支
如果兩個操作數都是整數,則執行整數除法,結果的小數部分將被丟棄。 如果其中有一個(或兩個)操作數是浮點值,則小數部分保留,結果為浮點數。
程序清單3.11 divide.cpp 代碼演示:
#include <iostream> int main ( )
{ using namespace std
; cout
. setf ( ios
:: fixed
, ios_base
:: floatfield
) ; cout
<< "Integer division: 9/5 = " << 9 / 5 << endl
; cout
<< "Floating-point division: 9.0/5.0 = " << 9.0 / 5.0 << endl
; cout
<< "Mixed division: 9.0/5 = " << 9.0 / 5 << endl
; cout
<< "double constants: 1e7/9.0 = " << 1e7 / 9.0 << endl
; cout
<< "float constants: 1e7f/9.0f = " << 1e7f / 9.0f << endl
; return 0 ;
}
運行結果:
不同類型計算時,C++把它們轉換為同一類型。 如果兩個操作數都是 double 類型,則結果為 double 類型。 如果兩個操作數都是 float類型,則結果為 float 類型。 浮點常量默認情況下是double 類型。
運算符重載簡介:
使用相同的符號進行多種操作。 根據上下文來確定運算符的含義。 C++有內置運算符重載,支持擴展運算符重載,以便能夠用于用戶定義的類。
求模運算符
返回整數除法的余數。
程序清單3.12 modulus.cpp 代碼演示:
#include <iostream> int main ( )
{ using namespace std
; const int Lbs_per_stn
= 14 ; int lbs
; cout
<< "Enter your weight in pounds:" ; cin
>> lbs
; int stone
= lbs
/ Lbs_per_stn
; int pounds
= lbs
% Lbs_per_stn
; cout
<< lbs
<< "pounds are" << stone
<< " stone," << pounds
<< "pounds(s).\n" ; return 0 ;
}
運行結果:
類型轉換
C++自動執行多種類型轉換:
將一種算術類型的值賦給另一種算術類型的變量時,C++將對值進行轉換。 表達式中包含不同類型時,C++將對值進行轉換。 將參數傳遞給函數時,C++將對值進行轉換。
初始化和賦值進行轉換
C++允許將一種類型的值賦給另一種類型的變量,值將被轉換為接受變量的類型。
注意:
int a
= 1 ;
long b
= 2 ;
b
= a
;
上面賦值完成后,a 的類型不變,生成和b類型相同的變量賦值給b。
潛在的數制轉換問題:
賦值給 bool 變量:
將 0 賦值給 bool 變量時,將被轉換為 false。 非零值將會被轉換為 true。
float 值對于 int 變量來說可能太大。
程序清單 3.13 assig.cpp 代碼演示:
#include <iostream> int main ( )
{ using namespace std
; cout
. setf ( ios
: : fixed
, ios_base
: : floatfield
) ; float tree
= 3 ; int guess ( 3.9832 ) ; int debt
= 7.2E12 ; cout
<< "tree = " << tree
<< endl
; cout
<< "guess = " << guess
<< endl
; cout
<< "debt = " << debt
<< endl
; return 0 ;
}
運行結果: 注意:將浮點型轉換為整型時,C++采取截斷(丟失小數部分)而不是四舍五入。
以 { } 方式初始化時進行的轉換(C++11)
C++使用 { } 的初始化稱為列表初始化。 常用用于給復雜類型提供值列表。
類型要求更嚴格:列表初始化不允許縮窄。
不允許將浮點型轉換為整型。 不同的整型之間或將整型轉換為浮點型:編譯器知道目標變量能夠正確存儲賦給它的值才會被允許。
表達式中的轉換
同一表達式中包含兩種不同的算術類型,執行兩種自動轉換:
整型提升
C++將表達式中的 bool、char、unsigned char、signed char 、short 值轉換為 int。(具體:true 被轉換為 1, false 被轉換為 0) 通常將 int 類型選擇為計算機最自然類型,計算機處理這種類型時,速度可能最快。 如果 short 比 int 短,unsigned short 將被轉換為 int。 如果short 和 int 長度相同,則 unsigned short 轉換為 unsigned int。 wchar_t 被提升為下列類型中第一個寬度足夠存儲 wchar_t 取值范圍的類型:int 、 unsigned 、 long 或 unsigned long。
不同類型進行算術運算
較小的類型將被轉換為較大的類型。
C++11校驗表
如果有一個操作數是 long double ,則將另一個操作數轉換為 long double。 否則,如果有一個操作數是 double,則將另一個操作數轉換為 double。 否則,如果有一個操作數是 float,則將另一個操作數轉換為 float。 否則,說明操作數都是整型,進行整型提升。 整型提升,如果兩個操作數都是有符號或無符號,低級別操作數類型轉換為高級別操作數類型。 如果一個操作數有符號,另一個操作數無符號,且無符號操作數的級別比有符號操作數的級別高,則將有符號操作數轉換為無符號操作數所屬的類型。 否則,如果有符號類型可表示無符號類型的所有值,則將無符號操作數轉換為有符號操作數的所屬類型。 否則,將兩個操作數都轉換為有符號類型的無符號版本。
整型級別:
有符號整型按照級別從高到低依次為:long long 、long 、int 、short 和 signed char。 無符號整型的排列順序與有符號整型相同。 char、signed char 和 unsigned char 的級別相同。 wchar_t 、 char_16_t 、 char32_t 的級別與其底層類型相同。 boo 級別最低。
傳參時轉換
傳遞參數時類型轉換通常由C++函數原型控制。
強制類型轉換
格式:
(long) thorn long (thorn)
強制類型轉換不會修改 thorn 的值,而是創建一個新的、指定類型的值。 C++引入4個強制類型轉換運算符。 static_cast<> 比傳統前置類型轉換更嚴格。
程序清單 3.14 typecast.cpp
代碼演示:
#include <iostream> int main ( )
{ using namespace std
; int auks
, bats
, coots
; auks
= 19.00 + 11.99 ; bats
= ( int ) 19.00 + ( int ) 11.99 ; coots
= int ( 19.00 ) + int ( 11.99 ) ; cout
<< "auks = " << auks
<< " bats = " << bats
<< " coots = " << coots
<< endl
; char ch
= 'Z' ; cout
<< "The code for" << ch
<< "is" << int ( ch
) << endl
; cout
<< "Yes, the code is " << static_cast < int > ( ch
) << endl
; return 0 ;
}
運行結果:
C++11中的 auto
讓編譯器根據初始值類型推斷變量的類型。
初始化過程中,如果使用關鍵字 auto 而不制定變量的類型,編譯器會把變量的類型設置與初始值相同。
auto n
= 100 ;
auto x
= 1.5 ;
auto y
= 1.3e12L ;
處理復雜類型,如STL中的類型時,使用 auto 自動推到類型。
總結 C++基本類型
整型
從小到大:bool、char、signed char、unsigned char、short、unsigned short、int 、unsigned int、long 、unsigned long 、C++11新增:long long 、unsigned long long 。 wchar_t 大小取決于實現。 C++11 新增 :char16_t 、char32_t 、存儲16位和32位字符編碼。 C++確保 char 足夠大,能夠存儲系統基本字符集中的任何成員。 wchar_t 能夠存儲系統擴展字符集中的任何成員。 short 至少 16位,int 至少和 short 一樣長,long 至少有3 2位且至少和int一樣長。 確切長度取決于實現。
浮點數
類型:float 、double 、long double。 C++確保:float 不超過 double,double 不會超過 long double。 通常 float:32位,double 64位,long double 80位 到 128位。
《新程序員》:云原生和全面數字化實踐 50位技術專家共同創作,文字、視頻、音頻交互閱讀
總結
以上是生活随笔 為你收集整理的C++Primer Plus (第六版)阅读笔记 + 源码分析【第三章:处理数据】 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。