このブログ記事では、C言語の基本的な概念を続けて紹介します。

Cの基本については読み飽きたと思うかもしれませんが、もう少しお付き合いください。これらの基本を注意深く学ぶことは将来にとって非常に重要です。
If文
たとえば、学生の成績に応じてコメントを与えるとしましょう。これを行うには、以下のようにif文を使用できます。
char grade = 'A';
if (grade == 'A') {
printf("完璧です!");
} else if (grade == 'B') {
printf("素晴らしい!");
} else if (grade == 'C') {
printf("素晴らしい!");
} else if (grade == 'D') {
printf("素晴らしい!");
} else if (grade == 'E') {
printf("なんとか合格しました。");
} else if (grade == 'F') {
printf("不合格です。");
} else {
printf("無効な成績です。");
}
しかし、上記のコードは理想的ではありません。なぜなら、同じことを出力する条件が三つあるからです。これをAND論理演算子&&
を使って簡略化できます。
char grade = 'C';
if (grade == 'A') {
printf("完璧です!");
} else if ('B' <= grade && grade <= 'D') {
printf("素晴らしい!");
} else if (grade == 'E') {
printf("なんとか合格しました。");
} else if (grade == 'F') {
printf("不合格です。");
} else {
printf("無効な成績です。");
}
AND演算子に加えて、OR演算子||
とNOT演算子!
もあります。if文の中では、<
と>
を使って大小比較を行い、==
を使って等しいかどうかを確認し、!=
を使って等しくないかどうかを確認できます。
Switch文
しかし、else if
がたくさんあるのは悪いコーディングプラクティスとされています。チェックする条件が多い場合、switch文を使用します。
switch (grade) {
case 'A':
printf("完璧です!");
break;
case 'B':
printf("素晴らしい!");
break;
case 'C':
printf("良いです。");
break;
case 'D':
printf("まあまあです。");
break;
case 'E':
printf("なんとか合格しました。");
break;
case 'F':
printf("不合格です。");
break;
default:
printf("無効な成績です。");
}
switch文の実行を停止するためにはbreak
を使用する必要があります。そうしないと、次のケースのプログラムも実行されてしまいます。
三項演算子
以下のコードは正しいですが、毎回これを書くのは非常に面倒です。
int a = 4;
int b = 3;
int min;
if (a < b) {
min = a;
} else {
min = b;
}
printf("最小値: %d", min);
代わりに、三項演算子を使ってコードを以下のようにリファクタリングできます。
int a = 4;
int b = 3;
// 三項演算子 (条件) ? trueの場合の値 : falseの場合の値;
int min = (a < b) ? a : b;
printf("最小値: %d", min);
これにより、多くのシナリオでコードを簡略化できます。
Forループ
C言語でforループを使いたい場合、以下のように行います。
// Forループ
// for (開始インデックス; 継続条件; インデックスの増加方法) { 操作 }
for (int i = 1; i <= 10; i++) {
printf("%d ", i);
}
// => 1 2 3 4 5 6 7 8 9 10
デクリメントも可能です。
// Forループ, デクリメント
for (int i = 10; i >= 1; i--) {
printf("%d ", i);
}
// => 10 9 8 7 6 5 4 3 2 1
// Forループ, 2ずつデクリメント
for (int i = 10; i >= 1; i-=2) {
printf("%d ", i);
}
// => 10 8 6 4 2
Whileループ
条件が満たされるまでプログラムを無限に実行したい場合、whileループを使用します。
int i = 1;
while (i <= 10) {
printf("%d ", i);
i++;
}
// => 1 2 3 4 5 6 7 8 9 10
最初に操作を実行し、その後繰り返すかどうかを決定したい状況もあります。そのような場合、do-whileループを使用します。
int age;
do {
printf("年齢は?: ");
scanf("%d", &age);
} while (age < 0);
printf("あなたの年齢は%d歳です", age);
まず年齢を尋ね、ユーザー入力に応じて再度尋ねるかどうかを決定します。
Break vs Continue
多くの初心者はbreak
とcontinue
の違いに非常に混乱するようなので、ここで説明します。
break
はループを終了しますが、continue
はループの1回の反復をスキップします。例を見てみましょう。
// Break
for (int i = 1; i <= 5; i++) {
if (i == 3) {
break;
} else {
printf("%d ", i);
}
}
// => 1 2
// Continue
for (int i = 1; i <= 5; i++) {
if (i == 3) {
continue;
} else {
printf("%d ", i);
}
}
// => 1 2 4 5
上記の例では、break
が使用された場合、出力は1 2
です。なぜなら、i==3
の時break
がループを終了したからです。
一方、continue
が使用された場合、出力は1 2 4 5
です。なぜなら、continue
が3をスキップしたからです。
break
とcontinue
は、ネストされたループでも同じレベルのループにのみ作用します。
// Break (i == jの場合、内側のループを終了)
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 5; j++) {
if (i == j) {
break;
} else {
printf("%d ", j);
}
}
printf("\n");
}
// => 1
// 1 2
// 1 2 3
// 1 2 3 4
// Continue (i == jの場合、スキップして内側のループを継続)
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 5; j++) {
if (i == j) {
continue;
} else {
printf("%d ", j);
}
}
printf("\n");
}
// => 2 3 4 5
// 1 3 4 5
// 1 2 4 5
// 1 2 3 5
// 1 2 3 4
配列
文字列(文字の配列)の初期化方法は見たことがありますが、他のデータ型ではどのように行うのでしょうか?以下のように行います。
int grades[] = {1,2,3,4,5};
配列の要素にアクセスするには、以下のようにします。
grades[0]; // => 1
grades[1]; // => 2
grades[2]; // => 3
配列を反復処理したい場合、sizeof
を使って要素の数を計算できます。
// 要素の数を取得
// 配列全体のサイズを最初の要素のサイズで割ります
// 配列のデータ型は一貫しているため、これが可能です
int size = sizeof(grades)/sizeof(grades[0]);
for (int i = 0; i < size; i++) {
printf("成績: %d\n", grades[i]);
}
配列は0インデックスである(0から数え始める)ため、<=
の代わりに<
を使用する必要があります。
関数
全てのコードをmain
関数に含めるのは、コードが長くなり、重複が起こりやすいので悪い考えです。
コードを簡略化するために、以下のようにmain
の前に他の関数を定義できます。
// 関数 出力タイプ 関数名 (入力) { 操作 }
void happyBirthday (char name[], int age) {
printf("誕生日おめでとう %s!\n", name);
printf("あなたは%d歳になりました!\n", age)
}
int square (int x) {
return x*x;
}
int main () {
char name[] = "マイケル・ジョーダン";
int age = 24;
happyBirthday(name, age);
int ageSquared = square(age);
printf("あなたの年齢の二乗は%dです",ageSquared);
return 0;
}
可読性のためにmain
の後に他の関数を定義し、関数を呼び出す前に関数が定義されていない場合、
多くのコンパイラはパラメータの一致をチェックしないため、予期しない動作が発生する可能性があります。そのため、コンパイラが正しく
パラメータの一致をチェックできるように、最初に関数プロトタイプを追加します。
// 関数プロトタイプ
void happyBirthday (char[], int);
int square (int);
int main () {
char name[] = "マイケル・ジョーダン";
int age = 24;
happyBirthday(name);
int ageSquared = square(age);
printf("あなたの年齢の二乗は%dです",ageSquared);
return 0;
}
void happyBirthday (char name[], int age) {
printf("誕生日おめでとう、%s!\n", name);
printf("あなたは%d歳になりました!\n", age)
}
int square (int x) {
return x*x;
}
クイズ
この記事では、学習した内容を確認するためのクイズを設けます。記事のメイン部分を読んだ後に、ぜひ自分で問題を解いてみることを強くお勧めします。各問題をクリックすると答えが表示されます。
リソース
- Bro Code. 2022. C if statements ✔️. YouTube.
- Bro Code. 2022. C switch statements 🔽. YouTube.
- Bro Code. 2022. C functions 📞. YouTube.
- Bro Code. 2022. C arguments 📧. YouTube.
- Bro Code. 2022. C return statement 🔙. YouTube.
- Bro Code. 2022. C function prototypes 🤖. YouTube.
- Bro Code. 2022. C for loops 🔁. YouTube.
- Bro Code. 2022. C while loops ♾️. YouTube.
- Bro Code. 2022. C do while loop 🤸♂️. YouTube.
- Bro Code. 2022. C break vs continue 🥊. YouTube.
- Bro Code. 2022. C arrays 🗃️. YouTube.