4.演算子と結果
 5.1 Cの演算子のいろいろ
 これまでに,演算子と名の付く記号をいくつか紹介しました.以下に列挙してみましょう.

 ・算術演算子
  +  −  *  /  %
 ・代入演算子
  =
 ・比較演算子
  >  <  ==  >=  <=  !=
 ・論理演算子
  &&  ||  !
 ・その他   ( )  ,  .   ー>   <>   [ ]   &   |   〜  ...

 この節のタイトルは「すべての演算子は結果を返す」になっています.算術演算子が結果を返すというのは,いうまでもないですが,でも,「その他の演算子の結果とは???」ということになると思います.
ここでは,多くの演算子のうち,とりあえず,プログラム作成時に,これだけは,ぜひ,知ってほしいと思う知識だけを紹介します.


 5.2 算術演算子と演算結果
 では,まず最初に算術演算子からいってみましょう.
次のプログラムの実行結果は,予測できますよね.ただ単に,変数aとbに代入された値の和,差,積,商,剰余を表示しているだけです.
言い換えれば,算術演算子の演算結果を表示しているだけです. ただ,この場合,演算結果を変数に代入していないので,結果はその場限りで消失します.

 プログラム例 5.2.1  実行結果
  #include <stdio.h>
  void main(void){
      int a, b;

      a=10;
      b=2;
      printf("%d\n", a + b);
      printf("%d\n", a - b);
      printf("%d\n", a * b);
      printf("%d\n", a / b);
      printf("%d\n", a % b);
  }
  12
  8
  20
  5
  1
  


 5.3 代入演算子の演算結果
 次に,代入演算子の場合について考えてみましょう.
次のプログラムのソースコードと実行結果とを比べてみてください..
理解できますか
何となく,感覚的にわかるような気が...でも,なんかちょっと変....

 プログラム例 5.3.1  実行結果
  #include <stdio.h>
  void main(void){
      int a, b, c;

      a=6;
      printf("1) %d \n", a);
      printf("2) %d \n", b = a);
      printf("3) %d \n", c = b = a);
      printf("4) %d \n", c = b = a = 10);
  }
  
  1) 6
  2) 6
  3) 6
  4) 10
  

 結果は,3つのprint()文が,6を表示し,4つ目のprintf()文が10を表示します.
まず,a=6で,変数aには,6が代入(記憶)されます.1つ目のprintf()は説明の必要はありませんね.そうです,変数aの内容を表示させるためのものです.
 しかし,次の2つの文は,変数bの内容や変数cの内容を表示させているのではありません.
   printf("%d\n",b=a);
   printf("%d\n",c=b=a);
 これらは,b=aの結果やc=b=aの結果,すなわち,代入演算の演算結果を表示させているのです.これは,2数の和を表示するとき,
   printf("%d",x+y)
と書くのと同じことです.(これもxやyの値を表示させているのではなく,x+yという演算の結果を表示させています)
  b=aと書くと,aの内容がbに代入されます.この時,(=)演算子は,結果として,bに代入された値を返すように作られているのです.
 したがって,2つめのprintf()は,b=aの演算結果6を表示します.言い換えれば,「b=aの演算を実行すると,結果としてbに代入された値を返す」ということになります.
 したがって,次の文の c=b=a の表現は,cでb=aの演算結果を受け取っていることになります.(この場合のcは,z=x+yのzのような役割をします)b=aの演算結果は,6ですからcには6が入ります.また,3つめのprintf()は,c=bの演算結果を表示しますから6を表示します.
 このことを応用すれば,1つの文で,複数の変数に同じ値を代入することができるということになります.すでに,どこかで見たことがあるかもしれませんが,例えば
   z=y=x=...=b=a=0;
のように書けば,=で結ばれたすべての変数に0が代入されます.


 5.4 比較演算子の演算結果
 次に,比較演算子の演算結果について,説明しましょう.「代入演算子」について理解できたのなら,簡単な説明で理解できると思います.実行結果をみれば,わかるように,比較演算子の演算結果は[1]または,[0]です.では,どのような,場合に0が返され,どのような場合に1が返されるのでしょうか.ソースコードを注意深く眺めてみてください.

 プログラム例 5.4.1  実行結果
  #include <stdio.h>
  void main(void){
      int a, b;

      a = 4;  b = 10;
      printf("1) %d \n", a > b);
      printf("2) %d \n", a >= b);
      printf("3) %d \n", a == b);
      printf("4) %d \n", a <= b);
      printf("5) %d \n", a < b);
      printf("6) %d \n", a != b);
  }
  
  1) 0
  2) 0
  3) 0
  4) 1
  5) 1
  6) 1
  





 このプログラムでは,比較演算子の結果を表示させる前に,
   a=4; b=10;
が実行されます.
したがって,
  1) a>b
  2) a>=b
  3) a==b
の3つの比較は成立しません.
しかし,
  4) a<=b
  5) a<b
  6) a!=b
の3つは,成立します.
ということは,比較演算子の演算結果とは,
  比較が成立するなら「1」を返す.
  比較が成立しないなら「0」を返す.
ということになります.
ここで,特に,意識してほしいのは,比較演算子の演算結果が数値で返されるということです.




 5.5 論理演算子の演算結果
 次に,論理演算子の演算結果について,みてみましょう。
a=3,b=4,c=10,d=20ですから,論理演算の成立,不成立は次のようになります.
   1)a<b で,かつ c<d     成立する.
   2)a>b で,かつ c<d     成立しない.
   3)a<b か,または c>d    成立する.
   4)a>b か,または c>d    成立しない.
以上のことに注意して,プログラムの実行結果をみてみると次のようなことがわかります.
比較演算子と同様,式が
    成立すれば   1
    成立しなければ 0
となります.
この場合も比較演算子の場合と同じく,結果が1または0の数値として返されることに注意してください


 プログラム例 5.5.1  実行結果
#include <stdio.h>
void main(void){
  int a, b;
  int a,b,c,d; 

  a=3; b=4; c=10; d=20;  
  printf(" a=%d b=%d c=%d d=%dの時\n", a, b, c, d);
  printf("1) a<b かつ c<d  = %d\n", a<b && c<d);
  printf("2) a>b かつ c<d  = %d\n", a>b && c<d);
  printf("3) a<b または c>d= %d\n", a<b || c>d);
  printf("4) a>b または c>d= %d\n", a>b || c>d);
}
  
 a=3 b=4 c=10 d=20の時
 1)a<b かつ c<d  = 1
 2)a>b かつ c<d  = 0
 3)a<b または c>d = 1
 4)a>b または c>d = 0




ついでに,論理否定演算子(!)の効果も見てみましょう.プログラム例5.5.1を書き換えてみます.
すべての結果が反転していることがわかりますね.

 プログラム例 5.5.2  実行結果
#include <stdio.h>
void main(void){
  int a, b;
  int a,b,c,d; 

  a=3; b=4; c=10; d=20;  
  printf(" a=%d b=%d c=%d d=%dの時\n", a, b, c, d);
  printf("1)a<b && c<dの否定= %d\n",!(a<b && c<d));
  printf("2)a>b && c<dの否定= %d\n",!(a>b && c<d));
  printf("3)a<b || c>dの否定= %d\n",!(a<b || c>d));
  printf("4)a>b || c>dの否定= %d\n",!(a>b || c>d));
}
  
 a=3 b=4 c=10 d=20の時
 1)a<b && c<dの否定= 0
 2)a>b && c<dの否定= 1
 3)a<b || c>dの否定= 0
 4)a>b || c>dの否定= 1  




 5.6 制御文の条件表現式
流れ制御文の書き方を復習してみましょう. 制御文の構造は次のような形をしていました.
   if(条件式){
     条件成立時に実行する内容;
   }

   while(条件式){
     条件成立時に実行する内容;
   }
ここで,条件式は,比較演算子や論理演算子を含む式で表現してきました.

 ここで,紹介したように比較演算子や論理演算子などの条件式は1または0の値を返します.条件が成立するときは1,そうでなければ0でした.ということは,条件式の代わりに1や0の定数,あるいは,0または1を返す式を書いてもてもよいということになります.
 以下のプログラムは,あまり意味のあるプログラムではありませんが,このようなことが実際可能だということを説明するためのプログラムです.

 プログラム例 5.6.1  実行結果
#include <stdio.h>
void main(void){
  int a;

  if(1){
      printf("1)条件式が定数1のとき\n");
  }

  if(0){
      printf("2)条件式が定数0のとき\n");
  }

  a=1;
  if(a){
      printf("3)条件式aが1のとき\n");
  }

  a=0;
  if(a){
      printf("4)条件式aが0のとき\n");
  }
}
 1)条件式が定数1のとき
 3)条件式aが1のとき




 while()文の条件式に定数「1」を書き込めば,ループ継続条件は常に「成立」ということになり.永久に止まらないループとなります.これが,よく話題になる「無限ループ」です.


 プログラム例 5.6.2  実行結果
#include <stdio.h>
void main(void){

  while(0){
      printf("1)条件式が定数0のとき\n");
  }

  while(1){
      printf("2)条件式が定数1のとき\n");
  }
}
 2)条件式が定数1のとき
 2)条件式が定数1のとき
 2)条件式が定数1のとき
 2)条件式が定数1のとき
 2)条件式が定数1のとき
 2)条件式が定数1のとき
 2)条件式が定数1のとき
 2)条件式が定数1のとき
 2)条件式が定数1のとき
 2)条件式が定数1のとき
 2)条件式が定数1のとき
 2)条件式が定数1のとき




 次の例は,条件式に比較演算子や論理演算子を使わず,ループの実行回数を制限する例です.
もちろん,ループの継続条件は,変数xの値で決まります.xの値が「0」になれば,ループ継続条件が不成立とみなされ計算の実行を停止します.
ここで,注してほしいのは,これまで,1なら条件成立と説明してきましたが,実は「( )中の値が0以外の値なら条件成立」ということです.これは,プログラムを作成する上でとても大切な知識です.


 プログラム例 5.6.3  実行結果
  #include <stdio.h>
  void main(void){
    int x, y;

    printf ("   x     y\n");
    x = 5;
    while(x){
        y = x * x + 2 * x + 3; 
        printf("%5d %5d\n", x, y);
        x--;
    }
  }
   x     y
    5    38
    4    27
    3    18
    2    11
    1     6




 5.7 if(a==b){ } を if(a=b){ } と書き間違えても...
 いま,つぎのように,配列aに代入された数値のうち2が何番目の配列要素に記憶されているかチェックするプログラムを作成したとしましょう.
   int a[5]={ 3, 7, 8, 2, 6};
もちろん.常識的には次のようなプログラムを書きます.if( )の条件式の表現に注意してください.


 プログラム例 5.7.1  実行結果
  #include <stdio.h>
  void main(void){
    int a[5]={ 3, 7, 8, 2, 6};
    int i;

    for(i=0; i<5; i++){
      if(a[i] == 2){
        printf("数値2は%d番目の要素の中です.\n",i);
      }
    }
  }
数値2は3番目の要素の中です.


 では,if()の条件式を書き間違えて,(==)を(=)と書いたとしましょう.これまでの説明で理解できると思いますが,条件式はa=2,したっがて,代入演算の結果は2,これは,if()文の条件成立と同じ事です.ご覧のとおりの実行結果となります.
Cのコンパイラーは,これを「間違いでは?」と指摘してくれません.しかも,これは,初心者のよく間違えるポイントの1つです.注意しましょう!


 プログラム例 5.7.2  実行結果
  #include <stdio.h>
  void main(void){
    int a[5]={ 3, 7, 8, 2, 6};
    int i;

    for(i = 0; i < 5; i++){
      if(a[i] = 2){
        printf("数値2は%d番目の要素の中です.\n",i);
      }
    }
  }
数値2は0番目の要素の中です.
数値2は1番目の要素の中です.
数値2は2番目の要素の中です.
数値2は3番目の要素の中です.
数値2は4番目の要素の中です.