C言語入門 3 (hello world解説)

  • by

今回取り組むこと

  1. プログラムにおける関数をなんとなく理解する
  2. 前回使ったプログラム(hello world)を理解する
  3. プログラムを変更してみる

前回のおさらい

前回の記事ではテキストエディタで作ったプログラムを、コマンドプロンプト上で
コンパイルをして、実行するところまで行きました。
最終的にコマンドプロンプト上に「Hello, World!」と表示されたのを確認しました。

0 Hello, World!

Hello, World! というフレーズは「文字を表示するテストに使われる代表」として非常に有名です。
例えば他のプログラミング言語環境を自分のコンピュータに構築したとき、
きちんと動くかどうかのテストとしてこの文言がよくつかわれます。
そのルーツはC言語のバイブルと言われる(出た当時は規格書として扱われるほどの権威)の書籍である
「プログラミング言語C(The C Programming Language)」からだと言われています。
著者のブライアン・カーニハンとデニス・リッチーはレジェンドとして扱われています。

1 関数について

関数という言葉は抽象的で、ときに多義的で理解しにくいですが、
プログラムでの数学でもごく基本的かつ一般的な概念であり、それゆえ尋常じゃないくらい頻出します。
ここを解説せずして、プログラミングを説明することは不可能だと考えられます。
(知っている方は読み飛ばすなり、間違いを指摘するなりしてください。)

関数とは、
入出力の関係を示すもの。機能。
と、私の辞書にはそう書いてあります。

数学的な定義まで含めると話がややこしくなる上に、
説明できなくなるのでイメージをつかむのが目的です。

関数のイメージ

まずFig. 1が基本となる画像になります。

Fig. 1 関数の概念

もちろんこれだけだとわかりにくいので、お肉で考えましょう。
お肉だいすき。(お肉の絵はいらすとやさんから引用しています)

Fig. 2 お肉と関数

生肉を関数という名前の箱にいれたら、焼肉がでてきました(Fig. 2)。
さて、この「関数という名前の箱」の中ではどんな操作が、入力に対しておこなわれたでしょうか?

Fig. 3 焼く関数

言わずもがな「焼く」という操作がおこなわれます。その結果が出力、すなわちこんがり肉となります。
こんなふうに関数は入力に対する操作ともとらえることができます。
もちろん肉に限らず魚でも野菜でも焼く操作をすると、焼かれたものが出来上がります。
ここでいう焼かれる前の生の素材を「入力」、焼くという操作を「関数」、
焼かれたあとのものを「出力」と呼びます。

この「焼く関数」ですが一度だけでなく、繰り返し使うこともできます。
こんがり肉をさらに焼くと、焦げますよね。
この場合、入力がこんがり肉、出力はコゲ肉です。

さて、もっと具体的に(まじめに?)表現するとFig. 4のようになります。

Fig. 4 関数の比較的真面目な表現と例

この関数は入力xに2をかけるというものです。
入出力の関係は

\[y=f(x)\]

で表されます。
xという入力を、fという関数に入れると2がかけられて、その値が出力yとなります。
プログラミング上ではこの入力を「引数(ひきすう)」、出力を「戻り値」と言います。
言葉の使い方としては、「~の関数に引数を渡す」「~の関数は〇〇という戻り値を返す」
といった感じです。(厳密なものでもないですけど…)

C言語における関数

C言語で関数を自分で作るときにも、入力と出力、そして入力に対しておこなう処理を記述します。
さらに加えて必要になるのが「型」の設定です。
例えば「焼く関数」を思い出してください。この焼く関数がグリルのように入り口の大きさが決められている場合、それより大きな具材(=入力)は入りません。また網を使って焼いている場合、網目よりも小さい具材は落ちてしまいます。もしくは焼くと危険なものがあるケースも考えられます。

関数において、入力(もしくは出力)するデータは、整数なのか、小数つきの数字なのか、文字なのか、その他か、といった素性を明らかにする必要があります。

それを踏まえた上でFig. 4の動作を再現したコードを見てみましょう。

int f(int x){
	int y;
	y = x * 2;
	return y;
}
Fig. 5 C言語の関数の具体例

int(イント)というのは整数を指しています。またFig. 5ではコードの中を色分けしています。
赤い部分が戻り値(出力)にかかわるところで、青が入力(引数)、緑が関数・処理と対応しております。

ここでは深く考えず、「入力に対して一定の出力を返すのが関数」「使う値(データ)がどういう型か書く必要がある」くらいに覚えて頂けるといいと思います。

2 プログラムの中身

#include<stdio.h>

int main(void){
	printf("Hello, world!");
	return 0;
}

プログラムの動作は、実行したら「Hello, world!」と表示する、というものでした。

1行目: #include<stdio.h>

以前の記事で「pathを通すこと」を「道具の場所」を教えることで例えました。
その例えに則れば、この文では「どの道具のセットを使うか」を宣言している部分です。
#include<stdio.h>を日本語に意訳すると、
「(コンパイラに対して、)path通した場所にstdio.hという道具
のセット があると思うからそれ使うよ!」と、なります。

実は書いたプログラム(ソースファイルと言います)を実行できるプログラムにする作業にはいくつか段階がありますが、本格的に翻訳する前に読み込む内容には先頭に#をつけます。予め使う道具のセットは使うことをあらかじめ教える必要があるのです。
したがって#includeというのは「あらかじめ使う道具のセットを宣言する」、という意味になります。

stdio.hというのは使う道具のセットの名前です。
stdioはStandard Input and Output(標準入出力)の略で、画面に文字を表示するだけでなく、
キーボードやマウスの値をとったり、テキストファイルをつくったり、読み込んだり、
する道具(関数)が集まっています。
道具のセットのことをヘッダーファイルといい、末尾に.hがついています。
(ヘッダーファイルは自分でも作れますがこの話は別にしましょう。)

ヘッダーファイル名を指定するとき、今回は<>を使いました。
これはpathを通してあるところを優先的に探すように指示しています。
初期設定のままであればC:\MinGW\includeの中(Fig. 1)を探します。

Fig. 1 C:\MinGW\include内にヘッダーファイルが格納されていることの確認

<>以外だと””(ダブルクォーテーション)で囲う表記があります。(例えば #include “hoge.h”)
この場合カレントディレクトリ(gcc コマンドを打つときにいる場所; 今だとC:\Users\(ユーザ名)\Cwork)
の中を優先的に探します。
なので<>は標準で入っているもの、””は自分で作ったもの、という使い分けが一般的です。

3行目: int main(void){

2行目は空白行です。あえてこういった空白を作ることで見やすくします。

行末に中カッコ{が浮いていますが、これは6行目の}とセットです。
C言語のプログラムではこの{}で囲まれた範囲を実行します。
関数のうちでもメインになる部分なので、メイン関数と言う、すごく特殊な関数です。

具体的には「とにかくこの部分を最初に実行するぞ!」という意味があります。
他に関数があってもとにかくメイン関数が最初に呼ばれます。
このメイン関数はCに限らずたいていのプログラミング言語にあり、
似たような機能を持っています。

メイン「関数」というからには入出力があるはずです!
入力は関数名(main)の後ろのカッコ内に答えがあります。何と書いてありますか?
→「void」: 空(から)、何もない
つまりは入力がないということです。
では出力はというと、型は関数名の前、つまりint(整数)で、値はreturn の後ろ、つまり0(ゼロ)!
この関数では入力もせず固定の値(=0)を出力することがわかります。

4行目: printf(“Hello, world”);

printfという関数に、”Hello, world!”という文字列を入力しています。
この関数、実は特殊な結構特殊な関数です。
(たいてい誰でもC言語教える時に初心者向けとしてにhelloworldをやりますが、
main関数やprintf関数というちょっと特殊なやつしか出てこないのでいつもモヤモヤします。)

とはいえども、機能自体は非常にシンプルです。引数の中身を画面に表示してくれます。
単純ながらパワフルな関数です。
この関数の使い方を説明するだけで記事が一つ書けてしまうほどです。(もしかしたら足りない)
ですが今回はここまでの説明にしておきましょう。

プログラムはエラー(文法の間違いなど)があるとコンパイルできませんが、
コンパイルされたプログラムが意図した通りに動かないことが多くあります。
それを確認するために頻繁に使います。

残り5,6行目

それぞれ前で述べた、main関数の戻り値とmain関数の終わりのカッコです。

3 プログラムの変更

ではコマンドプロンプト上でCworkフォルダに移動して「notepad he」まで打って、
「Tabキー」を押してみましょう。
そうすると自動的に「notepad hello.c」まで入力されたかと思います。こういった機能を補完機能といいます。たいていTabキーに割り当てられることが多いので覚えておくと便利です。
その状態でEnterキーを押すとテキストエディタが立ち上がります。

下のコードを見て前回と何が違うか探して変更して、実行してみましょう。

#include

int main(void){
	printf("Hello,\n world!");
	return 0;
}

実行するためには、まずテキストエディタ上で上書き保存(Ctrl+S)、コマンドプロンプト上で
コンパイル(gcc hello.c -o hello)をして、実行(hello と入力してEnter)します。

実行するとHello,の後ろで改行されたかと思います。
「\n」は改行文字と言ってその名前の通り、この文字を打てば改行されるという特殊な文字です。
プログラム上と普段使っている環境では文字の扱いも異なるので、面白いですね(こじつけ)。

まとめ

  • 関数のイメージの説明とC言語上での扱いについて
  • helloworldプログラムの解説
  • 表示文字列の変更(改行文字の追加)

というところまでやりました。特に重要なのが関数の概念ですね。
ここで全てを理解しようとすると無理があるので、
やっていくうちに理解できるように目指しましょう!

余談ですがプログラムの勉強はエラーを出してなんぼです。
見よう見まねでやって「あれ?」となるのが正解だと思っています。
型を他のものにしたらどうなるんだろう、mainのreturn 消したらどうなるんだろう、
行末の;消したらどうなるんだろう…ぜひなんでもやってみてください。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です