運算子就像是動詞。它們引發對變數的運算。
1 算術運算子
c 中有+、-、*和/這些常用的二元運算子,它們分別用於加、減、乘和除運算。
注意 如果除法運算子(/)的兩個運算元都是整數型別,則c 執行整數除法。整數除
法會把除法的結果進行擷取。例如,7 / 3 的值是2。
2 餘數運算子
餘數運算子或模運算子(%)計算乙個整數除法的餘數。例如,下面的表示式的結果是1:
1. int a = 7;
2. int b = 3;
3. int c = a%b; // c is now 1
餘數運算子的運算元必須都是整數型別。
3 自增和自減運算子
c 為自增和自減變數提供了運算子:
1. a++;
2.3. ++a;
兩行都給a 的值增加1。然而,當將兩個表示式用作乙個更大的表示式的一部分時,它們之間就有區別了。字首版++a,會在任何計算發生之前增加a 的值。在表示式中使用的是增加以後的a 值。而字尾版a++則是在其他計算進行之後才增加其值。在表示式中,使用的是其最初的值。這可以通過如下的示例來說明:
1. int a = 9;
2. int b;
3. b = a++; // postfix increment
4.5. int c = 9;
6. int d;
7. d = ++c; // prefix increment
自增運算子的字尾版,是在將變數的初始值用於表示式的計算之後,才將該變數增加1。
當示例中的**執行完以後,b 的值是9,而a 的值是10。自增運算子的字首版,是在該變數值用於表示式計算之前就增加它。因此在這個示例中,c 和d 的值都是10。自減運算子a--和--a 以類似的方式工作。
使用該運算子的字首版和字尾版之間的差別的**,很可能令除編寫者之外的人產生混淆。
4 優先順序
如下的表示式是等於18 還是22:
1. 2 *7 + 4
答案似乎是含糊的,因為這取決於是先進行加法還是先進行乘法運算。c 通過指定一條規則,即在執行加法和減法之前,先執行乘法和除法,從而解決了二義性問題;因此,該表示式的值是18。從技術性上來說,就是乘法和除法擁有比加法和減法更高的優先順序。如果需要先進行加法運算,可以使用圓括號指定:
1. 2 * (7 + 4)
編譯器將會尊重你的請求,先執行加法,然後再執行乘法。注意 c 為其所有的運算子定義了乙個複雜的優先順序表(參見
org/ wiki/order_of_operations)。使用圓括號來指定想要的運算順序,比努力記住運算子優先順序要容易得多。
5 取反
一元減法符號(-)把乙個算術值取反:
1. int a = 9;
2. int b;
3. b = -a; // b is now -9
6 比較
c 提供了用於比較的運算子。比較的值是乙個真值。如下的表示式,如果為真,則取值為1;如果為假,則取值為0。
1. a > b // true, if a is greater than b
2.3. a < b // true, if a is less than b
4.5. a >= b // true, if a is greater than or equal to b
6.7. a <= b // true, if a is less than or equal to b
8.9. a == b // true, if a is equal to b
10.11. a != b // true, if a is not equal to b
7 邏輯運算子
and 和or 邏輯運算子的形式如下:
1. expression1 && expression2 // logical and operator
2.3. expression1 || expression2 // logical or operator
c 使用短路計算方式。表示式從左向右計算,並且,只要整個表示式可以得出真值,計算就停止。如果乙個and 表示式中的expression1 取值為假,那麼,整個表示式的值都為假,從而expression2 就不再計算了。同樣,如果乙個or 表示式中的expression1 取值為真,那麼,整個表示式都為真,從而expression2 就不再計算了。如果第二個表示式有任何的***,短路計算就會得到有趣的結果。在下面的例子中,如果b 大於或等於a,就不會呼叫checksomething()函式(本章後面將要介紹if 語句)了:
1. if (b < a && checksomething())
2.8 邏輯取反
嘆號(!)是c 中的一元邏輯取反運算子。在如下的**行執行之後,如果expression為真(非0),則a 的值為0;並且,如果expression 的值為假(0),則a 的值為1:
1. a = ! expression;
9 賦值運算子
c 提供了基本的賦值運算子:
1. a = b;
上面的語句將b 的值賦給了a。當然,a 必須是能夠對其賦值的變數。可以對其賦值的實體叫做左值(lvalue)(因為它們放在賦值運算子的左邊)。如下是左值的一些例子:
1. /* set up */
2. float a;
3. float b[100]
4. float *c;
5. struct dailytemperatures today;
6. struct dailytemperatures *todayptr;
7. c = &a;
8. todayptr = &today;
9.10. /* legal lvalues */
11. a = 76;
12. b[0] = 76;
13. *c = 76;
14. today.high = 76;
15. todayptr->high = 76;
有些內容不是左值。不能對乙個陣列名稱、乙個函式的返回值或者任何沒有引用乙個記憶體位置的表示式賦值:
1. float a[100];
2. int x;
3.4. a = 76; // wrong
5. x*x = 76; // wrong
6. gettodayshigh() = 76; // wrong
10 轉換和強制型別轉換
如果賦值的兩端具有不同的變數型別,則右邊的型別會轉換為左邊的型別。從較短的型別轉換為較長的型別,或者從整數型別轉換為浮點型別,這不會引發問題。但是,反過來,從乙個較長的型別轉換為乙個較短的型別,就可能會導致有意義的數字丟失、截斷或者完全無意義。例如:
1. int a = 14;
2. float b;
3. b = a; // ok, b is now 14.0
4.5. float c = 12.5;
6. int d;
7. d = c; // truncation, d is now 12
8.9. char e = 128;
10. int f;
11. f = e; // ok, f is now 128
12.13. int g = 333;
14. char h;
15. h = g; // nonsense, h is now 77
可以使用強制型別轉換,來迫使編譯器把乙個變數的值轉換為不同的型別。在下面的示例中的最後一行,(float)強制轉換強迫編譯器把a 和b 轉換為浮點數,並且進行浮點數除法運算:
1. int a = 6;
2. int b = 4;
3. float c, d;
4.5. c = a / b; // c is equal to 1.0 because
integer division truncates
6.7. d = (float)a / (float)b; // floating-point
division, d is equal to 1.5
可以強制轉換指標,從而將一種型別的指標轉換為另一種型別的指標。強制轉換指標可能是有風險的操作,因為這可能會毀壞記憶體,但是,對於以void*型別傳遞給你的乙個指標來說,這是將其解引用的唯一方式。成功地強制轉換乙個指標,需要理解指標「實際」所指向的實體的型別。
11 其他賦值運算子
c 還有其他的快捷運算子,它們把計算和賦值組合了起來:
1. a += b;
2. a -= b;
3. a *= b;
4. a /= b;
其等價的形式分別如下:
= a - b;
4.5. aa = a * b;
6.7. aa = a / b;
C語言基礎 運算子
運算子 功能說明用途 按位取反 按位與 取出某數中想要的位 按位或 按位異或 1.特定位反轉 11001010 1111後四位反轉 2.交換兩個數的值 a a b b a b a a b 3.加密 a a b b 右移 左移 關於特殊運算子 1.賦值運算子 注 不能對常量賦值,不能對唯讀變數賦值 c...
c語言基礎 運算子。
運算子 算術運算子 運算子舉例 加 a b 減 a b 乘 ab 除 a b 求餘 a b 加減和乘法運算子不必多說,我們來看看除法運算子和求餘運算子 除法運算子 兩個實數相除的結果為雙精度實數,兩個整數相除的結果為整數 一般向0取整 例如 5 3 執行結果為1,捨去了小數部分 根據整數除法特性 四...
C語言基礎學習運算子 關係運算子
比較大小 首先,我們得先了解一下布林型別。c語言的c99標準支援布林型別,關鍵字為 bool,用於表示邏輯值true與false。c語言用值1表示true,用值0表示false。因此布林型別實際上是一種整數型別。程式常常使用含有關係運算子的表示式進行分支和迴圈操作。我們將在分支和迴圈的章節中具體學習...