3.アルゴリズムの流れの制御

 「簡単なプログラムの作成」の章では、プログラムを作って、コンピュータを電卓替わりに使えることを覚えました。そこでの知識に加えて、ここで説明する「制御構造」を覚えれば、電卓には出来ないような大量の計算を実行させることが出来るようになります。
3.1 アルゴリズムの流れを制御する
 普段,私たちはある目的をもって行動します.「授業が,面白くないから途中,教室からぬけだしメシをたべに行く」というのも目的をもった行動です.このような目的を達成するまでの間,私たちは,普段,意識しませんが,無意識のうちに,何段階もの判断や行動を実行しています.目的を達成するのに必要な個々の行動を,実行順に並べたものをアルゴリズムとよびます.
 CのソースコードはCPUにしてもらう処理のアルゴリズムをC言語の言葉を使って記述したものです。
また、プログラムとは、アルゴリズムの記述されたソースコードをCPUの言葉、すなわち、マシン語(機械語)に変換(コンパイル)したもののことです。 ここでは、はじめに、アルゴリズムの構造(記述のしかた)について考えてみましょう。 例えば、朝8時には,家をでなくてはならない人の行動を例にアルゴリズムの記述の仕方を考えてみます.

  1)朝起きる
  2)パジャマを脱ぐ
  3)シャワーを浴びる
  4)服を着る
  5)食事をする
  6)家をでる

 これは,時間を気にしなくてもよい人の出勤までの行動のアルゴリズムですね.このアルゴリズムの特徴は,流れるように,上から下へ順に直線的に実行するように構成されています.このような,流れをもつアルゴリズムの構造を「順次構造(or処理)」とよびます.「簡単なプログラムの作成」のところで紹介したプログラムはすべてこのような順次構造をもつタイプでした。
 でも,いろいろなアルゴリズムを記述するのには、順次構造だけでは不十分です。
例えば、朝起きて家をでるまで,時間的に余裕のないときは、どうなるのでしょうか.時間次第では、食事をとらず、出かけなければならないかも知れません。この場合のアルゴリズムは、次のように記述すればよいでしょう。

  1)朝起きる
  2)パジャマを脱ぐ
  3)シャワーを浴びる
  4)服を着る
  5)時計をみる
  6)もし,まだ,8時になってなければ,
     6.1)食事をする
  7)家をでる

 このアルゴリズムの特徴は、5)行目で時計を見たあと、
  ・まだ、8時になっていないければ、食事をし、そのあと家を出る.
  ・8時になっていれば、そのまま食事をとらず家を出る
ということを表現しようとしています。
1)〜5)まで,順次に実行してきたアルゴリズムの流れが、時間という条件次第で、枝分かれすることになります.
このように,アルゴリズムの実行の途中で,条件次第で,次に実行すべき内容を選択する必要のある場合がよくあります.われわれの日常の行動でも頻繁に行われていることです.したがって,アルゴリズムの記述には,次にとるべき行動がどれかを選択できるような表現が必要ということになります.アルゴリズムのこの部分を「選択(or分岐)構造」と呼びます.
 もっと,時間的に余裕のない人の行動は,次のようになります.

  1)朝起きる
  2)パジャマを脱ぐ
  3)シャワーを浴びる
  4)服を着る
  5)時計をみる
  6)8時になってなければ
     6.1)食事を一口食べる
   6.2)時計をみる.
6.3)6)に戻る.   7)家を出る.

 このアルゴリズムの特徴は5)から6.3)までの範囲で,時計を見て,時間という条件次第で,あるひとまとまりの行動を繰り返すことです.アルゴリズムのこの部分を「繰返し(or反復)構造」と呼びます.
分岐構造や繰返し構造は、アルゴリズムの流れを変えるもので、「流れ制御」ともよばれます。
ここでは、人の行動を例に説明しましたが、大切なことは、プログラムについても,アルゴリズムがどんなに複雑であっても,「順次構造」,「選択構造」,「反復構造」の3つの基本構造で,表現することができる(構成することができる)ということです.
したがって、C言語の文法にも、基本構造を表現するキーワードが必要だと言うことです。



3.2 アルゴリズムの流れを制御するCのキーワード
 上のアルゴリズムにC言語の流れ制御のキーワードを組み込んでみましょう。
まず、最初は、選択構造を表現するためのキーワードif文です。次のような形をしています。
   if(条件式){
      条件が成立するときのみ実行する内容
   }
 ()中の条件式が成立するときのみ、{...}中の内容を実行することになります。
 これを,先ほどのアルゴリズムの表現に適用してみます.

   1)朝起きる
   2)パジャマを脱ぐ
   3)シャワーを浴びる
   4)服を着る
   5)時計をみる
   6)if(8時になっていない場合){
       食事をする
    }
   7)家を出る


 繰り返し処理のキーワードとして,まずwhile文を紹介します。while文には、次のように、二つの書き方があります。
アルゴリズムとして2つのケースを考えてみました。
   do{
      条件式が成立するとき実行する内容
   }while(条件式)
または,
   while(条件式){
      条件式が成立するとき実行する内容
   }
いずれの場合も、繰り返しの対象となる範囲を{ }中に記述します.()の中には、{ }中の処理を繰り返すかどうかの条件式が書き込まれます。
 2つのwhile( )文の違いは、最初のdo0{・・・}while(条件)では、{ }中の内容を無条件に1回実行した後、条件判断を行いますが、while(条件){・・・}は、{ }中の内容を実行する前に判断を行うところです。
これらを、先述のアルゴリズム例に組み込むと次のようになります。

   1)朝起きる
   2)パジャマを脱ぐ
   3)シャワーを浴びる
   4)服を着る
   do{
     5)一口食べる
     6)時計をみる
   }while(まだ,8時でない場合)
   8)家を出る

この場合は,1回食べた後で,2回目以降から時間をチェックすることになります.


次の場合は,まず,時間をチェックすることから始まります.

   1)朝起きる
   2)パジャマを脱ぐ
   3)シャワーを浴びる
   4)服を着る
   5)時計をみる
   while(まだ、8時でない場合)
   {
      6)一口食べる
      7)時計をみる
   }
   8)家を出る



 3.3 選択処理 その1 if( )文と条件式
 次に実際のプログラムを例にこれらの流れ制御文の使い方を紹介しましょう。まず、選択処理から始めます。
最初の例は、試験点数をもとに合格点かどうかを判断し、合格点の場合のみ、点数と、合格ですというメッセージを表示するプログラムです。プログラム中の条件式,tensu>=60 は、tensuが60点以上ならばということを意味します。
 プログラム例中の記号>=は2つの数値の大小関係を表現する演算子で比較演算子とよばれます。(後で、まとめて説明します)


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

      tensu = 85;
      if(tensu>=60){
          printf("得点%d点で合格です", tensu);
      }
  }
  得点85点で合格です
  


 次の例は、合格なら(tensu>=60が成立するなら)「合格」、そうでなければ(else)「不合格」と表示します。
 プログラム例 3.3.2  実行結果
  #include <stdio.h>
  void main(void){
      int tensu = 85;

      if(tensu>=60){
          printf("得点%d点で合格です",tensu);
      }else{
          printf("得点%d点で不合格です",tensu);}
      }
  }
  
  得点85点で合格です
  


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

      if(tensu>=60){
          printf("得点%d点で合格です",tensu);
      }else{
          printf("得点%d点で不合格です",tensu);
      }
  }
  
  得点35点で不合格です
  


次の例は、評価を優、良、可、不可の4つに細かく分けて、取り扱う場合です。
条件式中の&& (アンド、ANDと読みます)は、論理演算子と呼ばれ、たとえば、
   tensu>=60 && tensu<70 は、tensu>=60 かつ tensu<70 が成立するとき
と言う意味です。(次のセクションでまとめます)

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

      if(tensu<60){
          printf("%d点は評価,不可です",tensu);
      }else if(tensu>=60 && tensu<70){
          printf("%d点は評価,可です",tensu);
      }else if(tensu>=70 && tensu<80){
          printf("%d点で評価,良です",tensu);
      }else if(tensu<80){
          printf("%d点は評価,優です",tensu);
      }
  }
  
  75点は評価,良です
  


分岐処理を表現するif( )文は、基本的に次のような構造をもつと覚えておけばよいとおもいます。

   if(条件式1){
     条件式1が成立するとき実行する内容
   }else if(条件式2){
     条件式2が成立するとき実行する内容
   }else if(条件式3){
     条件式3が成立するとき実行する内容
   }else{
     条件式1から3のいづれにも該当しない場合(その他)実行する内容
   }

もし、if( )文の条件成立時の実行内容が1行だけなら、
   if(条件式){
     実行内容;
   }
と書くこともできますが、{ }を省略して、次のように書くこともできます。
   if(条件式)
     実行内容;



 3.4 条件式について(比較演算子と論理演算子)
 if( )文の条件式や、次に紹介するwhile( )文の条件式中では、比較演算子や論理演算子が使われます。ここでは、この2種の演算子について説明します。

比較演算子は
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が等しくない(とき)

 比較演算子<=,>=,!=などの場合、=は必ず右側に来るということを、しっかり覚えておいて下さい。これらを複合演算子とよいびます。(なぜ、そのようによぶかはわかりますよね。)

論理演算子
2つの式A,Bの論理演算をします。論理演算とは、みなさんが高校の数学の「集合」で学習した演算のことです。

論理演算子 
 A&&B &&はANDと呼びます。「式Aが成立し、かつ、式Bが成立するとき」という意味
 A||B ||はORとよびます。「式Aが成立するか、または、式Bが成立するとき」という意味
 !A !はNOTと呼びます。「式Aが成立する」の否定を表します。式Aが成立しないときと考えてよい

 書き忘れましたが、&&を論理積、||を論理和、!を否定ともよびます。ここでの知識を頭に入れて、if( )文のプログラム例を見て下さい。
 ちょっと、プログラムに自信のあるひとは、「演算子と演算結果について」を読んで下さい。


 3.5 繰り返し処理 その1 while( )文
 ここでは、流れ制御文の2つめとして「繰り返し処理」を表現するキーワードwhile( )文のプログラム中での使い方について説明します。
 最初の例は、非常にシンプルですが、この例がちゃんと理解できれば、while( )文は理解できたことになります。じっくり考え,実行結果を予想してみて下さい。また、count=count+1 がなければ、実行結果がどうなるかも予想してみて下さい。


 プログラム例 3.5.1  実行結果
  #include <stdio.h>
  void main(void){
      int count ;
      count=1;
      while(count<=10){
          printf("繰り返し%d回目です\n",count);
          count=count+1;
      }
      printf(ループから抜け出しました\n");
  }
  
  繰り返し1回目です
  繰り返し2回目です
  繰り返し3回目です
  繰り返し4回目です
  繰り返し5回目です
  繰り返し6回目です
  繰り返し7回目です
  繰り返し8回目です
  繰り返し9回目です
  繰り返し10回目です
  ループから抜け出しました
  


 では、このプログラムをとおして、知ってもらいたいことがらを説明しましょう。while( )文の構造は、次のとおりだということは前に説明しました。
   while(条件式){
     繰り返し実行したい処理内容
   }
 したがって、このプログラムは、{ }で囲まれた次の2行を繰り返し実行します。
   printf("繰り返し%d回目です\n",count);
   count=count+1;
では、いつまで(何回)実行するのでしょうか。それを決めるのが( )中の条件式
   count<=10
です。すなわち、countの値が10になるまでということです。いまの、場合、while( )ループの{ }の内容を実行する前に条件のチェック、すなわち、
   count<=10
かどうかを確かめます。したがって、そこへくるまでに、countには値が与えられてなければなりません。最初のcountの値は
   count=1;
を実行することで、1となります。
{ } 内を実行し、最後の行、count=count+1(countの値を1増やす)を実行したら、また、先頭のwhile( )へ戻り、また条件をチェックします。条件count<=10 が成立するなら、また、{ }の内容を実行します。countの値が { } 内を1回実行するたびにチェックされるわけです。countが10を越えると、実行条件に合わなくなるので、ループは終了し、「ループから抜け出しました」と表示します。ここでのcountはループの繰り返し回数を数えるカウンターと見なすこともできます。このような変数をカウンターと呼びます。これはぜひ覚えておいて下さい。

 ところで、count=count+1がなければ、どういうことになるかわかりましたか。そうです。countの値が初期値1のままとなり、常にcount<=10とを満たすことになります。したがって、ループから抜け出すことは出来ません。
永久にループを繰り返します。よく無限ループという言葉を聞くと思いますが、このことです。
 ここにも、コンピュータの性格があらわれていますね。コンピュータは、プログラムで指示された内容を「忠実に」、「疲れもせず」、「文句も言わず(感情がない)」言われたとおり実行するということです。

 ここで、流れからそれて、ちょっと、説明しておきたいことがあります。
 それは、カウンター変数の値を増やすときの表現です。上のプログラムでは、カウンター変数の値を1増やすのに次のよう式が使われています。
   count=count+1
この式は、数学の式としてとらえるとおかしなことになります!この式の意味は、現在、変数 count に記憶されている数値に1を加えた値を、あたらしい変数countの値とすると言う意味なのです。CPUは、この式に遭遇すると、メモリー中の変数countの値を取り出して1を加え、もとのcountの位置に戻します。
 しかし、C言語では、変数の値を「1だけ、増やしたい」場合、通常、このような表現はあまり使わず、次のような表現をよく使います。
   count++、または、++count
もちろん++は演算子で、インクリメント演算子とよびます。
インクリメント演算子に対し、デクリメント演算子と呼ばれる演算子があり、変数の値を1だけ減算します。記号--で表します。
   count--、または、--count
と書きます。
 今後は、変数の値に1加算するとき、或いは、1減算するときはインクリメント演算子やデクリメント演算子を使います。
早速、前のプログラム例を、これらの演算子を使って書き換えてみましょう。次のようになります。

 プログラム例 3.5.2  実行結果
  #include <stdio.h>
  void main(void){
      int count ;
      count=1;
      while(count<=10){
          printf("繰り返し%d回目です\n",count);
          count++;
      }
      printf("ループから抜け出しました\n");
  }
  
  繰り返し1回目です
  繰り返し2回目です
  繰り返し3回目です
  繰り返し4回目です
  繰り返し5回目です
  繰り返し6回目です
  繰り返し7回目です
  繰り返し8回目です
  繰り返し9回目です
  繰り返し10回目です
  ループから抜け出しました
  


 デクリメント演算子の使用例も示しておきます.−−の作用をよく理解してください.

 プログラム例 3.5.3  実行結果
  #include <stdio.h>
  void main(void){
      int count ;
      count=5;
      while(count >= 0){
          printf("カウント %d\n",count);
          count--;
      }
      printf("GO! GO!\n");
  }
  
  カウント 5
  カウント 4
  カウント 3
  カウント 2
  カウント 1
  カウント 0
  GO! GO!
  


 ++や--などの演算子を変数の前においたときと、後ろに置いた時とで意味が違う場合があります。そのような例は、今後、いっぱい出てくると思いますので、そのとき説明します。


 3.6 カウンター変数を積極的に利用する
 カウンター変数は、ただ単に繰り返し回数をカウントするだけでなく、ループ中で積極的に利用します。
次のプログラムは、その1例です。x の値、ー5から+5の範囲で、y=2x+3の値を求めます。カウンター変数xをうまく利用した例です。繰り返し処理をつかわなければ、このような計算をするプログラムはどのような形におなるか想像してみて下さい。繰り返し処理の威力に感動しますよね!

   
 プログラム例 3.6.1  実行結果
  #include <stdio.h>
  void main(void){
      int x, y ;
      x = -5;
      while( x <= 5 ){
          y = 2 * x + 3;
          printf("x=%dのとき,y=%d\n", x, y);
          x++;
      }
  }
  
  x=-5のとき,y=-7
  x=-4のとき,y=-5
  x=-3のとき,y=-3
  x=-2のとき,y=-1
  x=-1のとき,y=1
  x=0のとき,y=3
  x=1のとき,y=5
  x=2のとき,y=7
  x=3のとき,y=9
  x=4のとき,y=11
  x=5のとき,y=13
  


 参考のため,デクリメント演算子をつかって同じ計算をしてみましょう.

 プログラム例 3.6.2  実行結果
  #include <stdio.h>
  void main(void){
      int x, y ;
      x = 5;
      while( x >= -5 ){
          y = 2 * x + 3;
          printf("x=%dのとき,y=%d\n", x, y);
          x--;
      }
  }
  
  x=5のとき,y=13
  x=4のとき,y=11
  x=3のとき,y=9
  x=2のとき,y=7
  x=1のとき,y=5
  x=0のとき,y=3
  x=-1のとき,y=1
  x=-2のとき,y=-1
  x=-3のとき,y=-3
  x=-4のとき,y=-5
  x=-5のとき,y=-7
  



 3.7 書式指定子の効果
プログラム例3.6.1と3.6.2の出力は乱雑で気に入りませんね.数値をきれいに並べるには書式指定子を使います.
次の2つのプログラムを比較してみてください.いづれも整数値を表示しますが,例3.7.1は,書式指定子に桁を指定しない場合,例3.7.2は,桁指定をした場合です.これで桁指定の効果がわかると思います.

 プログラム例 3.7.1  実行結果
  #include <stdio.h>
  void main(void){
      int x, y ;
      printf("    x     y\n");
      x = 1;
      while( x <= 30000 ){
          y = 2 * x + 5;
          printf("%d %d\n", x, y);
          x = x * 10;
      }
  }
  
   x     y
 1 7
 10 25
 100 205
 1000 2005
 10000 20005

上の出力表示は,ちょっと....ですね.では,数値をきれいに並べてみましょう.
※次のプログラムの %8d の意味は,整数値を正負の符合を含め8桁のスペースで表示しなさいという意味です.8桁のスペースで数値は右に詰めて表示されます.

 プログラム例 3.7.2  実行結果
  #include <stdio.h>
  void main(void){
      int x, y ;
      printf("    x      y\n");
      x = 1;
      while( x <= 30000 ){
          y = 2 * x + 5;
          printf("%6d %6d\n", x, y);
          x = x * 10;
      }
  }
  
    x      y
     1      7
    10     25
   100    205
  1000   2005
 10000  20005
  

 次に実数の場合を見てみましょう
まずは,桁数指定なしの場合です.

 プログラム例 3.7.3  実行結果
  #include <stdio.h>
  void main(void){
      int n;
      double x, y ;
      printf("    x       y\n");
      n = 0;
      x=0.0;
      while( n <= 5 ){
          y = 2.3 * x * x + 5.67;
          printf("%f %f\n", x, y);
          x += 5.0;
	  n++;
      }
  }
  
    x       y
0.000000 5.670000
5.000000 63.170000
10.000000 235.670000
15.000000 523.170000
20.000000 925.670000
25.000000 1443.170000
  

次に書式指定子に桁を指定してみます.%15.7fは,正負の符号と小数点を含め,数値全体を15桁で表示し,そのうちの7桁を小数点以下の表示に使用しなさいという意味です

 プログラム例 3.7.4  実行結果
  #include <stdio.h>
  void main(void){
      int n;
      double x, y ;
      printf("        x               y\n");
      n = 0;
      x=0.0;
      while( n <= 5 ){
          y = 2.3 * x * x + 5.67;
          printf("%15.7f %15.7f\n", x, y);
          x += 5.0;
	  n++;
      }
  }
  
        x               y
      0.0000000       5.6700000
      5.0000000      63.1700000
     10.0000000     235.6700000
     15.0000000     523.1700000
     20.0000000     925.6700000
     25.0000000    1443.1700000
  


どうですか,書式指定子の桁表示指定の使い方がわかりましたか?


 3.8 繰り返し処理 その2 for( )文
 繰り返し処理を表現する文として、もう一つ、for( )文というのがあります。 while( )文を使って、ループ処理を表現するときは、カウンター変数の初期化、カウンター変数の増加、繰り返しの条件が必要になります。for()文では、それら3つの要素をfor()の( )の中にまとめて記します.
プログラム例3.7.4をfor()文を使って、書き換えてみるとプログラム例3.8.1のようになります。
 プログラム中のfor( )の( )中の各式は、
   最初の式    i = 0  がカウンター変数の初期化
   2番目の式   i<5  が繰返しの条件
   3番目の式   i++   がカウンターの増加
ということになります。
多くの人はfor()文の方をよく使います.


 プログラム例 3.8.1  実行結果
  #include <stdio.h>
  void main(void){
      double x, y ;
      int i;
       
      printf("        x               y\n");
      x = 0.0;
      for( i = 0; i <= 5; i++){
          y = 2.3 * x * x + 5.67;
          printf("%15.7f %15.7f\n", x, y);
          x += 5.0;
      }
  }
  
        x               y
      0.0000000       5.6700000
      5.0000000      63.1700000
     10.0000000     235.6700000
     15.0000000     523.1700000
     20.0000000     925.6700000
     25.0000000    1443.1700000
  


 次のプログラムは,プログラム例3.8.1をさらに書き換えたものです.処理内容は,まったく同じです.3.8.1とどこが違うかよく調べてみてください.

 そうです.3.8.1で,変数xの初期化とxの増加処理を,それぞれ,ループの外と内部で行っていたのに,ここではそれをfor( )文中の( )の中にカウンター変数と並べて実行しているところです.
for( )文ではこのような記述もできます.

 プログラム例 3.8.2  実行結果
  #include <stdio.h>
  void main(void){
      double x, y ;
      int i;
       
      printf("        x               y\n");
      for( i = 0, x=0.0; i <= 5; i++, x+=5.0 ){
          y = 2.3 * x * x + 5.67;
          printf("%15.7f %15.7f\n", x, y);
      }
  }
  
        x               y
      0.0000000       5.6700000
      5.0000000      63.1700000
     10.0000000     235.6700000
     15.0000000     523.1700000
     20.0000000     925.6700000
     25.0000000    1443.1700000
  



 3.9 選択処理 その2 switch( )文
 選択構造を表現する文としてif( )文を紹介しましたが、他にswitch()文というのがあります。実用的なプログラムではよく使われます。例えば、ワープロソフトなどで、マウスを使ってメニューから処理を選択しますが、プログラム内部ではでは、switch()文を使って指定の処理を選択実行するようにしています。
 次のプログラム例では、番号付きの選択肢を画面上に表示し、それを見て、目的とする項目を番号で選択すれば、番号に対応する処理へ分岐するプログラムです。選択した項目の番号は、scanf()関数を使って、変数choiceに記憶されます。分岐先は、choiceに記憶された数値に対応するcaseです。例えば、実行例ではchoiceの値として3が選ばれています.
すると、case OS へ分岐し、そこの記述内容を実行し始め、breakに遭遇すると、switch文を抜け出し、終了と言うことになります。
 switch()文と記号定数は切り離すことは出来ません。なぜなら適当な記号定数でcaseのパラメータを表現することにより,ちょうど,英語の文章でも読むようにプログラムが見やすくなるからです.

 プログラム例 3.9.1  実行結果
#include <stdio.h>
#define CPU    1
#define MEMORY  2
#define OS    3
#define SPREAD  4
void main(void){
    int choice;

    /*まず、メニューを表示します*/
    printf("メニュー・リスト\n");
    printf("1)CPU\n");
    printf("2)メモリー\n");
    printf("3)OS\n");
    printf("4)表計算ソフト\n");

    /*scanf()で、キーボードから番号を受け取る*/
    printf("単語を番号で選択して下さい:");
    scanf("%d",&choice);

    /*番号にしたがって分岐する*/
    switch(choice){
    case  CPU:
        printf("Central Processing Unit\n");
        printf("中央演算処理装置\n");
        printf("プロセッサー\n");
    break;
    case  MEMORY:
        printf("主記憶装置\n");
        printf("メモリー\n");
    break;
    case  OS:
        printf("基本ソフトウェア\n");
        printf("オペレーティングシステム\n");
    break;
    case  SPREAD:
	printf("表計算ソフト");
	printf("スプレッドシート");
    defaullt:
        printf("メニューにない選択をしました。");
    break; 
	}

}
  
  メニュー・リスト
  1)CPU
  2)メモリー
  3)OS
  4)表計算ソフト
別称を知りたい単語を番号で選択して下さい:3

基本ソフトウェア
オペレーティングシステム



3.10 剰余演算子%使い方

 制御文の知識があれば,いろんなプログラムが作成できます.
ここでは,これまで紹介した知識を深めるための簡単なプログラムを紹介しましょう.
まずは,剰余演算子%です.剰余演算子は既に出てきましたが,次のような使い方もできます.
このプログラムは,関数値を計算し,結果を好きなレイアウトで表示するためのプログラムです.

 プログラム例 3.10.1  実行結果
#include <stdio.h>
void main(void){
   int i;
   int ncol = 4;/*1行に表示する数値の数*/
   double x, y;

   printf("yの値\n");
   for( i = 0; i<=30; i++){
      x=0.2*(double)i;
      y = 2. * x * x + 3.;
      printf(" %7.4f",y);

      /*次の1行がこのプログラムのポイント+/
      if( ((i+1) % ncol) == 0 )printf("\n");
   }
}
  
yの値
  3.0000  3.0800  3.3200  3.7200
  4.2800  5.0000  5.8800  6.9200
  8.1200  9.4800 11.0000 12.6800
 14.5200 16.5200 18.6800 21.0000
 23.4800 26.1200 28.9200 31.8800
 35.0000 38.2800 41.7200 45.3200
 49.0800 53.0000 57.0800 61.3200
 65.7200 70.2800 75.0000



3.11 グラフを描いてみよう

 Windowsの環境で,グラフィックスを使用するのは,大変です.そこへ到達するには,勉強すべき事がいっぱいあります,
しかし,文字を使ってグラフを作成することもできます.ここでは,文字を使って計算結果やデータをグラフにしてみましょう.
プログラムの注釈行に注意して理解を試みてください.
結果は,棒グラフになります.

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

      printf("    y = x * x + 3\n");
      for( x = 0; x<=5; x++){
          y =  x * x + 3;

          /*1)まずは,xの値を表示します*/
          printf(" %2d ",y);

          /*2)yの個数分*を表示します*/
          for(i = 0; i < y ; i++)
              printf("*");

          /*3)*を打ち終えたら開業*/
          printf("\n");
      }
  }
  
    y = x * x + 3
  0 ***
  1 ****
  2 *******
  3 ************
  4 *******************
  5 ****************************




 プログラム例11.1をちょっと書き換えれば,次のように曲線のグラフだって作成できます.

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

     printf("    y = x * x + 3\n");
     for( x = 0; x<=5; x++){
        y =  x * x + 3;

        /* 1)xの値を表示*/
        printf(" %2d ",x);

        /* 1)(y-1)個の空白を表示*/
        for(i = 0; i < y-1 ; i++)
           printf(" ");

        /*3) *を表示 */
        printf("*\n");
    }
  }
  
    y = x * x + 3
  0   *
  1    *
  2       *
  3            *
  4                   *
  5                            *



 上記の2つのプログラムは,整数値を扱うものでしたが,実数値の場合はどうなるでしょうか.
ここでは,三角関数を表示させてみます.
このグラフの特徴は,
 1)負の値をとる.
 2)最小値も最大値も絶対値1以下
そこでちょっと工夫が必要です

 プログラム例 3.11.3  実行結果
  #include <stdio.h>
  void main(void){
    double x, y;
    int shift=10;
    int i, j, iy;

    printf("         y = sin(x)\n");
    for( i = 0; i<=20; i++){
 
        /* xはradian単位です*/
      x = 3.1415 / 10. *(double)i; 
      y = sin(x);

      /* 1)yの範囲を(-1,1)から(0,20)に変換*/
      /* 2)さらにyを右にシフトさせる*/
      iy= (int)( 10. * y) + shift;

      /*2)グラフを作成*/
      printf(" %7.4f ",x);
      for(j = 0; j < iy ; j++)
        printf(" ");
        printf("*\n");
      }
   }
}
  
         y = sin(x)
  0.0000           *
  0.3142              *
  0.6283                *
  0.9425                   *
  1.2566                    *
  1.5708                    *
  1.8849                    *
  2.1991                   *
  2.5132                *
  2.8274              *
  3.1415           *
  3.4557        *
  3.7698      *
  4.0840   *
  4.3981  *
  4.7123  *
  5.0264  *
  5.3406   *
  5.6547      *
  5.9689        *
  6.2830           *