2. C言語の基本 その2

 

2.3 流れの制御

 

 C言語にはif()やfor()をはじめいくつかの制御構造を表す文があります。これらの動作は互いいにオーバラップしていて、どれを選んで使えばいいのか迷います。そこで簡単な例をあげてその使い分けと、あわせてC言語特有の条件式の書き方などをまとめてみます。

 

2.3.1 基本はif文

 どの言語でも同様ですが、制御構造の基本はif文でしょう。C言語のif文、if()みてみましょう。リストtest7_1.cでは文字コードの並び順を利用してキー入力された数字と文字とを区別します。getchar()はキーボードから入力された文字コードを返す関数です。

リストtest7_1.c

#include<stdio.h>

 

main()

{

int x;

x = getchar();

if(x <= '9'){

printf("suuji\n");

}

if('A' <= x){

printf("moji\n");

}

}

 

 

よく似た例のプログラムをもう1つ示します。

 

リスト

/*   if00.c */

/*数字を入力し正の数なら”+”、負の数なら”−”、0ならば”0”*/

/*を表示するプログラム                     */

main()

{

    int a;

    printf("数を入力して下さい-->");

    scanf("%d",&a);

    if(a< 0)

        printf("%d --> '-'\n",a);

    if(a==0)

        printf("%d --> '0'\n",a);

    if(a> 0)

        printf("%d --> '+'\n",a);

}

 

 

 

[基本事項1 if else]--------------------------------------------------------------------------------------------------

◆if else      

    if ( 条件式 ) 

      文1    

    [else     

      文2]    

 

・条件式が真と評価されたら文1が実行されます。      

・条件式が偽と評価されれば文2が実行されます。      

・真は式の値が0以外、偽は式の値が0のことをさします。

・elseと文2は無くてもかまいません。

-------------------------------------------------------------------------------------------------------------------------------------

C言語のif文の構造は[基本事項1]の様に決められています。大切なことは、条件式の制限が無いことです。つまり式ならどんなものでも、たとえば 1、a=1、a==1、a=func(b)、f=fopen(...)... 等なんでもかまいません。if(1)とすれば常に成立するif()が書けます。このことはwhile()の条件式、for()の条件式でも同様です。

 

2.3.2 while文

 if文での分岐先を条件判断よりも前にもっていくと「繰り返し」が可能になります。これをwhile文と呼びます。リストtest7_3.cのように一番最初に試した abc を表示するプログラムの中身をwhileで覆うと連続してabcを表示し続けるプログラムになります。(注意:このプログラムは終了しません、ウィンドウ右上の[×]ボタンで強制終了させてください。)

 

リストtest7_3.c

#include<stdio.h>

main()

{

while(1){

printf("abc");

}

}

 

 

リストtest7_3.cは実用的ではありません。通常は繰り返しから抜け出す処理が必要です。1から10までの数を表示する場合を試してみます。変数に最初に1を設定しwhileの中身を繰り返す毎にその数を増やすようにします。そしてその数が10を越えれば繰り返しをやめるような条件式を用意します。

 

リストtest7_4.c
#include<stdio.h>
main()
{
int x;
x = 1;
while(x < 11){
printf("%d \n", x);
x = x + 1;
}
}
 
実行結果

1
2
3
4
5
6
7
8
9
10

2.3.3 for文

 リストtest7_4.cで行われた 変数の初期値設定、条件判断、繰り返し毎の増減 は回数を決めて繰り返しの処理を行う場合には必ず必要になります。そこでこれらを文の中にまとめたものがfor文です。リストtest7_4.cをfor文を使ったプログラムに書き直してみます。while文、for文の構造はそれぞれ[基本事項2]のように決められています。

 

リストtest7_5.c

#include<stdio.h>

main()

{

int x;

for(x = 1 ; x < 11 ; x = x + 1){

printf("%d \n", x);

}

}

 

[基本事項2 whileとfor ]----------------------------------------------------------------------------------------------

◆for      

    for ( [ 式1 ] ; [ 式2 ] ; [ 式3 ] )

      文                

 

・文は、式2が真の間繰り返されます。      

・繰り返しを始める前に 式1が評価されます。      

 通常は、ループの初期設定のために使われます。      

・ループの繰り返しの後で、式3が評価されます。      

 通常は、ループカウンタを増減するために使われます。     

・すべての式は省略可能です。式2がない場合は、1が仮定されます。

・break, continue, goto などで実行を制御できます。

 

◆while      

    while ( 式 ) 文

 

・文は、式が真の間繰り返し実行されます。      

・条件判定は、文が実行される前に行なわれます。   

・break, continue, goto などで実行を制御できます。 

 

◆do-while 

do 文

while( 式 );

 

・文は式の値に関係なく必ず1度は実行されます。

-------------------------------------------------------------------------------------------------------------------------------------

2.3.4 while文とfor文の使い分け 〜ループにかかわるテクニック

 例えば、”10から20までの整数の2乗を求め出力するプログラム”を作る場合、while文を使ってもfor文を使っても可能です。

<リスト7>                 <リスト8>

/*   while00.c    */
/* 2乗の計算 while()を使用  */
main()
{
  int   i,i2;

  i=10;
  while(i<=20) {
   i2=i*i;
   printf("%d**2=%d\n",i,i2);
   i=i+1;
  }
}
   /*   for00.c     */
   /* 2乗の計算 for()を使用   */
   main()
   {
     int   i;

     for(i=10;i<=20;i=i+1)
      printf("%d**2=%d\n",i,i*i);
   }



 

 

 for()文は次のようにwhile文に置き換えることができます。

 





 
  for ( 式1 ; 式2 ; 式3 )

     文

 



  −>
 
     式1 ;
     while (式2 ) {
        文
        式3 ;
     }




 

                              

 これらをどう使い分けるかですが、一般にwhile()は上の例でいう式1、式3の不要な場合、又ははっきりしない場合に用いられ、for()は、ループの回数がはっきりしていような場合に用いられる傾向があります。ですから、”10から20までの整数の2乗を求め出力するプログラム”はfor()を使う方が適当だといえます。

 while()文を使うのが適当な例を次に示します。リストtest7_8.cでは . (ピリオド)が入力されるまで文字の入力の表示が繰り返されます。このプログラムでは正にfor()の式1、式3にあたるものが存在しません。

      

リストtest7_8.c

 

#include <stdio.h>      

main()      

{      

int c;      

while ((c=getch()) != '.'){      

     printf("%c",c);     

}

} 

 

 このような動作の場合、文字の入力は必ず1回は行われますのでdo-while文を利用することも可能です。その例をリストtest7_9.cに示します。リストtest7_9.cでは . (ピリオド)が表示された後、終了します。

 

 

リストtest7_9.c

#include<stdio.h> 

#include<conio.h>     

main()      

{      

int c;

do{

c = getch();

printf("%c",c);

}

while ( c != '.') ;    

} 

7.5 条件式の記述

 条件式の基本になるのは、等値演算子と関係演算子でしょう。例えば、変数aとbを比較する場合には、

 

    if( a < b )

 

のように記述します。

 C言語の特徴は、これらの関係演算子もほかの演算子と同様に、すべて式の値を持つことです。

例えば

 

    a=0;  b=1; c=a<b;

 

を実行すると変数cには1が入ります。

 

    a=0;  b=1; c=a>b;

 

ならば、変数cの値は0となります。この演算結果は普通の四則演算の結果と同じですから、変数aとbの大きな方をcに代入するには

 

    c=a*(a>b)+b*(a<b);

 

といった記述が可能になります。ただし、通常の数学の式の形式とは見た目が異なりますので、乱用はつつしみましょう。

 これらを組み合わせて複雑な条件を記述するために && || ! などの論理演算子があります。論理演算子は関係演算子と同様に

 

     a=1; b=1;

    c=a && b;

 

を実行すると変数cには1が入ます。

 条件式を記述するときには、演算子の優先順位に気をつけなければなりません。リストtest7_8.cの

    while ((c=getch()) != '.')      

    while (c=getch() != '.')      

のように書いてしまわないことです。下の場合だと、始めに getch() != '.' が計算され、それが c に代入されることになってしまいます。うっかりしてよくやまちがいに条件式に==のつもりで=をかいてしまうことがあります。C言語では条件式での演算に制限がありませんから==であろうと=であろうとコンパイラはワーニングすら出しません。注意してください。