下記のような時刻を書き出すプログラムが在ります。構造体や,まだ学んでいない標準関数が使われていますが、そこは本題ではないので気にしないでください。
/*time.c*/ #include<stdio.h> #include<time.h> int main(void) { time_t timer,now; int h; now=time(&timer); /*hに現在の時間を取り出す*/ h=localtime(&now)->tm_hour;/*警告されますが無視*/ printf("%d時です\n",h); return 0; }
ここで変数hに入る値は24時間制です。これを12時間制にして午前午後を付けて書き出すように書き換えなさい。
と書き出す
先ほどの例を基に、時刻に合わせた挨拶を
と書き出すプログラムを書いてください。(条件式の書き方に注意)
ここで上2つを組み合わせて
「おはようございます。 午前6時です。」のように書き出すプログラムを書いてください。
どちらが良いと思います?
似たような処理を繰り返すプログラムを、始めから繰り返しの構文で作ろうとすると難しい。
初めは、構文を使わずに少し繰り返しでプログラムを書いてみましょう。まったく同じことの繰り返しなら簡単に繰り返しの構文が使えます。でも繰り返しのように見えてどこか違うことが多いのです。
その違いを上手く繰り返しの構文の中に吸収するノウハウを見つけてください。
for文は繰り返しの回数が明らかなものに用いることが多い構文です。10回まわるとか100回まわるとか解っている場合にはfor文が使われます。
フィボナッチ数列は
A0=A1=1で
1<nについては
An = An-1 + An-2
となる数列です。ここで、繰り返しの構文を使わずにn=9まで計算する例を作ってみました。
/*Fibonacci.c フィボナッチ数列 Fibonacci sequence */ #include<stdio.h> int main(void) { int a[10]; a[0]=1; printf("a[0]=%d\n",a[0]); a[1]=1; printf("a[1]=%d\n",a[1]); a[2]=a[0]+a[1]; printf("a[2]=%d\n",a[2]); a[3]=a[1]+a[2]; printf("a[3]=%d\n",a[3]); a[4]=a[2]+a[3]; printf("a[4]=%d\n",a[4]); a[5]=a[3]+a[4]; printf("a[5]=%d\n",a[5]); a[6]=a[4]+a[5]; printf("a[6]=%d\n",a[6]); a[7]=a[5]+a[6]; printf("a[7]=%d\n",a[7]); a[8]=a[6]+a[7]; printf("a[8]=%d\n",a[8]); a[9]=a[7]+a[8]; printf("a[9]=%d\n",a[9]); return 0; } /* a[0]=1 a[1]=1 a[2]=2 a[3]=3 a[4]=5 a[5]=8 a[6]=13 a[7]=21 a[8]=34 a[9]=55 */
問題:for文を用いてn=20まで計算するプログラムを書きなさい。
A20=10946
次のような三角関数の表を書き出すプログラムをfor文を使って書きなさい。
角度[deg] | sin | cos |
0deg | 0.000000 | 1.000000 |
10deg | 0.173648 | 0.984808 |
20deg | 0.342020 | 0.939693 |
30deg | 0.500000 | 0.866025 |
40deg | 0.642788 | 0.766044 |
50deg | 0.766044 | 0.642788 |
60deg | 0.866025 | 0.500000 |
70deg | 0.939693 | 0.342020 |
80deg | 0.984808 | 0.173648 |
90deg | 1.000000 | 0.000000 |
三角関数の計算には下記の標準関数が使えます。
これらの関数を使うにはヘッダーファイルmath.hをincludeすることが必要です。さらに定数として円周率M_PIを使うにはmath.hをインクルードする前に_USE_MATH_DEFINESを#defineで定義しておくことが必要です。 以下にfor文を使わない例を示します。
/*sin_cos.c*/ #include<stdio.h> #define _USE_MATH_DEFINES #include<math.h> int main(void) { double x; printf("角度[deg] sin cos\n"); d=0 ; printf("%2ddeg %.6lf %.6lf\n",d,sin(d/180.0*M_PI),cos(d/180.0*M_PI)); d=10; printf("%2ddeg %.6lf %.6lf\n",d,sin(d/180.0*M_PI),cos(d/180.0*M_PI)); d=20; printf("%2ddeg %.6lf %.6lf\n",d,sin(d/180.0*M_PI),cos(d/180.0*M_PI)); d=30; printf("%2ddeg %.6lf %.6lf\n",d,sin(d/180.0*M_PI),cos(d/180.0*M_PI)); d=40; printf("%2ddeg %.6lf %.6lf\n",d,sin(d/180.0*M_PI),cos(d/180.0*M_PI)); d=50; printf("%2ddeg %.6lf %.6lf\n",d,sin(d/180.0*M_PI),cos(d/180.0*M_PI)); return 0; } /* 角度[deg] sin cos 0deg 0.000000 1.000000 10deg 0.173648 0.984808 20deg 0.342020 0.939693 30deg 0.500000 0.866025 40deg 0.642788 0.766044 50deg 0.766044 0.642788 */
次のような、99の掛け算表の16進数版を書き出すプログラムを書きなさい。
1 2 3 4 5 6 7 8 9 A B C D E F 2 4 6 8 A C E 10 12 14 16 18 1A 1C 1E 3 6 9 C F 12 15 18 1B 1E 21 24 27 2A 2D 4 8 C 10 14 18 1C 20 24 28 2C 30 34 38 3C 5 A F 14 19 1E 23 28 2D 32 37 3C 41 46 4B 6 C 12 18 1E 24 2A 30 36 3C 42 48 4E 54 5A 7 E 15 1C 23 2A 31 38 3F 46 4D 54 5B 62 69 8 10 18 20 28 30 38 40 48 50 58 60 68 70 78 9 12 1B 24 2D 36 3F 48 51 5A 63 6C 75 7E 87 A 14 1E 28 32 3C 46 50 5A 64 6E 78 82 8C 96 B 16 21 2C 37 42 4D 58 63 6E 79 84 8F 9A A5 C 18 24 30 3C 48 54 60 6C 78 84 90 9C A8 B4 D 1A 27 34 41 4E 5B 68 75 82 8F 9C A9 B6 C3 E 1C 2A 38 46 54 62 70 7E 8C 9A A8 B6 C4 D2 F 1E 2D 3C 4B 5A 69 78 87 96 A5 B4 C3 D2 E1
16進数で数値を書き出す書式指定子は%Xです。
while文は繰り返しの回数が不明で、繰り返しの条件のみが解っているときに良く使われます。
回数が不明なのでfor文の例題のように同じことを何度も書く形のプログラムにはできないことが多い。初めから繰り返しの構文を使って考えることになるでしょう。ここで大事なのは繰り返しの条件です。
標準入力からスペースや改行で区切られた整数値を読み込んで合計する。0が読みこまれた時を合計の終端とし、そこまでの合計値を標準出力に書き出すプログラムを書きなさい。
ヒント:scanf関数を使って読み取った数値を入れる変数、 数値を積算して行く変数などが必要です。
ヒント:繰り返しの条件は読み取った数値が0以外。
for文、while文のどちらでも繰り返しのプログラムを書くことができます。for文で書かれたプログラムをwhile文で書き直すのは難しくありません。繰り返しの回数が固定ならfor文の方が解り易く書けるだけのことです。
次のfor文で書かれたプログラムをwhile文で書き直しなさい。
#include<stdio.h> int main(void) { double sum=0; int n; int max=10000; for( n=max; 0<n; n--) { sum += 1.0/(n*n); } printf("1/n^2のn=1から%dまでの合計は %lf\n",max,sum); return 0; } /* 1/n^2のn=1から10000までの合計は 1.644834 */
関数f(x)が与えられていて、方程式 x=f(x) の解を求めたいとき、fのxによる微分df(x)/dxの絶対値が1以下であれば逐次代入法と呼ばれる計算方法が使えます。この方法はxの初期値x0から初めて
x1=f(x0); x2=f(x1); x3=f(x2); x4=f(x3); x5=f(x4); ...
と繰り返し計算しているうちにxnとxn-1の差が小さくなり収束して近似解xnが得られる手法です。
プログラムでこの部分を書くとしたら、添え字の終わりが見えないxnは使えませんから2つの変数x0,x1を使いまわすような工夫が必要になります。
x0=1;/*初期値*/ x1=f(x0); x0とx1の差が大きい場合以下を繰り返す。小さければ終了 x0=x1; x1=f(x0); x0とx1の差が大きい場合以下を繰り返す。小さければ終了 ...
1回計算するごとにx0とx1の差を見て収束判定が必要になります。この判定条件は
eps < fabs(x1-x0)
のような条件式で行えます。ここで関数fabsはdouble型の絶対値を戻す標準関数です。epsは十分に小さな数ですが、double型の有効数字は15〜16桁なので10のマイナス14乗程度が良いでしょう。
※fabsを使うためにはmath.hのインクルードが必要です。
問題:
次はx=cos(x)の解xを求める if と goto を用いたプログラム例です。これをwhileを用いて書きなおしなさい。
#include<stdio.h> #include<math.h> double f(double x) { return cos(x); } int main(void) { double x0=1,x1; double eps=1E-14; x1=f(x0); LOOP: if( eps < fabs(x1-x0) ) { x0=x1; x1=f(x0); goto LOOP; } printf("解は %lf\n",x1); return 0; }
do-whileを用いた解答例