[[Cygwinでデバッグ]]
#contents

** 例題 [#y07d8f9b]

例題を思いつくまま書き連ねてみます。

** 問 [#q22b5668]
+
 #include <stdio.h>
の "stdio" の読み方を記せ。
+ 以下のプログラムを読んで、次の問に答えよ。
 #include <stdio.h>
 
 int five_times(int x) {  /* (1) */
     x *= 5;              /* (2) */
     return x;            /* (3) */
 }
 
 int main(void) {
     int x = 5;                      /* (4) */
     int y = 10;                     /* (5) */
     
     printf("%d\n", five_times(x));  /* (6) */
     printf("%d\n", five_times(x));  /* (7) */
     printf("%d\n", five_times(y));  /* (8) */
     printf("%d\n", five_times(y));  /* (9) */
     return 0;
 }
++ (3) で返される x の変数と同じものは (1)〜(2), (4)〜(9) のうちどれであるか。
++ (2) で x の値は5倍になるが、(6) と (7) の表示は同じになるか。
++ (2) で x の値は5倍になるが、(8) と (9) の表示は同じになるか、それともコンパイルエラーになるか。

** 位取り [#c828b2ad]
次のような場合の時刻を表示せよ。時刻は 12:34:56 のような形式(24時間制)で表示するとする。(解答例は &ref(hms.c);)
+ (例) ある時計台では、7時〜21時の間、毎時0分に時報が鳴る。時報の鳴る時刻を表示せよ。
-- 出力例
  7:00:00
  8:00:00
  9:00:00
 10:00:00
 ...
 20:00:00
 21:00:00
-- プログラム例
 int i;
 for (i=7; i<=21; i++) {
     printf("%2d:00:00\n", i);
 }
+ ある駅では、7時から21時30分まで、30分おきに電車が出発する。電車が出発する時刻を表示せよ。
-- 出力例
  7:00:00
  7:30:00
  8:00:00
  8:30:00
 ...
 21:00:00
 21:30:00
+ ある駅では、7時から、30分おきに1本ずつ、合計14本の電車が出発する。電車が出発する時刻を表示せよ。
+ ある駅では、7時から、30分おきに1本ずつ、合計15本の電車が出発する。電車が出発する時刻を表示せよ。
-- プログラムのヒント(途中まで)
    int i, h=7, m=0, s=0;
 
    for (i=0; i<15; i++) {
        printf("%2d:%02d:%02d\n", h, m, s);
        m = m + 30;
        ...
+ ある駅では、7時から、35分おきに1本ずつ、合計15本の電車が出発する。電車が出発する時刻を表示せよ。
+ ある駅では、7時から、65分おきに1本ずつ、合計15本の電車が出発する。電車が出発する時刻を表示せよ。
+ ある駅では、7時から、65分おきに1本ずつ、合計20本の電車が出発する。電車が出発する時刻を表示せよ。
~ 
+ 深夜の宿直の交代は 20時から始まって3時間ごとで、翌朝8時まで続く。交代の時刻を表示せよ。
+ 20時から翌朝8時までの宿直の間、50分ごとに冷蔵庫の庫内温度を記録する。記録すべき時刻を出力せよ。
-- 出力例
 20:00:00
 20:50:00
 21:40:00
 ....
+ 20時から翌朝8時までの宿直の間、50分ごとに冷蔵庫の庫内温度を記録する。50分ごとにアラームの鳴る時計を利用したが、精度不良のため、実際には49分51秒ごとに記録していた。記録していた時刻を出力せよ。
-- 出力例
 20:00:00
 20:49:51
 21:39:42
 ....


** 考察せよ [#qccd6c85]
次の2つのプログラムの違いを考察せよ。
- (1)
 for (i=0; i<10; i++) {
    printf("接点番号 %d のx座標は %d で、y座標は %d です。\n", i, point[i].x, point[i].y);
 }
~
 for (i=0; i<10; i++) {
     printf("接点番号 %d のx座標は %d で、y座標は %d です。\n",
            i, point[i].x, point[i].y);
 }

- (2)
(デバッグライト (debug write) として)
 printf("%d\n", i);
 printf("%d\n", a[j]);
~
 printf("i=%d\n", i);
 printf("a[%d]=%d\n", j, a[j]);

- (3)
 int a[10];
 int sum = 0;
 ...
 for (i=0; i<=9; i++) {
     sum += a[i];
 }
~
 int a[10]
 int sum = 0;
 ...
 for (i=1; i<=10; i++) {
     sum += a[i-1];
 }

- (4)
 int a[10], b[10];
 ...
 for (i=0; i<10; i++) { a[i] = i; }
 for (i=0; i<10; i++) { b[i] = b[i] + a[i]; }
~
 int a[10], b[10];
 ...
 for (i=0; i<10; i++) {
     a[i] = i;
     b[i] = b[i] + a[i];
 }
次の場合について、2つのループを1つに統合できるのか考察せよ。
+++ 今回のケースに限った場合
+++ 一般の場合(いつでも)

** 間違いを直せ [#qd244603]

- (1)
 #include <stdio.h>
 
 int main(void) {
     int x = 5;
 
     printf("5x^2 + 3x + 1 = %d\n", 5x*x + 3x + 1);
     return 0;
 }
ちなみに、コンパイル時に以下のようなエラーが出る。
 $ gcc -Wall hoge.c
 hoge.c:6:37: error: invalid suffix "x" on integer constant
 hoge.c:6:44: error: invalid suffix "x" on integer constant

- (2)
 #include <stdio.h>
 #include <math.h>
 
 int main(void) {
     int x = 5, y = 7;
 
     printf("原点と (%d,%d) の距離は %g です。\n",
            x, y, sqrt(x ^ 2 + y ^ 2));
     return 0;
 }
ちなみに、コンパイル時には警告も出ないが、実行結果は以下のようになる。
 原点と (5,7) の距離は 3.74166 です。

- (3)
 #include <stdio.h>
 
 int main(void) {
     int i, a = 5;
 
     for (i=0; i<10; i++) {
         if (a = i) {
             printf("a=%d と i=%d は等しい\n", a, i);
         }
     }
     return 0;
 }
ちなみに、コンパイル時に以下のような警告が出る。
 $ gcc -Wall hoge.c
 hoge.c: In function ‘main’:
 hoge.c:7: 警告: 真偽値として使われる代入のまわりでは、丸括弧の使用をお勧めします
そのまま実行すると、次の出力のようになる。
 $ ./a.exe
 a=1 と i=1 は等しい
 a=2 と i=2 は等しい
 a=3 と i=3 は等しい
 a=4 と i=4 は等しい
 a=5 と i=5 は等しい
 a=6 と i=6 は等しい
 a=7 と i=7 は等しい
 a=8 と i=8 は等しい
 a=9 と i=9 は等しい

- (4)
 #include <stdio.h>
 
 int five_times(int x) {
     return x * 5;
 }
 
 int main(void) {
     int y = 3;
 
     printf("%d\n", five_times(int y));  /* 15 が表示されるようにしたい */
     return 0;
 }
ちなみに、コンパイル時に以下のようなエラーメッセージが出る。
 $ gcc -Wall hoge.c
 hoge.c: In function ‘main’:
 hoge.c:10: error: expected expression before ‘int’
 hoge.c:8: 警告: unused variable ‘y’

- (5)
 #include <stdio.h>
 
 int main(void) {
     int i, max, min;
     int a[10];
 
     for (i=0; i<10; i++) {
         printf("%d 個めのデータを入力して下さい >> ", i+1);
         scanf("%d", &a[i]);
     }
 
     for (i=0; i<10; i++) {
         if (min < a[i]) {
             min = a[i];
         }
         if (max > a[i]) {
             max = a[i];
         }
     }
     printf("データの最大値は %d です。\n", min);
     printf("データの最小値は %d です。\n", max);
     return 0;
 }
ちなみに、コンパイル時に以下のような警告が出る。
 $ \gcc -Wall -O hoge.c
 hoge.c: In function ‘main’:
 hoge.c:4: 警告: ‘min’ may be used uninitialized in this function
 hoge.c:4: 警告: ‘max’ may be used uninitialized in this function
実行例は以下のようになる。
 $ ./a.exe
 1 個めのデータを入力して下さい >> 2     
 2 個めのデータを入力して下さい >> 4
 3 個めのデータを入力して下さい >> 6
 4 個めのデータを入力して下さい >> 8
 5 個めのデータを入力して下さい >> 6
 6 個めのデータを入力して下さい >> 4
 7 個めのデータを入力して下さい >> 2
 8 個めのデータを入力して下さい >> 0
 9 個めのデータを入力して下さい >> -5
 10 個めのデータを入力して下さい >> 10
 データの最大値は 10 です。
 データの最小値は -1074566468 です。

- (6)
 #include <stdio.h>
 
 int main(void)
 {
     int i, sum = 0;
 
     for (i=1; i<=10; i++);
     {
         sum = sum + i;  /* 1〜10 までの和を求める */
     }
     printf("sum = %d\n", sum);
     return 0;
 }
ちなみに、コンパイル時には警告もない。実行すると "sum = 11" と表示される。
ヒント:ブロック開始の { を行末に書くと、このような間違いに悩まされずにすむ。

- (7)
 #include <stdio.h>
 
 int main(void) {
     int i, a[10];
 
     for (i=1; i<=10; i++) { a[i] = i * i; }
     for (i=1; i<=10; i++) { a[i] = a[i] + a[i-1]; }
     for (i=1; i<=10; i++) { printf("%d\n", a[i]); }
     return 0;
 }
ちなみに、コンパイル時にも、実行時にもエラーはでない(こともある)。

- (8)
 #include <stdio.h>
 #include <stdlib.h>
 #include <time.h>
 
 int main(void) {
     int i;
 
     for (i=0; i<10; i++) {
         srand(time(NULL));
         printf("%d\n", rand());  /* 毎回異なる値を表示させたい */
     }
     return 0;
 }
ちなみに、実行すると以下のように同じ値が10回表示される。
 % ./a.exe
 817376010
 817376010
 817376010
 817376010
 817376010
 817376010
 817376010
 817376010
 817376010
 817376010

トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS