1. 制御文とは
制御ステートメントは、プログラムのシーケンス構造、選択構造、ループ構造を実現するためにプログラムの実行フローを制御するために使用され、特定のステートメント定義子で構成されます。
C言語の制御文は9種類あり、以下の3つに分類できます。
(1) 分岐文:if 文、switch 文
(2) ループ実行文:do while 文、while 文、for 文。(3) Turn to ステートメント:break ステートメント、goto ステートメント、 continue ステートメント、return ステートメント。
2. 分岐ステートメント
2.1 if ステートメント
if ステートメントは、与えられた条件が満たされるかどうかを判断し、その判断結果に従って以降の処理を実行するために使用されます。if ステートメントには、単一分岐 if ステートメント、二重分岐 if ステートメント、および複数分岐 if ステートメントの 3 つの基本形式があります。
単一分岐の if ステートメントの基本形式は次のとおりです。
if(表达式) 语句;
実行プロセス: 式が true の場合はステートメントが実行され、それ以外の場合は実行されません。
コード例:
int main() { int age = 0; scanf("%d", &age); if (age < 18) //当只有单个语句时,可以不加大括号 printf("未成年\n"); return 0; }
二重分岐 if ステートメントの基本的な形式は次のとおりです。
if(表达式) 语句1; else 语句2;
実行処理: 式が真の場合はステートメント 1 を実行し、そうでない場合はステートメント 2 を実行します。
コード例:
int main() { int age = 0; scanf("%d", &age); if (age < 18) printf("未成年\n"); else printf("成年\n"); return 0; }
複数分岐の if ステートメントの基本形式は次のとおりです。
if(表达式1) 语句1; else if(表达式2) 语句2; else if(表达式3) 语句3; ... else if(表达式n) 语句n; else 语句n+1;
実行プロセス: 式 1 が真の場合はステートメント 1 を実行し、式 2 が真の場合はステートメント 2 を実行します。すべての式が false の場合、ステートメント n+1 が実行されます。
コード例:
int main() { int score = 0; scanf("%d", &score); if (score < 60) printf("不及格\n"); else if (score >= 60 && score < 70) printf("及格\n"); else if (score >= 70 && score < 85) printf("良好\n"); else printf("优秀\n"); return 0; }
else は常に最も近い if と一致することに注意してください。次のコードは一見すると「haha」を出力するかもしれませんが、else が最も近い if に一致するため、実際の出力は空です。
int main() { int a = 0; int b = 2; if(a == 1) if(b == 2) printf("hehe\n"); else printf("haha\n"); return 0; }
適切な { } を追加すると、コードのロジックがより明確になります。したがって、コードを記述するときは、コードの可読性を高めるための良い習慣を身につけなければなりません。
int main() { int a = 0; int b = 2; if(a == 1) { if(b == 2) printf("hehe\n"); else printf("haha\n"); } return 0; }
2.2 switch ステートメント
switch ステートメントを使用すると、変数が複数の値と等しいかどうかをテストできます。各値は case と呼ばれます。
switch ステートメントの基本的な形式は次のとおりです。
switch(表达式) { case 常量表达式1: 语句1; break; case 常量表达式2: 语句2; break; case 常量表达式3: 语句3; break; ... default: 语句n; break; }
実行プロセス: まず式の値を計算し、それを定数式と 1 つずつ比較します。式の値が定数式の値と等しい場合は、次のステートメントを実行し、switch case ステートメントから抜け出します。式の値がすべての定数式の値と等しくない場合は、次のステートメントを実行します。デフォルト後のステートメント。
注: (1) スイッチの背後にある式は整数式である必要があります。
(2) case の後には整数定数式が続き、文字は ASCII コード値としてメモリに格納されるため、文字型を使用できます。
(3) case の後の定数式は同じであってはなりません。
(4) case の後には複数のステートメントが許可されており、{ } なしで囲むことができます。
(5) ケースとデフォルトの順序は変更できます。
(6) 各 switch ステートメントには、default 節は 1 つだけ指定でき、default 節は省略できます。
コード例:
int main() { int day = 0; scanf("%d", &day); switch (day) { case 1: printf("星期一\n"); break; case 2: printf("星期二\n"); break; case 3: printf("星期三\n"); break; case 4: printf("星期四\n"); break; case 5: printf("星期五\n"); break; case 6: printf("星期六\n"); break; case 7: printf("星期日\n"); break; default: break; } return 0; }
switch文が以下の形式の場合、case値が1、2、3、4、5の場合は出力結果が同じになり、case値が6と6の場合も出力結果は同じになります。 7。
int main() { int day = 0; scanf("%d", &day); switch (day) { case 1: case 2: case 3: case 4: case 5: printf("工作日\n"); break; case 6: case 7: printf("休息日\n"); break; default: break; } return 0; }
switch ステートメントはネストすることもできます。次のコードでは、出力は m = 5、n = 3 です。
n = 1、case 1 ステートメントを入力します (この時点では m = 3) が、ブレークに遭遇しなかったため、次の case ステートメントの実行を続けます; case 2 ステートメントを入力します (n = 2); case 3 ステートメントを入力します (a) switch はこの時点でステートメントがネストされています。n は 2、case 2 ステートメントに入ります。m = 4、n = 3、ここでのブレークはネストされた switch ステートメントから飛び出すことであり、外側の switch ステートメントは継続します。case に入ります。 4 ステートメント、m = 5、n = 3、break は swtich ステートメントから飛び出します。
int main() { int n = 1; int m = 2; switch (n) { case 1:m++; case 2:n++; case 3: switch (n) { case 1:n++; case 2: m++;n++; break; } case 4: m++; break; default: break; } printf("m = %d, n = %d\n", m, n); return 0; }
3. ループ文
3.1 do while 文
do while ループの基本的な形式は次のとおりです。
do { 循环体语句; } while(表达式);
実行処理:まずループ本体文を実行し、式が真かどうかを判定し、真の場合はループを続行し、偽の場合はループから抜けます。
3.2while文
while ループの基本的な形式は次のとおりです。
while(表达式) { 循环体语句; }
実行プロセス: 最初に式を判定し、それが true の場合はループ本体のステートメントを実行し、false の場合はループから抜け出します。
コード例: 0 から 9 までの数字を出力します。
int main() { int i = 0; while (i < 10) { printf("%d ", i); i++; } return 0; }
while ループで中断して続行します。
Break はループを永久に終了し、Continue はこのループを終了して次のループに進みます。コードを通して、break と continue の違いを観察してみましょう。
コード 1:int main() { int i = 0; while (i < 10) { if (i == 5) break; printf("%d ", i); i++; } return 0; }
コード 2:
int main() { int i = 0; while (i < 10) { if (i == 5) continue; printf("%d ", i); i++; } return 0; }
コード 1 では、i=5 の場合、ループは直接終了し、実行結果は 0 1 2 3 4 になります。
コード 2 では、i=5 の場合、このループの後のステートメントをスキップして次のループに入ります。i の値は変更されていないため、無限ループに陥ります。
3.3 for ステートメント
for ループの基本的な形式は次のとおりです。
for(初始化表达式;条件表达式;更新表达式) { 循环体语句; }
実行処理: 最初に初期化式を解決し、次に条件式を解決し、true の場合はループ本体ステートメントを実行し、次に更新式を実行します。false の場合はループから抜けます。
注: (1) for ループ内の 3 つの式は省略できますが、「;」は省略できません。
(2) 初期化式と更新式は、単純な式またはカンマ式にすることができます。
(3)条件式は関係式や論理式が一般的であるが、数値式や文字式でもよい。
(4) for ループには複数のループ制御変数を含めることができます。
コード例:
int main() { int i = 0; int k = 0; for (i = 0, k = 0; k = 0; i++, k++) k++; return 0; }
このコードは 0 回ループします。まず、条件式の判定ではなく「k=0」を代入します。次に、式の値が 0 であり、0 は false なので、ループは 1 回も入りません。
for ループを中断して続行します。
for ループでは、break と continue は while ループと同じ効果がありますが、使用した場合の結果は多少異なります。
コード 1:
int main() { int i = 0; for (i = 0; i < 10; i++) { if (i == 5) break; printf("%d ", i); } return 0; }
コード 2:
int main() { int i = 0; for (i = 0; i < 10; i++) { if (i == 5) continue; printf("%d ", i); } return 0; }
コード 1 の実行結果は 0 1 2 3 4 で、コード 2 の実行結果は 0 1 2 3 4 6 7 8 9 です。Break を使用した場合、i=5 はループを直接終了し、Continue を使用した場合、i=5 は現在のループをスキップし、更新式を実行して次のループに入ることがわかります。
4.goto文
goto ステートメントの基本形式は次のとおりです。
goto 语句标号; ... 语句标号: 语句;
実行処理:無条件でステートメントラベルにジャンプし、以下のコードを実行します。
注: (1) ステートメントラベルは文字、数字、アンダースコアで構成できます。最初の文字は文字またはアンダースコアである必要があります。
(2) goto 文は深いループから抜け出すために使用できますが、コード構造レベルが曖昧になり、読みにくくなるため、goto 文は合理的に使用する必要があります。
5. 練習する
1.nを計算してみよう!
int main() { int n = 0; scanf("%d", &n); int mul = 1; for (int i = 1; i <= n; i++) { mul *= i; } printf("mul = %d\n", mul); return 0; }
2. 1!+2!+3!+...+10!を計算します。
方法 1:
int main() { int sum = 0; for (int i = 1; i <= 10; i++) { int mul = 1; for (int j = 1; j <= i; j++) { mul *= j; } sum += mul; } printf("sum = %d\n", sum); return 0; }
方法 2 (最適化):
int main() { int mul = 1; int sum = 0; for (int i = 1; i <= 10; i++) { mul *= i; sum += mul; } printf("sum = %d\n", sum); return 0; }
3. 半分で探す
int main() { int arr[] = { 0,1,2,3,4,5,6,7,8,9 }; int len = sizeof(arr) / sizeof(arr[0]); int left = 0; int right = len - 1; int k =7; int flag = 0; while (left <= right) { //int mid = (right + left) / 2; //当left和right过大时,二者的和可能会超出整型所能表示的最大范围,发生越界 //所以采用下面这种方式 int mid = left + (right - left) / 2; if (arr[mid] < k) { left = mid + 1; } else if (arr[mid] > k) { right = mid - 1; } else { printf("找到了!下标是%d\n", mid); flag = 1; break; } } if (flag == 0) printf("没找到!\n"); return 0; }
4. 複数のキャラクターが両端から移動し、中央に向かって収束していることを認識します。
#include <stdio.h> #include <string.h> #include <Windows.h> int main() { char arr1[] = "hello world!"; char arr2[] = "************"; int left = 0; int right = strlen(arr1) - 1; while (left <= right) { arr2[left] = arr1[left]; arr2[right] = arr1[right]; printf("%s\n", arr2); Sleep(1000); //停止1000毫秒 system("cls"); //清屏 left++; right--; } printf("%s\n", arr2); return 0; }
5. 数字当てゲーム(1~100)
#include <stdio.h> #include <stdlib.h> #include <time.h> void menu() { printf("********************\n"); printf("******1.0 start*****\n"); printf("******0.0 exit*****\n"); printf("********************\n"); } void game() { //设置随机数 int ret = rand() % 100 + 1; //猜数字 int input = 0; while (1) { printf("请输入->"); scanf("%d", &input); if (input < ret) { printf("猜小了\n"); } else if (input > ret) { printf("猜大了\n"); } else { printf("猜对了!\n"); break; } } } int main() { int input = 0; //随机数生成器 srand((unsigned)time(NULL)); do { menu(); printf("请选择->"); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("退出游戏\n"); break; default: printf("选择错误\n"); break; } } while (input); return 0; }