プログラミング演習第4回制御文（while）

目次

1 基本データ型についての復習 1 2 取り込んだ文字列を変換する 3 3 while 文 (フィボナッチ数列) 4 4 問題 6

1 基本データ型についての復習

変数のデータ型について，関数 printf を使って復習します．変数の型の主なものは，次の４つでした．

char 文字型， 1 byte = 8 bit

int 整数型， 4 byte = 32 bit

float 小数（現在はあまり使わない） 4 byte = 32 bit

double 小数 8 byte = 64 bit

char 型は文字を代入することが多いというだけで， 1 byte で表わされる範囲の整数を扱うことも出来ます．

1 byte = 8 bit ですので， 0 から 2^{8} = 256 までの大きさの整数，または， −2^{7} = −128 から， 2^{7} − 1 = 127 までの整数が扱えます．どちらの範囲の整数が使用できるかは，機械（コンパイラー）によって異なりますので， 0 から 127 までを使うようにするのが無難でしょう．

整数型は −2^{32} = −2147483648 から 2^{32−1} = 2147483647 まで取り扱うことができます.

次のプログラムを見て，変数の型とその表示の方法について復習しましょう．

/* char, int, double, の変数と文字型配列を表示 */
#include <stdio.h>
main()
{
  char    moji;    /* 主に文字を扱う */
  int     suji;    /* 整数 */
  double  shosu;   /* 実数（浮動小数） */
  char    bun[80]; /* 文字列は配列に代入する*/
  moji = '!';      /* 文字を代入するときは， ' で囲む*/

suji = 8; /* 数字を代入するときはそのまま */

  shosu = 7.0;    /* double 型への代入は小数にしてから */

/* 文字列は"で囲んで strcpy で配列名に代入 */

  strcpy(bun, "is my birthday");

/* %2.0f とは小数を２桁で小数点以下を０桁で出力せよ

* という意味

   */
  printf("%d %2.0f %s %c \n", suji, shosu, bun, moji);
}

文字列を char 型の配列に代入するには，関数 strcpy を使います．最初の引き数に char 型の配列の配列名，２番目の引き数には，文字列を"で括って書きます．その際，代入する文字列よりも配列の長さを長くとっておきます．

注意

     strcpy(bun, "is my birthday");

の部分は

     bun = "is my birthday";

とすることは出来ません．

その他の部分のプログラムの説明はコメントに書いてある通りです．では上のプログラムをタイプして実行してみて下さい．（ファイル名 4-

1.c）

次に文字型変数に整数を代入して出力する例をみてみましょう．次のプログラムを良く読んで出力結果を予想して下さい，それから実際に作成して実行してみて下さい．（ファイル名 4-2.c）

#include <stdio.h>
main()
{
  char    a, b, c, one, two, three;

/* 次の 10 進数は， 16 進数では幾つになるでしょう？ */

  a = 65; b = 66; c = 67;

/* 10 進整数として出力するときは， %d を使用します */

printf("%d %d %d\n", a, b, c);

/* 16 進整数として出力するときは， %x を使用します */

printf("%x %x %x\n", a, b, c);

/* %c を使用すると ASCII コードに対応する文字を出力します */

printf("%c %c %c\n", a, b, c);

/* 16 進数の代入は数字の前に 0x を書きます*/

one = 0x31;   /* 文字'1' に対応するコードは 0x31 = 49 */
two = 0x32;   /* 文字'2' に対応するコードは 0x32 = 50 */
three = 0x33; /* 文字'3' に対応するコードは 0x33 = 51 */
printf("%d %d %d\n", one, two, three);
printf("%c %c %c\n", one, two, three);
}

実験してみてわかるように，文字型変数に代入した’ 文字’ は対応する ASCII コード（整数）を値として持っています．整数 d を文字として扱うとき, %c で出力されるのは, d を 16 進法で表した数に対応するコードが表現される.

2 取り込んだ文字列を変換する

前回使用した関数 gets は，キーボードから入力した文字列をプログラムに取り込むものでした．基本的にキーボードからの入力は文字列になります．

前の節で見たように，文字にはコードが割り当てられているので，入力文字がすべて数字の場合，コード表の規則に従うと整数に変換することが出来ます．

また，以下のように関数 sscanf を使って変換も出来ます． (ファイル 4-3.c)

/* 文字列を２つの整数に変換する */

#include <stdio.h>
main()
{
  char    mojiretsu[80];  /* 入力文字列 */
  int     m, n;           /* 変換された整数を m, n に保存 */

printf("２つの整数を空白で区切って入力して下さい >> ");

/* キーボードからの入力を mojiretsu に格納します */

  gets(mojiretsu);

/* 文字配列 mojiretsu から整数を取り出します

* m, n の前に & （アンパサンド）が必要です

   */
  sscanf(mojiretsu, "%d %d", &m, &n);

/* m, n を使った計算結果の表示 */

  printf("m = %d, n = %d m+n = %d\n", m, n, m+n);
}

関数 sscanf の最初の引き数は，文字列の入っている配列の名前です．２番目の引き数は取り出すデータの型を”で囲んで記述します． printf と大体同じです． double 型のデータを受け取るときは， %f を使用します．変換された整数を受け取る変数の前には & が必要です．

確認

scanf と sscanf の違いを確認しましょう.

確認上のプログラムで 3 個以上の整数を入力しても最初の 2 個以外は無視されることを確かめよ.

これ以降キーボードからの入力が必要なプログラムについては， gets, sscanf を組合せて使うと良いでしょう．

3 while 文 (フィボナッチ数列)

前回 for 文を用いて簡単な数列の和について求めましたが、 1 回生のとき触れたフィボナッチ数列 {f_{n}} 取り上げます. 今回は while 文を使用します． while 文は次のように使います．

     while (条件式) {

条件式が真ならここを実行

     }

では次のプログラムを入力し，実行してみて下さい．（ファイル名 4-4.c）フィボナッチ数列の漸化式は,

f_{1} = 1, f_{2} = 1, f_{n+2} = f_{n+1} + f_{n} (n = 1, 2, ⋯)

です.

この数列を与えられた正の数までの表を作りましょう.

#include<stdio.h>
main()
{
  int fn, fn1, fn2, m;    /* 変数 fn, fn1, fn2, m の整数型の宣
言*/
  fn = 1, fn1 =1, fn2 =2; /* 変数 fn, fn1, fn2 の初期化 */
  printf("正の整数を入力して下さい >>");
  scanf("%d", &m);

printf("%d までのフィボナッチ数列は以下のとおり\n",m);

  printf("------------------------------------------------\n");
  printf("%d, %d,", fn, fn1);
  while(fn2 <=m){
    fn = fn1, fn1 = fn2, fn2 = fn + fn1;  /*フィボナッチ数列*/
    printf("%d,", fn2);
       }
}

例えば 100 までのフィボナッチ数列は, 1,1,2,3,5,8,13,21,34,55,89 となります.

4 問題

問題 1 上のプログラムを改良し, 与えられた整数に対して, それより小さい中で一番近いフィボナッチ数列の値を求めるプログラムを作成せよ.

問題 2 先週のセンター試験の問題のプログラムを while 文を使って作成せよ.

問題 3 (レポート問題) ユークリッドの互除法を用いて，２つの正の整数の最大公約数を求めるプログラムを作成せよ．（ヒント： r = x%y とすると x を y で割った余りが， r に代入される．）