C言語の演算子

C言語で値を計算したり、値を比較するには演算子を使います。この記事では、C言語で使える演算子の一覧と優先順位をご紹介します。これを見れば、C言語における演算子の使い方がわかるようになります。

加算

C言語において加算(足し算)を行うには、+ 演算子を使う。

#include <stdio.h>
int main(int argc, char *argv[]) {
  int i = 1 + 2;
  printf("%d\n", i);
}

減算

C言語において減算(引き算)を行うには、- 演算子を使う。

#include <stdio.h>
int main(int argc, char *argv[]) {
  int i = 1 - 2;
  printf("%d\n", i);
}

乗算

C言語において乗算(掛け算)を行うには、* 演算子を使う。

#include <stdio.h>
int main(int argc, char *argv[]) {
  int i = 2 * 3;
  printf("%d\n", i);
}

除算

C言語において除算(割り算)を行うには、/ 演算子を使う。

#include <stdio.h>
int main(int argc, char *argv[]) {
  float f = 5.0 / 2.0;
  printf("%f\n", f);
}

整数型で割り算する場合、端数は切り捨てられる。

#include <stdio.h>
int main(int argc, char *argv[]) {
  int i = 5 / 2;
  printf("%d\n", i);
}

剰余

C言語において剰余(割った余り)を求めるには、% 演算子を使う。

割った余りを計算できるのは整数型のみである。実数型(float, double)で剰余を計算するソースコードはコンパイルエラーとなる。

#include <stdio.h>
int main(int argc, char *argv[]) {
  int i = 5 % 2;
  printf("%d\n", i);
}

=

C言語において変数に値を代入するには、= 演算子を使う。

#include <stdio.h>
int main(int argc, char *argv[]) {
  int i = 1;
  printf("%d\n", i);
}

+=

C言語において加算と代入を同時に行うには、+= 演算を使う。

#include <stdio.h>
int main(int argc, char *argv[]) {
  int i = 1;
  i += 2; /* i = i + 2; と同じ */
  printf("%d\n", i);
}

-=

C言語において減算と代入を同時に行うには、-= 演算を使う。

#include <stdio.h>
int main(int argc, char *argv[]) {
  int i = 2;
  i -= 1; /* i = i - 1; と同じ */
  printf("%d\n", i);
}

*=

C言語において乗算と代入を同時に行うには、*= 演算を使う。

#include <stdio.h>
int main(int argc, char *argv[]) {
  int i = 2;
  i *= 3; /* i = i * 3; と同じ */
  printf("%d\n", i);
}

/=

C言語において除算と代入を同時に行うには、/= 演算を使う。

#include <stdio.h>
int main(int argc, char *argv[]) {
  int i = 4;
  i /= 2; /* i = i / 2; と同じ */
  printf("%d\n", i);
}

%=

C言語において剰余と代入を同時に行うには、%= 演算を使う。

#include <stdio.h>
int main(int argc, char *argv[]) {
  int i = 5;
  i %= 2; /* i = i % 2; と同じ */
  printf("%d\n", i);
}

比較演算子

比較演算子とは、2つの値を比較する演算子である。

C言語の比較演算子
演算子 説明
== 等しい
!= 等しくない
< 小さい
<= 以下
> 大きい
>= 以上

論理演算子

論理演算子とは、ANDやOR、NOTなどの論理演算を行う演算子である。

George Boole
Figure 1. George Boole
C言語の論理演算子
演算子 説明
&& 論理積(AND)
|| 論理和(OR)
! 否定(NOT)

ビット演算子

ビット演算子とは、ビット演算を行う演算子である。

C言語のビット演算子
演算子 説明
& ビット論理積
| ビット論理和
<< 左シフト
>> 右シフト

&

C言語における & は、ビット毎の論理積 (AND) を示す演算子である。

x = 0b11111111 & 0b00001111; /* 0b00001111 */

|

C言語における | は、ビット毎の論理和 (OR) を示す演算子である。

x = 0b00001111 | 0b11110000; /* 0b11111111 */

<<

C言語における << は、左シフトを示す演算子である。

プログラミング言語によっては算術シフトと論理シフトで演算子が異なることがあるが、C言語ではそのような違いはない。符号付き (signed) 数値をシフトする場合は算術シフト、符号無し (unsigned) 数値をシフトする場合は論理シフトとなる。

#include <stdio.h>
int main(int argc, char **argv) {
  printf("%d\n", 1 << 1);
  printf("%d\n", 1 << 2);
}

上記プログラムの実行結果を以下に示す。

$ gcc -o example example.c
$ ./example
2
4

>>

C言語における >> は、右シフトを示す演算子である。

プログラミング言語によっては算術シフトと論理シフトで演算子が異なることがあるが、C言語ではそのような違いはない。符号付き (signed) 数値をシフトする場合は算術シフト、符号無し (unsigned) 数値をシフトする場合は論理シフトとなる。

#include <stdio.h>
int main(int argc, char **argv) {
  printf("%d\n", 8 >> 1);
  printf("%d\n", 8 >> 2);
}

上記プログラムの実行結果を以下に示す。

$ gcc -o example example.c
$ ./example
4
2

sizeof

sizeof演算子は、データ型や変数の大きさをバイト単位で返します。

sizeof(データ型)
sizeof(変数名)

例えば sizeof(short)は2を返します。

配列を指定したときは、配列全体の大きさを返します。例えば short s[32]; という配列があった場合、sizeof(s) は64を返します。

#include <stdio.h>
int main(int argc, char **argv) {
  int i;
  int j[2]
  printf("%zu\n", sizeof(int));
  printf("%zu\n", sizeof(i));
  printf("%zu\n", sizeof(j));
}

上記プログラムの実行結果を以下に示す。

$ gcc -o example example.c
$ ./example
4
4
8

インクリメント演算子

インクリメント演算子は、変数の値に1を加える演算子です。変数の前または後に ++ を付けます。

インクリメント演算子を変数の前に付けるか、後に付けるかで若干動作が異なります。どちらも変数の値に1を加えることは共通ですが、変数の値の評価の仕方が違います。

インクリメント演算子を変数の前に付けた場合、変数の値に1を加えてから、変数の値を評価します。インクリメント演算子を変数の後に付けた場合、変数の値を評価してから、変数の値に1を加えます。

たとえば、次のようなC言語のソースプログラムがあったとします。

#include <stdio.h>
int main(int argc, char **argv) {
  int a, b = 1;
  a = ++b;
  printf("a = %d, b = %d\n", a, b);
}

この場合、まず変数 b の値である1に1を加えるので、変数 b の値が2になります。その後、変数 b の値である2が変数 a に代入されます。つまり、次のソースコードと同じ結果になる。

#include <stdio.h>
int main(int argc, char **argv) {
  int a, b = 1;
  b = b + 1;
  a = b;
  printf("a = %d, b = %d\n", a, b);
}

また、次のようなC言語のソースプログラムがあったとします。

#include <stdio.h>
int main(int argc, char **argv) {
  int a, b = 1;
  a = b++;
  printf("a = %d, b = %d\n", a, b);
}

この場合、まず変数 b の値である1が変数 a に代入されます。代入が終わった後に、変数 b の値である1に1を加えて変数 b の値が2になります。つまり、次のソースコードと同じ結果になる。

#include <stdio.h>
int main(int argc, char **argv) {
  int a, b = 1;
  a = b;
  b = b + 1;
  printf("a = %d, b = %d\n", a, b);
}

関数の引数にインクリメント演算子を指定した場合、var++は関数の引数に変数varの値を渡した後に変数varの値を1増やし、++varは変数varの値を1増やした後に関数の引数に値を渡す。

#include <stdio.h>

void func(int a, int b) {
  printf("func: a=%d, b=%d\n", a, b);
}

int main() {
  int a = 1, b = 1;

  func(a++, ++b);
  printf("main: a=%d, b=%d\n", a, b);
}

上記のプログラムの実行結果は、次の通りとなる。

func: a=1, b=2
main: a=2, b=2

つまり、次のソースコードと同じ結果になる。

#include <stdio.h>

void func(int a, int b) {
  printf("func: a=%d, b=%d\n", a, b);
}

int main() {
  int a = 1, b = 1;

  b = b + 1;
  func(a, b);
  a = a + 1;
  printf("main: a=%d, b=%d\n", a, b);
}

デクリメント演算子

デクリメント演算子は、変数の値から1を減らす演算子である。変数の前または後に -- を付ける。

--variable
variable--

デクリメント演算子を変数の前に付けるか後ろにつけるかで変数の値の評価の仕方が違う点はインクリメント演算子と同じである。

三項演算子

三項演算子とは、被演算子を3つとる演算子のことである。英語では「ternary operator」という。C言語では三項演算子を次のように記述する。

条件式 ? 値1 : 値2

条件式が真であれば値1が評価され、条件式が偽であれば値2が評価される。たとえば、三項演算子は次のように使う。

max = (a > b ? a : b);

a の値が b の値より大きければ max = a が実行され、a の値が b の値以下であれば max = b が実行される。

三項演算子を使った式を、if文を使って表現すると次のようになる。

if (a > b) {
  max = a;
} else {
  max = b;
}

演算子の優先順位

演算子には優先順位があります。次に演算子の優先順位を示します。

演算子の優先順位
優先順位 演算子の種類 演算子
高い


低い
左から右 関数、添え字、構造体、
後置インクリメント、後置デクリメント
() [] . -> expr++ expr--
右から左 前置インクリメント、前置デクリメント、単項式 ++expr --expr ! ~ + - * & sizeof
キャスト (type)
左から右 剰除余 * / %
加減 + -
シフト << >>
比較 < <= > >=
等値、非等値 == !=
ビット AND &
ビット XOR ^
ビット OR |
論理積 &&
論理和 ||
右から左 3項演算子 ? :
代入演算子、複合代入演算子 = += -= *= /= %= &= ^= |= <<= >>=
左から右 順次演算子 ,

(優先順位の高い演算子である)括弧で括ることにより、演算子の優先順位を変えることができます。

次の例では、まず b * c が計算されて、その値と a が足し算されます。

ans = a + b * c;

括弧で括ることにより、a + b を先に計算させることができます。

ans = (a + b) * c;

べき乗

C言語において、べき乗の計算をする演算子は無い。C言語でべき乗を求めるには、pow関数を使う。

#include <math.h>

double pow(double x, double y);

pow関数は、次のように使う。

#include <stdio.h>
#include <math.h>

int main(int argc, char **argv) {
  double x, y, z;

  x = 2.0;
  y = 3.0;
  z = pow(x,y);

  printf("%lf の %lf 乗は %lf\n", x, y, z);
}