前回の授業ではGCCコンパイラをインストールし、一番簡単なhello worldサンプルを作成しました。今回の授業ではこのサンプルを解説していきます。まずコードは下記の通りです。
#include <stdio.h>
int main()
{
printf("hello, world\n");
return 0;
}
Code language: Arduino (arduino)
コードは非常にシンプルで、1行の文字を出力するだけの機能です。
次に上から下へ、1行ずつコードを解析します。
1. #include <stdio.h>
前回の授業でプリプロセスについて簡単に触れましたが、この最初のコードがプリプロセス命令です。どこから判断するか?先頭の#記号が目印です。
#:プリプロセス命令のマーカー。プリプロセッサに渡して処理され、コンパイルの最初の工程で実行されます。
include:ヘッダーファイルを読み込むキーワード。指定したファイル内のコードを現在のプログラムにコピーする役割があります。
<stdio.h>:標準入出力ヘッダーファイル(standard input output)。画面への出力、キーボードからの入力など入出力関数がまとめて定義されており、下で使用するprintf関数はこのファイル内に定義されています。
厳密に言うとプリプロセスはC言語自体の文法に含まれません。C言語のプリプロセスはC言語のコア文法の一部ではない、コンパイラが本コンパイルの前に独立して実行する工程です。コンパイル全体の流れの一部ですが、C言語本来の文法・意味体系に属さない処理となります。
簡単に説明すると、独立したプリプロセスプログラムが文字置換を実行します。例えば#include <stdio.h>はstdio.hの中身すべてをこの行にコピーし、元の1行ごと置き換えます。仮にstdio.hの内容がAAAAAAAAAだったとします。
するとコンパイラに渡される段階で、コードは以下のようになります。
AAAAAAAAA
int main()
{
printf("hello, world\n");
return 0;
}
Code language: Arduino (arduino)
もちろんこれは仮の話で、実際のヘッダーファイルは複雑な内容になっています。興味のある方は実際にファイルを開いて確認してみてください。
このヘッダーファイルはPC内に保存されており、OSによって保存パスが異なります。
Linux/Unixシステム:通常 /usr/include/stdio.h に配置
Windows (Visual Studio):VC/include/stdio.h に配置
macOS (Xcode):/Applications/Xcode.app/.../usr/include/stdio.h に配置
各自PC内のファイル検索ツールで、実際の配置場所を探してみましょう。
これでプリコンパイルについて基礎的な理解ができたでしょうか?
もし#include <stdio.h>の行を削除すると、コンパイラはprintfを認識できずエラーを出力します。実際にこの行を消し、gccでコンパイルして動作を確認してみてください。

再度コンパイルを実行するとエラーメッセージが表示されます

2. int main()
main = C言語のプログラムエントリーポイント関数
- どんなCプログラムも実行時、OSが自動的に
main関数から処理を開始します。プログラムにはmainが一つだけ存在しなければならない int:関数の戻り値型を表し、整数(integer)を意味します。():これが関数であることを示す記号。括弧内に引数を記述可能、空括弧は引数なしを意味します。
このmainの記法は後世の多くのプログラミング言語に継承されています。exeファイルをダブルクリックする、またはコマンドラインから実行コマンド(helloなど)を打つと、OSが自動的にmain関数を呼び出してプログラムが起動します。
先頭のintは関数の戻り値型で、今後自作関数を定義する際にすべて記載する必要があります。後の講義で詳しく解説します。
丸括弧()は関数が受け取る引数の型を宣言する箇所です。今回は空なので引数を受け取らない設定です。引数を受け取る書き方は以下の通りです。
int main(int argc, char *argv[])Code language: CSS (css)
こちらはint型と文字列配列の2つの引数を受け取る記法で、詳細は後の授業で説明します。
main関数の引数はOSから渡されます。ではこの引数はどこから取得されるのでしょう?
コマンドラインツールのpingコマンドを使ったことがある方も多いでしょう。例えばping 12.36.4.xxxで通信確認をする場合、pingがping.exeプログラム、後ろのIPアドレス12.36.4.xxxがping.exeのmainに渡される引数となります。
同様にhelloプログラムをコマンドラインでhello abcと実行した場合、abcが引数として渡されます。main後ろの丸括弧内の変数は、このようにユーザーが入力しOSから転送された値を受け取る役割です。
まとめて覚えておきましょう:mainはプログラム唯一の実行開始点、1つだけ定義しOSによって呼び出され、コマンドライン入力の値はOS経由でmainに渡されます。
3. { } 波括弧
関数本体の境界を定義します。{が関数処理開始、}が終了を表し、関数内の全コードを2つの括弧の間に記述します。
4. printf("hello, world\n");
printf:print formatの略、フォーマット出力関数。コンソールに文字を出力する機能です。- 二重引用符
" ":文字列定数を囲む記号、中に出力したいテキストを記載します。 \n:エスケープシーケンス、改行文字。文字出力後自動的に次の行へ移動します。;:C言語の文終了マーカー。実行可能な1文ごと末尾に記述しないとコンパイルエラーが発生します。
関数名末尾のfはフォーマット出力を意味し、後の講義で深く解説します。今は単純に「hello, world\nという文字をコンソールに表示し、\nで自動改行する」と理解してください。
5. return 0;
return:main関数に整数を返却し、現在実行中の関数を終了させます。なぜreturnが必要か?mainの先頭にintと戻り値型を宣言しているため、関数内で整数を返す必要があるからです。0:業界共通の規約で、プログラムが正常にエラーなく終了したことを意味し、OSに実行結果を通知します。- 0を返却 = プログラム正常終了
- 0以外の数字(例:
return 1;)= プログラム異常終了
最新のC規格ではmain末尾の
return 0;を省略可能で、コンパイラが自動補完します。ただ初心者は規則通り記載することを推奨します。