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

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


更新日
6/27 Fri 01:17

第11回課題

  1. [pe11-1.c] (必須) 以下の指示に従ってプログラムを完成させなさい。
    1. 文字列の 先頭から size 個の文字を別の文字型配列にコピーし,さらにコピー先の配列の内容を文字列にする関数
      char *arrayncopy(char *dest, const char *src, int size)
      を作りなさい。 ここで dest はコピー先の配列(の先頭アドレス)であり,src はコピー元の文字列(の先頭アドレス),size はコピーする要素数である。

    2. 次のとおりに宣言・初期化された配列 str1 を表示した後, str1 のうち,Hello の部分だけを別の配列 str2 にコピーして, str2 の内容を表示するプログラムを作りなさい。 関数 arrayncopy を用いて配列をコピーし,その戻り値を使って str2 の表示を行うこと。
      char *str1 = "Hello World!";

  2. [pe11-2.c] (必須) 次の文
    char *suit[] = {"hearts", "diamonds", "clubs", "spades"};
    により宣言・初期化された配列 suit を使うプログラムを以下の指示に従って作りなさい。
    1. for 文による繰り返しと,配列 suit を使って
      hearts diamonds clubs spades
      と出力するプログラムを作りなさい。(文字列を空白区切りで表示し,最後に改行する)
    2. for 文による繰り返しと,配列 suit を逆順に使って
      spades clubs diamonds hearts
      と出力するコードをプログラムに追加しなさい。
    3. さらに,文字列の先頭文字を大文字にした
      H D C S
      を出力するコードをプログラムに追加しなさい。 この出力も配列 suit と繰り返し構文で行うこと。 標準ライブラリ関数 toupper を使うこと。

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

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

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



6/20 Fri 00:26

第10回課題

  1. [pe10-1.c] (必須) 文字列に関する 次のコードをコメントに従って完成させなさい。 表示する際には必ず配列 a を用いること。 なお,コメントの入力は不要である。
    #include <stdio.h>
    
    int main()
    {
         char a[] = "ABCDE";
         int i;
         
         printf("#1:");
         /* A と表示する */
         printf("____\n", ____);
    
         printf("#2:");
         /* ABCDE と表示する */
         printf("____\n", ____ );
    
         printf("#3:");
         /* ABC と表示する */
         a[____] = '____' ;
         printf("%s\n", ____ );
    
         printf("#4:\n");
         /* ABC を 1 行につき 1 文字ずつ表示する。*/
         for (i = 0; ________ ; i++)
             printf("____", ____);
         
         return 0;
    }
    
    実行結果は次のとおりになる。
    #1:A
    #2:ABCDE
    #3:ABC
    #4:
    A
    B
    C
    

  2. [pe10-2.c] (必須) ポインタと文字列に関する 次のプログラムの下線部を,コメントの指示に従って埋めなさい。 なお,コメントの入力は不要である。
     
    #include <stdio.h>
    
    int main()
    {
        char *p = NULL;
        
    /* 文字列リテラル "abc" の先頭アドレスを表示する */
        printf("Address of \"abc\": ____\n", "abc");
    
    /* 文字列リテラル "ABC" の先頭アドレスを p を使って表示する */
        ______ ;
        printf("Address of \"ABC\": ____\n", p);
    
    /* p を使って A と表示する */
        printf("print \"A\": ____\n", ____ );
    
    /* p を使って BC と表示する */
        ____ ; /* p の内容を変更する(ポインタ演算) */
        printf("print \"BC\": ____\n", p);
    
    /* p を使った 2 通りの方法で ABC と表示する */
        ____ ; /* p の内容を変更する(ポインタ演算) */
        printf("print \"ABC\": ____\n", p);
    
        printf("print \"ABC\": ");
        while (*p != ____) {
            printf("____", *p);
            ____ ; /* p の内容を変更する(ポインタ演算) */
        }
        printf("\n");
    
        return 0;
    }
    
    このプログラムの出力は次のようになる。ただし,アドレスは例示である。
     
    0x55f91411a004
    0x55f91411a00c
    A
    BC
    ABC
    ABC
    

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

    char *str1 = "Hello World!";

  4. [pea10-2.c] 次のとおりに宣言・初期化された配列 str1 を表示した後で, str1 に格納されている文字列 (Hello ) の後ろに,ポインタ変数 str2 が指す文字列 (World!)を追加して, str1 の内容が全体として文字列 (Hello World!) になるようにする プログラムを作りなさい。 出来上がった文字列 str1 も表示すること。
    char str1[20] = "Hello ";
    char *str2 = "World!";



6/11 Wed 02:10

第9回課題

  1. [pe9-1.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;
    }
    

  2. [pe9-2.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
    

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



6/6 Fri 01:39

第8回課題

  1. [pe8-1.c] (必須) 次のプログラムをコメントに従って完成させなさい。 ただし,コメントの入力は不要である。
    #include <stdio.h>
    
    int main()
    {
        int i = 10;
        int *p;       /* ポインタ変数 p の宣言 */
    
    /* 変数 i のアドレスを 2 通りの方法で表示する (変数 p への初期値設定) */
        printf("address of i: %p\n", &i);
        ____ = ____ ;
        printf("address of i: %p\n\n", p);
    
    /* 変数 i の値を 2 通りの方法で表示する */
        printf("i: %d\n", i);
        printf("i: %d\n\n", ____ p);
    
    /* p を使って変数 i の値を 10 増やし,その値を表示する */
        ____ += 10;
        printf("i: %d\n", i);
    
        return 0;
    }
    

  2. [pe8-2.c] (必須) プログラム内のコメントに従って下線部を埋めなさい。

    また,このプログラムの実行結果より,同じ配列の各要素がメモリ(記憶域)上に連続して配置されることを確認しなさい。

    なお,最初の printf で使われている %lu は sizeof 演算子によって得られる値の型である unsigned long int 型の値を表示するためのものである。

    #include <stdio.h>
    
    int main()
    {
         int a[] = {10, 20, 30, 40, 50};
         int size;
         int i;
         ____ = NULL; /* ポインタ変数 p の宣言と初期化 */
                      /* p には size や a の要素のアドレスを格納する */
    
         /* int 型のサイズ */
         printf("size of int is %lu bytes.\n", ________ );
         putchar('\n');
    
         /* 配列 a の要素数を sizeof 演算子で求める */
         size = _________________ ;
         printf("number of elements of array \"a\" is %d.\n", size);
    
         /* 変数 size のアドレス */
         printf("address of \"size\" is %p.\n", ____ );
    
         /* 配列要素 a[0] のアドレス */
         printf("address of a[0] is %p.\n\n", ____ );
    
         /* 配列 a の各要素の添字,アドレス,値 */
         printf("subscript, address and value of a[i]:\n");
         for (i = 0; i < size; i++) {
              printf("  %d, %p , %d \n", i, ____ , ____);
         }
         putchar('\n');
    
         /* ポインタ変数 p の初期値 */
         printf("initial value of p is %p.\n", p);
    
         /* ポインタ変数 p を使って a[0] のアドレスと値を表示する */
         p = ____ ;
         printf("a[0]: %p, %d\n", ____ , ____ );
    
         /* ポインタ変数 p を使って a[3] のアドレスと値を表示する */
         p += ____ ;
         printf("a[3]: %p, %d\n", ____ , ____ );
    
         /* ポインタ変数 p を使って a[1] のアドレスと値を表示する */
         p -= ____ ;
         printf("a[1]: %p, %d\n", ____ , ____ );
    
         /* ポインタ変数 p を使って size のアドレスと値を表示する */
         p = ____ ;
         printf("size: %p, %d\n", ____ , ____ );
    
         return 0;
    }
    

  3. [pea8-1.c] 第7回課題 1 のプログラムを次のように書き換えなさい。

    main 内の各二次元配列の行数を,sizeof 演算子と配列の列数を用いて自動的に求め, printArray の引数に与えるようにする。



5/30 Fri 00:48

第7回課題

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

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

  2. [pe7-2.c] (必須) 資料のリスト 2.11 のプログラムを, 関数 bubble_sort を使ってバブルソートを行うプログラムに書き換えなさい。 関数 bubble_sort は一次元配列とその要素数を受け取り, 引数を通じて呼び出し元の配列を変更するものとする。 なお,関数 bubble_sort は 予め用意されている関数ではなく,自分で定義する必要がある。

    さらに,リスト 2.11 の各走査における繰り返しの回数には無駄があるので, 余分な繰り返しを無くすように関数 bubble_sort を改良してみなさい。

  3. [pea7-1.c] 1 x 1 から 9 x 9 までの九九の結果を2次元配列に格納し,表示するプログラムを作りなさい。

  4. [pea7-2.c] ランダムな整数を格納した,適当なサイズの2次元配列を作り,その各行をソートして表示するプログラムを作りなさい。 設問 2 で定義した関数 bubble_sort を使うこと。 仮に配列名が array である二次元配列を用意したとすれば, array[0] は最初の行を要素とする一次元配列であり, array[1] はその次の行を要素とする一次元配列であるので, 関数 bubble_sort には,これら二次元配列の各行を引数として渡せばよい。



5/22 Thu 21:32

第6回課題

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

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

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

    1.5 2.5 3.5 4.5 5.5
    プログラムでは,main 内で平均値を求める値の入った配列を用意して,それを関数 array_ave に渡すこと。 array_ave の戻り値(平均値)を表示するコードも main に書くこと。 また,関数 array_ave が,パラメータを通じて 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 Fri 10:35

第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/2 Fri 14:00

第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 = 1; i <= 10; i++) {
            printf("Loop #%d: " , i);
            printf("count() returned %d\n", count());
        }
    
        return 0;
    }
    
    
    int count(void)
    {
        int i;
    
        printf("count() prints %d; ", i);
    
        return ++i;
    }
    

  2. [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;
      }
      

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



4/25 Fri 09:50

第3回課題

  1. [pe3-1.c] (必須) 3つのサイコロを振って,出目の和が 偶数ならば Even と表示し, 奇数ならば Odd と表示するプログラムを作りなさい。

    プログラムではサイコロ振りを行う関数 roll3dice を定義すること。 roll3dice は三つのサイコロ振りを乱数で模擬し,合計を返すように定義すること。 また,roll3dice の本体では,各サイコロの出目を表示させること。

    関数 main では,関数 roll3dice を呼び出し,戻り値が 2 で割り切れるかどうかによって, サイコロの出目の和が偶数か奇数かを表示させること。

  2. [pe3-2.c] (必須) 課題 1 のプログラムを次の三つのファイルに分割し,コンパイルして実行しなさい。
    • 関数 main の定義: pe3-2.c
    • 関数 roll3dice の定義: pe3-2-sub.c
    • 関数 roll3dice のプロトタイプ宣言(ヘッダファイル): pe3-2.h

  3. [pea3-1.c] 変数 m と n に正の整数を読み込んで,m から n の間に存在するすべての自然数について,その逆数の和 1/m + 1/(m + 1) + ... + 1/(n - 1) + 1/n を求めるプログラムを作りなさい。和は関数 interval_sum に求めさせること。



4/18 Fri 12:03

第2回課題

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

  2. [pe2-2.c](必須)次の 1, 2 を順に行いなさい。
    1. 変数 n に正の整数を読み込んで 1 + 2 + ... + n を求めて表示するプログラムを作りなさい。 ただし,和の計算は関数 interval_sum を作って行うこと。

      関数 main が行うことは, 変数 n にキーボードから正の整数を入力し, 和を求める関数 interval_sum を呼び出し, 計算結果である interval_sum の戻り値を表示するだけである。

      和の計算は interval_sum に行わせること。 関数 interval_sum は和を計算して,それを呼び出し元に戻り値として返す関数とすること。 interval_sum の本体には,計算結果を表示する文は書かないこと。

    2. 先のプログラムを, 変数 m と n に正の整数を読み込んで,m から n の間に存在するすべての自然数の和 m + (m + 1) + ... + (n - 1) + n を求めるプログラムに変更しなさい。 和は関数 interval_sum に求めさせること。

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

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

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

4/11 Fri 00:49

第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 を求めるプログラムを作りなさい。

    (データ型)





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