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

TCP/IPソケットプログラミング C言語編を読みたいが故に柴田望洋さんの明解C言語入門編からC言語の勉強を始めました。でただいま中級編に入ったところです。前回に引き続き章末に自由課題が載っているのでやってみたシリーズ。できあがったプログラムをPythonで書いてみるとか洒落たことはしないでとにかく進む君。この中級編ですが、例題からこなしていって、応用>応用と追うように進めるので、学習しやすいようになっているようだ。

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

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

では1問目から。

#include <stdio.h>
#include <time.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);
}

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("クロック数は %.1lu です。\n", c);
  return 0;
}

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

#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関数はヘッダファイルにしました。

#include <time.h>
#include <stdio.h>
#include <string.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 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問目 どちら向きにするかぐらいは、さすがに入力をとるようにしました。

#include <time.h>
#include <stdio.h>
#include <string.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 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 -> %d", muki);
  scanf("%d", &muki);
  telop("pikachu", muki, 1000, 5);
}

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

#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枚に入れらないのを書くのが難しい。

#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を作ってみようって本があるみたいなんで、それを見てみようかなあと。

 

んな感じです。

Related Posts


投稿者: Takeken

インターネット利用者のITリテラシーを向上したいという設定の2次元キャラです。 サーバー弄りからプログラミングまで手を付けた自称エッセイストなたけけんの物語。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です