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から231−1の乱数を発生させる. 通常,次のように して使う.
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から28−1 までの乱数を十分沢山発生させ,その値が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 ;
}