KID's World
 

おしながき
トップページ
プログラミング
研究
いんすぴ
色日記
ソフトウェア
KID's Worldの歴史
リンク
小出俊夫について


式とは何なのか

式の意味について考える

 

なんか物足りない...

 もうここまでで、文字の表示のしかたや計算のしかたなどは分かったと思います。main関数の中に実行する関数等を羅列すると、制御はmain関数の上から下へ流れていき、一つずつ順番に実行していきます。しかし、何か物足りないですねぇ。それだけでは、あまり役に立つプログラムは作れそうにありません。このいわゆる「制御の流れ」のようなものを変えることはできないのでしょうか。

 とまぁ、こう話を振ったということは「ある」ということです。C言語にはいくつかそういった制御の流れを変えるがあります。しかしこれを理解するには、ちょっとした予備知識が必要です。まずはこれらの文を理解するために、このページを完璧に理解してください。

 

式と文

 とは何か。式とはある値を持つもののことといってもいいでしょう。しかし何も新しい概念ではありません。「i = 0」も「printf("Hello!")」も実は式です。そして、この式の最後にセミコロン「;」をつけるとになります。つまり「i = 0;」や「printf("Hello!\n");」は文です。

 ただ、何か変に感じたことはありませんか? さっき式はある値を持つと言いましたね。ということは、「i = 0」という式全体が値を持つ、という事なのでしょうか? そう、実はこの式は値を持っています。その値は「0」。左辺のiに代入された値です。これを左辺値と言ったりします。という事は、こんなことも可能なんです。

#include <stdio.h>

main()
{
    int i1, i2, i3;

    i3 = i2 = (i1 = 10) + 10;

    printf("%d\n", i3);
}

 では、このプログラムを順に解読してみます。

  1. int型変数、i1,i2,i3を宣言。
  2. まず最初に「i1 = 10」が評価される。つまりi1には10が入る。
  3. 「i1 = 10」という式は10という値を持つ。
  4. その値(10)足す10がi2に代入される。つまりi2には20が入る。
  5. そしてその値(20)はi3に代入される。

 つまり画面には「20」という数値が表示されます。

 もうちょっと考えを深めてみると、こんな書き方もできることに気付くと思います。

#include <stdio.h>

main()
{
    int i1, i2, i3;

    printf("%d\n", i3 = i2 = i1 = 10);
}

 「i3 = i2 = i1 = 10」という式全体で10という値になるので、これもやはり画面に「10」という数値が表示されます。

 

式はなんでも値を持つ?

 さて、もうひとつ気になったことはありませんか。前に「printf("Hello!\n")」も式だと言いました。が、こんなのが値を持つと言うのでしょうか?

 これもやっぱり式なので値を持ちます。どういう値を持つのか、試してみればすぐ分かります。

#include <stdio.h>

main()
{
  printf("%d\n", printf("Hello!\n"));
}

 こういう書き方が可能だということは分かりますね? 「printf("Hello!\n")」は式だから、「10」や「20」と同じように考えてかまわないのです。実行結果は、

 
Hello!
7

となります。一行目の「Hello!」は、「printf("Hello!\n")」が表示したものです。そして次に「7」と表示されていますね。これが式「printf("Hello!\n")」の値です。正解を言ってしまうと、printf 関数は、表示した文字の数を式の値として持ちます。

 さて、もうちょっとこだわってみると、「printf("Hello!\n")」が「7」という数値になるということは、普段何気なく「printf("Hello!\n");」と書いているのは、表面上は「7;」と同じである、という事なのでしょうか。やっぱりこれもそういうことです。だから、

#include <stdio.h>

main()
{
    7;
}

これも文法上成り立ち、コンパイルできるのです。言うまでもないのですが、このプログラムは何もしない、やるだけ無駄なプログラムです。

 

ブロック(複文)で一つの文に見せ掛ける

 次回、制御の流れを変える文を説明する中で、「文を書く」場所があります。しかし文というからには「printf("Hello!\n");」等としかかけず、二つ以上のことをしたいときはどうしようもありません。そんなときに有効なのがブロックです。ブロックは「{」から「}」で成り立ち、その中にはいくつも文を書くことができますが、文法上は「{」から「}」までをひとつの文とみなすことができます。文を書くように言われたら、ブロックを使っていくつもの文を一つの文と見せ掛けることができます。

 main関数にも「{」や「}」がありましたが、これも同じです。ただしちょっと性質が違っていて、一つの文しか書かないときはブロックにしなくてもいい、というわけにはいきません。しかしmain関数のはじめのほうで変数の宣言ができたように、ブロックの最初でも変数が宣言できるので、性質は似ています。

#include <stdio.h>

main()
{
  int i = 10;

  {
    int j = 100;
    printf("%d %d\n", i, j);
  }
}

 ただしブロック内で宣言した変数は、ブロック内でしか使うことができません。既にある変数名で宣言することもできます。この場合は宣言したブロック内でだけその変数は新しく作られ、ブロックの外には干渉しません(混同するのであまりしないほうがいいのですが)。

#include <stdio.h>

main()
{
  int i = 10;

  {
    int i = 100;
    printf("%d\n", i);
    i = 1000;
  }

  printf("%d\n", i);
}

 実行結果は、

 
100
10

となります。結果の2行目が「1000」になっていないところに注目してください。つまりブロック内で新しく変数を作った場合は、それがブロック外に存在したとしても、いくら暴れたところでブロックの外には何の影響も無いのです。そのため、宣言のときに代入した「10」が、そのまま表示されたのです。

 ところで上の2つの例、わざと文の書く位置をずらしています。こうすると「ブロック内の文だ」という事が見てすぐに分かるからです。これを全部同じ位置に揃えてしまうと、見にくいプログラムになってしまいます。「{」が来たら右にインデントする習慣を付けておくとよいでしょう。

 

制御文を使いこなすために

 いよいよ次ページでは制御の流れを変える文を紹介します。これらの文のことを一般に制御文といいます。制御文の多くは条件を表す式を要求してきます。しかしその式はいたって簡単で、例えば「aがbより大きい」という条件を表す式は、「a>b」となります。この「>」のことを関係演算子といいます。以下に関係演算子の表を書きますので参考にしてください。

関係演算子
a<b aはbよりも小さい
a>b aはbよりも大きい
a<=b aはb以下
a>=b aはb以上
a==b aはbと等しい
a!=b aはbと等しくない

 これらも「式」ですので、何らかの値を持つことになります。その値は、条件が満たされたとき(真という)は1、満たされなかったとき(偽という)は0になります。

 そう考えると「a<b<c」という書き方はエラーにはなりませんが意味が違ってしまいます。この場合、まず「a<b」が評価され、その値(1か0)とcを比べることになります。もし数学上でいう「a<b<c」を評価したい場合は、論理演算子というものを使います。

論理演算子
a&&b aとbが真なら真、でなければ偽になる(「しかも」という意味になる)
a||b a,bのどちらかが真なら真、でなければ偽になる(「または」という意味になる)
!a 真偽が反転する(「…ではなかったら」という意味になる)

 つまり意味を分割させて、「aはbよりも小さくて、しかもbはcよりも小さい」と考え、
 a<b && b<c
とすると、数学上の「a<b<c」と同じ意味になり、うまく処理されることになります。ではこれらを踏まえた上で制御文をマスターしていきましょう。

 

まとめ。

  1. は値(左辺値)を持つ。
  2. 式の最後にセミコロン「;」をつけるとになる。
  3. 一つの文しか書けないところにはブロックを使って対処する。
  4. ブロックは「{」から「}」で成り立ち、先頭で変数を宣言できる。
  5. ブロック内で宣言した変数はブロック内でしか効かず、いくら暴れても外には影響が無い。
  6. ブロックを右にインデントして、見易いプログラムづくりに勤める。
  7. 条件を表すには、関係演算子論理演算子を使う。
  8. 条件が真のときは1、偽の時は0になる。

(1997/01/30, 1999/03/13 改)

[目次へ] [次へ]

 著作権は全て小出 俊夫にあります。KID's World © 1996-2003 Toshio Koide.

 対応ブラウザについて