2009年9月29日火曜日

第14回 for文③ 多重ループ

お題:
原点を通る一次関数(y=a*x)のグラフを■で表現する。グラフはx,y軸が正の領域(第一象限)のみ。
①初めにグラフの規模(n*n)を尋ね、設定する。nは整数で、n<100。
②一次関数の傾きaを尋ね、設定する。aは小数点にも対応する。
③グラフを描く。

プログラム実行例:
imageimageimage

必須事項:
・for文を2回以上使う事

注意事項:
・if文なども駆使してください
・全角記号□と■は半角数字の2個分のスペースです
・表現方法はたくさんあるので、上の実行例と全く同じにしなくても大丈夫です

解答は10月3日に掲載します。それまでにプログラムを作成し、
・プログラム文
・その実行ファイル
をメールに添付して以下のアドレスに送ってください。

解答、質問はこちらまで
cosmo-cleaner@za.pial.jp

---------------------------------------------------------------

解答例

1

2
3
4

5
6
7
8

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32

#include <stdio.h>

int main () {
    int n,x,y;
    double a;

    puts("グラフの規模は? n×n");
    printf("n=");    scanf("%d",&n);
    printf("\n直線の傾きは?\n");
    printf("a=");    scanf("%lf",&a);

    for(y=n;y>=0;y--){
        if (y > 9)
            printf("%d",y);
        else
            printf(" %d",y);
       for(x=0;x<=n;x++){
            if (a*x >= y && a*x <y+1){
                printf("■");
            }
            else if (x >= y/a && x - 1< y/a)
                printf("■");
            else
                printf("□");
        }
        printf("\n");
    }

    printf("  ");
    for(x=0;x<=n;x++) {
        if (x < 10)
            printf("%d ",x);
        else
            printf("%d",x);
    }
}

実行例は上と同じです

解説

今回使った変数とその役割

n
x
y

a
グラフの規模(x,y軸の表示する範囲)
xの値
yの値
直線の傾き

紫のfor文はy軸で、青いfor文はx軸です。
グラフはy軸正方向(上)から描いていくので、for文も上からに設定します。なので9行目の通り、y=nから始まり、y=0になるまで1づつ降りて行きます。

青いfor文はx=0からx=nまで1づつ増やしながら■か□を1つづつ表示していきます。
考え方としては、下の図のようなイメージです。
image

現在紫のfor文で実行中のyの値とa*xがぶつかった所に■、それ以外には□を表示します。yは整数なのでa*xが小数の時にも対応するため、15行目のように、”1”の大きさの範囲を設けます。

18行目は直線が途切れなく表示されるためのif文です。これが無いと以下のようになります。

image

なぜ空白があくかというと、下の図のようなイメージです。

image

この時、現在のyに注目し、図の緑の点が現在のxの範囲に入っているかどうかを検討します。それが18行目です。
これさえあれば15行目はいらないのでは?と思うかもしれませんが、18行目だけだと傾きaが1以下の時に、同じような空白が出る現象が起こります。

答えられる範囲で質問いつでも受け付けます。
cosmo-cleaner@za.pial.jp

2009年9月27日日曜日

第13回 for文② 多重ループ

お題:
物体を自由落下させた時に進む距離を求めるプログラムを作成する。
様々な初速度で落下させ、重力によってどれだけ落ちるかを計算する。
①初速度は0,1,2,3,4,5,6,7[m/s]
②重力の加速度は9.8[m/s^2]とする
③落下させてから0秒から1秒ごとの落下距離を表示する。n秒まで表示させる
④nを初めに入力させる

プログラム実行例:

何秒後まで表示させますか?
n=5

初速度  0[m/s],1[m/s],2[m/s],3[m/s],4[m/s],5[m/s]
1秒      4.9[m],5.9[m],6.9[m],7.9[m],8.9[m],9.9[m]
2秒 ・・・
・・・
5秒 ・・・

必須事項:
・for文を2回使う事

注意事項:
・二乗は単純に二回掛けください
・分数を使う場合は数式をよく確認してください

予備知識:

等加速度運動をする物体が進む距離Xは、時間をt、初速度をv、加速度をaとすると、以下の式で表されます

X = v*t + (a*t^2) / 2

for文の中にfor文を入れる事が出来ます。例えば、123456・・・と数字を並べて、1行7つ数字を表示すると改行するようにするには、以下のようなプログラムになります。

#include <stdio.h>

int main () {
    int i,t,y;
    i=0;
    for (t=1;t<=5;t++) {
        for(y=1;y<=7;y++) {
            i++;
            printf("%d ", i);
        }
        printf("\n");
    }
}

(実行結果)
image

このプログラムでは
tが行
yが列
iが数

の変数です。iは青い部分のfor文を抜けても数値は保存されたままなので、カウントアップできます。

解答は9月28日に掲載します。それまでにプログラムを作成し、
・プログラム文
・その実行ファイル
をメールに添付して以下のアドレスに送ってください。

解答、質問はこちらまで
cosmo-cleaner@za.pial.jp

---------------------------------------------------------------

解答例

1

2
3
4
5

6
7
8

9
10
11
12
13

14
15
16
17
18
19
20
21

#include <stdio.h>

int main () {
    int n,t,v;
    double a;
    a=9.8;

    puts("何秒後まで表示させますか?");
    printf("n=");    scanf("%d",&n);
    puts("");

    printf("初速度 ");
    for (v=0;v<=7;v++) {
        printf("%d[m/s], ",v);
    }
    printf("\n");

   for(t=1;t<=n;t++){
        printf("%d秒    ",t);
        for(v=0;v<=7;v++){
            printf("%.1f[m],",v*t+a*t*t/2);
        }
        printf("\n");
    }
}

実行例は次の通りです

image

解説

今回使った変数とその役割

n
t
v

a
求める最大の時間(秒)
時間(秒)
初速度[m/s]
重力の加速度9.8[m/s^2]

赤いfor文が行、青いfor文が列です。
まず、赤いfor文でtを設定し、青いfor文で初速度vを1づつ増やしながらtを代入していきます。青いfor文で初速度v=7[m/s]までいくと一行が完成し、赤いfor文に戻り、tが1秒増え、また青いfor文に入ります。

printf(“\n”)で最後の改行を入れています。

17行目の%.1fは、小数点以下2桁目を四捨五入して小数点以下1桁から上を表示させるという意味です。

答えられる範囲で質問いつでも受け付けます。
cosmo-cleaner@za.pial.jp

2009年9月22日火曜日

第12回 for文①

お題:
第11回と同じプログラムをfor文を使って作成する
n個の整数に関して数値をそれぞれ入力し、その整数の合計を求めるプログラム
①はじめに、整数の個数nを入力させる
②n個分の整数を入力する
③合計値を出す

プログラム実行例

整数の個数nを入力してください
n=3
a0=3
a1=4
a2=5
よって合計値は
3+4+5=12
です

必須事項
・for文、配列を使う事

注意事項
・合計値の式はfor文で工夫
・配列の数え方 (a[0],a[1],a[2]・・・)
・配列は事前にたくさん用意すると対応できる (百個とか)

予備知識:
for文は以下のように書きます。

for ( ① ; ② ; ③ ) {
    命令文;
}

for文はwhile文と同じ、ブロックの中の命令文を繰り返して実行するものです。①、②,③で、繰り返しを制御します
①は初期値のようなものです。for文の繰り返しの1回目に1度だけ実行されます。
②は繰り返しの条件です。この条件に合う時だけ繰り返します。
③はブロックの中の命令文が実行された後に実行されます。

例えば、変数iを0から5まで表示したい場合は、

for(i=0;i<=5;i++){
    printf("%d \n",i);
}

となります。i=0が初期値で、iが5になるまで、printfでiを表示します。printfで表示した後はi++が実行され、iが1増えて、また最初にもどり条件に合うかどうか判断されます。合わない場合、つまりiが6以上になるとfor文から抜けます。

解答は9月24日に掲載します。それまでにプログラムを作成し、
・プログラム文
・その実行ファイル
をメールに添付して以下のアドレスに送ってください。

解答、質問はこちらまで
cosmo-cleaner@za.pial.jp

---------------------------------------------------------------

解答例

1

2
3

4
5

6
7
8
9

10

11
12
13
14
15
16

#include <stdio.h>

int main () {
    int n,a[100],i,sum;

    puts("整数の個数nを入力してください");
    printf("n=");    scanf("%d",&n);

   for ( i=0; i<=n-1; i++) {
        printf("a%d = ",i);
        scanf("%d",&a[i]);
    }

    puts("よって合計値は");

   for ( i=0; i<=n-2; i++) {
        printf("%d + ",a[i]);
        sum += a[i];
    }
     printf("%d = %d",a[n-1],sum + a[n-1]);
}

実行例は次の通りです

整数の個数nを入力してください
n=4
a0 = 123
a1 = 456
a2 = 789
a3 = 321
よって合計値は
123 + 456 + 789 + 321 = 1689

解説

第11回のwhile文よりスッキリしたプログラムになりました。

赤い部分、青い部分は第11回と対応しています。

答えられる範囲で質問いつでも受け付けます。
cosmo-cleaner@za.pial.jp

2009年9月16日水曜日

第11回 while文③ 配列を使ったプログラム

お題:
n個の整数に関して数値をそれぞれ入力し、その整数の合計を求めるプログラム
①はじめに、整数の個数nを入力させる
②n個分の整数を入力する
③合計値を出す

プログラム実行例

整数の個数nを入力してください
n=3
a0=3
a1=4
a2=5
よって合計値は
3+4+5=12
です

必須事項
・while文、配列を使う事

注意事項
・合計値の式はwhile文で工夫
・配列の数え方 (a[0],a[1],a[2]・・・)
・配列は事前にたくさん用意すると対応できる (百個とか)

予備知識:
配列は、数値を入れる箱です。箱を用意する方法は

int = a[3];

と書きます。この場合、a[0],a[1],a[2]という3つの箱ができます。

配列は、例えばiという変数を用意した時、

a[i]

といった書き方が出来ます。iにはもちろん数字を入れなければなりませんが、iが1づつ増えていく場合、a[i]とするだけで、a[0],a[1],a[2]とiの数の配列が指定されることになり、便利です。

解答は9月18日に掲載します。それまでにプログラムを作成し、
・プログラム文
・その実行ファイル
をメールに添付して以下のアドレスに送ってください。

解答、質問はこちらまで
cosmo-cleaner@za.pial.jp

---------------------------------------------------------------

解答例

1

2
3
4

5
6

7
8
9
10
11
12

13

14
15
16
17
18
19
20
21

#include <stdio.h>

int main () {
    int a[100],i,n,sum;
    sum=0;

    puts("整数の個数nを入力してください");
    printf("n=");    scanf("%d",&n);

   i=0;
    while (i <= n-1) {
        printf("a%d = ",i);
        scanf("%d",&a[i]);
        i += 1;
    }


    puts("よって合計値は");

    i=0;
    while (i <= n-2) {
        printf("%d + ",a[i]);
        sum += a[i];
        i += 1;
    }

    printf("%d = %d",a[n-1],sum + a[n-1]);
}

実行例は次の通りです

整数の個数nを入力してください
n=10
a0 = 1
a1 = 2
a2 = 3
a3 = 4
a4 = 5
a5 = 6
a6 = 7
a7 = 8
a8 = 9
a9 = 10
よって合計値は
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = 55

整数の個数nを入力してください
n=1
a0 = 1
よって合計は
1 = 1

解説

赤い部分(3行目)はa[100]とすることで、a[0]からa[99]までの変数を作っています。これは、入力する整数を記憶する変数になり、つまりこのプログラムは100個までの足し算が出来る事になります。

青い部分では、入力する数値を受け付けます。iが配列a[?]?を指定しています。iは初めは0でwhile文に入ります。printfでa0=と出力され、scanfでa[0]に数値が代入されます。
i += 1; は、i=i+1; と同じ意味になります。while文を実行すると最後にiが1増えます。
これが整数の個数n回だけ繰り返されます。a[0]からa[n-1]まで数字が入る事になります。

紫の部分では、計算式と合計値を表示します。while文で計算式をどんどん書いています。整数の個数n個分繰り返すと、計算式の最後に+が出てきてしまうので、while ( i <= n-2 ) { としています。n-1個分繰り返して、最後にa[n-1]だけを添えます
while文では計算式を書くと同時に合計値sumの計算をしています。while文はn-1回しか繰り返さないので、正確には
sum = a[0] + ・・・ + a[n-2]
で、本当の合計値はsum + a[n-1]となります。

答えられる範囲で質問いつでも受け付けます。
cosmo-cleaner@za.pial.jp