02 関数と main 関数・コマンドライン引数

プログラムは処理を 関数 という部品に分けて組み立てる。C言語では実行が必ず main 関数から始まり、main は実行時に外部から コマンドライン引数argc / argv で受け取れる。2級ではユーザー定義関数の3パターン(戻り値・引数の有無)と、argcargv の中身がよく問われる。

✅ この章のゴール:① ユーザー定義関数を「戻り値あり/なし・引数あり/なし」で書き分けられる ② 関数を使うメリットを説明できる ③ mainargc(プログラム名を含む個数)・argvargv[0]=プログラム名、argv[argc]NULL)を正しく読める。

02-1 ユーザー定義関数とは

関数は、いくつかの処理を ひとまとめにした部品 である。特定のタスクを行うコードを関数に分けておくと、同じ処理を使い回せて、修正やテストもしやすくなる。

関数のメリット

メリット内容
再利用性同じ処理を複数箇所で使い回せる。
読みやすさプログラム全体を小さな部品に分けることで理解しやすくなる。
メンテナンス性修正が必要なとき、その関数を直すだけで済む。
テストの容易さ関数単位で動作を確認できる。

関数の基本構造

戻り値の型 関数名(引数リスト)
{
    /* 処理内容 */
    return 戻り値;
}

02-2 関数の3パターン

関数は「戻り値の有無」と「引数の有無」の組み合わせで書き分ける。戻り値が無い関数は型を void にする。

例1:戻り値があり、引数を取る関数

#include <stdio.h>

int add(int a, int b)
{
    return a + b;
}

int main(void)
{
    int result;

    result = add(3, 5);          /* result に 8 が格納される */
    printf("%d¥n", result);
    return 0;
}

例2:戻り値がなく、引数も取らない関数

void printHello(void)
{
    printf("Hello, World!¥n");
}

呼び出しは printHello(); とする。戻り値が無いので void、引数も無いので (void) と書く。

例3:戻り値がなく、引数がある関数

void printNumber(int num)
{
    printf("Number: %d¥n", num);
}

呼び出しは printNumber(42);。これで Number: 42 が出力される。

void は「型が無い/値を返さない」という意味。void 関数は値を返さないので、x = printHello(); のように戻り値を受け取ることはできない。

02-3 main 関数の構造

main 関数は C プログラムの エントリーポイント(入口)である。プログラムの実行は必ず main から始まる。

int main(int argc, char *argv[])
{
    /* 処理内容 */
    return 0;
}
⚠ 引数を使わないときは int main(void) と書く。コマンドライン引数を受け取りたいときだけ int main(int argc, char *argv[]) の形にする。

02-4 コマンドライン引数(argc と argv)

プログラム名のうしろに付けて渡す値を コマンドライン引数 という。main はこれを argcargv で受け取る。

名前意味
argc引数の 個数プログラム名を含む。最小値は 1(プログラム名のみ)。
argv[0]プログラム名
argv[1] 以降渡されたコマンドライン引数(文字列)。
argv[argc]配列の末尾を示す NULL

例:./example -size 1024 input.csv

次のように実行すると、各値は下表のようになる。

要素中身
argc4
argv[0]"./example"(プログラム名)
argv[1]"-size"
argv[2]"1024"
argv[3]"input.csv"
argv[4]NULL
argcプログラム名を1個として数える。だから「引数を2つ渡した」なら argc3
argv[0] は必ず プログラム名。実際の引数は argv[1] から。
argv[argc](最後の要素)には、引数の末尾を示す NULL が入る。

02-5 OSごとの実行形式とコンパイル

コンパイルしてできる実行ファイルの「呼び方」は OS によって違う。

OS実行のしかた
Windows拡張子 .exe を付けて実行する。example.exe
Linux / Unix / macOS拡張子は不要。カレントディレクトリの実行ファイルは先頭に ./ を付ける。./example

example.c の例

#include <stdio.h>

int main(int argc, char *argv[])
{
    if (argc < 3) {
        printf("Usage: example.exe <arg1> <arg2>¥n");
        return 1;
    }
    printf("Arg1: %s¥n", argv[1]);
    printf("Arg2: %s¥n", argv[2]);
    return 0;
}

この例では、引数が足りない(argc < 3、つまり引数が2つ未満)ときに使い方(Usage)を表示して return 1; で終了している。

コンパイルと実行(Windows)

Windows 環境では cl.exe(Microsoft の C コンパイラ)でコンパイルする。

cl.exe example.c

これで example.exe という実行ファイルが生成される。引数を渡して実行すると:

example.exe hello world

出力結果:

Arg1: hello
Arg2: world
⚠ 戻り値の return 1; は「エラーで終わった」ことを OS に伝える合図。正常終了は return 0;。引数チェックに失敗したときに 0 以外を返すのが定石。

02-6 📝 過去問で確認

過去問(関数・main関数)— まず自分で解いてみよう
関数・main関数の過去問 問題①
問題 ①
関数・main関数の過去問 問題②
問題 ②
解説を表示
関数・main関数の過去問 解説
解説

02-7 まとめ


02-8 理解度チェック

Q1. ./example -size 1024 input.csv を実行したとき、argc の値はどれか。

解説を表示

正解:エ(4)

argcプログラム名を含む引数の個数。argv[0]="./example"argv[1]="-size"argv[2]="1024"argv[3]="input.csv" の4個なので argc は 4。

Q2. コマンドライン引数の argv[0] に入っているものはどれか。

解説を表示

正解:イ(プログラム名)

argv[0] には必ず プログラム名が入る。実際に渡したコマンドライン引数は argv[1] 以降。引数の個数は argc

Q3. argv[argc](配列の最後の要素)に格納されているものはどれか。

解説を表示

正解:ウ(NULL)

argv の末尾、すなわち argv[argc] には、コマンドライン引数の末尾を示す NULL が格納される。

Q4. 戻り値を返さない関数を定義するとき、戻り値の型に書くものはどれか。

解説を表示

正解:ウ(void)

値を返さない関数は戻り値の型を void にする(例:void printHello(void))。void 関数の戻り値を変数で受け取ることはできない。

Q5. 次の関数 add について、add(3, 5) の戻り値はどれか。

int add(int a, int b)
{
    return a + b;
}
解説を表示

正解:イ(8)

adda + b を返す関数。a=3b=5 なので戻り値は 8。

Q6. 次のプログラムを ./program hello world として実行したとき、標準出力に表示されるものはどれか。

#include <stdio.h>

int main(int argc, char *argv[])
{
    if (argc != 3) {
        printf("Usage: ./program <arg1> <arg2>¥n");
        return 1;
    }
    printf("Arg1: %s¥n", argv[1]);
    printf("Arg2: %s¥n", argv[2]);
    return 0;
}
解説を表示

正解:ウ(Arg1: hello / Arg2: world)

./program hello world では argc が 3 なので if (argc != 3) は成立せず、Usage は表示されない。argv[1]="hello"argv[2]="world" なので、Arg1: helloArg2: world が(それぞれ改行付きで)出力される。argv[0] がプログラム名である点に注意。

Q7. 上の ./program を引数なし(./program だけ)で実行したとき、表示されるものはどれか。

解説を表示

正解:ア(Usage 行)

引数なしで実行すると argc は 1(プログラム名のみ)。argc != 3 が成立するので、Usage: ./program <arg1> <arg2> を表示して return 1; で終了する。