Cによるプログラミング入門2
プログラムの基本構造

 今回は、前回見たプログラムの説明をします。


 前回は、以下のように、プログラムhello.cを書いて、実行してみました。(ここで、文字はすべて半角英字であることに注意してください。\(円記号)は、もともとバックスラッシュですが、日本の多くの環境では、\(円記号)を使うのでそうします。)

#include <stdio.h>

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

 まず、1行目は「stdio.hというファイルの内容をここに持って来い」という意味です。stdio.hは、どこかに置いてあるファイルで、そこには、「標準的な入出力に必要な情報」(あとで使うprintfなどの情報)が入っているのです。このようなものを、インクルード文などといいます。一般に、「標準的な入出力」をするプログラムでは、はじめに、このインクルード文を書くのです。

 2行目は何も書いていない行です。これは、プログラムを見やすくするために入れたもので、あってもなくてもかまいません。Cのプログラムでは、(基本的には)改行はあってもなくても同じなのです。

 3行目、4行目、それと最後の行は連動しています。というのは、

Cでは、プログラムの中心部分を

int main(void)
{
    中身
}

などと書くことになっているのです。(実は、先頭のintは省略できます。また、丸カッコの中のvoidを省略することもあります。)
 また、中身の最後には、一般に、「return 0;」を入れることになっています。この意味はなかなか難しく入門10にいくまで説明できないのですが、最初は「おまじない」と思って気にしないようにしてくだい。

 この形の詳しい意味は、入門がもう少し進んでから説明します。とりあえず、プログラムの中心は、このように書くということを理解しておいてください。
 すると、このプログラムで本当に意味のある部分は、

    printf("hello, world\n");

だけということになります。これさえわかればよいのです。


 さて、一般に、Cでは、何かしてくれるものを関数といいます。数学でいう関数と同じ名前ですが、別物です。そして、hello.cに登場したprintfは、データを画面に出力する関数なのです。たとえば、文字列を画面に出力したい場合は、

    printf("文字列");

とするのです。
 hello.cのprintfの丸カッコの中身は、

    "hello, world\n"

ですね。文字列を扱うときは、「"」で囲むことになっています。つまり、「hello, world\n」という文字列が「"」で囲まれているわけです。したがって、「printf("hello, world\n");」は、「hello, world\n」の出力ということなのです。
 この文字列の中に、「\n」という不思議なものが見えますね。実は、これは「改行」という意味です。そのため、「hello, world」という文字列を出力したあとに改行されることになるのです。なっとくがいかない人は、hello.cで「\n」だけ削除して実行してみてください。最後の改行がなくなるはずです。
 ところで、printfのある行の最後には「;」とあります。これはprintfの一部ではありません。これは「この行(命令)はここで終わり」というほどの意味なのです。今の例の「printf("hello, world\n");」は、「printf("hello, world\n")」を実行して、この命令は終わりということなのです。

 整理すると、「hello.cは、大部分がルールにしたがって書かれていて、その実質的な内容はprintf("hello, world\n");だけ」ということになります。そして、それは、「hello, world」と出力して改行せよ、ということなのです。

 多少しっくりいかないところもあると思いますが、だいたいの仕組みをつかみ、「どういうコードを書けば、何が起こる」という形で理解していってください。ここで、コードとは、「プログラム全体またはその一部」を意味する言葉として使います。最初からすべてを理解することはできませんが、コードを書いていると、だんだんにいろいろわかってくるのです。


 今回の話がわかったかどうかは、次の問題ができるかどうかでわかります。

 問題:「こんにちは」と画面に出力してから改行し、さらに「お元気ですか?」と
     出力してからまた改行し、終了するプログラムを書いてください

さあ、どうでしょう。

 プログラムの基本形は説明してあります。また、「文字列の出力」はprintfでできるといいました。すると答は、次のようになるのではないでしょうか。

#include <stdio.h>

int main(void)
{
    printf("こんにちは\n");
    printf("お元気ですか?\n");
    return 0;
}

 このプログラムはhello2.cという名前にします。コンパイルして実行してみると次のようになります。

Fig.1 hello2.exeの実行画面

 どうやら、うまくいったようです。これが正解(のひとつ)なのです。
 上のプログラムを見て、何が何をしているかわかりますか?大部分は、基本的なルールにしたがって書いたコードで、実質的に意味があるのは、mainの中の2行のprintfだけですね。printfを2回使うことで、2行出力しているのです。もう一度、よく考えてみてください。

 しかし、実は、同じ仕事をするプログラムを、次のように書くこともできます。

#include <stdio.h>

int main(void)
{
    printf("こんにちは\nお元気ですか?\n");
    return 0;
}

 「\n」は出力における改行を表わすのでした。したがって、上のように文字列を1行で書いても、出力は「\n」のところで改行されるのです。これでも、実行すれば、hello2.cのときと同様になるので、これも正解です。


 次に進む前に、いくつかコメントをしておきます。
 まず、Cでは、意味のあるものの途中でなければ、空白を入れても入れなくてもよいことになっています。(ただし、日本語の空白、つまり全角の空白は、「空白」ではなく「文字」として扱われます。)たとえば、printfの前の空白は、インデント(字下げ)などとよばれるもので、コンピュータへの命令としては意味はありません。これは、見やすくするために入れたものなのです。プログラムの実行に関しては、あってもなくても同じです。
 また、Cでは、改行も空白の一種と考えられるので、改行も自由に入れたり、あるいは取ったりすることもできるのです。つまり、たとえば、上のプログラムを

#include <stdio.h>
int main(void){  printf("こんにちは\nお元気ですか?\n");  }

と書いても、

#include <stdio.h>

int main(void)
{


printf("こんにちは\nお元気ですか?\n"


  );
    return 0;}

と書いてもよいのです。特に、下の方の形で、

printf("こんにちは\nお元気ですか?\n"


  );

は、わざといやらしい書き方をしました。このようなことをしてもよいのです。
 しかし、むやみに改行を入れたものや、極端に空白の少ないものは、読みづらいと思います。そこで、一般には、インデントをうまく使い、見やすいプログラムを書くことが推奨されるのです。

 もちろん、改行を含む空白を、意味のあるかたまりの中に入れることはできません。たとえば、printfはひとつの関数の名前ですから、空白を使って、途中で切ってしまうことはできないのです。つまり、たとえば、

pri ntf("こんにちは\nお元気ですか?\n"); 

とすれば、エラーになります。
 また、「"」で囲まれた文字列を文字列リテラルなどというのですが、文字列リテラルの途中で改行を入れることはできません。そういうものなのです。しかし、空白(改行も空白です。くどいですね)で分けられた文字列リテラルは、自動的につなげられるということになっています。この性質を利用すると、hello2.cを

#include <stdio.h>

int main(void)
{
    printf("こんにちは\n"
            "お元気ですか?\n");
    return 0;
}

のように書き直してもよいのです。printfの丸カッコの中には、「"こんにちは\n"」という文字列リテラルと「 "お元気ですか?\n"」という文字列リテラルがあります。これらの間には、空白しかありませんが、空白は無視され、2つの文字列リテラルは1つに結び付けられるのでした。その結果、「こんにちは\nお元気ですか?\n」を出力するのと同じことになるのです。

 今回はこの辺にしましょう。

課題2


C入門目次

前のページ  後のページ