🖥️

【C言語超入門】 第11回 Forループとインクリメント

2024/12/25に公開

https://youtu.be/wdYIiyyOGZI

四国めたん
\textcolor{pink}{四国めたん: }教師役ですわ

ずんだもん
\textcolor{lime}{ずんだもん: }生徒役なのだ

\footnotesize \textcolor{pink}{四国めたん:} 皆さん、こんにちは。四国めたんです

\footnotesize \textcolor{lime}{ずんだもん:} ずんだもんなのだ。こんにちはなのだ

\footnotesize \textcolor{pink}{四国めたん:} 今回もC言語のお勉強をしていきましょう

\footnotesize \textcolor{lime}{ずんだもん:} レッツゴーなのだ

\footnotesize \textcolor{pink}{四国めたん:} 第11回目の今回は Forループとインクリメント についてお話ししますわ

\footnotesize \textcolor{lime}{ずんだもん:} 前回は 配列 だったので、いよいよ 反復 についての話しをしてくれるのか?

\footnotesize \textcolor{pink}{四国めたん:} はい、まずは 反復 の内の1つ、 Forループ についてお話ししますわ

\footnotesize \textcolor{lime}{ずんだもん:} よろしくなのだ

\footnotesize \textcolor{pink}{四国めたん:} さらに 反復 には 配列インクリメント が付き物ですので、それも説明して行きますわ

\footnotesize \textcolor{lime}{ずんだもん:} りょうかいなのだ

forループで繰り返します

\footnotesize \textcolor{pink}{四国めたん:} 前回の 配列 の説明では各要素の指定には直接インデックスを指定していましたわ

\footnotesize \textcolor{lime}{ずんだもん:} かなりめんどうだったのだ

\footnotesize \textcolor{pink}{四国めたん:} 確かに、配列としてまとめる利点は、多くの変数を宣言、初期化するのを避けられることですわ

\footnotesize \textcolor{lime}{ずんだもん:} でも、各要素を個別に指定したのでは効果は半減なのだ

\footnotesize \textcolor{pink}{四国めたん:} ここで前回の最初のサンプルプログラムを見てみましょう

#include <stdio.h>

void main() {
  int apple[3] = {300, 250, 310};
  int average = (apple[0] + apple[1] + apple[2]) / 3;

  printf("リンゴの重さの平均は%dグラムです\n", average);
}

\footnotesize \textcolor{pink}{四国めたん:} とりあえず初期化も平均値の計算も要素が3つ程度であれば問題ありませんわ

\footnotesize \textcolor{lime}{ずんだもん:} それでも100個とか、要素が多くなった場合には、とてもではないけどプログラムを書いていられないのだ

\footnotesize \textcolor{pink}{四国めたん:} はい、それを簡単なプログラムにできるようにするのが 反復 ですわ

\footnotesize \textcolor{pink}{四国めたん:} それでは100個のリンゴの重さを平均するプログラムを考えてみましょう

\footnotesize \textcolor{lime}{ずんだもん:} それぞれのリンゴの重さはどうするのだ?

\footnotesize \textcolor{pink}{四国めたん:} 100グラム、101グラム、…、199グラムと1グラムずつ異なる重さとしますわ

#include <stdio.h>

void main() {
  int apple[100] = {0};
  int total = 0;

  for (int i = 0; i < 100; i = i + 1) {
    apple[i] = 100 + i;
  }

  for (int j = 0; j < 100; j = j + 1) {
    total = total + apple[j];
  }

  int average = total / 100;
  printf("リンゴの重さの平均は%dグラムです\n", average);
}

\footnotesize \textcolor{pink}{四国めたん:} 実行してみましょう

リンゴの重さの平均

\footnotesize \textcolor{lime}{ずんだもん:} 「リンゴの重さの平均は149グラムです」と表示されたのだ

プログラムを説明しましょう

\footnotesize \textcolor{pink}{四国めたん:} ではプログラムの説明をして行きましょう

\footnotesize \textcolor{pink}{四国めたん:} 最初は"apple"を100個の配列として宣言し、0グラムに初期化しますわ

\footnotesize \textcolor{lime}{ずんだもん:} "{0}"で初期化すれば、すべての要素を0にできるのだ

\footnotesize \textcolor{pink}{四国めたん:} ついでに重さの累計を保持しておく変数"total"を宣言、初期化しておきますわね

\footnotesize \textcolor{pink}{四国めたん:} 次に forループ により"apple"の各要素に重さを代入していきますわ

\footnotesize \textcolor{lime}{ずんだもん:} forループ

\footnotesize \textcolor{pink}{四国めたん:} 詳細は少し後に説明しますわね

\footnotesize \textcolor{lime}{ずんだもん:} わかったのだ

\footnotesize \textcolor{pink}{四国めたん:} 更にループにより"apple"の各要素を足し合わせて行きますわ

\footnotesize \textcolor{lime}{ずんだもん:} 最後に"total"を100で割れば、平均の重さになるのだ

forループの構造を見てみよう

\footnotesize \textcolor{pink}{四国めたん:} それでは forループ について説明しますわね

\footnotesize \textcolor{lime}{ずんだもん:} まっていたのだ

\footnotesize \textcolor{pink}{四国めたん:} 今回使用したループは forループ と呼ばれるものですわ

\footnotesize \textcolor{lime}{ずんだもん:} ほかにもループがあるのか?

\footnotesize \textcolor{pink}{四国めたん:} 次回以降でお話ししますが、 whileループ というループがありますわね

\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ

\footnotesize \textcolor{lime}{ずんだもん:} それで、 forループ はどのように書けばいいのだ?

\footnotesize \textcolor{pink}{四国めたん:} for (前処理; 条件式; 後処理) { 処理 }の形式となりますわ

\footnotesize \textcolor{pink}{四国めたん:} なお 前処理条件式後処理 の間はセミコロン";"で区切りますわ

\footnotesize \textcolor{lime}{ずんだもん:} なんか、複雑なのだ

\footnotesize \textcolor{pink}{四国めたん:} 少しずつ説明しますので我慢してくださいね

forループの前処理は何をするの?

\footnotesize \textcolor{pink}{四国めたん:} まずは forループ前処理 についてですわね

\footnotesize \textcolor{lime}{ずんだもん:} なにをする場所なのだ?

\footnotesize \textcolor{pink}{四国めたん:} forループ前処理 は、ループに入る直前に1回だけ実行される式を記述しますわ

\footnotesize \textcolor{lime}{ずんだもん:} int i = 0int j = 0という式になっている部分がそうなのか

\footnotesize \textcolor{pink}{四国めたん:} その通りですわ

\footnotesize \textcolor{lime}{ずんだもん:} どのような式を記述できるのだ?

\footnotesize \textcolor{pink}{四国めたん:} 基本的にはどのような式でも記述できますが、一般的にはカウンターとなる変数を宣言、初期化しますわね

\footnotesize \textcolor{lime}{ずんだもん:} 今回の場合は変数"i"や"j"を int型 で宣言して0に初期化しているのだ

\footnotesize \textcolor{lime}{ずんだもん:} ところでカウンターの変数名に"i"とか"j"を使っているのには、何か意味があるのか?

\footnotesize \textcolor{pink}{四国めたん:} C言語での慣習として、カウンターには"i"とか"j"が使用されることが多いですわね

\footnotesize \textcolor{pink}{四国めたん:} ただ、慣習ですのでどのような変数名でも問題ありませんわ

\footnotesize \textcolor{lime}{ずんだもん:} つまり、変数名を"counter"とかにしても問題ないのだ

\footnotesize \textcolor{pink}{四国めたん:} その通りですわ

\footnotesize \textcolor{lime}{ずんだもん:} ところで今回はカウンターの変数の宣言を forループ の前処理でおこなっているのだ

\footnotesize \textcolor{pink}{四国めたん:} そうですわね

\footnotesize \textcolor{lime}{ずんだもん:} forループ の前におこなってもいいのではないか?

\footnotesize \textcolor{pink}{四国めたん:} 当然、 forループ の外でおこなっても問題ありませんわ

\footnotesize \textcolor{pink}{四国めたん:} 確認してみましょう

#include <stdio.h>

void main() {
  int apple[100] = {0};
  int total = 0;
  int i = 0;

  for (; i < 100; i = i + 1) {
    apple[i] = 100 + i;
  }

  i = 0;
  for (; i < 100; i = i + 1) {
    total = total + apple[i];
  }

  int average = total / 100;
  printf("リンゴの重さの平均は%dグラムです\n", average);
}

変数の初期化

\footnotesize \textcolor{lime}{ずんだもん:} 前と同じで「リンゴの重さの平均は149グラムです」と表示されたのだ

\footnotesize \textcolor{pink}{四国めたん:} でも、変数"i"の宣言と初期化は forループ の前に行い、前処理では何もしていませんわ

\footnotesize \textcolor{lime}{ずんだもん:} たしかに 前処理 は空になっているのだ

\footnotesize \textcolor{pink}{四国めたん:} ただ、セミコロン";"だけは必須ですので、忘れないでくださいね

\footnotesize \textcolor{lime}{ずんだもん:} わかったのだ

\footnotesize \textcolor{lime}{ずんだもん:} ところで、カウンターの宣言を forループ の前に行う利点はあるのか?

\footnotesize \textcolor{pink}{四国めたん:} 利点としては forループ の後でカウンターの値を保持できることでしょうか?

\footnotesize \textcolor{lime}{ずんだもん:} 使い道を思いつかないのだが?

\footnotesize \textcolor{pink}{四国めたん:} そうかもしれませんわね

forループを2つに分けよう

カウンターを forループ の外で宣言、初期化することで forループ を分けることができます

以下、例を見てみましょう

#include <stdio.h>

void main() {
  int apple[100] = {0};
  int total = 0;
  int i = 0;

  for (; i < 50; i = i + 1) {
    apple[i] = 100 + i;
  }
  for (; i < 100; i = i + 1) {
    apple[i] = 200 + i;
  }

  for (int j = 0; j < 100; j = j + 1) {
    total = total + apple[j];
  }

  int average = total / 100;
  printf("リンゴの重さの平均は%dグラムです\n", average);
}

インデックスが0~49までの"apple"は100 + 1で、50~99までの"apple"は200 + iで初期化しています

このように前の forループ のカウンターの値を引き継いで次の forループ を続けることができます

\footnotesize \textcolor{pink}{四国めたん:} ちなみに forループ前処理 で宣言した変数は forループ の中のみでしか使用できませんわ

\footnotesize \textcolor{lime}{ずんだもん:} そうなのか?

\footnotesize \textcolor{pink}{四国めたん:} 例を見てみましょう

#include <stdio.h>

void main() {
  int apple[100] = {0};
  int total = 0;

  for (int i = 0; i < 100; i = i + 1) {
    apple[i] = 100 + i;
  }

  for (i = 0; i < 100; i = i + 1) {
    total = total + apple[i];
  }

  int average = total / 100;
  printf("リンゴの重さの平均は%dグラムです\n", average);
}

エラー表示

\footnotesize \textcolor{pink}{四国めたん:} 2番目の forループ の変数"i"は E0020 識別子 "i" が定義されていません としてエラーとなっていますわね

\footnotesize \textcolor{lime}{ずんだもん:} たしかにエラーとなっているのだ

forループの条件式ってなにをするの?

\footnotesize \textcolor{pink}{四国めたん:} 次は forループ条件式 について説明しますわね

\footnotesize \textcolor{lime}{ずんだもん:} おねがいなのだ

\footnotesize \textcolor{pink}{四国めたん:} forループ条件式 は、 forループ 内の 処理 を行う直前に、毎回、評価されますわ

\footnotesize \textcolor{lime}{ずんだもん:} 評価の結果、どのような動作になるのだ?

\footnotesize \textcolor{pink}{四国めたん:} 評価の結果がtrueであれば forループ 内の 処理 を1回実行しますわ

\footnotesize \textcolor{lime}{ずんだもん:} ふむふむ

\footnotesize \textcolor{pink}{四国めたん:} 評価の結果がfalseであれば forループ の次の行に実行が移りますわ

\footnotesize \textcolor{lime}{ずんだもん:} forループ 内の 処理 は行われないのか?

\footnotesize \textcolor{pink}{四国めたん:} スキップされますわね

\footnotesize \textcolor{lime}{ずんだもん:} なるほどなのだ

\footnotesize \textcolor{pink}{四国めたん:} ところで forループ 中に配列の要素にアクセスする場合は注意が必要ですわ

\footnotesize \textcolor{lime}{ずんだもん:} そうなのか?

\footnotesize \textcolor{pink}{四国めたん:} はい、カウンターを配列の要素のインデックスに使用する場合には、配列の範囲外にアクセスしないように充分に注意して下さいね

\footnotesize \textcolor{lime}{ずんだもん:} 配列の範囲外にアクセスしたら、大変なことになるので気をつけるのだ

\footnotesize \textcolor{pink}{四国めたん:} ベテランのプログラマーでも結構やらかしますので、本当に注意して下さいね

forループの後処理は何を行うのですか?

\footnotesize \textcolor{pink}{四国めたん:} 次は forループ後処理 ですわ

\footnotesize \textcolor{lime}{ずんだもん:} 後処理 とは何なのだ?

\footnotesize \textcolor{pink}{四国めたん:} forループ後処理 は、 forループ 内の 処理 の直後に毎回実行されますわ

\footnotesize \textcolor{lime}{ずんだもん:} 別に forループ 内の 処理 の最後に書いておけばいいのではないのか?

\footnotesize \textcolor{pink}{四国めたん:} まぁ、そういう考え方もありますわね

\footnotesize \textcolor{pink}{四国めたん:} でも、 後処理 は必ず実行されますが、 処理 の最後の場合は実行されない場合もあるのですわ

\footnotesize \textcolor{lime}{ずんだもん:} なるほど、実行されることが保証されているのが重要なのか

\footnotesize \textcolor{pink}{四国めたん:} その通りですわ

\footnotesize \textcolor{pink}{四国めたん:} 通常は 後処理 はカウンターとなる変数のカウントアップに使用されますわね

\footnotesize \textcolor{lime}{ずんだもん:} サンプルプログラムではi = i + 1となっているのだ

\footnotesize \textcolor{pink}{四国めたん:} はい、"i"はカウンターなので 処理 を1回行う毎に1ずつアップしていますわ

カウンターに便利な演算子を紹介します

\footnotesize \textcolor{pink}{四国めたん:} forループ後処理 は一般的にカウンターのカウントアップに使用されますわ

\footnotesize \textcolor{lime}{ずんだもん:} さっきも同じことを言っていたのだ

\footnotesize \textcolor{pink}{四国めたん:} 1ずつカウントアップすることを インクリメント と言いますわ

\footnotesize \textcolor{lime}{ずんだもん:} インクリメント ?りょうかいなのだ

\footnotesize \textcolor{pink}{四国めたん:} また、1ずつカウントダウンすることを デクリメント と言いますわ

\footnotesize \textcolor{lime}{ずんだもん:} デクリメント ?わかったのだ

複合代入演算子を使おう

\footnotesize \textcolor{pink}{四国めたん:} サンプルプログラムでは、カウントアップの演算としてi = i + 1のような式を使用していましたわ

\footnotesize \textcolor{pink}{四国めたん:} でも、式の書き方として、同じ変数"i"を2度書くのは少々めんどうですわ

\footnotesize \textcolor{lime}{ずんだもん:} この程度は、めんどうがらずに書いた方がいいのではないか?

\footnotesize \textcolor{pink}{四国めたん:} まぁ、そうなのですが、C言語では 複合代入演算子 と呼ばれる便利な演算子が用意されていますわ

\footnotesize \textcolor{lime}{ずんだもん:} 複合代入演算子

\footnotesize \textcolor{pink}{四国めたん:} 複合代入演算子 とは、読んで字のごとく代入演算子"="と、四則演算子"+-*/"などを1つにまとめた演算子となりますわ

\footnotesize \textcolor{lime}{ずんだもん:} ずいぶんと便利な感じがするのだ

\footnotesize \textcolor{lime}{ずんだもん:} どのような形式なのだ?

\footnotesize \textcolor{pink}{四国めたん:} こんな感じになりますわ

複合代入演算子

複合代入演算子 同等の式
i += n i = i + n
i -= n i = i - n
i *= n i = i * n
i /= n i = i / n

\footnotesize \textcolor{lime}{ずんだもん:} "i"とか"n"とかは何なのだ?

\footnotesize \textcolor{pink}{四国めたん:} "i"は変数、"n"は数値もしくは変数ですわ

\footnotesize \textcolor{lime}{ずんだもん:} つまり インクリメントi = i + 1の代わりにi += 1を使えるということか

\footnotesize \textcolor{pink}{四国めたん:} その通りですわ

\footnotesize \textcolor{lime}{ずんだもん:} とはいえ 複合代入演算子 を使用しても1文字分しか得にならないのだ

\footnotesize \textcolor{pink}{四国めたん:} その通りですが、カウントアップなどの意味を明確にするために、積極的に使ってくださいね

\footnotesize \textcolor{pink}{四国めたん:} とりあえず、最初のサンプルプログラムを書き換えてみましょう

#include <stdio.h>

void main() {
  int apple[100] = {0};
  int total = 0;

  for (int i = 0; i < 100; i += 1) {
    apple[i] = 100 + i;
  }

  for (int j = 0; j < 100; j += 1) {
    total += apple[j];
  }

  int average = total / 100;
  printf("リンゴの重さの平均は%dグラムです\n", average);
}

複合代入演算子

\footnotesize \textcolor{pink}{四国めたん:} まぁ、結果は変わりませんわね

\footnotesize \textcolor{lime}{ずんだもん:} でもtotal = total + apple[j]の部分も 複合代入演算子 に変わっているのだ

\footnotesize \textcolor{pink}{四国めたん:} はい、この部分は文字数を少なくできましたわ

インクリメントとデクリメントは便利ですよ

\footnotesize \textcolor{pink}{四国めたん:} さて、カウントアップやカウントダウンの演算として 複合代入演算子 を紹介しましたわ

\footnotesize \textcolor{pink}{四国めたん:} でも、 インクリメントデクリメント の場合には、もっと便利な演算子が用意されていますわ

\footnotesize \textcolor{lime}{ずんだもん:} もっと短く書けるのか?

\footnotesize \textcolor{pink}{四国めたん:} はい、それが インクリメント演算子 "++"と デクリメント演算子 "--"ですわ

\footnotesize \textcolor{lime}{ずんだもん:} インクリメント演算子デクリメント演算子

\footnotesize \textcolor{pink}{四国めたん:} はい、使い方は簡単で、変数の前、もしくは後ろに演算子を付け加えるだけですわ

\footnotesize \textcolor{lime}{ずんだもん:} 前と後ろのどちらでもいいのか?

\footnotesize \textcolor{pink}{四国めたん:} はい、例えば変数"i"を1だけカウントアップする場合には++ii++等と記述しますわ

\footnotesize \textcolor{lime}{ずんだもん:} 違いはないのか?

\footnotesize \textcolor{pink}{四国めたん:} forループ後処理 でのカウントアップに使用する場合には++ii++のどちらを使ってもかまいませんわ

\footnotesize \textcolor{lime}{ずんだもん:} りょうかいなのだ

\footnotesize \textcolor{pink}{四国めたん:} でも、それ以外の場合には、違いが出ますが、今は無視してかまいませんわ

\footnotesize \textcolor{lime}{ずんだもん:} ぶ~ぶ~

前置と後置

インクリメント演算子"++"とデクリメント演算子"--"は、演算子を変数の前に置く 前置 と、演算子を変数の後に置く 後置 があります

前置 の例としては++i--iがあります

後置 の例としてはi++i--があります

両者の違いは、戻り値です

以前にお話ししました通り、演算子は必ず戻り値があります

前置 ではインクリメント/デクリメント後の値が戻り値となります

後置 ではインクリメント/デクリメント前の値が戻り値となります

インクリメントの例を見てみましょう

#include <stdio.h>

void main() {
  int i = 0;
  int j = 0;

  printf("前置のインクリメントは%dになります\n", ++i);
  printf("後置のインクリメントは%dになります\n", j++);
}

出力は以下のようになります

前置のインクリメントは1になります
後置のインクリメントは0になります

前置 の場合には、インクリメント後の値、つまり1がコンソールの出力となります

後置 の場合には、インクリメント前の値、つまり0がコンソールの出力となります

当然ですが、printfの後にブレークポイントを置いて"i"と"j"の値を確認すると1になっているのがわかります

\footnotesize \textcolor{pink}{四国めたん:} と云う訳でサンプルプログラムを書き換えてみましょう

#include <stdio.h>

void main() {
  int apple[100] = {0};
  int total = 0;

  for (int i = 0; i < 100; i++) {
    apple[i] = 100 + i;
  }

  for (int j = 0; j < 100; j++) {
    total += apple[j];
  }

  int average = total / 100;
  printf("リンゴの重さの平均は%dグラムです\n", average);
}

インクリメント演算子

\footnotesize \textcolor{pink}{四国めたん:} まぁ、結果は変わりませんわね

\footnotesize \textcolor{lime}{ずんだもん:} ところで インクリメント演算子デクリメント演算子int型 などの整数型の変数だけに使えるのか?

\footnotesize \textcolor{pink}{四国めたん:} 浮動小数点数型や真偽値型に適用することも可能ですが、意図した結果にならないので、避けて下さいね

\footnotesize \textcolor{lime}{ずんだもん:} わかったのだ

結局どれが良いのか?

まとめ

\footnotesize \textcolor{pink}{四国めたん:} お疲れさまでした

\footnotesize \textcolor{pink}{四国めたん:} 以上で Forループとインクリメント を終了しますわ

\footnotesize \textcolor{lime}{ずんだもん:} おつかれなのだ

Discussion