• 検索結果がありません。

演習問題

ドキュメント内 note.dvi (ページ 53-56)

6.9 いくつかのプログラム

6.10.9 演習問題

#include <stdio.h>

int main(int argc, char **argv) {

double x=1.0 ; while(1) {

x -= 0.1 ;

printf("x = %.16f\n", x) ; if (x == 0.0) break ; }

return 0 ; }

この場合, 0.0になっていると思われる時の前後の出力は, x = 0.1000000000000001

x = 0.0000000000000001 x = -0.0999999999999999

となり,正しく0.0にはなっていない.

この例を正しく動作するように直すには,

#include <stdio.h>

#include <math.h>

#define EP 1.0E-12

int main(int argc, char **argv) {

double x=1.0 ; while(1) {

x -= 0.1 ;

printf("x = %.16f\n", x) ; if (fabs(x) < EP) break ; }

return 0 ; }

とすればよい.

6.10.9.1 必要な関数と簡単な例

ここで述べた関数については,詳しくはオンライン・マニュアルを参照すること.29 6.10.9.1.1 getchar 標準入力から1文字を入力するための関数は, getcharである.

int getchar() 利用法は,以下の通り.

Example 6.10.24 標準入力から1文字を読んで,それを出力する. プログラムを終了するには,Control+D を入力する.

int c ;

while ((c = getchar()) != EOF) { printf("%c",c) ;

}

ここで,getcharの戻り値として,int型の変数で受けていることに注意. char 型ではない. また,EOF とは,ファイルの終りを表す特別な文字である.

6.10.9.1.2 数値を入力する 多くのC言語の教科書には,「標準入力から整数数値を入力するためには,

scanfを使う. 」と書いてある. これは大きな間違い!

少なくともこの段階で利用できるものだけを使うとすると,標準入力から1文字を読み,それを数値に変 換することを考えよう. もし,文字集合がASCII であることが仮定できれば,

int c, n ; c = getchar() ;

if (isdigit(c)) n = c - ’0’ ;

とすれば, 標準入力から読んだ文字が 0から 9であるときには,その数値を nに代入することが出来る.

文字集合を仮定しないのであれば, int c, n ;

c = getchar() ; switch(c) {

case ’0’: n = 0 ; break ; case ’1’: n = 1 ; break ; case ’2’: n = 2 ; break ; case ’3’: n = 3 ; break ; case ’4’: n = 4 ; break ; case ’5’: n = 5 ; break ; case ’6’: n = 6 ; break ; case ’7’: n = 7 ; break ; case ’8’: n = 8 ; break ; case ’9’: n = 9 ; break ; }

29オンライン・マニュアルで,期待のものが出てこない時には,man -s 3s getcharなどと-s 3sを入れてみると良い.

とするしかないであろう. 文字列を使えば,もう少しエレガントに操作することが出来る.

6.10.9.1.3 乱数の発生 random()という関数は 0から2311の乱数を発生させる. 通常,次のように して使う.

Example 6.10.25 乱数を2つ発生させる.

long n,m ;

srandom((unsigned int)time(NULL)) ; n = random() ;

m = random() ;

srandomの部分は,乱数を初期化する部分で,現在の時刻から決まる数を使って初期化をしている.

6.10.9.2 演習問題

Exercise 6.10.4 摂氏と華氏の温度対応は, C = (5/9)(F 32)である. 華氏の温度(整数)を入力し て,摂氏の温度を印字するプログラムを書け. その際,摂氏の温度として,小数点以下切捨て,小数点以下四 捨五入,小数点以下第2桁めを四捨五入の3種類を書け.

Exercise 6.10.5 標準入力から入力された1文字が英字でなければ, そのまま印字し, 大文字の英字なら 小文字に,小文字の英字なら大文字を印字するプログラムを書け. ただし,改行だけが入力された場合には, 終了するようにしなさい. また,入力された文字はASCIIコードで表現されていることに注意せよ.

Exercise 6.10.6 unsigned long型の数値を入力して,それを2進数で表示するプログラムを書け.

Exercise 6.10.7 0から281 までの乱数を十分沢山発生させ,その値が27以下の確率を表示するプロ グラムを書け.

Exercise 6.10.8 次のコードの最後の比較は,どうなるかを考察せよ.

double x ; x = 0.1 ;

if (0.5 == 5*x) {

print ("0.5 と 5 * 0.1 は等しい\n") ; }

else {

print ("0.5 と 5 * 0.1 は等しくない\n") ; }

Exercise 6.10.9 画面に 次のうちの誰が好きですか?

1. 本上まなみ

2. 桜井淳子

3. 戸田菜穂

4. 中山美穂

5. 今井美樹

6. 上原多香子 7. 若村麻由美 8. 葉月里緒菜

9. 松雪泰子

0. どれでもない

と表示して, 0 〜9 迄を入力した時には, 何か好きなことを表示して, それ以外の時には, もう一度質問を 表示するプログラムを書け. (当たり前なのだが,別に葉月里緒菜などにする必要はない.)

Exercise 6.10.10 次のプログラムの出力結果がなぜそのようになるかを考えよ.

#include <stdio.h>

int x ;

int main(int argc, char **argv) {

x = 0 ;

if (x == 0) { printf("if part\n") ; } else { printf("else part\n") ; } if (x) { printf("if part\n") ; } else { printf("else part\n") ; } if (!x) { printf("if part\n") ; } else { printf("else part\n") ; } x = 1 ;

if (x&1) { printf("if part\n") ; } else { printf("else part\n") ; } if (x&1==0) { printf("if part\n") ; } else { printf("else part\n") ; } return 0 ;

}

ドキュメント内 note.dvi (ページ 53-56)