以下介紹5種C++基本運算符
+、-、×、/、%
注意/為第一個數除以第二個數,結果為商的整數部分,小數部分被丟棄
%求模,兩個操作數必須是整型,它生成第一個數除以第二個數的余數
如果其中一個是負數,那么結果的符號滿足:(a/b)*b+a%b=a
程序清單3.10 arith.cpp //arith.cpp - - some C++ arithmetic
#include<iostream>
int main() { using namespace std; float hats, heads; cout.setf(ios_base::fixed, ios_base::floatfield); cout << "Enter a number: "; cin >> hats; cout << "Enter another number:"; cin >> heads; cin.get(); 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; cin.get(); }
得到輸出:
11.17+50.25=61.42,輸出為61.41998,這不是運算問題,而是float表示有效位數能力有限。
它只保證6位有效位,四舍五入成6位就是61.4200是對的,cout打印6個小數,使用double能保證更好的精度。
1.運算符優先級和結合性
先乘除后加減,也可以用括號來執行自己定義的優先級
而×、/、%優先級相同,這個時候需要考慮結合性,可去附錄D查看
如float logs=120/4*5;
乘除都是從左到右的,所以結果為150
僅當兩個運算符被用於同一操作數時,優先級和結合性規則才有效
如int dues=20*5+24*6;
程序清單3.11 divide.cpp //divide.cpp - - integer and floating-point division
#include<iostream>
int main() { using namespace std; cout.setf(ios_base::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 = " << 1e7f / 9.0 << endl; //1.e7f也可以
cout << "float constants: 1e7f/9.0f = " << 1e7f/ 9.0f << endl;
cin.get(); }
浮點常量在默認情況下為double類型,兩操作數為float則結果為float,一個double,一個float也為double
運算符重載是什么意思?
比如你定義一個類型“學生”
現在如果你把兩個“學生”類型的變量相加, 那系統怎么知道你要怎么加? 如果是數字的話,系統知道。
那這個時候,你就要為“學生”這個類型重載加號運算符
然后在這個重載的方法里實現相加的意義,比如“學生”類型的年齡相加,或是其它東西相加,這個就你自己定義了
2.求模運算符
它返回整數除法的余數,適用於解決要求將一個量分成不同整數單元的問題
程序清單3.12 modulus.cpp //modulus.cpp - - uses % operator to convert lbs to stone
#include<iostream>
int main() { using namespace std; const int Lbs_per_stn = 14; int lbs; cout << "Enter your weight in pounds:"; cin >> lbs; cin.get(); int stone = lbs / Lbs_per_stn; int pounds = lbs%Lbs_per_stn; cout << lbs << " pounds are " << stone << " stone," << pounds << " pounds\n"; cin.get(); }
得到結果:
3.類型轉換
C++允許將一種類型的值賦給另一個類型的變量
so_long = thirty;
程序將thirty的值擴展為long,擴展后得到一個新值,被存儲在so_long中,而thirty內容不變。值不會改變,只是占用更多的字節。
將較大的浮點類型轉換為較小的浮點類型,如將double轉換為float | 精度(有效位數)降低,值可能超出目標類型的取值范圍,在這種情況下,結果將是不確定的 |
將浮點類型轉換為整型 | 小數部分丟失,原來的值可能超出目標類型的取值范圍,在這種情況下,結果將是不確定的 |
將較大的整型轉換為較小的整型,如將long轉換為short | 原來的值可能超出目標類型的取值范圍,通常只復制右邊的字節 |
像一個long值,(如2111222333)賦給float精度將下降,float只有6位有效數字,四舍五入為2.11122E9
將浮點轉化為整型會將數字截短,其次float相對於int太大了,float至少32位,int至少16位。
程序清單3.13 assign.cpp //init.cpp - - type changes on initialization
#include<iostream>
int main() { using namespace std; cout.setf(ios_base::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; cin.get(); }
得到輸出:
int變量無法存儲3.0E12,導致C++沒有對結果進行定義的情況發生。
使用大括號的初始化稱為列表初始化,給復雜的數據類型提供值列表。它對類型的轉換要求更加嚴格,列表初始化不允許縮窄。即變量的類型無法表示賦給它的值。
條件是編譯器知道目標變量能夠正確的存儲賦給它的值。
const int code=66;
int x =66;
char c1 {31325}; 縮窄
char c2 = {66};
char c3 = {code};
char c4 = {x}; x是一個變量,編譯器不會跟蹤從x被初始化到它被用來初始化c4
x=31325;
char c5 = x; 允許
自動轉換:
在計算表達式時,C++將bool、char、unsigned char和short值轉換為int叫做整型提升,當運算涉及兩種類型時,較小的類型被轉化為較大的類型。
(1)如果有一個操作數類型為long double,則將另一個轉換為long double
(2)否則,有一個類型為double,則將另一個轉化為double
(3)否則,一個類型為float,則另一個為float
(4)否則,操作數都是整型,因此執行整型提升
(5)如果兩操作數都是有符號或無符號的,且其中一個操作數比另一個低,則轉換為高的級別
(6)如果一個有符號,一個無符號,無符號操作數比有符號的高,則將有符號轉化為無符號的類型
(7)如果有符號類型可表示無符號的所有可能取值,則將無符號轉化為有符號操作數所屬類型
(8)否則,將兩個操作數都轉化為有符號類型的無符號版本
有符號整型按級別從高到底:long long、long、int、short和signed char。無符號整型和有符號整型排列順序相同。類型char、signed char和unsigned char相同,類型bool級別最低,wchar_t、char16_t、char32_t級別和底層類型相同。
強制類型轉化(將thorn中的int值轉化為long類型)
(long) thorn
long (thorn)
強制類型通用格式
(typeName) value
typeName (value)
第一種格式來自C語言,第二種格式是C++,就像是函數調用。
C++還引入了四個強制類型轉換符,static cast<>通用格式
static_cast<typeName> (value)
程序清單3.14 typecast.cpp //typecast.cpp - - forcing type changes
#include<iostream>
int main() { using namespace std; int auks, bats, coots; auks = 19.99 + 11.99; bats = (int)19.99 + (int)11.99; coots = int(19.99) + int(11.99); cout << "auks = " << auks << ",bats = " << bats; cout << ",coots = " << coots << endl; char ch = 'Z'; cout << "The code for " << ch << "is "; cout << int(ch) << endl; cout << "Yes,the code is "; cout << static_cast<int>(ch) << endl; cin.get(); }
結果:
auto這個新工具能夠根據初始值的類型來推斷變量的類型
auto n=100; int
auto x=1.5; double
auto y=1.3e12L; long double
但也會導致問題
如要把x、y、z指定為double類型
auto x=0.0;
double y=0;
auto z=0; 可知z是int類型