C言語の基本|代入演算子の使い方

=は等しいではなく、値を渡して保存する記号。代入の流れを理解して、変数の変化を正しく追いかけよう。

C言語のプログラムでは、変数に値を保存したり、すでに入っている値を更新したりする処理が何度も登場します。その中心になるのが代入演算子です。

特によく使うのが、次の記号です。

=

数学では=を左右が等しいという意味で使います。しかし、C言語の=は、右辺の値を左辺へ保存するという操作を表します。

たとえば、次の文を見てみましょう。

count = 10;

この文は、countと10が等しいという意味ではありません。右辺の10を、左辺の変数countへ保存するという意味です。

代入を理解するときは、次の流れで考えると分かりやすくなります。

右辺の値を求める
        ↓
求めた値を左辺へ保存する

代入では、定数だけでなく、別の変数の値や計算結果も保存できます。また、現在の値を使って同じ変数を更新したり、複数の変数へ続けて代入したりすることもできます。

ここでは、次の内容を順番に確認していきましょう。

  • 単純代入演算子=の基本
  • 右辺から左辺へ値が渡される流れ
  • 代入の左辺に書けるものと書けないもの
  • 複数の変数へ連続して代入する方法
  • 複合代入演算子による値の更新
  • 代入式そのものが持つ値

代入演算子は2種類に分けられる

C言語の代入演算子は、単純代入演算子と複合代入演算子に分けられます。

種類演算子の例役割
単純代入演算子=右辺の値を左辺へ保存する
複合代入演算子+=、-=、*=、/=、%=計算結果を同じ変数へ保存して更新する

単純代入演算子=は、変数に新しい値を保存するときに使います。

value = 20;

複合代入演算子は、現在の値を使って計算し、その結果を同じ変数へ保存するときに使います。

value += 5;

この文が実行されると、valueの現在値に5を加えた結果がvalueへ保存されます。

単純代入演算子=の基本

単純代入演算子=は、右辺の値を左辺へ保存します。

基本的な形は次のとおりです。

保存先 = 保存する値;

左辺は値を保存できる場所、右辺は保存する値を作る部分です。

x = 7;

この文では、右辺の7が左辺の変数xへ保存されます。

右辺:7
左辺:x
処理:7をxへ保存する

代入を読むときは、右から左へ値が移動すると考えると分かりやすくなります。

図1:右辺の値を左辺へ保存する流れ

この図から分かること

代入では、右辺の処理が先に行われます。

priceとfeeの値を加算して1500を作り、その結果を左辺の変数totalへ保存します。

=は左右が等しいことを表しているのではありません。右辺で作られた値を左辺へ渡して保存する操作を表しています。

定数を変数へ代入する

右辺には、整数や小数などの定数を指定できます。

x = 7;

この文が実行されると、変数xに7が保存されます。

別の値を代入すると、以前の値は新しい値で上書きされます。

x = 7;
x = 12;

処理後のxは12です。

最初の代入後:xは7
次の代入後:xは12

変数には、最後に代入された値が保存されています。

別の変数の値を代入する

右辺には、別の変数を書くこともできます。

x = y;

この文では、yに保存されている値を取り出し、その値をxへコピーします。

yが20の場合は、次のようになります。

代入前:xは5、yは20
実行文:x = y;
代入後:xは20、yは20

この代入によって、yの値が消えたり変更されたりするわけではありません。yの値を読み取り、その値をxへ保存しています。

代入後にxの値を変更しても、yの値はそのままです。

x = y;
x = 30;

yが20だった場合、最後の状態は次のとおりです。

xは30
yは20

xとyは別々の変数であり、それぞれが独立した保存場所を持っています。

計算結果を代入する

右辺には、演算を含む式も指定できます。

x = z + 2;

この文は、次の順番で実行されます。

  1. 変数zの値を取り出す
  2. zの値に2を加える
  3. 加算結果を変数xへ保存する

zが8の場合は、次のようになります。

z + 2
8 + 2
10

最終的に、xへ10が保存されます。

x = z + 2;

この文では、z + 2が右辺の式、xが計算結果の保存先です。

変数の現在値を使って更新する

代入では、左辺と右辺に同じ変数が現れることがあります。

x = x + 1;

数学の等式として考えると不自然ですが、C言語ではxの値を1増やして更新する処理です。

xの値が5だった場合、次の順番で実行されます。

1. 右辺のxから現在値5を取り出す
2. 5に1を加えて6を作る
3. 計算結果の6を左辺のxへ保存する

実行後のxは6です。

実行前のx右辺の計算実行後のx
55 + 16
1010 + 111
-2-2 + 1-1

左辺のxは保存先、右辺のxは計算に使う現在値です。同じ名前でも、式の中での役割が異なります。

代入によって処理件数を変化させるプログラム

ファイル名:6_4_1.c

#include <stdio.h>

int main(void)
{
    int completed = 0;
    int transferred = 35;

    /* 定数を代入する */
    completed = 20;
    printf("最初の処理件数は%d件です。\n", completed);

    /* 別の変数の値をコピーする */
    completed = transferred;
    printf("引き継いだ処理件数は%d件です。\n", completed);

    /* 現在値を使って更新する */
    completed = completed + 8;
    printf("追加処理後は%d件です。\n", completed);

    return 0;
}
実行結果の例
最初の処理件数は20件です。
引き継いだ処理件数は35件です。
追加処理後は43件です。

代入によって値を変化させるプログラムの解説

変数completedとtransferredを宣言し、それぞれ初期値を設定しています。

int completed = 0;
int transferred = 35;

変数の宣言と同時に値を設定することを初期化といいます。この2行は代入文ではなく、変数の宣言と初期化です。

最初の代入では、定数20をcompletedへ保存しています。

completed = 20;

この代入によって、completedの値は0から20へ変化します。

次に、transferredの値をcompletedへコピーしています。

completed = transferred;

transferredには35が入っているため、completedの値も35になります。

ただし、transferredの値は変化しません。

completedは35
transferredも35

最後に、completedの現在値へ8を加えています。

completed = completed + 8;

右辺のcompletedは現在値の35です。

completed + 8
35 + 8
43

計算結果の43が左辺のcompletedへ保存されるため、以前の35は43で上書きされます。

代入の左辺に書けるもの

代入演算子の左辺には、値を保存できる場所が必要です。

基本的な例が変数です。

value = 10;

変数valueには値を保存できるため、この代入は有効です。

C言語では、代入によって変更できる左辺を変更可能な左辺値と呼びます。入門段階では、値を書き込める変数が必要だと考えると分かりやすいでしょう。

代入の左辺に定数は書けない

次の代入は無効です。

1 = value;

左辺の1は定数です。定数には新しい値を保存できないため、コンパイルエラーになります。

右辺と左辺を入れ替えれば、有効な代入になります。

value = 1;

代入では、保存先を左辺に、保存する値を右辺に書きます。

計算結果を左辺には書けない

次の書き方も無効です。

a + b = 30;

a + bは計算によって作られる一時的な値であり、値を保存する変数ではありません。

有効な書き方にするには、計算結果を保存する変数を左辺に置きます。

result = a + b;
書き方有効か理由
x = 7;有効xは値を保存できる変数
x = y;有効yの値をxへ保存できる
x = a + b;有効計算結果をxへ保存できる
1 = x;無効1は書き換えられない定数
a + b = 30;無効a + bは保存先ではない

複数の変数へ連続して代入する

C言語では、1つの文で複数の変数へ同じ値を代入できます。

a = b = c = 10;

この代入は、右から左へまとまります。

a = (b = (c = 10));

処理の流れは次のとおりです。

  1. cへ10を代入する
  2. c = 10という代入式の値が10になる
  3. その10をbへ代入する
  4. b = c = 10という代入式の値も10になる
  5. その10をaへ代入する

最終的には、すべての変数へ10が保存されます。

aは10
bは10
cは10

図2:連続した代入が右から左へ進む流れ

この図から分かること

a = b = c = 10;では、最初にcへ10が代入されます。次に、その値がbへ渡され、最後にaへ渡されます。

代入式そのものが値を持つため、1つの値を右から左へ受け渡すように連続した代入ができます。

連続代入を分けて書く方法

連続代入は短く書けますが、慣れていないうちは処理の順番が分かりにくくなることがあります。

a = b = c = 10;

同じ処理を分けて書くと、次のようになります。

c = 10;
b = c;
a = b;

それぞれの文で、どの値をどこへ保存しているのかが明確になります。

書き方特徴
a = b = c = 10;短く書ける
c = 10; b = c; a = b;代入の順番を追いやすい

同じ値を複数の変数へ設定するだけなら、連続代入を使ってもよいでしょう。式が長くなったり、異なる計算が含まれたりする場合は、複数の文に分けると読みやすくなります。

複合代入演算子とは

複合代入演算子は、計算と代入をまとめて書くための演算子です。

たとえば、次の文はxの現在値に5を加え、結果をxへ保存します。

x = x + 5;

複合代入演算子+=を使うと、次のように書けます。

x += 5;

単純な変数を更新する場合、2つの書き方は同じ目的で使用できます。

通常の代入複合代入処理
x = x + 5;x += 5;xに5を加える
x = x - 2;x -= 2;xから2を引く
x = x * 3;x *= 3;xを3倍する
x = x / 4;x /= 4;xを4で割る
x = x % 10;x %= 10;xを10で割った余りにする

複合代入では、左辺の変数が計算の対象と保存先の両方になります。

+= で値を増やす

+=は、左辺の現在値に右辺の値を加え、その結果を左辺へ保存します。

score += 10;

scoreが50の場合、次のように処理されます。

現在のscore:50
加える値:10
計算結果:60
更新後のscore:60

意味を展開すると、次の形になります。

score = score + 10;

-= で値を減らす

-=は、左辺の現在値から右辺の値を引き、結果を左辺へ保存します。

stock -= 3;

stockが12の場合、更新後の値は9です。

12 - 3 = 9

*= で値を掛ける

*=は、左辺の現在値と右辺の値を掛け、結果を左辺へ保存します。

value *= 2;

valueが7の場合、更新後の値は14です。

/= で値を割る

/=は、左辺の現在値を右辺の値で割り、結果を左辺へ保存します。

value /= 4;

valueが20の場合、更新後の値は5です。

valueがint型なら整数除算になります。たとえば、valueが22の場合、22 / 4の結果として5が保存されます。

%= で余りを保存する

%=は、左辺の現在値を右辺の値で割り、その余りを左辺へ保存します。

value %= 10;

valueが37の場合、37を10で割った余りである7がvalueへ保存されます。

%=は整数型の値に使用します。

複合代入演算子で口座残高を増減するプログラム

ファイル名:6_4_2.c

#include <stdio.h>

int main(void)
{
    int balance = 5000;

    printf("現在の残高は%d円です。\n", balance);

    /* 入金した金額を加える */
    balance += 2000;
    printf("入金後の残高は%d円です。\n", balance);

    /* 支払った金額を引く */
    balance -= 1500;
    printf("支払い後の残高は%d円です。\n", balance);

    return 0;
}
実行結果の例
現在の残高は5000円です。
入金後の残高は7000円です。
支払い後の残高は5500円です。

複合代入で残高を更新するプログラムの解説

最初に、変数balanceを5000で初期化しています。

int balance = 5000;

入金処理では、複合代入演算子+=を使用しています。

balance += 2000;

この文では、現在のbalanceである5000に2000を加え、その結果をbalanceへ保存します。

5000 + 2000 = 7000

処理後のbalanceは7000です。

支払い処理では、複合代入演算子-=を使用しています。

balance -= 1500;

現在のbalanceである7000から1500を引き、結果の5500をbalanceへ保存します。

7000 - 1500 = 5500

複合代入演算子を使うと、現在値をどのように更新するのかが短い式で表せます。

図3:複合代入演算子で値を更新する流れ

この図から分かること

balance += 2000;では、現在の残高5000円に2000円を加え、結果の7000円を同じbalanceへ保存します。

続くbalance -= 1500;では、現在値7000円から1500円を引き、結果の5500円をbalanceへ保存します。

複合代入演算子は、現在の値を使った計算と、計算結果の保存を1つの式で表します。

複合代入を使う場面

複合代入演算子は、現在値を増減させる処理に向いています。

  • 得点を加算する
  • 在庫数を増減する
  • 残高を更新する
  • 移動距離を合計する
  • 値を一定倍にする
  • 余りを新しい値として保存する

たとえば、変数totalへpriceを加える処理は、次のように書けます。

total += price;

処理内容を展開すると、次の形です。

total = total + price;

何を加え、どの変数を更新するのかが明確な場合は、複合代入を使うと読みやすくなります。

式が複雑で処理を追いにくくなる場合は、無理に短くせず、計算と代入を分けても構いません。短さよりも、処理内容を正しく読み取れることが大切です。

代入は値を持つ式でもある

C言語では、代入そのものも式です。

次の代入式では、xへ3が保存されます。

x = 3

同時に、この代入式全体も3という値を持ちます。

そのため、次のような書き方ができます。

a = (b = 10);

最初にbへ10が代入され、b = 10という式の値が10になります。その値がaへ代入されます。

bへ10を代入する
        ↓
代入式の値が10になる
        ↓
aへ10を代入する

処理後は、aとbの両方が10になります。

この仕組みがあるため、次の連続代入も可能です。

a = b = c = 10;

ただし、代入を重ねた式は、慣れていないと読みづらくなることがあります。処理の順番を分かりやすくしたい場合は、複数の文へ分けましょう。

代入文の読み方を確認しよう

実行される処理
x = 3;xへ3を保存する
x = y;yの値をxへコピーする
x = y + 2;y + 2を計算し、結果をxへ保存する
x = x + 1;xの現在値に1を加え、結果をxへ保存する
x += 1;xを1増やして更新する
x -= 2;xを2減らして更新する
a = b = c = 10;右から左へ代入し、すべてを10にする

代入を読むときは、まず右辺の値を求め、次に左辺へ保存するという順番で追いかけます。

左辺が値を保存できる場所になっているか、右辺でどのような値が作られるか、代入後に変数の値がどう変化するかを確認すると、コードの動きを読み解きやすくなります。