
この記事の要点
- 算術演算子では代入は行われないが、インクリメント(デクリメント)では代入まで行われる
- インクリメント(デクリメント)演算子は、前置きと後置きで処理順が変わる
- 比較演算子や論理演算子は、主にif文などの条件判定で使われる
以前、C言語とはどんな言語か、またどんな業務で利用されるのかなど、基本を解説していました。
C言語の中でも初心者の方にとってハードルが高いのが、演算子です。
C言語の演算子の種類はたくさんあり、初心者が全て覚えるのは困難です。
そこで当記事では、C言語の演算子の使い方をサンプルコード付きで丁寧に解説しています。
1記事でほとんどの演算子をカバーしているため、網羅的に演算子を学習することができます。
目次
算術演算子とインクリメント・デクリメント演算子
「算術演算子」は、足し算や引き算などの計算を行うための演算子です。
「インクリメント演算子」「デクリメント演算子」は、足し算、引き算と代入を一度に行える演算子です。
それぞれ具体的に見ていきましょう。
算術演算子
| 演算子 | 使用例 | 説明 | 
|---|---|---|
| + | a + b | a に b を加えた結果を返す | 
| - | a - b | a から b を引いた結果を返す | 
| * | a * b | a に b をかけた結果を返す | 
| / | a / b | a を b で割った結果を返す | 
| % | a % b | a を b で割った余りを返す | 
以下はサンプルコードです。
int a = 5;
int b = 2;
printf("%d\n", a + b); // 7
printf("%d\n", a - b); // 3
printf("%d\n", a * b); // 10
printf("%d\n", a / b); // 2
printf("%d\n", a % b); // 1
printf("a : %d b : %d\n", a, b); // a : 5 b : 2
気を付けていただきたいのは、算術演算子を使っただけでは、aやbの値が変わっていないことです。
これは、算術演算子では、代入処理が行われていないからです。
インクリメント演算子、デクリメント演算子
| 演算子 | 使用例 | 説明 | 
|---|---|---|
| ++ | a++, ++a | a に 1 を加えた値を a に代入する(インクリメント) | 
| -- | a--, --a | a から 1 を引いた値を a に代入する(デクリメント) | 
サンプルコードは次のようになります。
int a = 5;
a++;
printf("%d\n", a); // 6
a--;
printf("%d\n", a); // 5
算術演算子と違うのは、計算結果の代入まで行われる点です。
インクリメントやデクリメントは、特にfor文内で使われることが多くあります。
for(int i = 0; i < 10; i++){
}
前置きと後置き
「++」や「--」を変数の前につける(前置き)か、後につける(後置き)かで、処理の順序が変わります。
| 使用例 | 説明 | |
|---|---|---|
| 前置き | ++a, --a | 他の処理より前にインクリメント(デクリメント)を行う | 
| 後置き | a++, a-- | 他の処理より後にインクリメント(デクリメント)を行う | 
説明だけだと理解しづらいと思うので、具体例を見ていきましょう。
// 前置き
int a1 = 5;
int b1 = ++a1;
printf("a1 : %d b1 : %d\n", a1, b1); // a1 : 6 b1 : 6
// 後置き
int a2 = 5;
int b2 = a2++;
printf("a2 : %d b2 : %d\n", a2, b2); // a2 : 6 b2 : 5
前置きの場合、b1への代入処理より前に、a1のインクリメントが行われるため、b1には加算後の「6」が代入されます。
一方、後置きの場合、b2への代入処理の後に、a2のインクリメントが行われます。
つまり、b2への代入処理の時点では加算されていないので、b2に「5」が代入されます。
代入演算子
「代入演算子」は、変数に値を代入するための演算子です。
算術演算子とセットになった、「複合代入演算子」も合わせてご紹介します。
| 演算子 | 使用例 | 説明 | 
|---|---|---|
| = | a = b | a に b を代入する | 
| += | a += b | a に a + b の計算結果を代入する | 
| -= | a -= b | a に a - b の計算結果を代入する | 
| *= | a *= b | a に a * b の計算結果を代入する | 
| /= | a /= b | a に a / b の計算結果を代入する | 
| %= | a %= b | a に a % b の計算結果を代入する | 
以下はサンプルコードです。
int a = 5;
int b = 2;
a += b;
printf("%d\n", a); // 7
a -= b;
printf("%d\n", a); // 5
a *= b;
printf("%d\n", a); // 10
a /= b;
printf("%d\n", a); // 5
a %= b;
printf("%d\n", a); // 1
複合代入演算子を使う度に、aの値が変化していることがおわかりいただけると思います。
比較演算子
「比較演算子」は、ある値どうしを比較したい場合に使います。
| 演算子 | 使用例 | 説明 | 
|---|---|---|
| < | a < b | a が b より小さければtrue、それ以外false | 
| > | a > b | a が b より大きければtrue、それ以外false | 
| <= | a <= b | a が b 以下ならtrue、それ以外false | 
| >= | a >= b | a が b 以上ならtrue、それ以外false | 
| == | a == b | a が b と等しいならtrue、それ以外false | 
| != | a != b | a が b と等しくないならtrue、それ以外false | 
以下はサンプルコードです。
int a = 0;
int b = 5;
while(true){
    if(a == b){
        break;
    }
    if(a < b){
        a++;
    }
}
printf("%d", a); // 5
aがbより小さい間、aをインクリメントし続け、aとbが等しくなったらループを脱出します。
このように、比較演算子はif文などの条件判定に使うことがほとんどです。
論理演算子
「論理演算子」は、論理値(true, false)の計算に使います。
| 演算子 | 使用例 | 説明 | 
|---|---|---|
| ! | !a | aを否定する(aがtrueならfalse、falseならtrue) | 
| && | a && b | a、bの論理積(a、bが共にtrueならtrue、それ以外false) | 
| || | a || b | a、bの論理和(a、bが共にfalseならfalse、それ以外true) | 
それぞれ、trueとfalseの組合せで次のような結果になります。
| a | b | !a | a && b | a || b | 
|---|---|---|---|---|
| true | true | false | true | true | 
| true | false | false | false | true | 
| false | true | true | false | true | 
| false | false | true | false | false | 
こちらも多くの場合、比較演算子と同様にif文などの条件分岐判定に使われます。
ビット演算子とシフト演算子
「ビット演算子」は、ビット単位での計算を行いたい場合に利用します。
「シフト演算子」は、ビットの桁移動を行いたい場合に利用します。
どちらも、メモリリソースが制限される、組み込み系プログラミングなどで利用されます。
しかし、かなりややこしい上に使う場面は限定的なので、初心者の方は必要になったときに勉強すれば十分です。
前項の論理演算子でも登場した記号(&、|)が使われていますが、全く別の演算なので混同しないよう注意してください。
| 演算子 | 使用例 | 説明 | 
|---|---|---|
| & | a & b | a と b のビット単位の論理積 | 
| | | a | b | a と b のビット単位の論理和 | 
| ^ | a ^ b | a と b の排他的論理和 | 
| ~ | ~a | a のビットパターンを反転 | 
| << | a << b | a を b桁左シフト | 
| >> | a >> b | a を b桁右シフト | 
以下はビット演算のコードサンプルです。
2進数の演算の知識が必要なため詳細な説明は割愛しますが、「|」を使うことで、flagという1つの変数に、flag1とflag3という2つのフラグを持たせています。
また、フラグがたっているかの判定に「&」を使っています。
short int flag1   = 0b0001;
short int flag2   = 0b0010;
short int flag3   = 0b0100;
short int flag4   = 0b1000;
short int flag = flag1 | flag3; // 0101
if((flag & flag1) != 0){
    puts("flag1");
}
if((flag & flag2) != 0){
    puts("flag2");
}
if((flag & flag3) != 0){
    puts("flag3");
}
if((flag & flag4) != 0){
    puts("flag4");
}
以下はシフト演算のサンプルです。
こちらも2進数の桁移動に関する理解が必要になりますが、「<>」を使って2のn乗分の1の計算を行っています。
算術演算子を使う場合より、高速に計算できます。
int num = 30;
num = num << 2; // 30 * 2の2乗
printf("%d\n", num); // 120
num = num >> 3; // 120 / 2の3乗
printf("%d", num); // 15
その他よく使う演算子
こちらでは、その他のよく使う演算子をご紹介します。
sizeof演算子
「sizeof演算子」は、型の大きさを調べるために使います。
| 演算子 | 使用例 | 説明 | 
|---|---|---|
| sizeof | sizeof(a) | a の型の大きさを返す | 
例えば、
sizeof(int)
と記述すると、多くの処理系では4が返って来ます。
これは、int型の変数には、メモリが4Byte割り当てられていることを意味します。
キャスト演算子
「キャスト演算子」は、明示的に型変換したい場合に利用します。
| 演算子 | 使用例 | 説明 | 
|---|---|---|
| (型名) | (double)a | a の型をdoubleに変換する | 
例えば、以下のサンプルをご覧ください。
int num1 = 5; int num2 = 3; double result = num1 / num2;
このようにすると、intどうしの割り算となり小数点以下が切り捨てられます。
結果、resultには、1.000…が入ります。
そこで、以下のようにキャストを使います。
double result = (double)num1 / num2;
こうすると、doubleとintの割り算になるため、小数点以下も有効となります。
resultには1.6666…が入ります。
演算子の優先順位
演算子には優先順位があります。
優先順位が高いものほど、先に評価されます。
例えば、
int num = 1 + 2 * 3;
とすると、「+」より「*」のほうが優先順位が高いため先に計算され、numには7が入ります。
当記事でご紹介した演算子の優先順位一覧は以下の通りです。
| 優先度 | 演算子 | 説明 | 結合の向き | 
|---|---|---|---|
| 1 | ++ | 後置インクリメント | 左から右 | 
| -- | 後置デクリメント | ||
| 2 | ! | 論理否定 | 右から左 | 
| ~ | ビット否定 | ||
| ++ | 前置インクリメント | ||
| -- | 前置デクリメント | ||
| sizeof | 型の大きさを取得 | ||
| 3 | (型名) | キャスト | 右から左 | 
| 4 | * | 掛け算 | 左から右 | 
| / | 割り算 | ||
| % | 剰余 | ||
| 5 | + | 足し算 | 左から右 | 
| - | 引き算 | ||
| 6 | << | 左シフト | 左から右 | 
| >> | 右シフト | ||
| 7 | < | 左の方が小さい | 左から右 | 
| <= | 左は右以下 | ||
| > | 左の方が大きい | ||
| >= | 左は右以上 | ||
| 8 | == | 等しい | 左から右 | 
| != | 等しくない | ||
| 9 | & | ビット単位の論理積 | 左から右 | 
| 10 | ^ | ビット単位の排他的論理和 | 左から右 | 
| 11 | | | ビット単位の論理和 | 左から右 | 
| 12 | && | 論理積 | 左から右 | 
| 13 | || | 論理和 | 左から右 | 
| 14 | = | 代入 | 右から左 | 
| += | 足し算 + 代入 | ||
| -= | 引き算 + 代入 | ||
| *= | 掛け算 + 代入 | ||
| /= | 割り算 + 代入 | ||
| %= | 剰余 + 代入 | 
まとめ
C言語は演算子の数が多く、最初は覚えきれないと感じるかもしれません。
特に、「=」と「==」、「&」「|」と「&&」「||」を混同してしまうのは初心者あるあるなので、注意してください。
使っているうちに自然と身についていくので、焦らずじっくり取り組みましょう。
もし忘れてしまったら、その都度当記事を参照して、復習してみてください。
また、演算子と同じく初心者がC言語でつまずきやすいのが「ポインタ」です。
ポインタが難しいと感じている方や、ポインタの使い方やメリットがわからないという方に向けて、ポインタを効果的に習得する方法をご紹介しています。
「ポインタ」と混同されやすい「配列」についても解説していますので、こちらも参考にしてください。









