C言語⑪[for~while~swich(制御文)]

for文

・書式

int ii;//カウンタ
for(ii = 0; ii < 10; ii++){
 //処理①
}
※処理①を10回行う。

意味と処理順序

for(最初に一回だけ行う処理; 条件式; 命令文を実行した後に行う処理){
 処理;
}

①最初に1回だけ行う処理を事項
例)ii=0; ←カウンタの初期化
②条件式の判定を行う
例)ii < 10; ←カウンタの値が10よりも小さいかどうかを判定
⇒③条件式が成立している(真)の場合:命令文の実行
⇒③条件式が成立していない(偽)の場合:ループを終了
④「命令文を実行した後に行う処理」を実行
例)ii++; ←カウンタのインクリメント
⑤条件式の判定に戻る・・・条件式が「偽」になるまで繰り返し

なお、カウンタの初期化で定義した変数”ii”は、定義したforループ内だけで有効なため、forループ外では使えない。逆に、forループ外におなじ名前の変数があってもそれはforループには影響しない。
このため、for文が複数存在している場合にもカウンタ用の変数は同じ名前を使いまわせる。
※ただし、入れ子になっているfor文では不可
for文外で定義したカウンタ変数も当然使えるが、バグの元になりやすいため基本的にはfor文内で定義するのが安全。

また、初期化部分,更新処理部分には”,”で区切ることで複数処理を記述可能。
(例)

#include <stdio.h>

int main(void) {
    int i, j;
    for (i = 0, j = 10; i < j; i++, j--) {
        printf("i = %d, j = %d\n", i, j);
    }
    return 0;
}

・二重ループ

for(int yy = 0; yy <3; yy++){
    for(int xx = 0; xx < 7; xx++){
         //処理
    }
}
int main(void)
{
	int num = 0;
	char alp = 'a';
	char big = 'A';

	for (int yy = 0; yy < 3; yy++) {
		for (int xx = 0; xx < 7;xx++) {
			printf("%2d ", num);
			num++;
		}
		printf("\n");
	}

実行結果

 0  1  2  3  4  5  6
 7  8  9 10 11 12 13
14 15 16 17 18 19 20

while文

・書式

while(条件式){
    処理;
}

①条件式が成り立っていれば(真)、ブロック内の処理を実行
②条件判が成り立っていれば、ブロック内の処理を実行~以下繰り返し

do~while文

・書式

do{
 処理;
}while(条件式);

①ブロック内の処理が1度実行される。
②条件判定が真ならば、ブロック内の処理を実行
③条件判定~以下繰り返し

	do {
		a = fgets();
		printf("%c", a);
	} while (a != 'e');

実行結果

abcdefg
abcde

・・・abcdefgって文字列では??getchar()って一文字しか取得できないのでは??

getchar()とscanf()の違いが説明されていないと、初学者にはかなり混乱の元になりますね。その例で出ている挙動は、**getchar()の「一文字ずつ取得」+「改行も一文字として扱う」**という仕様が原因です。

✅ getchar()とは?
標準入力(キーボード)から1文字を取得する関数。

入力バッファから順に1文字ずつ取り出す。

char型で返される。

Enterキーで確定された文字列全体(例:three\n)はバッファに入っており、それを順に取り出す。

🔍 コード解析(あなたの提示したコード)
char a;
do {
	a = getchar();          // 1文字取得(改行含む)
	printf("%c", a);        // 取得した1文字を表示
} while (a != 'e');         // eが入力されたら終了

実際の入力例と出力例:
入力:two[Enter]
入力バッファ:t, w, o, \n
getcharで順に取得 → t, w, o, \n

どれも != 'e' → ループ継続

入力:two[Enter]
再び t, w, o, \n
またループ継続
入力:three[Enter]
t, h, r, e, e, \n

最初のeで ループ条件成立 (a == 'e') → その時点でループ終了

→ だから出力が「thre」で終わる(後半のeと\nが処理される前に終了)

あなた:
いや、getchar()の教科書の説明が「キーボードから入力された半角文字一つを得ます」だったので、abc、って文字列じゃん??って思っただけです(笑)


ChatGPT:
それ、めちゃくちゃ良い視点です!✨
**「abcって文字列じゃん?なんで一文字ずつ?」**って、最初に絶対引っかかるべき超重要ポイントなんです。むしろそこに気づいてる時点で、Cの「入力バッファ」の実態にほぼ足かかってます(笑)

🍜 getchar()の真相:
たとえば、あなたがキーボードでこう打ったとします:

abc[Enter]
これ、実はPC内部ではこう扱われます:
'a' → 'b' → 'c' → '\n'
この4つが入力バッファに並んでいて、getchar()はこのキューを1つずつ取り出すだけの単純な奴なんです(笑)

📘 教科書の「一文字入力」って説明があいまいな理由
教科書:「キーボードから1文字」
↳ 実際はバッファに溜まった入力を1文字だけ読み取る

だから abc[Enter] は1文字ずつ4回 getchar() で取り出せる。

🧠 たとえるなら…
getchar()って、お皿に置いた文字列から1文字ずつフォークで刺して食べるみたいな感じ。
scanf("%s")は、一気に麺をズルッとすするような感じ(笑)

🎁 おまけ:おもしろコードで体感する

#include <stdio.h>

int main(void) {
    char c;
    while ((c = getchar()) != '\n') {
        printf("入力されたのは %c\n", c);
    }
    return 0;
}
入力:abc → Enter

出力:
入力されたのは a
入力されたのは b
入力されたのは c

(by ChatGPT)

ループの中断(break文)

ループ中にbreak;を見つけると、「直近のループ」を抜ける。

while(true){
    if(flg == true)break; //flgがtrueになったらwhileループを抜ける。

※「Cの絵本」の説明について

あなた:
break文の説明で、「一番近いブロックの終わりに移動」とあったんですが、forとかwhileループの中に置かれたifブロック中にbreak文があった場合、どうなるのですか?

ChatGPT:

とてもいい質問です!
break は「if」じゃなくて、forやwhileなどの「ループ構造」に対してのみ効力があります。**


目次

  1. ChatGPT:
  2. ✅ 結論
  3. 🔍 なぜ if に対しては効かないのか?
  4. 🧪 具体例で見てみよう
    1. 🧾 出力:
  5. ⚠️ 注意点
  6. ✅ まとめ

✅ 結論

for (...) {
    if (...) {
        break;  // → この break は for の外に飛び出す!
    }
}

このように、break「一番近いループ構造(for, while, do-while, switch)」の外へジャンプします。


🔍 なぜ if に対しては効かないのか?

if は「条件によって処理を分けるだけの文」であって、
「繰り返し」や「制御構造」ではないからです。


🧪 具体例で見てみよう

#include <stdio.h>

int main() {
    for (int i = 0; i < 5; i++) {
            printf("i = %d\n", i);
                    if (i == 2) {
                                break;  // for ループを抜ける
                                } 
                    }
     printf("ループ終了\n");
     return 0;}

🧾 出力:

i = 0 i = 1 i = 2 ループ終了

iが2になった時点で if に入る → break 実行 → for から脱出


⚠️ 注意点

もし if の中に break を書いて、その外側にループもswitchもなかった場合

if (true) {
    break;  // ❌ コンパイルエラーになります
}

「breakの相手がいない」のでエラーになります!


✅ まとめ

場所break できる?理由
for, while, do-whileループを中断するための文
switchcaseごとの処理を切り分けるために使う
if, else条件分岐なだけで「中断」対象が存在しない

いつでも「break は誰に向かって放たれているのか?」を意識すると、使い方がブレなくなりますよ😉
(by ChatGPT)


繰り返しの次の回に移る(continue文)

ループの中にcontinue;を見つけると、処理を中断して「直近のループ」の先頭に戻る(ループは繰り返す)。


処理を選択する(switch()文)

書式

switch(式){
   case 値1:
     //処理① ⇒式=値1のときの処理
     break;
   case 値2:
     //処理② ⇒式=値2のときの処理
     break;
   case 値3:
     //処理③ ⇒式=値3のときの処理
     break;
   default: //処理上必要なければ記載不要。
     //処理 ⇒式の値がcaseのどれにも該当しない場合の処理
     break;
     }

※式の結果は整数値になる場合にしか使えない

int mode = 0;
while(true){
  switch(mode){
    case 0: //同じ処理を行いたいときは、breakを省き、処理を空にすることもできる。
    case 1:
      printf("mode:%d\n",mode);
      break;
    case 2:
      printf("mode:%d\n",mode);
      break;
    case 3:
      printf("mode:%d\n",mode);
      break;
    case 4:
      printf("mode:%d\n",mode);
      break;
    default:
      printf("modeが範囲外(%d)\n",mode);
      break;
  }
	if (mode >= 10)break;
	mode++
}

実行結果

mode:0
mode:1
mode:2
mode:3
mode:4
modeが範囲外(5)
modeが範囲外(6)
modeが範囲外(7)
modeが範囲外(8)
modeが範囲外(9)
modeが範囲外(10)

参考:https://9cguide.appspot.com/08-03.html

コメント

タイトルとURLをコピーしました