05章で学んだ算術演算子に加え、複合代入・インクリメント/デクリメント・比較・論理演算子を学ぶ。
これらは if 文や繰り返しの条件式で必ず使う。
| 演算子 | 意味 | 例 | 結果 |
|---|---|---|---|
+ | 加算 | 3 + 2 | 5 |
- | 減算 | 3 - 2 | 1 |
* | 乗算 | 3 * 2 | 6 |
/ | 除算 | 7 / 2 | 3(整数同士は切り捨て) |
% | 剰余 | 7 % 2 | 1(余り) |
% は整数型同士にしか使えない。float や double に使うとコンパイルエラーになる。
「演算した結果を同じ変数に入れる」操作を短く書ける記法。
| 演算子 | 意味 | 展開した形 |
|---|---|---|
x += 3 | 3を加える | x = x + 3 |
x -= 3 | 3を引く | x = x - 3 |
x *= 3 | 3を掛ける | x = x * 3 |
x /= 3 | 3で割る | x = x / 3 |
x %= 3 | 3で割った余りにする | x = x % 3 |
#include <stdio.h>
int main(void)
{
int a = 5;
int b = 10;
int c = 3;
int d = 20;
int e = 13;
a += 3;
printf("a += 3 → a = %d¥n", a); /* 8 */
b -= 4;
printf("b -= 4 → b = %d¥n", b); /* 6 */
c *= 4;
printf("c *= 4 → c = %d¥n", c); /* 12 */
d /= 5;
printf("d /= 5 → d = %d¥n", d); /* 4 */
e %= 5;
printf("e %%= 5 → e = %d¥n", e); /* 3 */
return 0;
}
a += 3 → a = 8 b -= 4 → b = 6 c *= 4 → c = 12 d /= 5 → d = 4 e %= 5 → e = 3
変数の値を1だけ増やす・減らす専用の演算子。
繰り返し処理のカウンタとして頻繁に使う。
| 書き方 | 名称 | 動作 |
|---|---|---|
++x | 前置インクリメント | x を 1 増やしてから式の値として使う |
x++ | 後置インクリメント | 式の値として使ってから x を 1 増やす |
--x | 前置デクリメント | x を 1 減らしてから式の値として使う |
x-- | 後置デクリメント | 式の値として使ってから x を 1 減らす |
x++; と書く場合は前置・後置どちらも結果は同じ。
#include <stdio.h>
int main(void)
{
int x, y;
/* 前置インクリメント:増やしてから代入 */
x = 5;
y = ++x;
printf("前置 ++x : x = %d, y = %d¥n", x, y); /* x=6, y=6 */
/* 後置インクリメント:代入してから増やす */
x = 5;
y = x++;
printf("後置 x++ : x = %d, y = %d¥n", x, y); /* x=6, y=5 */
/* 前置デクリメント */
x = 5;
y = --x;
printf("前置 --x : x = %d, y = %d¥n", x, y); /* x=4, y=4 */
/* 後置デクリメント */
x = 5;
y = x--;
printf("後置 x-- : x = %d, y = %d¥n", x, y); /* x=4, y=5 */
return 0;
}
前置 ++x : x = 6, y = 6 後置 x++ : x = 6, y = 5 前置 --x : x = 4, y = 4 後置 x-- : x = 4, y = 5
x++; だけの行)は前置・後置のどちらでも結果は同じ。x++)を使うのが慣習的。
複数の演算子が混在するとき、計算される順序に規則がある。
よく使う演算子の優先順位を高い順に示す。
| 優先度 | 演算子 | 説明 |
|---|---|---|
| 高 | () | カッコ |
| ↑ | ++ --(前置)! | 単項演算子 |
| | | * / % | 乗算・除算・剰余 |
| | | + - | 加算・減算 |
| | | < <= > >= | 大小比較 |
| | | == != | 等値比較 |
| | | && | 論理 AND |
| | | || | 論理 OR |
| ↓ | = += -= *= /= | 代入 |
| 低 |
sizeof は、型や変数が何バイトのメモリを使っているかを調べる演算子。
関数のように見えるが演算子であり、コンパイル時に値が決まる。
sizeof(型名)
sizeof(変数名)
#include <stdio.h>
int main(void)
{
int x = 100;
/* 型のサイズを調べる */
printf("char : %d バイト¥n", (int)sizeof(char));
printf("short : %d バイト¥n", (int)sizeof(short));
printf("int : %d バイト¥n", (int)sizeof(int));
printf("long : %d バイト¥n", (int)sizeof(long));
printf("long long : %d バイト¥n", (int)sizeof(long long));
printf("float : %d バイト¥n", (int)sizeof(float));
printf("double : %d バイト¥n", (int)sizeof(double));
/* 変数のサイズを調べる */
printf("¥n変数 x のサイズ : %d バイト¥n", (int)sizeof(x));
return 0;
}
実行結果(Visual Studio / Windows 環境):
char : 1 バイト short : 2 バイト int : 4 バイト long : 4 バイト long long : 8 バイト float : 4 バイト double : 8 バイト 変数 x のサイズ : 4 バイト
sizeof の戻り値は size_t 型(環境によって異なる符号なし整数型)。printf で表示するときは (int) でキャストして %d を使うか、%zu を使うとよい。
sizeof を使えばプログラム上で実際に確認できる。long など)の確認に特に有用。
2つの値を比較して、結果を 真(1) または 偽(0) で返す。
if 文や while 文の条件式で必ず使う。
| 演算子 | 意味 | 例 | 結果(x=5 のとき) |
|---|---|---|---|
== | 等しい | x == 5 | 1(真) |
!= | 等しくない | x != 0 | 1(真) |
> | より大きい | x > 3 | 1(真) |
< | より小さい | x < 3 | 0(偽) |
>= | 以上 | x >= 5 | 1(真) |
<= | 以下 | x <= 4 | 0(偽) |
=(代入)と ==(比較)を混同しないこと。= を書いても文法エラーにならず、意図しない動作になる頻出バグ。
C言語では 0 が偽、0 以外がすべて真 として扱われる。
比較の結果が「真」なら 1、「偽」なら 0 という整数値が返る。
#include <stdio.h>
int main(void)
{
int x = 5;
printf("x == 5 : %d¥n", x == 5); /* 1(真) */
printf("x != 5 : %d¥n", x != 5); /* 0(偽) */
printf("x > 3 : %d¥n", x > 3); /* 1(真) */
printf("x < 3 : %d¥n", x < 3); /* 0(偽) */
printf("x >= 5 : %d¥n", x >= 5); /* 1(真) */
printf("x <= 4 : %d¥n", x <= 4); /* 0(偽) */
return 0;
}
x == 5 : 1 x != 5 : 0 x > 3 : 1 x < 3 : 0 x >= 5 : 1 x <= 4 : 0
複数の条件を組み合わせるときに使う。
| 演算子 | 意味 | 真になる条件 | 例 |
|---|---|---|---|
&& | AND(かつ) | 両方が真のとき | x > 0 && x < 10 |
|| | OR(または) | どちらかが真のとき | x < 0 || x > 100 |
! | NOT(否定) | 元の条件が偽のとき | !(x == 0) |
#include <stdio.h>
int main(void)
{
int x = 5;
/* AND:両方の条件が成立するか */
printf("x>0 && x<10 : %d¥n", x > 0 && x < 10); /* 1(真) */
printf("x>0 && x>10 : %d¥n", x > 0 && x > 10); /* 0(偽) */
/* OR:どちらかの条件が成立するか */
printf("x<0 || x>3 : %d¥n", x < 0 || x > 3); /* 1(真) */
printf("x<0 || x>10 : %d¥n", x < 0 || x > 10); /* 0(偽) */
/* NOT:条件を反転する */
printf("!(x==5) : %d¥n", !(x == 5)); /* 0(偽) */
printf("!(x==0) : %d¥n", !(x == 0)); /* 1(真) */
return 0;
}
x>0 && x<10 : 1 x>0 && x>10 : 0 x<0 || x>3 : 1 x<0 || x>10 : 0 !(x==5) : 0 !(x==0) : 1
&& や || では、左辺の結果だけで全体の結果が決まる場合、右辺は評価されない。
| 演算子 | 左辺が偽のとき | 左辺が真のとき |
|---|---|---|
A && B | B を評価しない(全体が偽と確定) | B を評価する |
A || B | B を評価する | B を評価しない(全体が真と確定) |
これを利用してゼロ除算を防ぐ安全な書き方ができる:
/* x が 0 でないことを先に確認してから割り算する */
if (x != 0 && 100 / x > 1) {
printf("OK¥n");
}
x != 0 が偽(x が 0)なら 100 / x は評価されない。ゼロ除算が起きない安全な書き方。
次のコードを実行する前に、各 printf の出力を予測してからプログラムを打ち込んで確認しよう。
#include <stdio.h>
int main(void)
{
int a = 10;
a += 5;
a *= 2;
a -= 3;
a /= 3;
printf("a = %d¥n", a); /* 予測:? */
int b = 7;
printf("b++ : %d¥n", b++); /* 予測:? */
printf("b : %d¥n", b); /* 予測:? */
printf("++b : %d¥n", ++b); /* 予測:? */
printf("b : %d¥n", b); /* 予測:? */
return 0;
}
a = 9 b++ : 7 b : 8 ++b : 9 b : 9
a の計算:10→15→30→27→9(27÷3)
b++ は現在値(7)を表示してから増加 → 表示は7、その後 b=8
++b は増加してから表示 → b=9 を表示
次のコードで x の値を変えながら実行し、各条件の結果(1 か 0)がどう変わるか確認しよう。
まず x = 5 で実行し、次に x = 0・x = 15 で試してみよう。
#include <stdio.h>
int main(void)
{
int x = 5; /* ← この値を変えて試そう */
printf("x = %d のとき:¥n", x);
printf(" x > 0 : %d¥n", x > 0);
printf(" x >= 0 && x <= 10 : %d¥n", x >= 0 && x <= 10);
printf(" x < 0 || x > 10 : %d¥n", x < 0 || x > 10);
printf(" x %% 2 == 0 : %d¥n", x % 2 == 0); /* 偶数判定 */
return 0;
}
x = 0
x = 0 のとき: x > 0 : 0 x >= 0 && x <= 10 : 1 x < 0 || x > 10 : 0 x % 2 == 0 : 1
x = 15
x = 15 のとき: x > 0 : 1 x >= 0 && x <= 10 : 0 x < 0 || x > 10 : 1 x % 2 == 0 : 0
Q1. a *= 2 を展開した形として正しいものはどれか。
正解:イ
複合代入 a *= 2 は a = a * 2 と同じ。
Q2. 次のコードの出力として正しいものはどれか。
int x = 5;
int y = x++;
printf("%d %d¥n", x, y);
正解:ウ
後置インクリメントなので、まず y に x の現在値(5)を代入してから x を 1 増やす。
結果:x=6、y=5。
Q3. x = 8 のとき、x >= 5 && x <= 10 の結果はどれか。
正解:イ
x >= 5 は真(1)、x <= 10 も真(1)。AND なので両方真 → 結果は 1。
Q4. 短絡評価について正しい説明はどれか。
正解:イ
&& は左辺が偽の時点で全体が偽と確定するため、右辺を評価しない。
この性質を使って「ゼロでないか確認してから除算する」などの安全な書き方ができる。
| 演算子の種類 | 主な演算子 | ポイント |
|---|---|---|
| 複合代入 | += -= *= /= %= | x += 3 は x = x + 3 の短縮形 |
| インクリメント/デクリメント | ++ -- | 前置は増減してから使用、後置は使用してから増減 |
| 比較 | == != > < >= <= | 結果は真(1)か偽(0)。= と == の混同に注意 |
| 論理 | && || ! | 条件の組み合わせ。短絡評価を活用できる |