操作符和表达式的问题总结
操作符:
- 算術操作符 + - * / %
%操作符的兩個操作數必須為整數
- 移位操作符
<< 左移操作符
>> 右移操作符:邏輯移位(左邊?0填充)、算術移位(左邊?原該值的符號位填充)
注意:對于移位運算符,不要移動負數位,這個是標準未定義的
- 位操作符
& 按位與 | 按位或 ^ 按位異或
注:他們的操作數必須是整數
- 賦值操作符 = :復合賦值符 += -+ *= >>= <<= &= |=
- 單?操作符
! 邏輯反操作
- 負值
+ 正值
& 取地址
sizeof 操作數的類型?度(以字節為單位)
~ 對?個數的?進制按位取反
-- 前置、后置--
++ 前置、后置++
* 間接訪問操作符(解引?操作符)
(類型) 強制類型轉換
- 關系操作符? ? > >= < <= != ==
- 邏輯操作符? ? && 邏輯與 | | 邏輯或
&&的特性:若&&前面已經為0(假),就沒有必要進行后面的運算
| | 的特性:若||前面遇到0,則繼續;若遇到非0,就停下
- 條件操作符? ? exp1 ? exp2 : exp3
- 逗號表達式? ? exp1, exp2, exp3, …expN
逗號表達式,就是?逗號隔開的多個表達式。
逗號表達式,從左向右依次執?。整個表達式的結果是最后?個表達式的結果。
- 下標引?[ ]、函數調?( )和結構成員./->
?
表達式求值
隱式類型轉換
C的整型算術運算總是?少以缺省整型類型的精度來進?的。
整型提升:表達式中的字符和短整型操作數在使?之前被轉換為普通整型。
char a,b,c; a = b + c;b和c的值被提升為普通整型,然后再執?加法運算。加法運算完成之后,結果將被截斷,然后再存儲于a中。
char a,b; a = (~a ^ b << 1)>> 1;由于存在求補和左移操作,所以8位的精度是不夠的。標準要求進?完整的整型求值,所以對于這類表達式的結果,不會存在歧義.
?
算術轉換
如果某個操作符的各個操作數屬于不同的類型,那么除?其中?個操作數的轉換為另?個操作數的類型,否則操作就?法進?。
尋常算術轉換:
- long double
- double
- float
- unsigned long int
- long int
- unsigned int
- int
如果某個操作數的類型在上?這個列表中排名較低,那么?先要轉換為另外?個操作數的類型后執?運算。
float f = 3.14; int num = f;//隱式轉換,會有精度丟失上面的例子可以看出:算術轉換要合理,要不然會有?些潛在的問題。
?
操作符的屬性
復雜表達式的求值:
- 操作符的優先級
- 操作符的結合性
- 是否控制求值順序
兩個相鄰的操作符先執?哪個?取決于他們的優先級。如果優先級相同,取決于他們的結合性。
?
來看看一些問題表達式:
//表達式一 a*b + c*d + e*f;表達式一:由于 * 比 + 的優先級高,只能保證第一個 * 比第一個 + 計算的早,但優先級并不能保證第三個 * 比第一個 + 執行的早。
//表達式二 c + --c;表達式二:操作符的優先級只能決定?減 -- 的運算在 + 的運算的前?,但是我們并沒有辦法得知 + 操作符的左操作數的獲取在右操作數之前還是之后求值,所以結果是不可預測的,有歧義。
//表達式三 int main() {int i = 10;i = i-- - --i * ( i = -3 ) * i++ + ++i;printf("i = %d\n", i); return 0; }表達式三:是一個非法表達式,在不同編譯器中有不同的結果。
//表達式四 int fun() {static int count = 1;return ++count; } int main() {int answer;answer = fun() - fun() * fun();printf("%d\n", answer);//輸出多少?return 0; }總結:不要寫出依賴求值順序的表達式。這樣的表達式是不可移植的。一定要避免。
總結
以上是生活随笔為你收集整理的操作符和表达式的问题总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux——进程间关系和守护进程(总结
- 下一篇: 标识符的链接属性