1. C言語文
C 言語のステートメントはセミコロンで;
終わります
C ステートメントは、次の 5 つのカテゴリに分類できます。
- 式ステートメント
- 関数呼び出しステートメント
- 制御文
- 複合文
- 空のステートメント
この章では制御文について説明します
制御ステートメントは、プログラムのさまざまな構造モード (C 言語ではシーケンシャル構造、選択構造、ループ構造の 3 つの構造をサポートします) を実現するためにプログラムの実行フローを制御するために使用されます。これらは特定のステートメント定義子で構成されており、C 言語には9種類の制御文。
次の 3 つのカテゴリに分類できます。
- 条件判断ステートメントは、分岐ステートメントとも呼ばれ
if
ますswitch
。 - ループ実行ステートメント:
do while
ステートメント、while
ステートメント、for ステートメント; - ステートメントに移ります:
break
ステートメント、goto
ステートメント、Continue ステートメント、return
ステートメント。
2. 分岐ステートメント
2.1 if ステートメント
C プログラムを作成する場合、多くの場合、さまざまな条件に基づいてコードを選択的に実行する必要があります。これが if ステートメントの動作です。if ステートメントは、条件が true か false に応じて異なるコード ブロックを実行する条件付きステートメントです。
if
ステートメントの基本的な構文は次のとおりです。
if (condition) {
// 如果条件为真,执行这里的代码
}
if ステートメントは、キーワードif
、括弧で囲まれた条件式condition
、中括弧で囲まれたコード ブロックで構成されます。条件式が評価されます。結果が true (ゼロ以外) の場合、中括弧内のコード ブロックが実行されます。結果が false (ゼロ) の場合、if ステートメント全体がスキップされ、後続のコードが実行されます。実行され続けます。
if ステートメントの実行フローは次のとおりです。
- 条件式の値を決定します。
- 条件が true の場合、if ステートメントのコード ブロックが実行されます。
- 条件が false の場合、if ステートメントのコード ブロックをスキップし、後続のコードの実行を続けます。
if-else
ステートメントの構文は次のとおりです。
if (condition) {
// 如果条件为真,执行这里的代码
} else {
// 如果条件为假,执行这里的代码
}
if-else ステートメントを使用した例を次に示します。
int num = -5;
if (num > 0) {
printf("Number is positive.\n");
} else {
printf("Number is not positive.\n");
}
上記例では、 のnum
値に応じて、num
0より大きい場合は「数値が正です。」を出力し、num
0以下の場合は「数値が正ではありません。」を出力します。
マルチブランチの構文はelse if
次のとおりです。
if (condition1) {
// 如果条件1为真,执行这里的代码
} else if (condition2) {
// 如果条件1为假且条件2为真,执行这里的代码
} else {
// 如果所有条件都为假,执行这里的代码
}
使用する場合はelse if
、if ステートメントの後、else
ステートメントの前に配置する必要があります。複数の else if を使用して、さらに条件分岐を追加できます。
else if
使用例を次に示します。
int score = 75;
if (score >= 90) {
printf("优秀\n");
} else if (score >= 80) {
printf("良好\n");
} else if (score >= 70) {
printf("中等\n");
} else if (score >= 60) {
printf("及格\n");
} else {
printf("不及格\n");
}
上記の例では、score
変数の値に応じて、異なるスコア範囲に応じて異なる評点が出力されます。条件の順序に従って、条件を満たす最初のコード ブロックのみが実行されます。score
90 以上の場合は「優秀」を出力し、最初の条件は満たさないが 2 番目の条件 (80 <= スコア < 90) を満たしている場合は「良好」を出力します。
C 言語の式では、0 は false を意味し、ゼロ以外は true を意味します。
2.1.1 フローティングelse
このコードを書いたとき:
int main()
{
int a = 0;
int b = 2;
if(a == 1)
if(b == 2)
printf("hehe\n");
else
printf("haha\n");
return 0;
}
//注意程序中else不是跟第一个if匹配,而是和第二个匹配,所以a==1 为假,程序直接return 0;
C では、else は最も近い不一致の if ステートメントと一致します。
改正:
//适当的使用{}可以使代码的逻辑更加清楚。
//代码风格很重要
#include <stdio.h>
int main() {
int a = 0;
int b = 2;
if (a == 1) {
if (b == 2) {
printf("hehe\n");
}
} else {
//else匹配左边的右括号的if
printf("haha\n");
}
return 0;
}
2.1.2 ifの書き方の比較
//代码1
if (condition) {
return x;
}
return y;
//代码2
if (condition)
{
return x;
}
else
{
return y;
}
//代码3
int num = 1;
if (num == 5)
{
printf("hehe\n");
}
//代码4
int num = 1;
if (5 == num)
{
printf("hehe\n");
}
2.2 switch ステートメント
switch
式の値に基づいてさまざまな実行パスを選択する条件文。これにより、if
複数のステートメントを使用するよりも、考えられる複数の分岐を処理するためのより簡潔で読みやすい方法が提供されます。
switch
ステートメントの基本構造は次のとおりです。
switch (expression) {
case constant1:
// 执行代码块1
break;
case constant2:
// 执行代码块2
break;
...
case constantN:
// 执行代码块N
break;
default:
// 当expression与上述常量都不匹配时执行的代码块
}
expression
case
は、結果が各ステートメントに続く定数と比較される式です。expression
の値がcase
次の定数のいずれかに一致する場合、case
ステートメントに関連付けられたコード ブロックが実行されます。break
このステートメントは、分岐の実行後にステートメントから抜け出してswitch
、次の分岐の実行を防ぐために使用されます。
switch
ステートメントに関する重要な注意事項をいくつか示します。
expression
の結果は、float や string ではなく、整数型 (int
、char
、 など) である必要があります。enum
case
次の定数は定数式、つまりコンパイル時に決定できる値である必要があり、変数にすることはできません。- 各
case
分岐のコード ブロックには任意の数のステートメントを含めることができます。ステートメントがない場合はbreak
、次の分岐の実行が続行されます。これは「ケースの貫通」と呼ばれます。 default
expression
ブランチはオプションであり、すべてにcase
一致するものがない場合を処理するために使用されます。分岐がない場合、default
match がないcase
場合、switch
ステートメントは何も行いません。switch
ステートメントは他のステートメント内にネストできますswitch
が、コードの理解を難しくする過度のネストを避けるように注意する必要があります。
簡単なステートメントの例を次に示しますswitch
。
int day = 2;
switch (day) {
case 1:
printf("Monday\n");
break;
case 2:
printf("Tuesday\n");
break;
case 3:
printf("Wednesday\n");
break;
default:
printf("Invalid day\n");
}
この例では、day
変数の値に応じて、プログラムは対応する出力、つまり「火曜日」を出力します。day
値が 1、3、またはその他の場合は、異なる出力が出力されます。day
値がどの にも一致しない場合case
、default
分岐が実行され、「無効な日」が出力されます。
ステートメントを使用するとswitch
、式の値に基づいて複数の選択肢をすばやく切り替え、対応するコード ブロックを実行できます。
2.2.1 スイッチのネスト使用
void test{
int n = 1;
int m = 2;
switch (n) {
case 1:
m++;
case 2:
n++;
case 3:
switch (n) {
//switch允许嵌套使用
case 1:
n++;
case 2:
m++;
n++;
break;
}
case 4:
m++;
break;
default:
break;
}
printf("m = %d, n = %d\n", m, n);
}
//输出结果:m = 5, n = 3
case
ステートメントは継続的に照合して「大文字と小文字の区別」効果を実現できます。つまり、特定の一致が見つかった後、case
ステートメントが見つかるかステートメントが終了case
するまで、後続のステートメントが実行され続けます。break
switch
switch
ステートメントはネストでき、case
1 つのステートメント内でステートメントを再使用できますswitch
。default
ブランチはオプションであり、一致しないすべてのケースを処理するために使用されます。- ステートメントを使用するときは
switch
、コード ロジックが正しいことを確認するために、制御フローのフローの方向に注意してください。
3. ループ文
3.1 while ループ
while
ループは、特定の条件が満たされなくなるまでコードのブロックを繰り返し実行するために使用される条件ベースの反復構造です。その基本的な構文は次のとおりです。
while (condition) {
// 循环体代码
// 在每次迭代时执行的代码
}
condition
は式であり、通常はブール値に関連付けられた条件です。これが true (ゼロ以外)である限りcondition
、ループ本体のコードが実行されます。各繰り返しでは、condition
最初に判定が行われ、判定結果が真の場合、ループ本体のコードが実行されます。次に、もう一度確認して、condition
次の反復に進むかどうかを決定します。ループは、true である限り実行され続けますcondition
。
while
ループの実行は次のようになります。
- チェックされた
condition
値。 - false (0)の場合
condition
、ループは終了し、ループ本体のコードは実行されません。 - true (ゼロ以外)の場合
condition
、ループ本体のコードが実行されます。 condition
手順1に戻って値の確認を続け、判定結果に応じてループを継続するかどうかを決定します。
while
以下は、ループの使用を示す簡単な例です。
int count = 0;
while (count < 5) {
printf("Count: %d\n", count);
count++;
}
この例では、count
初期値 0 の変数が定義されています。次にwhile
ループに入り、count < 5
状態を確認します。初期値が0なので条件が成立するので、ループ本体のコードが実行されます。現在のcount
値がループ本体に出力され、その後count
増加します。while
次に、ループの先頭に戻り、条件を再度確認し、count
の値が 5 以上になるまで上記の手順を繰り返します。
3.1.1 while ループでの中断と続行
while
ループ内でbreak
andcontinue
ステートメントを使用して、ループの動作を制御できます。
break
ステートメント: ループ内でステートメントが検出されるとbreak
、プログラムは直ちにループを終了し、ループ後のコードの実行を続行します。残りの反復を実行せずにループを途中で終了するために使用されます。
以下にbreak
ステートメントを使用した例を示します。
int i = 0;
while (i < 5) {
if (i == 3) {
break;
}
printf("%d ", i);
i++;
}
この例では、i
の値が 3 に等しいときにステートメントが検出されましたbreak
。この時点でループは終了し、それ以上の繰り返しは実行されません。したがって、出力は次のようになります。
0 1 2
2.continue
ステートメント: ループ内でステートメントが見つかるとcontinue
、プログラムは現在の反復の残りのコードを直ちにスキップし、次の反復に直接入ります。ループを終了せずに特定の反復をスキップするために使用されます。
以下にcontinue
ステートメントを使用した例を示します。
以下にcontinue
ステートメントを使用した例を示します。
int i = 0;
while (i < 5) {
i++;
if (i == 3) {
continue;
}
printf("%d ", i);
}
この例では、i
の値が 3 に等しいときにステートメントが検出されましたcontinue
。この時点で、printf
現在の反復内のステートメントの後のコードはスキップされ、次の反復に直接進みます。したがって、出力は次のようになります。
1 2 4 5
注: break
andcontinue
ステートメントを使用する場合は、無限ループや論理エラーが発生しないように注意してください。意図した制御フローを実現するには、適切な条件下でこれらのステートメントを使用してください。
いくつかのコードを観察してください。
#include <stdio.h>
int main() {
int ch = 0;
while ((ch = getchar()) != EOF)
putchar(ch);
return 0;
}
//这里的代码适当的修改是可以用来清理缓冲区的.
#include <stdio.h>
int main() {
char ch = '\0';
while ((ch = getchar()) != EOF) {
if (ch < '0' || ch > '9')
continue;
putchar(ch);
}
return 0;
}
//这个代码的作用是:只打印数字字符,跳过其他字符的
3.2 do while ループ
do...while
ループは、ループ条件をチェックする前にループ本体内のコードを実行するテスト後のループ構造です。ループ本体の実行は、ループ条件が満たされる限り、ループ条件が満たされなくなるまで継続されます。do...while
ループは、ループ条件が最初から満たされていない場合でも、ループ本体を少なくとも 1 回実行します。
do...while
ループの基本的な構文は次のとおりです。
do {
// 循环体代码
// 在每次迭代时执行的代码
} while (condition);
まず、do
キーワードに続くループ本体のコードが 1 回実行されます。次に、ループ本体を 1 回実行した後、プログラムはループ条件をチェックしますcondition
。ループ条件が true (ゼロ以外) の場合、実行は次の反復に継続され、ループ本体内のコードが再度実行されます。ループ条件が false (0) の場合、ループを終了し、ループ後のコードの実行を続行します。
do...while
以下は、ループの使用を示す簡単な例です。
int count = 0;
do {
printf("Count: %d\n", count);
count++;
} while (count < 5);
この例では、ループの本体が 1 回実行され、初期count
値が出力されます。次にループ条件がチェックされcount < 5
、条件が満たされた場合は次の反復に進みます。反復ごとに、現在のcount
値を出力し、count
それを増分します。ループは、count
の値が 5 以上になるまで継続します。
3.2.1 do while ループでの中断と続行
do...while
ループ内でのbreak
andcontinue
ステートメントの使用法と機能は、他のループ構造 ( for
andなど)while
の場合と同じです。これらは、ループの実行フローを制御するためにループの本体内で使用されます。
break
ステートメント: ループ内でステートメントが検出されるとbreak
、プログラムは現在のループを直ちに終了し、残りの反復を実行せず、ループ後のコードの実行を続行します。
以下にbreak
ステートメントを使用した例を示します。
int i = 0;
do {
if (i == 3) {
break;
}
printf("%d ", i);
i++;
} while (i < 5);
この例では、i
の値が 3 に等しいときにステートメントが検出されましたbreak
。この時点でループは終了し、それ以上の繰り返しは実行されません。したがって、出力は次のようになります。
0 1 2
continue
ステートメント: ループ内でステートメントが検出されるとcontinue
、プログラムは現在の反復の残りのコードを直ちにスキップし、次の反復に直接進みます。
以下にcontinue
ステートメントを使用した例を示します。
int i = 0;
do {
i++;
if (i == 3) {
continue;
}
printf("%d ", i);
} while (i < 5);
この例では、i
の値が 3 に等しい場合にステートメントが発生しますcontinue
。この時点で、printf
現在の反復内のステートメントに続くコードはスキップされ、次の反復が直接実行されます。したがって、出力は次のようになります。
1 2 4 5
3.3 for ループ
for
ループは、コードを繰り返し実行するためによく使用されるループ構造で、初期化式、ループ条件、ループ反復ステートメントの 3 つの部分で構成されます。
for
ループの基本的な構文は次のとおりです。
for (初始化表达式; 循环条件; 循环迭代语句) {
// 循环体代码
// 在每次迭代时执行的代码
}
- 初期化式を実行します。これは通常、ループ変数を初期化するために使用されます。
- ループ条件がチェックされ、ループ条件が true (ゼロ以外) の場合、ループ本体内のコードが実行されます。ループ条件が false (0) の場合、ループを終了し、ループ後のコードの実行を続行します。
- ループ本体内のコードを実行します。
- ループ反復ステートメントを実行します。これは通常、ループ変数の値を更新するために使用されます。
- 2 番目のステップに戻り、ループ条件を再確認し、ループ条件の結果に基づいてループを続行するかどうかを決定します。
for
以下はループの使用を示す簡単な例です。
for (int i = 0; i < 5; i++) {
printf("%d ", i);
}
この例では、初期化式はint i = 0
ループ変数をi
初期値 0 に初期化します。ループ条件は変数が 5 未満かどうかをi < 5
チェックし、5 未満の場合はループ本体内のコードを実行します。i
反復ごとに、現在のi
値を出力します。ループ反復ステートメントは、ループ変数の値i++
をインクリメントするために使用されます。i
ループは、ループ条件が満たされなくなるまで継続します。
このコードは次を出力します。
0 1 2 3 4
3.3.1 for ループと while ループ
int i = 0;
//实现相同的功能,使用while
i = 1; //初始化部分
while (i <= 10)//判断部分
{
printf("hehe\n");
i = i + 1;//调整部分
}
//实现相同的功能,使用for
for (i = 1; i <= 10; i++) {
printf("hehe\n");
}
while
サイクル内のサイクルに必要な条件がまだ 3 つあることがわかりますが、スタイルの問題により、3 つの部分が遠くに逸脱する可能性が高いため、検索と修正が集中して便利ではありません。したがって、for
ループ スタイルが優れており、for
ループ頻度も最も高くなります。
3.3.2 for ループで中断して続行する
for
ループ内でのbreak
andステートメントの使用法と効果は、 and などcontinue
の他のループ構造の場合と同じです。while
do...while
//代码1
int main() {
int i = 0;
for (i = 1; i <= 10; i++) {
if (i == 5)
break;
printf("%d ", i);
}
return 0;
}
//输出结果:1 2 3 4
//代码2
int main() {
int i = 0;
for (i = 1; i <= 10; i++) {
if (i == 5)
continue;
printf("%d ", i);
}
return 0;
}
//输出结果:1 2 3 4 6 7 8 9 10
3.3.3 forループのループ制御変数
提案:
- for ループが制御不能になるのを防ぐために、for ループの本体内のループ変数を変更しないでください。
- for文のループ制御変数の値は、「最初に閉じてから開く間隔」で記述することを推奨します。
int i = 0;
//前闭后开的写法
for (i = 0; i < 10; i++) {
}
//两边都是闭区间
for (i = 0; i <= 9; i++) {
}
3.3.4 for ループのバリエーション
for (;;) {
printf("hehe\n");
}
forループ内の初期化部分、判定部分、調整部分は省略することもできますが、初心者の場合は省略すると問題が発生しやすくなるためお勧めできません。
初期化部分を省略した場合、ここには何個のヘヘが出力されますか?
int i = 0;
int j = 0;
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {
printf("hehe\n");
}
}
//100次hehe
初期化部分を省略した場合、ここには何個のヘヘが出力されますか?
int i = 0;
int j = 0;
for (; i < 10; i++) {
for (; j < 10; j++) {
printf("hehe\n");
}
}
//10次heh
複数の変数を含む制御ループ
int x, y;
for (x = 0, y = 0; x < 2 && y < 5; ++x, y++) {
printf("hehe\n");
}
//2次hehe
練習:
何回ループするか聞いてもいいですか?
int main() {
int i = 0;
int k = 0;
for (i = 0, k = 0; k = 0; i++, k++)
k++;
return 0;
}
このプログラムのループ回数は0回です。
for ループの条件部分では、等価演算子 (==) の代わりに代入演算子 (=) が使用され、条件が常に true (ゼロ以外) になるため、ループは無限に実行されます。ループ本体では k に対して自己インクリメント演算 (k++) が実行されますが、ループ条件では k の値が 0 に再代入されるため、ループごとに k の値は 0 にリセットされます。したがって、ループは決して終了できず、プログラムは無限ループ状態になり、0 を返すことはありません。
4.goto文
C言語では、goto
プログラム中のラベルに無条件に転送するために文を使用します。現在の関数やブロック内など、プログラム内の任意の場所にジャンプできます。
goto
以下に、ステートメントの使用法を示すプログラム例を示します。
#include <stdio.h>
int main() {
int i = 0;
start:
printf("i = %d\n", i);
i++;
if (i < 5) {
goto start;
}
return 0;
}
goto
ステートメントを誤って使用すると、コードの理解や保守が困難になる可能性があるため、慎重に使用する必要があることに注意することが重要です。多くの場合、コードをより構造化して読みやすくするために、ステートメントの代わりにループや条件ステートメント (例for
、 、while
、if
など) を使用できます。goto