1.C++算術運算子
1.1 基本運算子
讀者可能還對學校里的算術練習記憶猶新,在計算機上也能夠獲得同樣的樂趣,C++使用運算子來運算,它提供了幾種運算子來完成五種基本的算術運算:加法、減法、乘法、除法以及求模,每種運算子都使用兩個值來計算結果,運算子及其運算元構成了運算式,例如:int wheels = 4 + 2;4和2都是運算元,+是加法運算子,4+2則是一個運算式,加減乘除就不多贅述了,只說一下取余:%,5%2結果就是1,因為余數就是1,而且%的運算元只能是整數,
1.2 優先性和結合性
<1> int a = 2 - 3 * 4 + 5;運算元3旁邊有兩個運算子 - 和 *,當多個運算子可用于同一個運算元時,C++使用優先級規則來決定先使用哪個運算子,和我們小數學的四則運算一樣,先乘除,再加減,答案為-5,優先級*、/、%同級,
<2> float logs = 120 / 4 * 5;有時候優先級串列并不夠用,運算元4也位于兩個運算子之間,但運算子乘除一樣,計算機該怎么計算呢,這里答案是6,因為C++的結合性,將從右往左運算,
<3> int dues = 20 / 4 + 2 * 3;僅當兩個運算子被用于同一個運算元時,優先性和結合性規則才有效,優先級表示在做加法之前必須計算除法和乘法,但是優先級和結合性都沒有指出應該先計算20 / 4還是2 * 3;事實上,C++吧這個問題留給了實作,讓它來決定在系統中的最佳順序,
運算子優先性和結合性在C++中遠遠不止這么一點,當邏輯運算子,算術運算子,關系運算子等結合在一起時,那才是腦殼大(我們后面慢慢來),
2.型別轉換
2.1 隱式轉換
C++豐富的型別允許根據需要選擇不同的型別,這也使計算機的操作更復雜,例如,將兩個short值相加涉及到的硬體編譯指令可能會與兩個long值相加不同,由于有11種整型和3種浮點型別,因此計算機需要處理大量不同的情況,尤其是對不同的型別進行運算時,為處理這種潛在的混亂,C++自動執行很多型別轉換==>>:
一、將一種算術型別的值賦給另一種算術型別的變數時,C++將對值進行轉換; 二、運算式種包含不同的型別時,C++將對值進行轉換; 三、將引數傳遞給函式時,C++將對值進行轉換,
如果程式員不知道進行這些自動轉換時將發生的情況,將無法理解一些程式的結果,<1>隱式轉換:低精度-》高精度,有符號-》無符號,優先級:int -> unsigned int -> long -> unsigned long -> long long -> unsigned long long -> float -> double -> long double,比如說寧不小心把一個浮點數賦值給了整型:--> int a = 1.34;根據隱式轉換,C++將直接丟棄小數部分,所以a = 1;(注意是直接丟棄,而不是四舍五入!),繼續:--> int b = 7.2E12;

整型變數無法存盤7.2E12,這導致C++沒有對結果進行定義的情況發生,在我這種系統中b的值為2147483647,在不同編譯器上,值也不一定是這個,
下面看一個經典例子:
查看代碼
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
unsigned int a = 6;
int b = -20;
cout << hex << b << endl;
cout << hex << a + b << endl;
if(a + b > 0)
cout << "ok!" << endl;
else
cout << "error!" << endl;
return 0;
}
利用iomanip頭檔案可以讓輸出輸入格式化,這里我們用cout列印16進制,if else是簡單的條件分支陳述句,滿足a + b > 0就會執行 cout << "ok!" << endl;不滿足就執行else后面的陳述句,
我們可以猜猜結果是列印ok還是error,可能大家會覺得a + b不就是-14嗎,肯定會列印error,其實不然,結果是ok,我們知道一、有符號會向無符號隱式轉換,二、無符號最高位不表示符號,三、整型資料在計算機的存盤,-->(https://www.cnblogs.com/hbnb/p/15783996.html)我們根據這些就可以推斷出結果,步驟如下:
首先將6和-20都轉換為二進制:a = (前面28個0)0110;b = (前面24個1)1110 1100;我們把兩個相加,結果為:(前面28個1)0010;令人震驚的是,無符號最高位不是符號位,那么結果顯而易見了,a + b的結果為0xfffffff2,也就是4294967282,這當然是大于0的了,所以會列印ok,
2.2 強制轉換
Ok,Anyway!上面是一個經典的隱式轉換的例子,<2>下面看看強制轉換:除了隱式轉換規則,C++還允許通過強制轉換機制直接轉換型別:
int a = 9; long b = (long) a; long c = long (a);這會將int型別的a強制轉換為long的值,強制轉換并不是修改a本身,而是創建一個新的值,供給運算式使用,強制轉換有兩種格式,(long) a來自C語言,long (c)是C++新的強制轉換規則,這看起來像函式呼叫一樣,
還需要注意的是,在進行運算時,會先運算后轉換型別:比如 int auks = 19.99 + 11.99; a的值就是31,(又來挖坑了,C++還有四個強制轉換運算子,對它們的使用要求更加嚴格,或者以后不止是簡單的基本資料型別的轉換,還有不同型別別的轉換,咱們慢慢來吧),
2.3 auto宣告
C++11新增了一個工具,讓編譯器能夠根據初始值的型別推斷變數的型別,為此,它重新定義了C語言中auto的含義,在初始化宣告中,如果使用關鍵字auto,而不是指定變數的型別,編譯器將把變數的型別設定成與初始值相同:
auto x = 100;// x is int
auto y = 1.5;//y is double
auto z = 1.3e12L;//z is long double
auto的優勢當然不是為了處理這些簡單情況,在處理復雜型別時,如STL中的型別時,自動型別推斷有時才能顯現出來,例如,對于下述C++98代碼:
std::vector<double> scores;
std::vector<double>::iterator pv = scores.begin();
//C++11允許將其重寫為這樣:
std::vector<double> scores;
auto pv = scores.begin();
看不懂沒關系,后面會講到的,路漫漫其修遠兮,吾將上下而求索,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/412824.html
標籤:C++
