1、運算子優先順序很容易引起問題,如a = 4<<1+1,由於<<的優先順序低於+,故其執行過程為 a = 4<<(1+1);
常見的運算子優先關係:(具體參照部落格)
優先順序 |
運算子 |
名稱或含義 |
使用形式 |
結合方向 |
說明 |
1 |
[] |
陣列下標 |
陣列名[常量表示式] |
左到右 |
-- |
() |
圓括號 |
(表示式)/函式名(形參表) |
-- |
||
. |
成員選擇(物件) |
物件.成員名 |
-- |
||
-> |
成員選擇(指標) |
物件指標->成員名 |
-- |
||
|
|||||
2 |
- |
負號運算子 |
-表示式 |
右到左 |
單目運算子 |
~ |
按位取反運算子 |
~表示式 |
|||
++ |
自增運算子 |
++變數名/變數名++ |
|||
-- |
自減運算子 |
--變數名/變數名-- |
|||
* |
取值運算子 |
*指標變數 |
|||
& |
取地址運算子 |
&變數名 |
|||
! |
邏輯非運算子 |
!表示式 |
|||
(型別) |
強制型別轉換 |
(資料型別)表示式 |
-- |
||
sizeof |
長度運算子 |
sizeof(表示式) |
-- |
||
|
|||||
3 |
/ |
除 |
表示式/表示式 |
左到右 |
雙目運算子 |
* |
乘 |
表示式*表示式 |
|||
% |
餘數(取模) |
整型表示式%整型表示式 |
|||
4 |
+ |
加 |
表示式+表示式 |
左到右 |
雙目運算子 |
- |
減 |
表示式-表示式 |
|||
5 |
<< |
左移 |
變數<<表示式 |
左到右 |
雙目運算子 |
>> |
右移 |
變數>>表示式 |
|||
|
|||||
6 |
> |
大於 |
表示式>表示式 |
左到右 |
雙目運算子 |
>= |
大於等於 |
表示式>=表示式 |
|||
< |
小於 |
表示式<表示式 |
|||
<= |
小於等於 |
表示式<=表示式 |
|||
7 |
== |
等於 |
表示式==表示式 |
左到右 |
雙目運算子 |
!= |
不等於 |
表示式!= 表示式 |
|||
|
|||||
8 |
& |
按位與 |
表示式&表示式 |
左到右 |
雙目運算子 |
9 |
^ |
按位異或 |
表示式^表示式 |
左到右 |
雙目運算子 |
10 |
| |
按位或 |
表示式|表示式 |
左到右 |
雙目運算子 |
11 |
&& |
邏輯與 |
表示式&&表示式 |
左到右 |
雙目運算子 |
12 |
|| |
邏輯或 |
表示式||表示式 |
左到右 |
雙目運算子 |
|
|||||
13 |
?: |
條件運算子 |
表示式1? 表示式2: 表示式3 |
右到左 |
三目運算子 |
|
|||||
14 |
= |
賦值運算子 |
變數=表示式 |
右到左 |
-- |
/= |
除後賦值 |
變數/=表示式 |
-- |
||
*= |
乘後賦值 |
變數*=表示式 |
-- |
||
%= |
取模後賦值 |
變數%=表示式 |
-- |
||
+= |
加後賦值 |
變數+=表示式 |
-- |
||
-= |
減後賦值 |
變數-=表示式 |
-- |
||
<<= |
左移後賦值 |
變數<<=表示式 |
-- |
||
>>= |
右移後賦值 |
變數>>=表示式 |
-- |
||
&= |
按位與後賦值 |
變數&=表示式 |
-- |
||
^= |
按位異或後賦值 |
變數^=表示式 |
-- |
||
|= |
按位或後賦值 |
變數|=表示式 |
-- |
||
|
|||||
15 |
, |
逗號運算子 |
表示式,表示式,… |
左到右 |
--
|
2、c++巨集定義時要對每個變數和語句加上括號,在編譯之前,將巨集帶入語句看有沒有邏輯錯誤,
在c++中使用巨集定義的函式儘量使用行內函數代替;
使用巨集來儲存常量的儘量使用const變數代替;
使用巨集來縮短長變數名的,可以用引用來代替;
3、給巨集定義命名時,要避免巨集名稱與系統庫的定義同名。
4、將char轉換為int時,一定要注意char的最高位是0還是1,一般系統中char為為有符號的,在將char轉換為int時,先將char轉換為unsigned char
char a = 0x9A; int util = (int)(unsigned char)a;
將int轉換為char時,如果系統預設char為unsigned char,則下面會出現問題:
char c; while((c = getchar())!=EOF){ //如果char是unsigned char則EOF(-1)會轉換為(unsigned char)255 putchar(c); }
解決方法是
int c; //去除int轉換為char的強制轉化 while((c = getchar())!=EOF){ putchar(c); }
對於變數的強制轉換,需要注意型別的截斷和擴充套件。
一定要注意有符號int和無符號int比較的後果:
#include <iostream> #include <vector> using namespace std; int main(){ vector<int> a; a.push_back(1); a.push_back(2); int i = -1; if(i< a.size()) cout<<"True"<<endl; ////由於size()返回的是size_t,其是unsigned int此時i會轉換成unsigned int, else cout<<"False"<<endl; return 0; }
在位域結構體中,注意結構體變數型別
#include <iostream> #include <vector> using namespace std; struct data{ int flag : 1; //注意這代表符號位,取值範圍為0或-1 int other: 31; }; int status(){ return 1; } int main(){ struct data test; test.flag = 1; //返回值1賦給flag時會出現溢位, cout<<test.flag; }
解決方法是將結構體中的變數變成unsigned int
5、浮點數比較時,一般比較他們的差值在一定範圍內
6、關於常量指標和指標常量:
int *const px ; //指真本身是常量,它指向的地址是不可改變的,但地址裡的內容可以通過指標改變。
const int *py; // 指標指向的是常量,它不能指向變數,它指向的內容不能改變,不能通過指標來修改它指向的內容,但指標本身不是常量,它自身的值可以改變。
7、關鍵字extern可以置於變數和函式前,以表示變數或者函式的定義在別的檔案中,提示編譯器遇到此變數或函式時在其他模組中尋找定義。
8、對結構體進行賦值時,建議具體到結構體的成員變數名。
struct rectangle { int length; int width; } struct rectangle rect ={rect.length = 4, rect.width = 2};
9.關於cin>>和getline混用導致的奇怪問題
#include <iostream> #include <vector> using namespace std; int main(){ int num; string str; cin >> str; //讀取到連續的字串後,立即停止,使用者按下Enter鍵時,"\n"留在輸入流中 cin.ignore(); //解決方法用cin.ignore()清除留在輸入流中的換行符 getline(cin,str); //getline遇到換行符結束 cout<<num << " "<<str<<endl; }