明解C言語の中級2章末問題を解いてみた

前回に引き続いて解いてみたシリーズです。
できあがったプログラムをPythonで書いてみるとか洒落たことはしないぜ。
とにかく進む君。

今回は補足があって、この本の例題はおそらくだけどWindowsで学習するのを前提にしているのかなという感じで、clock関数で時間をとったり、CLOCKS_PER_SEC = 1000 になってます。

こちとらはScientificLinuxとgccな環境で、計算時間についてはdifftime関数を使って、CLOCKS_PER_SEC = 1000000 ぐらいになっていますんで、そこんとこよろすく。

では1問目から。

$ cat kadai2-1.c
#include <stdio.h>
#include <time.h>
#include "sleep.h"

int main(void)
{
        int i;
        clock_t c;
        double diff;

        clock_t time0 = time(NULL); //時刻

        for(i = 5; i > 0; i--){
                printf("\r%2d", i);
                fflush(stdout);
                sleep(1000);
        }

        printf("\r\aFIRE!!\n");

        clock_t time1 = time(NULL);
        c = clock();

        printf("プログラム開始から%.1f秒経過しました。\n", diff = difftime(time1, time0));
        printf("クロック数は%dです。\n", c);
    return 0;
}

2問目 手抜きと言えば手抜きだす。

$ cat kadai2-2.c
#include <time.h>
#include <stdio.h>

int sleep(unsigned long x)
{
        clock_t c1 = clock(), c2;
        do{
                if ((c2 = clock()) == (clock_t)-1) // error
                        return 0;
        } while(1000.0 * (c2 - c1) / CLOCKS_PER_SEC < x);
        return (1);
}

void gput(const char *s, int speed)
{
        int i;

        for(i = 0; i < 3; i++){
                putchar(s[i]);
                fflush(stdout);
                sleep(speed);
        }
        putchar('\n');
}

int main(void)
{
        gput("ABC", 100);
}

3問目 sleep関数はヘッダファイルにしました。

$ cat kadai2-3.c
#include <time.h>
#include <stdio.h>
#include <string.h>
#include "sleep.h"

void bput(const char *s, int d, int e, int n)
{
        int i, x;

        for (x = 0; x < n; x++) {
                        printf("\r%s", s);
                        fflush(stdout);
                        sleep (d);

                        printf("\r             ");
                        fflush (stdout);
                        sleep(e);
                }
        putchar('\n');
}

int main(void)
{
        bput("Takeken San", 1000, 500, 5);
}

4問目 どちら向きにするかぐらいは、さすがに入力をとるようにしました。

$ cat kadai2-4.c
#include <time.h>
#include <stdio.h>
#include <string.h>
#include "sleep.h"

void telop(const char *s, int direction, int speed, int n)
{
                int i, a;
                int cnt = 0;
                int name_len = strlen(s);

        if(direction == 0){
                for(a = 0;  a <= n; a++){
                        putchar('\r');

                        for(i = 0; i < name_len; i++){
                                if(cnt + i < name_len)
                                        putchar(s[cnt + i]);
                                else
                                        putchar(s[cnt + i - name_len]);
                        }

                        fflush(stdout);
                        sleep(speed);

                        if(cnt < name_len -1)
                                cnt++;
                        else
                                cnt = 0;
                }
        } else

                for(a = 0; a <= n; a++){
                        putchar('\r');

                        for(i = 0; i < name_len; i++){
                                if(cnt + i < name_len)
                                        putchar(s[cnt + i]);
                                else
                                        putchar(s[cnt + i - name_len]);
                        }

                        fflush(stdout);
                        sleep(speed);

                        if(cnt > 0)
                                cnt--;
                        else
                                cnt = name_len - 1;
                }
}

int main(void)
{
        int muki;
        printf("0 or 1 ->", muki);
        scanf("%d", &muki);
        telop("pikachu", muki, 1000, 5);
}

5問目 デバッグがめんどくさいので、問題数を少なくしてます。あときまぐれでsscanfを使ってみた。

$ cat kadai2-5.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
        int stage;
        int a, b, c;
        int x;
        int n;
        double diff, sum;
        clock_t buf[11];
        char buffer[5];

        srand(time(NULL));

        printf("START \n");

        for(stage = 0; stage < 3; stage++){
                a = 1 + rand() % 100; // 乱数を生成
                b = 1 + rand() % 30;
                c = 1 + rand() % 50;
                n = 1 + rand() % 17;

                buf[stage] = time(NULL);
                printf("%d%*s+%*s%d%*s+%*s%d:", a, n, "", n, "", b, n, "", n, "", c);

                do{
                        fgets(buffer, 10, stdin);
                        sscanf(buffer, "%d", &x);
                        if(x == a + b + c)
                                break;
                        printf("\a違います。");
                }while(1);
        }
        buf[3] = time(NULL); // 計算用に最後に時間をとる

        for(stage = 0; stage < 3; stage++){
        printf("%d回目%.lf秒\n", stage+1, diff = difftime(buf[stage+1], buf[stage]));
        sum += diff;
        }
        printf("平均%.2f秒かかっているようですな\n", sum / 3);
        return 0;
}

6問目 慣れてないと、こういう画面1枚に入れらないのを書くのが難しい。

$ cat kadai2-6b.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
        int keisan;
        int stage;
        int a, b, c;
        int x;
        int n;
        double diff, sum;
        clock_t buf[11];
        char buffer[5];

        srand(time(NULL));
        printf("START \n");

        for(stage = 0; stage < 3; stage++){
                a = 1 + rand() % 100; // 乱数を生成
                b = 1 + rand() % 30;
                c = 1 + rand() % 50;
                n = 1 + rand() % 17;
                keisan = rand() % 4;

                buf[stage] = time(NULL);

                switch(keisan){
                        case 0:printf("%d%*s+%*s%d%*s+%*s%d:", a, n, "", n, "", b, n, "", n, "", c);
                                do{
                                        fgets(buffer, 10, stdin);
                                        sscanf(buffer, "%d", &x);
                                                if(x == a + b + c)
                                                        break;
                                        printf("ちがいます");
                                }while(1);

                                break;

                        case 1:printf("%d%*s+%*s%d%*s-%*s%d:", a, n, "", n, "", b, n, "", n, "", c);
                                do{
                                        fgets(buffer, 10, stdin);
                                        sscanf(buffer, "%d", &x);
                                                if(x == a + b - c)
                                                        break;
                                        printf("ちがいます");
                                }while(1);

                                break;

                        case 2:printf("%d%*s-%*s%d%*s+%*s%d:", a, n, "", n, "", b, n, "", n, "", c);
                                do{
                                        fgets(buffer, 10, stdin);
                                        sscanf(buffer, "%d", &x);
                                                if(x == a - b + c)
                                                        break;
                                        printf("ちがいます");
                                }while(1);

                                break;

                        case 3:printf("%d%*s-%*s%d%*s-%*s%d:", a, n, "", n, "", b, n, "", n, "", c);
                                do{
                                        fgets(buffer, 10, stdin);
                                        sscanf(buffer, "%d", &x);
                                                if(x == a - b - c)
                                                        break;
                                        printf("ちがいます");
                                }while(1);

                                break;
                }

        }
        buf[3] = time(NULL); // 計算用に最後に時間をとる

        for(stage = 0; stage < 3; stage++){
        printf("%d回目%.lf秒\n", stage+1, diff = difftime(buf[stage+1], buf[stage]));
        sum += diff;
        }
        printf("平均%.2f秒かかっているようですな\n", sum / 3);
        return 0;
}

こんな感じです。

この中級編ですが、例題からこなしていって、応用>応用と追うように進めるので、学習しやすいようにはなっているようだ。

まだまだ先の話だけど、この本が終わったら別の著者のポインタの本に進もうかなと。んで次からOSを作ってみようって本があるみたいなんで、それを見てみようかなあと。

 

んな感じです。

 

Similar Posts:


Leave a Reply

Your email address will not be published. Required fields are marked *