[サイトマップ] [トップページ]

トップページ > 授業のページ > コンピュータプログラミングII >
プログラミング課題


更新日
7/12 Fri 23:11

第14回課題

  1. [pe14-1.c] (必須) 次の指示に従ってプログラムを作成しなさい。
    1. リスト 5.3 のプログラムが動作することを確認してから, カードを 5 枚だけ 1 人に配る(最初の 5 枚だけを一列に表示する)ように, 関数 deal を変更しなさい。 deal の変更は関数本体の変更のみとする。

    2. 次の関数定義を先のプログラムの末尾に追加しなさい。
      char *checkPairs(Card *wdeck)
      {
          int i, j;
          static char *result;
      
          result = "";
          for (i = 0; i < 4; i++) {
              for (j = i + 1; j < 5; j++) {
      /***
                  printf("i:%d %d %s - j:%d %d %s\n",
                          i, wdeck[i].face, wdeck[i].suit,
                          j, wdeck[j].face, wdeck[j].suit);
      ***/
                  if (wdeck[i].face == wdeck[j].face) {
                      result = "PAIR(S)";
                  }
              }
          }
      
          return result;
      }
      
    3. 関数 main における関数 deal の呼び出し箇所の後ろに,関数 checkPairs の戻り値を表示するコードを追加することにより,配られた 5 枚のカードに同じ数 (face) のものが含まれていれば,PAIR(S) と表示するようにしなさい。

    以下は関数 checkPairs 内のコメント ( /*** と ***/ ) を外した場合の実行例である。

    実行例 1

           5 of Diamonds
           9 of Hearts  
           2 of Hearts  
           4 of Diamonds
           8 of Diamonds
    
    i:0 5 Diamonds - j:1 9 Hearts
    i:0 5 Diamonds - j:2 2 Hearts
    i:0 5 Diamonds - j:3 4 Diamonds
    i:0 5 Diamonds - j:4 8 Diamonds
    i:1 9 Hearts - j:2 2 Hearts
    i:1 9 Hearts - j:3 4 Diamonds
    i:1 9 Hearts - j:4 8 Diamonds
    i:2 2 Hearts - j:3 4 Diamonds
    i:2 2 Hearts - j:4 8 Diamonds
    i:3 4 Diamonds - j:4 8 Diamonds
    

    実行例 2

           3 of Hearts  
           8 of Spades  
           1 of Hearts  
           1 of Diamonds
           6 of Hearts  
    
    i:0 3 Hearts - j:1 8 Spades
    i:0 3 Hearts - j:2 1 Hearts
    i:0 3 Hearts - j:3 1 Diamonds
    i:0 3 Hearts - j:4 6 Hearts
    i:1 8 Spades - j:2 1 Hearts
    i:1 8 Spades - j:3 1 Diamonds
    i:1 8 Spades - j:4 6 Hearts
    i:2 1 Hearts - j:3 1 Diamonds
    i:2 1 Hearts - j:4 6 Hearts
    i:3 1 Diamonds - j:4 6 Hearts
    PAIR(S)
    

  2. [pe14-2.c] (必須) 前のプログラムの関数 checkPairs を,手札がポーカーのワンペアであるかどうかを判定する関数 isOnePair に書き換えなさい。 この関数は,ワンペアのときに ONE PAIR という文字列を返し,そうでないときには空の文字列を返すこととする。

    ツーペアやスリーカード,フォーカードの場合にワンペアと判定しないようにすること。 そのためには isOnePair の本体でペアがいくつあるかを数え,一つの場合のみワンペアとすればよい。

    さらに,main で isOnePair を呼び出して,ワンペアの場合には,その旨を表示するプログラムにしなさい。

  3. [pea14-1.c] 前のプログラムを,ワンペアに加え,他の少なくと も一つ以上のポーカーの役も判定できるように,役を判定する関数の定 義と呼び出しを追加しなさい。



7/11 Thu 21:15

第13回課題

  1. [pe13-1.c] (必須) 第12回課題 1 (pe12-1.c) のプログラムを基にして,次の指示に従ってプログラムを作成しなさい。
    1. struct point 型の変数 pointA と pointB を宣言し,座標の初期値を各々 (1, 1,5) と (4, 5.5) にしなさい。
    2. 与えられた点の座標を表示する次の関数の定義をプログラムに追加しなさい(下線部には適当な語を入れる)。
      void printCoord(____________ pnt)
      {
           printf("(%___, %___)\n", _______, _______ );
      }
      
      さらに関数 main の本体において, Initial points: と表示した後に, printCoord を呼び出して pointA と pointB の座標を表示するプログラムにしなさい。 実行して次の出力が得られることを確かめなさい。
      Initial points:
      (1.00, 1.50)
      (4.00, 5.50)
      
    3. 2点間の距離を計算する関数 calcDist を定義しなさい。 calcDist は 点(struct point 型の値)を二つ受け取り, 距離を double 型で返すように作ること。 calcDist の本体では printf 等による表示を行わないこと。

      また,関数 main の本体に,calcDist の呼び出しによって pointA と pointB の間の距離を求めて次のように表示するコードを加えなさい。

      Distance: 5.00
      

    4. 点の x 座標と y 座標を,与えられた量だけ増やす(点を移動する)関数 addToCoord を定義しなさい。 addToCoord は
      1. struct point 型の点のアドレス(ポインタ)
      2. x 座標の増加量 dx (double 型)
      3. y 座標の増加量 dy (double 型)
      を受け取って,点の座標を (x+dx, y+dy) にするものとする。 戻り値は返さない。

    5. 関数 addToCoord を呼び出すことで pointA の x, y 座標を 1, 0.5 だけ増やし, さらに pointB の x, y 座標を 0.5, 2.5 だけ増やして, 結果の座標を printCoord で表示させなさい。 さらに 2 点間の距離を calcDist で計算し,結果を表示するコードも加えなさい。 プログラムは,全体として次を出力するようにすること。
      Initial points:
      (1.00, 1.50)
      (4.00, 5.50)
      Distance: 5.00
      Move to:
      (2.00, 2.00)
      (4.50, 8.00)
      Distance: 6.50
      

  2. [pea13-1.c] 次の指示に従い,プログラムを作りなさい。
    1. 平面上の点の座標を格納するための Point 型を定義しなさい。 Point 型は, x 座標と y 座標を保持するために,double 型の構造体メンバー x と double 型の構造体メンバー y を持つこととする。
    2. 平面上の点を原点を中心に反時計回りに45度回転させた点の座標を計算する関数 rotate45deg を作りなさい。

      この関数は Point 型の値を受け取り,回転後の座標を求めて, Point 型の値として返すものとする。 すなわち,この関数のプロトタイプ宣言は

      Point rotate45deg(Point);
      である。

      また,座標 $(x_0, y_0)$ の点を 原点を中心に反時計回りに45度回転させた点の座標 (x, y) は 次式で計算できる。

      $\displaystyle \begin{array}{c}
x = \frac{1}{\sqrt{2}}(x_0 - y_0), \\
y = \fr...
...}{\sqrt{2}}(x_0 + y_0).
\end{array} %x = \frac{\sqrt{2}}{2}(x_0 - y_0), \\
$
      通常,ヘッダファイル math.h には,少なくとも double 型の精度で 2 の平方根の値 (1.4142...) を持つ記号定数 M_SQRT2 やその逆数 M_SQRT1_2 が定義されており,自分のコードに #include <math.h> を書くことによって使えるようになる。 2の平方根を計算せずに済ますために,これらの利用を試すとよい。なお,実習用コンピュータでは,ヘッダファイル math.h のマニュアル(英語)を man math.h で閲覧できる。

    3. 関数 main の中で Point 型の変数 a を宣言し, a に座標 (2, 0) の点としての初期値を設定しなさい。

      次に, 関数 rotate45deg を用いて,a を 45 度回転させた後の座標を求めて表示しなさい。 なお,a の回転を行う文は a = rotate45deg(a); である。

      さらに,もう一度,45度回転させた後の座標も表示するプログラムにしなさい。

      出力例)

      Initial coordinates: (2.000000, 0.000000)
      Rotation: (1.414214, 1.414214)
      Rotation: (0.000000, 2.000000)
      

  3. [pea13-2.c] 座標 $(x_0, y_0)$ の点を 原点を中心に反時計回りに $\theta$ ラジアンだけ回転させた点の座標 (x, y) は 次式で計算できる。
    $\displaystyle \begin{array}{c}
x = ( \cos\theta ) x_0 - ( \sin \theta ) y_0, \...
...ta ) x_0 + ( \cos \theta ) y_0.
\end{array} %x = \cos t\,x_0 - \sin t\,y_0,\
$

    さて, 平面上の点を表す Point 型(前の問題で定義した型)の値(座標値)と角度を受け取って, その角度だけ点を回転させた結果(点の座標値)を求める関数 rotate を定義しなさい。 関数 rotate の戻り値は Point 型とすること。

    さらに,関数 main も定義して,関数 rotate を使う適当なプログラムを作成しなさい。

    なお,通常,ヘッダファイル math.h には,少なくとも double 型の精度の円周率を値とする記号定数 M_PI が定義されており, #include <math.h> によって使えるようになる。

    【参考】点の回転は 2 x 2 の行列を使うと

    $\displaystyle \left(
\begin{array}{c}
x\\
y
\end{array} \right)
=
\left(...
...nd{array} \right)
\left(
\begin{array}{c}
x_0\\
y_0
\end{array} \right)
$
    と書ける。

    <<< 実行例 >>>
    Initial Location (Current 0 deg.): (2.000000, 0.000000)
    Rotate 30 deg. (Current 30 deg.): (1.732051, 1.000000)
    Rotate 30 deg. (Current 60 deg.): (1.000000, 1.732051)
    Rotate 30 deg. (Current 90 deg.): (0.000000, 2.000000)
    Rotate 30 deg. (Current 120 deg.): (-1.000000, 1.732051)
    Rotate 30 deg. (Current 150 deg.): (-1.732051, 1.000000)
    Rotate 30 deg. (Current 180 deg.): (-2.000000, 0.000000)
    



7/4 Thu 20:44

第12回課題

  1. [pe12-1.c] (必須) 次のプログラムは,平面上の点の座標を格納する point 構造体を定義し, 点 pointA の x, y 座標を表示するものである。

    まず, 構造体変数 pointA のメンバー x と y に 1.0 と 1.0 が入るように pointA を宣言・初期化し, その後,pointA のメンバー y の値を,代入文によって 1.5 に変更してから,pointA の座標を表示するプログラムとなるよう,下線部を埋めなさい。

    次に,このプログラムにおいて,点の座標を保持する新たな変数 pointB を宣言して座標 (4.0, 5.5) を与えるコードを加え,その座標も表示するようにしなさい。

    さらに, pointA と pointB の距離を計算して表示するプログラムにしなさい。

    なお,距離の計算には,平方根を求める数学ライブラリ関数 sqrt を使うこと。 座標 $(x_1, y_1)$$(x_2, y_2)$ の点間の距離は $\sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2}$である。

    また,ソースコードの後に記した実行結果を出力をするプログラムにすること。

    #include <stdio.h>
    
    struct point {
         double x;
         double y;
    };
    
    int main()
    {
         _______________ pointA = ______________ ;
    
         _______ = _______ ;
    
         printf("A: (%f, %f)\n", ______ , ______ );
    
         return 0;
    }
    

    実行結果

    A: (1.00, 1.50)
    B: (4.00, 5.50)
    distance: 5.00
    

  2. [pe12-2.c] (必須) プログラム中のコメントの指示に従って下線部を埋めなさい。 ipoint は,整数 (int 型) を座標値とする平面上の点のための構造体であり, 横座標のためのメンバー i と縦座標のためのメンバー j を持つ。 プログラムの実行結果はソースコードの後に示したとおりである。 なお,ポインタ変数を使った点の座標表示では配列の添字記法は使わないこと。
    #include <stdio.h>
    
    #define SIZE 5 /* 配列の要素数 */
    
    /* 構造体 ipoint の定義 */
    _______ ipoint {
         ________ ;
         ________ ;
    };
    
    int main()
    {
         _____________ pnt[_____]; /* SIZE 個の要素を持つ構造体 ipoint 型の配列 */ 
         _____________ p; /* 構造体 ipoint 型を指すポインタ変数 */
         int i;
    
         /* 配列 pnt の各要素(点)に横座標と縦座標の値を設定 */
         for (i = ___; _______; _______) {
              ________ = i;
              ________ = i * 2;
         }
    
         /* 全ての点の座標を表示 */
         for (i = ___; _______; _______) {
              printf("(%___, %___)\n", pnt[i]_____, pnt[i]_____);
         }
         putchar('\n');
    
         /* ポインタ変数 p を使って全ての点の座標を表示 */
         p = ___;
         for (i = ___; _______; _______) {
              printf("(%___, %___)\n", p____, p____);
              ___ ;
         }
    
         return 0;
    }
    

    実行結果

    (0, 0)
    (1, 2)
    (2, 4)
    (3, 6)
    (4, 8)
    
    (0, 0)
    (1, 2)
    (2, 4)
    (3, 6)
    (4, 8)
    



6/28 Fri 03:26

第11回課題

  1. [pe11-1.c] (必須) 次の文
    char *suit[] = {"hearts", "diamonds", "clubs", "spades"};
    により宣言・初期化された配列 suit を使って,
    hearts
    diamonds
    clubs
    spades
    と出力するプログラムを作りなさい。 配列 suit の要素を参照するために for 等による繰り返しの構文を使うこと。

    さらに,文字列の先頭文字を大文字にした

    H D C S
    を出力するコードを追加しなさい。この出力も配列 suit と繰り返し構文で行うこと。 標準ライブラリ関数 toupper を使うこと。

  2. [pe11-2.c] (必須) キーボードから入力した文字の並び(文字数は 10 文字を上限とする)を Hello, に続いて表示するプログラムを次の方法で作りなさい。

    このプログラムは,例えば,world! と入力したら Hello, world! と出力するように作成する。

    1. 文字列 Hello, の入った char 型配列を予め用意しておく。
    2. fgets を用いて,上記の配列内の Hello, の後ろにキーボードから文字列を格納する。
    3. その配列の内容を表示する。
    用意した要素数を越える配列要素への代入はできないプログラムとすること。 なお,キーボードから入力する文字数を制限することによって,文字入力の終わりの改行文字が読み込まれず,出力の最後に改行が起きないことがあり得るが,ここではそのようなプログラムでもよしとする。

  3. [pea11-1.c]次の文
    char *suit[] = {"hearts", "diamonds", "clubs", "spades"};
    により宣言・初期化された配列 suit を使って,
    HEARTS
    DIAMONDS
    CLUBS
    SPADES
    と出力するプログラムを作りなさい。 配列 suit の要素を参照するために for 等による繰り返しの構文を使うこと。 標準ライブラリ関数 toupper を使うこと。



6/20 Thu 22:14

第10回課題

  1. [pe10-1.c] (必須) 次のコードの下線部 (1) から (10) をコメントに従って完成させなさい。 文字を出力する際には必ず配列 a を用いること。
    #include <stdio.h>
    
    int main()
    {
         char a[] = "abcd";
         int i;
         
         printf("#1:");
         /* a と表示する */
         printf("__(1)__\n", __(2)__);
    
         printf("#2:");
         /* abcd と表示する */
         printf("__(3)__\n", __(4)__ );
    
         printf("#3:");
         /* abc と表示する */
         a[__(5)__] = '__(6)__' ;
         printf("%s\n", __(7)__ );
    
         printf("#4:\n");
         /* abc を 1 行につき 1 文字ずつ表示する。*/
         for (i = 0; ____(8)____ ; i++)
             printf("__(9)__", __(10)__);
         
         return 0;
    }
    
    実行結果は次のとおりになる。
    #1:a
    #2:abcd
    #3:abc
    #4:
    a
    b
    c
    

  2. [pe10-2.c] (必須) 次のプログラムの下線部を,コメントの指示に従って埋めなさい。
     
    /* pointer and strings */
    #include <stdio.h>
    
    int main()
    {
        char *p = NULL;
        
    /* 文字列リテラル "abc" の先頭アドレスを表示する */
        printf("%p\n", __(1)__);
    
    /* 文字列リテラル "ABC" の先頭アドレスを p を使って表示する */
        p = __(2)__ ;
        printf("%p\n", p);
    
    /* p を使って A と表示する */
        printf("__(3)__\n", __(4)__ );
    
    /* p を使って BC と表示する */
        __(5)__ ; /* ポインタ演算 */
        printf("__(6)__\n", __(7)__ );
    
    /* p を使った 2 通りの方法で ABC と表示する */
        __(8)__ ; /* ポインタ演算 */
        printf("__(9)__\n", p);
    
        while (*p != __(10)__) {
          printf("__(11)__", *p);
          __(12)__ ; /* ポインタ演算 */
        }
        printf("\n");
    
        return 0;
    }
    
    このプログラムの出力は次のようになる。ただし,アドレスは例示である。
     
    0x402010
    0x402018
    A
    BC
    ABC
    ABC
    

  3. [pea10-1.c] 次のとおりに宣言・初期化された文字列 str1 を表示した後,始めの 5 文字 (Hello の部分) だけを別の配列 str2 にコピーしてから,str2 の内容を文字列にして表示するプログラムを作りなさい。

    char *str1 = "Hello World!";



6/13 Thu 22:28

第9回課題

  1. [pe9-1.c] (必須) 資料のリスト 3.7 を参考にして, double 型配列に入った値を逆順(左右対称)に入れ替えて表示するプログラムを作りなさい。 ただし,二つの double 型変数の値(内容)を交換する関数 dswap を定義して使うこと。

    下記のように出力するプログラムを作ること。 配列の初期値はプログラム内で与えておくこと。

    Initial array:
     5.0 1.5 3.5 2.0 4.5 4.0 1.0
    Calling dswap.
    Reversed array:
     1.0 4.0 4.5 2.0 3.5 1.5 5.0
    

  2. [pea9-1.c] 資料のリスト 3.7 のプログラムを,double 型の配列に対して降順のソートを行うプログラムに変更しなさい。 ソートの対象となる配列は,前の問題と同じものとする。

    また,リスト 3.7 のソートプログラムにおける繰り返しの回数には無駄がある。 余分な繰り返しを無くすように,関数 bubbleSort を改良しなさい。



6/6 Thu 23:33

第8回課題

  1. [pe8-1.c] (必須) 次のプログラムにおいて, 注釈 #1と#2のprintfによる表示が同じになるように空白部分を埋めなさい。 ただし,#2 では配列の添字 [ ] を使わないこと。 #3と#4,並びに#5と#6も同じになるようにしなさい。
    #include <stdio.h>
    
    int main()
    {
        int a[5] = {1, 3, 5, 7, 9};
        int *p = NULL;
    
        printf("#1 %p\n", &a[0]);     /* #1 */
        printf("#2 %p\n", __(1)__ );  /* #2 */
        p = __(1)__ ;
    
        printf("#3 %p\n", &a[3]);     /* #3 */
        p += __(2)__ ;
        printf("#4 %p\n", p);         /* #4 */
    
        printf("#5 %d\n", a[1]);      /* #5 */
        p -= __(3)__;
        printf("#6 %d\n", __(4)__ p); /* #6 */
    
        return 0;
    }
    

  2. [pe8-2.c] (必須) まず,下記のプログラムを実行して, 予想どおりの結果が得られるか,確認しなさい。

    次に, 関数 incByVal と incByRef を使って,1 から 5 までの整数を,それぞれ 1 回ずつ表示するよう, このプログラムに必要な変更を施しなさい。

    ただし,incByVal に関わる変更は,関数 incByVal の本体のみとすること。 また,関数 incByRef は戻り値を返さないまま (void) とすること。

    #include <stdio.h>
    
    int  incByVal(int);
    void incByRef(int);
    
    int main()
    {
        int i, a = 0, b = 0;
      
        for (i = 0; i < 5; ++i) {
            a = incByVal(a);
            printf("a = %d\n", a);
        }
    
        for (i = 0; i < 5; ++i) {
            incByRef(b);
            printf("b = %d\n", b);
        }
    
        return 0;
    }
    
    int incByVal(int c)
    {
        ++c;
    
        return 0;
    }
    
    void incByRef(int c)
    {
        ++c;
    }
    

  3. [pea8-1.c] 第7回課題 3 のプログラムを,線形探索の関数を定義して,それを呼び出す形に変更しなさい。探索結果の表示形式は元のプログラムと同じとする。

    線形探索の関数は,引数として,

    a) 2次元配列,b) 探索キー,c) 2次元配列の行数,d) 2次元配列の列数,
    に加え, 2次元配列内に探索キーとして与えた整数が見つかったときの配列の行と列の添字を, 関数 main 内の2つの変数に格納するための 2 つの引数を与えて呼び出すように作ること。 そのため,探索の関数は,合計で 6 個の引数を与えて呼び出すように定義することになる。

    なお,探索の関数の戻り値については特に指定はしないが,探索に 成功した場合には 0 以上の数を, 失敗した場合には負の数を返すようにして, 探索が成功かどうかを 関数 main 内で判定する用途に使えるようにすることが考えられる。



5/31 Fri 14:04

第7回課題

  1. [pe7-1.c] (必須) リスト 2.10 の関数 printArray を,2 行 3 列の二次元配列のみならず,任意の行数の二次元配列を受け取って内容を出力する関数に書き換えなさい。なお,列数は 3 列に固定である。 そのためには,printArray のパラメータに二次元配列の行数 n を受け取るパラメータを追加して,関数定義の頭部を
    void printArray(int a[][3], int n)
    とするとともに,関数本体に必要な変更を加えればよい。

    また,リスト 2.10 のプログラムを, 変更した printArray を用いて array1 と array2 の内容を表示した後で,さらに 3 行 3 列の配列 array3 (値は任意に与えてよい)の内容も表示するプログラムとしなさい。

  2. [pe7-2.c] (必須) コメントに従い,下線部 (1) から (10) に適当なものを入れて,プログラムを完成させなさい。
    #include <stdio.h>
    
    int main()
    {
        int i = 10;
        int __(1)__ ;         /* ポインタ変数 ptr の宣言 */
    
    /* 変数 i のアドレスを 2 通りの方法で表示する */
        printf("address of i: __(2)__\n", __(3)__ i);
        __(4)__ = __(5)__ ;   /* 変数 ptr への初期値設定 */
        printf("address of i: __(6)__\n\n", ptr);
    
    /* 変数 i の値を 2 通りの方法で表示する */
        printf("i: __(7)__\n", i);
        printf("i: __(8)__\n\n", __(9)__ ptr);
    
    /* ptr を使って変数 i の値を 10 増やし,その値を表示する */
        __(10)__ += 10;
        printf("i: %d\n", i);
    
        return 0;
    }
    

  3. [pea7-1.c] ある値が表の中に存在するかどうかを出力するプログラムを作りなさい。

    プログラムにおいて,表は2行4列の二次元配列で実現することとし, 二次元配列には予め次の値を入れておくこととする。

    2 13 5 17
    11 3 7 19

    探す値はキーボードから入力することとし, 値が二次元配列に存在すれば,このプログラムは

    n was found at (row, col).
    のように出力し,存在しなければ
    n was not found.
    のように出力するようにしなさい。 ここで,n は入力した値であり,row と col は n が入った配列要素の添字とする。 例えば,5 の入力に対しては 5 was found at (0, 2). のように出力されるようにする。

    なお,このプログラムでは main 以外の関数は定義しないでよい。



5/24 Fri 01:24

第6回課題

  1. [pe6-1.c] (必須) 配列に格納された 1月から12月までの各月の日数をすべて表示した後で, それらの和(1年間の日数)を求めて表示するプログラムを作りなさい。 ここで 2 月の日数は 28 日(うるう年でない)とする。 ただし, 1年間の日数を各月の日数から求めるために, int 型の配列とその要素数 (int 型) を受け取って, 配列内の要素の和 (int 型) を求めて返す関数 arraySum を定義して使うこと。 また, 次の事項に従うこと。
    • 各月の日数を格納した配列は関数 main の本体で用意し,その配列と要素数を関数 arraySum に渡すこと。
    • 配列の内容(各月の日数)を表示するコードと, arraySum を呼び出して戻り値(一年間の日数)を表示するコードは main の本体に書くこと。
    • 関数 arraySum が,パラメータを通じて main 内の配列を書き換えることのできないプログラムにすること。

  2. [pe6-2.c] (必須) double 型の一次元配列とその要素数を受け取って, 配列内の値の平均を求めて返す関数 arrayAve を定義しなさい。

    さらに,関数 main から 関数 arrayAve を呼び出して, 次の値の平均値を求めて表示するプログラムを作りなさい。

    1.5 2.5 3.5 4.5 5.5
    プログラムでは,main 内で平均値を求める値の入った配列を用意して,それを関数 arrayAve に渡すこと。 arrayAve の戻り値(平均値)を表示するコードも main に書くこと。 また,関数 arrayAve が,パラメータを通じて main 内の配列を書き換えることのできないプログラムにすること。

  3. [pea6-1.c] 関数 main 内で同じ要素数を持つ 2 つの int 型配列を宣言し, 一方の配列の内容を,もう一方の配列に全てコピーするプログラムを作りなさい。 プログラムは次の実行例のように,コピー元の配列の内容を全て表示した後で, コピーされた配列の内容を表示するように動作すること。
    Source: 31 28 31 30 31 30 31 31 30 31 30 31 
    Destination: 31 28 31 30 31 30 31 31 30 31 30 31
    

    ただし,次の指示に従うこと。

    • 配列のコピーには, 関数 array_copy を定義して使うこと。 関数 array_copy は, 引数を通じて呼び出し元の配列を操作する関数であり, その仕様(プロトタイプ宣言)を
      void array_copy(int dest[], const int src[], int size);
      
      とする。この関数は第 2 引数に与えられた配列 src から, 第 1 引数に与えられた配列 dest に対し, 第 3 引数で指定された size 個分の要素をコピー (src の要素を dest の要素に代入)する。
    • 関数 main の本体では, 値の格納されている配列 (配列名は例えば array1 ) と, 宣言のみを行った配列(例えば array2)を用意して,
      array_copy(array2, array1, 12);
      
      の形で array_copy を呼び出し,配列をコピーさせる。
    • コピー元の配列 (array1) とコピー先の配列 (array2) の表示も main 内で行うこと。

  4. [pea6-2.c] 次の実行例のように,配列の要素のコピーを逆順で行うプログラムを作りなさい。
    Source: 31 28 31 30 31 30 31 31 30 31 30 31 
    Destination: 31 30 31 30 31 31 30 31 30 31 28 31
    
    そのために,前の問題における配列のコピーを行う関数の定義を改めなさい。



5/16 Thu 23:39

第5回課題

  1. [pe5-1.c] (必須) 1 年間の日数を, 各月の日数から計算して出力するプログラムを作りなさい。 各月の日数は,プログラム内で配列に格納しておくこと。 合計の計算には for ループを用いること。 なお,2 月の日数は 28 日(うるう年でない)とする。

  2. [pe5-2.c] (必須) キーボードから入力した10個以内の整数を逆順に出力(表示)するプログラムを作成しなさい。 ただし,このプログラムは,最初に,整数の個数をキーボードから読み込み,続いて与えられた個数の整数を読み込むものとする。 例えば,4 個の整数 11, 5, 13, 27 を与えるには 4 11 5 13 27 と入力する (入力値は改行で区切ってよい)。 ここで 4 は int 型の通常の変数に,11, 5, 13, 27 は配列に格納する。

    また,用意した配列の範囲外を利用しないように, 例えば次のようなコードで,必ず適切な入力値であることのチェックを行うこと。

    if (n > ARRAYSIZE) {
      printf("Too many integers\n");
      return 1;	
    }
    
    ここで n は入力する整数の個数であり, ARRAYSIZE は配列の要素数として使用されている記号定数とする。

    実行例 1:

    4
    11 5 13 27
    27 13 5 11
    

    実行例 2:

    11
    Too many integers
    

  3. [pea5-1.c] 二つのサイコロを振って出目の和を求めるサイコロ振りシミュレーションを 200 回行って, 2 から 12 までの各目が出た回数,割合(%),ヒストグラムを出力するプログラムを作りなさい。 プログラムを実行する度にサイコロ振りの結果が変わるプログラムにすること。 見やすい出力となるように工夫すること。



5/9 Thu 22:44

第4回課題

  1. [pe4-1.c] (必須) 下記のプログラムに対して,次の操作を順に行いなさい。

    1. 実行結果を予想してから,プログラムを実行してみなさい。
    2. 関数 count 内の変数 i の宣言部分を int i = 0; に変更しなさい。 実行結果を予想してから,実行しなさい。
    3. 関数 count が 1 から 10 までの整数を main に返し, それが表示されるようにプログラムを変更しなさい。 ただし,変更は関数 count の本体のみとする。

    #include <stdio.h>
    
    int count(void);
    
    int main()
    {
         int i;
    
         for (i = 0; i < 10; i++) {
             printf("loop %d:" , i);
             printf("count() returns %d\n", count());
         }
    
         return 0;
    }
    
    
    int count(void)
    {
         int i;
    
         return ++i;
    }
    

  2. [pe4-2.c] (必須) 第3回課題 3 を,作成するファイル名を第4回課題2(必須)のファイル名で行いなさい。 すなわち, 第3回課題 2 における, 関数 main の関数定義を pe4-2.c で行い, 関数 isEven の関数定義を pe4-2-sub.c で行う。さらにヘッダファイル pe4-2.h を読み込むことによって関数 isEven のプロトタイプ宣言を行うようにしてプログラムを作成しなさい。 プログラムをコンパイルして,正しく実行できることを確かめなさい。

  3. [pea4-1.c] 講義資料のリスト 1.8 等を参考に, キーボードから入力した整数の階乗を再帰呼出しによって求める過程と結果を, 次の実行結果例のように出力するプログラムを作りなさい。

    実行結果例(プログラムの実行後にキーボードから 3 を入力した場合)
    3
    factorial(3) called.
    factorial(2) called.
    factorial(1) called.
    1 returned by factorial(1).
    2 returned by factorial(2).
    6 returned by factorial(3).
    3! = 6
    

    プログラムは次の動作をするように作ること。

    • 関数 main は,キーボードから整数 n を読み込み, その階乗を関数 factorial の呼び出しによって求めて 「n! = n の階乗」の形式で表示する。
    • 関数 factorial は,呼び出される度に 「factorial(n) called.」 と出力し, 計算結果を返す前に 「nの階乗 returned by factorial(n)」 と出力する。 ここで n は factorial が受け取った引数の値である。

      この動作のためには,関数 factorial は戻り値を return で返す前に一度変数に格納しておく必要があるため,次の定義を参考にするとよい。

      long factorial(long n)
      {
          long ret;
      
          if (n <= 1)
              ret = 1;
          else
              ret = n * factorial(n - 1);
      
          return ret;
      }
      

  4. [pea4-2.c] キーボードから入力する正の整数を変数 n に読み込んで 1 + 2 + ... + n を求めて表示するプログラムを作りなさい。ただし,再帰関数を作成して使うこと。



4/29 Mon 16:42

第3回課題

  1. [pe3-1.c] (必須) 10 回のコイン投げをシミュレートするプログラムを作りなさい。 コインが表なら Head,裏なら Tail と表示し, プログラムを実行する度に裏と表の出方が変わるようにすること。 この問題で作成する関数は main のみとする。

  2. [pe3-2.c] キーボードから入力した整数が偶数ならば Even と,奇数ならば Odd と表示するプログラムを作りなさい。

    このプログラムでは, 引数に与えられた整数が偶数かどうかを判定する関数 isEven を定義し, 関数 main の中から isEven を呼び出して利用すること。 関数 main は,キーボードからの値の取り込みと,isEven を用いた偶数/奇数の判定,および,その結果の表示を行うように作ること。

    isEven は,引数として int 型の値を受け取り,それが偶数ならば 1 (真) を,奇数ならば 0 (偽) を返すように定義すること。

    なお,isEven は真偽の値を返すので,if (isEven(n) == 1) と書くのと if (isEven(n)) と書くのは同じことであり,後者に慣れるのが望ましい (「もし n が偶数である (is even) ならば」と素直に読める。)。

  3. [pea3-1.c] 前の課題のプログラムを,関数 main の関数定義を pea3-1.c で, 関数 isEven の関数定義を pea3-1-sub.c で行い,さらにヘッダファイル pea3-1.h を読み込むことによって関数 isEven のプロトタイプ宣言を行うように変更しなさい。 プログラムをコンパイルして,プログラムが正しく実行できることを確かめなさい。



4/19 Fri 00:57

第2回課題

  1. [pe2-1.c] (必須) 画面に Hello World! と表示するプログラムを作りなさい。 ただし, 画面に Hello World! と表示して改行する関数 hello を定義し, 関数 main から関数 hello を呼び出すことによって動作するプログラムとすること。

  2. [pe2-2.c] (必須) 0.1 から 1.0 までの間を 0.1 刻みで変化させた各数の 3 乗を表示するプログラムを作りなさい。 ただし, double 型の数値を受け取って,その 3 乗値を求めて返す関数 cube を作り, 関数 main から呼び出すプログラムとすること。 関数 cube は戻り値のデータ型も double 型とする。

  3. [pea2-1.c] キーボードから入力した整数を一辺の長さとする正方形を,* で描くプログラムを作りなさい。 ただし,関数 printsquare を定義して,関数 main から呼び出すようにすること。 関数 printsquare は,引数を通じて整数を一つ受け取り,その値を一辺の長さとする正方形を * で出力する関数とすること。

    例えばキーボードから 3 を入力したときに,このプログラムは画面に次の出力をする。

    ***
    ***
    ***
    
    また,キーボードから 0 以下の数を入力したときには,
    Invalid number.
    
    のようなメッセージを出すことが望ましい。



4/11 Thu 22:59

第1回課題

  1. [pe1-1.c](必須) 変数 a と b に標準入力(キーボード)から値を読み込み, それらの値を一度出力した後で,変数 ab に a と b の積を代入し,「? x ? = ?」(数の表示は小数点以下第2位まで)の形で結果を出力するプログラムの空白部分 (a) から (e) を埋めなさい。

    (変数,四則演算,scanf と printf による入出力)

    /* pe1-1.c: multiplication program */
    #include <stdio.h>
    
    int main()
    {
        double a, b, ab;
    
        scanf("%lf%lf", [(a)    ]);
        printf("a: %f\n", [(b)  ]);
        printf("b: %f\n", [(c)  ]);
    
        [(d)      ];
        [(e)                     ];
    
        return 0;
    }
    

  2. [pe1-2.c](必須) 変数 n に正の整数を読み込んで 1 + 2 + ... + n を求めるプログラムの空白部分 (a) から (e) を埋めなさい。 なお,このプログラムは n までの和を求める途中の過程も表示する。

    (反復構造,合計を求めるアルゴリズム)

    /* pe1-2.c: summation program */
    #include <stdio.h>
    
    int main()
    {
        [(a) ]  i, n, sum;
    
        printf("Enter integer.\n");
        scanf([(b)        ]);
    
        sum = [(c) ];
        for (i = 1; [(d)         ]) {
            sum += [(e)  ]
            printf("%d\t%d\n", i, sum);
        }
    
        return 0;
    }
    

  3. [pea1-1.c] 変数 n に正の整数を読み込んで 1 + 1/2 + ... + 1/n を求めるプログラムを作りなさい。

    (データ型)





[サイトマップ] [トップページ]