前言
在程式語言中,運算子是使用符號的指令。由於運算子無法再化約成更細的指令,運算子可視為程式語言的基本指令。本文介紹 C++ 的運算子。
用 assert
取代標準輸出
在本文及之後的文章中,我們會在一部分範例中用 assert
來取代標準輸出入,這是因為使用 assert
可以明顯地從程式碼中看出程式設計者的意圖,如下例:
#include <cassert>
#include <iostream>
int main(void)
{
assert(3 + 4 == 7);
return 0;
}
在這個例子中,我們可以明確地知道我們要檢查的程式碼;如果使用標準輸出,我們還得將程式編譯後輸出,然後再人工確認答案,反而比較麻煩。透過 cassert 函式庫即可使用 assert
敘述。
註:assert
敘述實際上是巨集 (macro)。
算術運算子 (Arithmetic Operators)
算術運算子用於基本的代數運算。以下是 C++ 的算術運算子:
a + b
:相加a - b
:相減a * b
:相乘a / b
:相除a % b
:取餘數+a
:取正數-a
:取負數
以下是範例程式:
#include <cassert>
int main(void)
{
assert(+3 == 3);
assert(-3 == -3);
assert(3 + 4 == 7);
assert(3 - 4 == -1);
assert(3 * 4 == 12);
/* Integer division. */
assert(3 / 4 == 0);
assert(3 % 4 == 3);
return 0;
}
注意整數相除得整數結果,浮點數相除得浮點數結果。浮點數和整數混合運算時,會將整數提升成浮點數。
遞增 (Increment) 和遞減 (Decrement)
遞增/遞減運算是一種語法糖。相當於把 a = a + 1;
簡化成表達式的寫法。根據其情境共有以下四種:
++a
:前綴遞增。先遞增再取值a++
:後綴遞增。先取值再遞增--a
:前綴遞減。先遞減再取值a--
:後綴遞減。先取值再遞減
需注意前綴和後綴的差異。以下是範例程式:
#include <cassert>
int main(void)
{
auto n = 3;
assert(n++ == 3);
assert(n == 4);
n = 3;
assert(++n == 4);
assert(n == 4);
return 0;
}
前半的 n++
是後綴遞增,所以先進行比較完才遞增 1
。相對來說,後半的 ++n
是前綴遞增,先遞增 1
才進行比較。
二元運算子 (Bitwise Operators)
二元運算子用於二進位數運算。以下是 C++ 的二元運算子:
&
:且 (bitwise and)|
:或 (bitwise or)^
:互斥或 (bitwise xor)~
:取補數<<
:左移>>
:右移
以下是 bitwise and 的運算方式:
p | q | r |
---|---|---|
1 | 1 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 0 |
以下是 bitwise or 的運算方式:
p | q | r |
---|---|---|
1 | 1 | 1 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
以下是 bitwise xor 的運算方式:
p | q | r |
---|---|---|
1 | 1 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
以下列出實例:
#include <cassert>
int main(void)
{
auto a = 0b0101;
auto b = 0b0011;
assert((a & b) == 0b0001);
assert((a | b) == 0b0111);
assert((a ^ b) == 0b0110);
assert((a << 1) == 0b1010);
assert((a >> 1) == 0b0010);
return 0;
}
指派運算子 (Assignment Operators)
指派運算子算是一種語法糖。像是 a = a + 1;
就可以改寫成 a += 1;
。以下是 C++ 的指派運算子:
=
:指派,未進行其他運算+=
:相加後指派-=
:相減後指派*=
:相乘後指派/=
:相除後指派%=
:取餘數後指派&=
:進行 bitwise and 運算後指派|=
:進行 bitwise or 運算後指派^=
:進行 bitwise xor 運算後指派<<=
:進行左移後指派>>=
:進行右移後指派
以下是實例:
#include <cassert>
int main(void)
{
auto a = 3; a += 4;
assert(a == 7);
a = 3; a -= 4;
assert(a == -1);
a = 3; a *= 4;
assert(a == 12);
a = 3; a /= 4;
assert(a == 0);
a = 3; a %= 4;
assert(a == 3);
return 0;
}
比較運算子 (Comparison Operators)
比較運算子用來比較兩值間的相對關係。以下是 C++ 的比較運算子:
==
:相等!=
:相異、不相等>
:大於>=
:大於或等於<
:小於<=
:小於或等於
以下是實例:
#include <cassert>
int main(void)
{
assert(3 + 4 == 7);
assert(3 + 4 != 5);
assert(3 + 4 > 5);
assert(3 + 4 >= 5);
assert(3 + 4 < 8);
assert(3 + 4 <= 8);
return 0;
}
邏輯運算子 (Logic Operators)
邏輯運算子用於邏輯運算。以下是 C++ 的邏輯運算子:
&&
:且 (logical and)||
:或 (logical or)!
:非 (logical not)
以下是 logic and 運算的方式:
p | q | r |
---|---|---|
true | true | true |
false | true | false |
true | false | false |
false | false | false |
以下是 logic or 運算的方式:
p | q | r |
---|---|---|
true | true | true |
false | true | true |
true | false | true |
false | false | false |
以下是 logic not 運算的方式:
p | r |
---|---|
true | false |
false | true |
以下是實例:
#include <cassert>
int main(void)
{
// AND
assert((true && true) == true);
assert((true && false) == false);
assert((false && true) == false);
assert((false && false) == false);
// OR
assert((true || true) == true);
assert((true || false) == true);
assert((false || true) == true);
assert((false || false) == false);
// NOT
assert((!true) == false);
assert((!false) == true);
return 0;
}
運算子優先順序 (Operator Precedence)
在同一行敘述內碰到多個運算子時,會以運算子優先順序來決定運算順序。這裡有一份 C++ 的運算子優先順序清單。
實際上,程式設計師不太去記憶運算子優先順序。運算子優先順序和數學運算方式相符。可以藉由撰寫簡明的敘述來減少單一敘述內的運算子數量。真的碰到較複雜的敘述時,可以用括號 (
和 )
改變運算子優先順序。