第1章04 printf で迷路モドキの表示@イチからゲーム作りで覚えるC言語

ぷらんくちゃんがHello, World

ぷらんく ちゃん 寝起き

イチからゲーム作りで覚えるC言語
連載ページ一覧へ
1章05 エラーが出た時の対応
NEXT : 1章05 エラーが出た時の対応
1章03 初めてのプログラム、文字の表示 : PREV

この記事でやること

前回はMicrosoft社の Visual Studio で初めてC言語でソースコードを書いて、”hello, world” を表示するプログラムをビルドで作成するまですすめました。
今回は前回のソースコードがどんな内容だったのかを理解して、コードを変えてみて、簡単な迷路モドキを表示させるところまで行きたいと思います。
最初は内容は詳しくわからないけど、なんとなく動いているというところから始めて、徐々に理解していくというステップになるかと思いますが、一緒にがんばりましょー。(最初は覚えることが多くて特に大変です。)

この記事はゆる~くC言語でゲームを作りながらプログラミングを学ぶための連載記事です。シリーズものですので記事の一覧はこちらを参照してくださいね。

ソースコードの中身(おさらい)

前回、「hello, world」を表示するプログラムを作るために、こんなソースコードを書きました。

#include <stdio.h>
void main ()
{
 printf("hello, world\n");
}

簡単にそれぞれの行がなにやってるのかをお話したいと思います。あ、その前になのですが、ソースコードは、基本的には上から下のほうに実行されていきます。今回のようなシンプルなソースコードはとりあえず一番上から順に見ていけば、どんなプログラムになるのか、想像がつきやすいです。

一つ一つ読み込みながらCPUに命令を実行させることを逐次処理(ちくじしょり)と呼んだりします。

「#include <stdio.h>」とは?

まず1行目の「#include <stdio.h>」ですが、この行はいろんなC言語のソースコードの頭にでてくる、”おまじない”として有名です。いろんなC言語の解説でもとりあえずおまじないとして最初に書いてー、と書かれてることが多いです。
「#include」はインクルード文と呼ばれます。
「#include <stdio.h>」と書くことで「stdio.h」という、C言語側であらかじめ用意されたファイルで書いている、標準的な(画面などへの)入力出力の命令たちをこのソースコードファイルの中で使えるように読み込むという意味をもちます。具体的に今回のソースコードでは、この後登場する、 printf という命令が使えるようになります。
とりあえず、ファイルの最初に書いておけばOKくらいの認識でも構いません!後の方の章で必要になったとき詳しく説明するかと思います。

「void main ()」とは?

2行目の「void main ()」は main関数と呼ばれます。コンソールプログラムでは、プログラムはここから開始されます。
C言語の解説書によっては 「main()」とか「int main ()」 とか「int main( void )」とか「int main( int argc, char *argv[] )」なんて書いてあるかもですが、どれもちゃんと動きますし、どれも間違えというわけではないです。どれも main 関数でありプログラムがここからはじまるのも一緒です。

この行では main 関数を宣言 しており、この後の行で実際に main 関数の中身の命令を書いていく、という定義をしています。
詳細は後の章に譲るとし、まずは main関数を宣言&定義している ということ。main関数からコンソールプログラムが実行される、ということを覚えておけばOKです。

ちなみに、main関数をタイプミスで打ち間違えたりして一つもプロジェクトの中に存在しない状態だと、コンソールプログラムがスタートする場所がなくなってしまうので、ビルド時にエラーがでます。(プログラムが実行できないです)
この辺は具体的には次の記事で書こうと思います。

int main の書き方は C言語の仕様書(C11 N1570)には例として
int main( void )」、「int main ( int argc, char *argv[] )
の二つが挙げられています。ですのでどれが良いかと聞かれれば、一応上記2つがお勧めとなります。

「{」、「}」とは?

3行めの「{」は関数の中身など、命令のカタマリを書くときの最初に書きます。一つの前の行が main 関数のはじまりを書いていていて、次の行に「{」と書いてあるので、これは「ここから main 関数の中身をかくよ」という意味になります。こまかな一つ一つの役割は頭の片隅においておいて、最初のうちは、このあたりは丸暗記でも良いかと思います。
「{」は必ず「}」の記号で終わります。「}」は5行目に書いてありますね。
この記号で関数の始まりと終わりの範囲を表すことができます。

main関数のブロック

main関数のブロック

C言語だけではなく、いろいろなプログラミング言語で、関数等の開始と終了を表す記号として、「{」「}」の記号が良く使われます。関数等で順番に命令が実行されるカタマリはブロック構造と呼ばれます。
英語ではココの記号「{」「}」のことを brace と呼びます。

「printf」とは?

printf とは、(通常は)コンソールウィンドウ上に文字を出力するための関数(命令)の一つです。今回のプログラムを実行すると「hello, world」と文字が出たと思いますが、この関数が文字を出しているのです。

関数の呼び出し方

数学で下のような式をみたことがあるかと思います。

f(x) = x + 5

これは変数 x を与えてあげると、x + 5 という計算を行った結果を出す f という名前の関数です。
例えば x に 1 を入れると、f(1) = 1 + 5 = 6 という結果になります。
C言語でも関数の形はとても似ています。

C言語で関数を呼び出すときは以下のように呼び出します。後の章で関数の書き方はまた詳しく書くので、ここでは基本だけお話しときます。

関数名 ( 1個目の引数, 2個目の引数, 3個目の引数,… );

引数(ひきすう)とは、関数を呼び出すときに関数に渡してあげる数値や文字を渡すところです。関数によって引数で渡せる数やモノ(数字とか文字とか)が違います。引数がまったくない関数もあります。
引数と引数の間は 記号「,」(カンマ)で区切ります。
今回の printf はカンマで区切ったりしていないので、1個の引数を指定して呼び出ししていますね。
最後に「;」(セミコロンと呼びます)が書いてありますが、これは関数(命令)を呼び出す記載はここまで。という意味です。これを書き忘れるとエラーとなります。(そしてセミコロンの書き忘れはとても良くあることです・・!)
ついでに、引数がまったくない関数の呼び出し方もお話しておきます。

関数名 ( );

こんな感じで呼び出すことができます。「(」「)」の間に何も書かなければ(見やすさのためにスペースとかいれても大丈夫です)引数0個の関数を呼び出すことができます

記号「”」~「”」とは?

記号「”」~「”」は文字のカタマリを定義するときに使います。この文字のカタマリを文字列とよく呼びます。今回の printf でも使っています。

printf("hello, world\n");

オレンジ色で下線引いたところが文字列です。
printf 関数の1個目の引数が 「“hello, world\n”
ですので、今回は 「hello, world\n」 という文字列を表示せよ、という命令になります。

記号「,」カンマは関数を呼び出すときの引数の区切りとお話しましたが、「”」~「”」に囲まれた場所では、引数の区切りではなく、文字列の一部として扱われます。

最後の2文字「¥n」は「改行せよ」という特殊な文字を表します。「¥」と「n」の2文字が連続で書いてないと効果がでません。ここで「¥」のかわりに「\」(バックスラッシュと読みます)で文字が表示されていることがあるかもしれませんが、これは「¥」(日本の円の記号)と同じ意味、同じ文字です。海外のPC上では通常「¥」は「\」で表示されます

いくつか「\」と組み合わせた2文字で効果を発揮する特殊文字というものが存在するので必要に応じてお話しようと思いますが、特に重要なのはこの改行のための特殊文字です。コイツ(\n)は改行コードとよく呼ばれています。C言語だけでなくいろんなところで登場するので、覚えておくときっと役に立ちます。

ソースコードを書き換えて遊んでみる

ソースコードの解説が一通りおわったので、ソースコードの中身を書き換えて遊んでみましょう!printf は文字を表示する関数です。この中身を書き換えれば、別のメッセージを表示したりできます。

1つのprintf関数で日本語を2行表示してみる

通常のOS環境であれば、日本語もそのまま入力して表示できるかと思います。下に書いたコードのように、printfの中身を日本語で書いてみて、デバッグ(D)デバッグなしで開始(H)、もしくは、[Ctrl + F5] を押してみましょう。

#include <stdio.h>
void main ()
{
  printf("日本語も大丈夫!\nここから2行目。\n");
}

うまくいくとウィンドウが表示され結果が見えるはず。

printfで日本語を2行表示

printfで日本語を2行表示

実行するとこんな結果になりました。
「日本語も大丈夫!」の後に「\n」があり、コンソールに表示されるときここで改行が入ります。
その後、「ここから2行目」という文字列が表示され、その後に「\n」でさらに改行されて、プログラムが終了する、という流れです。

「続行するには何かキーを押してください・・・」はビルドの設定で、プログラム終了時にキー入力するように前の記事で設定したために表示されています。

複数のprintf関数呼び出しで日本語を表示してみる

今度は printf 関数を複数書いてみましょう。

#include <stdio.h>
void main ()
{
  printf("日本語も大丈夫!\nここから2行目。\n");
  printf("3行目だ!");
  printf("3行目の続き。\n");
}
複数のprintf関数で文字を表示

複数のprintf関数で文字を表示

main関数からプログラムがスタートし、上から順番に実行されていきます。

  1. 4行目のprintf関数で、「日本語も大丈夫!」表示→改行→「ここから2行目。」表示→改行となります。
  2. 次に5行目のprintf関数で「3行目だ!」が表示されます。
    ここのポイントは、一つ前の printf関数 で表示したテキストの最後の表示位置が記録され、続きの3行目から表示されることです。
    また、「3行目だ!」の末尾に改行コード(\n)を書いていませんので、改行はされません。このテキストの位置も記録され、6行目に続きます。
  3. 6行目のprintf関数で「3行目の続き。」が改行なしで表示されます。ここでmain関数のブロック(処理のカタマリ)はおしまいとなります。

順番に追っていけばそんなに難しくないですね。

printf関数を使った迷路の表示

簡単な迷路みたいなものを表示してみます。とりあえず今回は表示するだけなので、印刷して紙で遊ぶことくらいしかできないです。笑

#include <stdio.h>
void main()
{
  printf("あなたは身に覚えのない借金を背負い\n");
  printf("洞窟で財宝を探しています。\n");
  printf("財宝までつながってるのは1~3番のうち何番でしょう?\n");
  printf("*--+--+-----+---+----+---*\n");
  printf("|1 | 2|     |   |    |   |\n");
  printf("|  |     |    |   |  | | |\n");
  printf("|  +-----+----+ +-+  | | |\n");
  printf("|             |   +-++ | |\n");
  printf("+----+ -----+ | |   |  | |\n");
  printf("|  3 |      +-+-+ --+ ++ |\n");
  printf("|    | |  | |   |     |  |\n");
  printf("|   ++-++-+ | | +-----+ -+\n");
  printf("| --+   | | +-+ |        |\n");
  printf("|     |   |   |     財宝 |\n");
  printf("+-----+---+---+-+--------+\n");
}

結果、ちゃんと迷路が表示されました!

printf で財宝探しの迷路を表示

printf で財宝探しの迷路を表示

迷路の答えは・・・わかりましたでしょうか。笑
ぱっと見、ちゃんと道が空いているのかみえずらくて混乱するかもです。
単純に文字を表示する方法はこれで分かったかと思います。

あとがき

次の記事ではエラーを取り除く初歩的な見方を書いていこうと思います。
今回はここまで。お疲れさまでした。
あれっ、迷路に出口つくってない・・。
そしたらどれをえらんでも結局・・。

出口のない迷宮

出口のない迷宮

イチからゲーム作りで覚えるC言語
連載ページ一覧へ
1章05 エラーが出た時の対応
NEXT : 1章05 エラーが出た時の対応
1章03 初めてのプログラム、文字の表示 : PREV

非常に参考になったサイトさまや、参考文献など

ページの更新

ページの更新履歴

更新日更新内容
2018.6.21アイキャッチなどを修正