C言語

C言語入門

コードを書き、コンパイルと実行を繰り返しながら、C言語の基礎を一歩ずつ学びましょう。

この講座はC17を基準にしています。

01

C言語とは

C言語は、OS、組み込み機器、ライブラリなど幅広い分野で使われるコンパイル型言語です。値がメモリ上でどのように扱われるかを意識して書くため、コンピュータの仕組みを学ぶ入口にもなります。

C言語で学べること
  • ソースコードを機械が実行できる形へ変換する流れ
  • 型とメモリサイズを意識したデータ処理
  • 関数へ処理を分ける設計
  • ポインタを使ったメモリとデータ構造の操作
02

コンパイルして実行しよう

GCCまたはClangを用意し、ターミナルで確認します。WindowsではWSLやVisual Studioの開発者コマンドプロンプトなど、環境に合う方法を選びます。

バージョン確認COMMAND
gcc --version

hello.cを作成します。拡張子は.cです。

hello.cC
#include <stdio.h>

int main(void) {
    printf("こんにちは、C言語!\n");
    return 0;
}
コンパイルと実行COMMAND
gcc -std=c17 -Wall -Wextra -pedantic hello.c -o hello
./hello
実行結果OUTPUT
こんにちは、C言語!
Windowsの場合 生成されたファイルがhello.exeなら、PowerShellでは.\hello.exeを実行します。
03

プログラムの基本構造

#includeは必要な宣言を取り込み、main関数が実行の入口になります。文の末尾にはセミコロンを書き、波かっこで処理のまとまりを表します。

コメントと順序C
#include <stdio.h>

int main(void) {
    // 1行コメント
    printf("1番目\n");
    printf("%d\n", 10 + 20); /* 複数行にも使えるコメント */
    printf("3番目\n");
    return 0;
}
実行結果OUTPUT
1番目
30
3番目
04

変数とデータ型

C言語では、変数を使う前に型と名前を宣言します。型によって表せる値とサイズが異なります。

用途printfの指定
int整数%d
double小数%f
char1文字%c
size_tサイズ・要素数%zu
変数とsizeofC
#include <stdio.h>

int main(void) {
    int age = 20;
    double height = 170.5;
    char grade = 'A';

    printf("年齢: %d\n", age);
    printf("身長: %.1f\n", height);
    printf("評価: %c\n", grade);
    printf("intのサイズ: %zuバイト\n", sizeof(int));
    return 0;
}
実行例OUTPUT
年齢: 20
身長: 170.5
評価: A
intのサイズ: 4バイト
サイズは環境による sizeof(int)の結果は処理系で異なる可能性があります。固定値と思い込まず、必要ならsizeofで確認します。
05

安全に入力を受け取る

初学者向けの例でも、入力が常に正しいとは限りません。fgetsで一行を配列へ読み、sscanfの戻り値で変換できたか確認します。

年齢を入力C
#include <stdio.h>

int main(void) {
    char line[100];
    int age;

    printf("年齢を入力してください: ");
    if (fgets(line, sizeof line, stdin) == NULL) {
        fprintf(stderr, "入力を読み取れませんでした\n");
        return 1;
    }
    if (sscanf(line, "%d", &age) != 1 || age < 0) {
        fprintf(stderr, "0以上の整数を入力してください\n");
        return 1;
    }
    printf("来年は%d歳です\n", age + 1);
    return 0;
}
実行例OUTPUT
年齢を入力してください: 20
来年は21歳です

&ageは変数ageのアドレスです。詳しくは発展編のポインタで学びます。

06

演算子と型変換

整数の割り算C
#include <stdio.h>

int main(void) {
    int total = 7;
    int count = 2;
    printf("整数: %d\n", total / count);
    printf("小数: %.1f\n", (double)total / count);
    printf("余り: %d\n", total % count);
    return 0;
}
実行結果OUTPUT
整数: 3
小数: 3.5
余り: 1

整数同士の/は小数部分を切り捨てます。(double)によるキャストで一方を小数へ変換すると、小数の割り算になります。

07

条件分岐

点数を判定C
#include <stdio.h>

int main(void) {
    int score = 82;
    if (score >= 80) {
        printf("合格(よくできました)\n");
    } else if (score >= 60) {
        printf("合格\n");
    } else {
        printf("再挑戦\n");
    }
    return 0;
}
実行結果OUTPUT
合格(よくできました)
比較と代入 ==は比較、=は代入です。条件式で取り違えないよう、警告を有効にします。
08

繰り返し

forとwhileC
#include <stdio.h>

int main(void) {
    for (int i = 1; i <= 3; i++) {
        printf("%d回目\n", i);
    }
    int count = 3;
    while (count > 0) {
        printf("%d ", count);
        count--;
    }
    printf("スタート\n");
    return 0;
}
実行結果OUTPUT
1回目
2回目
3回目
3 2 1 スタート
無限ループ whileの条件に使う値を更新し忘れると終了しません。終了条件を先に決めましょう。
09

配列

配列は同じ型の値を連続して並べます。添字は0から始まり、要素数はsizeof scores / sizeof scores[0]で求められます。

平均点C
#include <stdio.h>

int main(void) {
    int scores[] = {70, 85, 90};
    size_t length = sizeof scores / sizeof scores[0];
    int total = 0;
    for (size_t i = 0; i < length; i++) {
        total += scores[i];
    }
    printf("合計: %d\n", total);
    printf("平均: %.1f\n", (double)total / length);
    return 0;
}
実行結果OUTPUT
合計: 245
平均: 81.7
範囲外は未定義動作 3要素の配列で使える添字は0〜2です。scores[3]を読み書きしてはいけません。
10

文字列

C言語の文字列は、末尾にヌル文字'\0'を持つchar配列です。strlenは終端を除く長さを返します。

文字列の長さC
#include <stdio.h>
#include <string.h>

int main(void) {
    char name[] = "Mity";
    printf("名前: %s\n", name);
    printf("長さ: %zu\n", strlen(name));
    printf("配列サイズ: %zu\n", sizeof name);
    return 0;
}
実行結果OUTPUT
名前: Mity
長さ: 4
配列サイズ: 5

配列サイズが5なのは、4文字に終端の1バイトを加えるためです。日本語の文字数とバイト数は一致しない場合があります。

11

関数

関数の宣言では、戻り値の型、名前、引数の型を書きます。呼び出しより前にプロトタイプ宣言を置くと、定義を下へ分けられます。

合計を返す関数C
#include <stdio.h>

int calculate_total(int price, int count);

int main(void) {
    int total = calculate_total(500, 3);
    printf("合計は%d円です\n", total);
    return 0;
}

int calculate_total(int price, int count) {
    return price * count;
}
実行結果OUTPUT
合計は1500円です
関数を分けるコツ
  • 名前から役割が分かるようにする
  • 一つの関数へ一つの役割を持たせる
  • 入力・表示と計算を分ける
  • 結果は戻り値で返し、グローバル変数を増やさない
12

変数のスコープと寿命

波かっこの中で宣言した変数は、その範囲の外から使えません。必要な場所に近い位置で宣言すると、誤って変更される範囲を小さくできます。

ブロックスコープC
#include <stdio.h>

int main(void) {
    int total = 100;
    if (total > 0) {
        int tax = 10;
        printf("税込: %d\n", total + tax);
    }
    /* ここではtaxを使えない */
    return 0;
}
実行結果OUTPUT
税込: 110
PRACTICE

練習問題:最高点を求める

整数配列{68, 92, 75, 88}から最高点を探す関数find_maxを作り、「最高点: 92」と表示してください。関数には配列と要素数を渡します。

進め方 最初の要素を最高点の候補にし、2番目以降と順に比較します。完成後は全要素が同じ場合や負の数でも確認しましょう。
NEXT

次に学ぶこと

基礎を実行できたら、C言語の重要な仕組みをテーマ別に学びます。