特別課題B 「関数」「変数の取り扱い」「ファイルの取り扱い」「構造体」

(1)三角形の2辺の長さとその挟む角を与えて,残りの1辺の長さを求める関数を次の仕様で作成しなさい。
  関数内でprintfを使用してはならない。検査するためのprintfはmain()内に記述しなさい。 (pe02ex01.c)
 double triangle1(double sideA, double sideB, double angleC)
 ただし
    sideA :1辺の長さ
    sideB :もう1辺の長さ
    angleC :2辺の挟む角(単位はrad)
        関数の返す値 残りの1辺の長さ

 動作の検証のためにmain()も作成しなさい。
 「#include <math.h>」の記述を忘れないこと。
 次の例でこの関数の正当性を確かめなさい。
 1)2辺の長さ:1.0,1.0,挟む角:90度 残りの1辺は√2になる。
 2)2辺の長さ:2.0,√3,挟む角:30度 残りの辺は1になる。

(2)三角形の2辺の長さと残りの1辺の長さを与えて,2辺の挟む角を求める関数を次の仕様で作成しなさい。
  関数内でprintfを使用してはならない。検査するためのprintfはmain()内に記述しなさい。 (pe02ex02.c)
 double triangle2(double sideA, double sideB, double sideC)
 ただし
    sideA :1辺の長さ
    sideB :もう1辺の長さ
    sideC :残りの1辺の長さ
        関数の返す値 sideAとsideBに挟まれる角度(単位はrad)

 動作の検証のためにmain()も作成しなさい。
 「#include <math.h>」の記述を忘れないこと。
 次の例でこの関数の正当性を確かめなさい。
 1)2辺の長さ:1.0,1.0,残りの1辺が√2 挟む角は90度になる。
 2)2辺の長さ:2.0,√3,残りの辺が1  挟む角は30度になる。

(3)int型の配列arrayと配列内の有効データ数sizeを与えると,配列array内の最大値をint型で返す関数
int findMax(int array[], int size)
を作り,動作を検査しなさい。ただし,関数内でprintfを使用してはならない。
検査するためのprintfはmain()内に記述しなさい。
   (pe02ex03.c)
動作の検査に当たっては,1,2,3,4,5,6,7,8,9,10の10個の値を使い,最大値が10になることを示しなさい。
また,-10,-20,-30,-40,-50の5個の値を使い,最大値が-10になることを示しなさい。

(4)電話番号文字列を受け取って,数字以外の文字があったら,取り除く関数
void modifyphonenumber(char phonenumber[])
を作り,動作を検査しなさい。動作の検証のために次のようなmain()も作成しなさい。
また関数内でprintfを使用してはならない。 (pe02ex04.c)

 例えば
    char phonenum[]="042-668-5111";
 の時
    puts(phonenum);
    modifyphonenumber(phonenum);
    puts(phonenum);
 のような検査用mainによって,次のように表示されれば正しい動作である。
 042-668-5111
 0426685111

 また,例えば
    char phonenum[]="042 668 5199";
 の時は,
次のように表示されれば正しい動作である。
 042 668 5199
 0426685199

(5)関数int difference(int value)を作成しなさい。 (pe02ex05.c)
この関数は1つのint型の引数valueを持ち,関数の返す値は,
引数として与えたvalueから前回呼び出したときのvalueを引いた値である。
すなわち,前回呼び出しとの差を返す関数となっている。
動作の検証のために次のようなmain()も作成しなさい。
また関数内でprintfを使用してはならない。

    int x,x2;
    int y;
    for(x=0;x<10;x++) {
        x2=x*x;
        y=difference(x2);
        printf("x2=%6d difference=%6d\n",x2,y);
    }
 このような検査用のmain()を用いた時,

    x2=     0 difference=     0
    x2=     1 difference=     1
    x2=     4 difference=     3
    x2=     9 difference=     5
    x2=    16 difference=     7
    x2=    25 difference=     9
    x2=    36 difference=    11
    x2=    49 difference=    13
    x2=    64 difference=    15
    x2=    81 difference=    17

 このようになれば正しい動作である。


(6)プログラムとこのプログラム動作時の様子が示されている。 (pe02ex06.c)

    int main()
    {
        unsigned int x=521;
        int y;
        int i;
        for (i=0; i<100; i++) {
            x=x*197+109;
            y=x%1000;
            printf("%4d",y);
            if (i%10==9) printf("\n");
        }
        return 0;
    }
    
     746  71  96 149 366 435 916 937 866  63
     848 981 638 811 508  97 298 967 144 285
     350 923 908 625 106 751 616 981 142  27
      36  57 386 487  88 757 694 179 420 593
      34 335  64 781 550 171 172 713 354 855
     808 573 486 571 748 361 498 423 168 445
     342 939   4 697 818 639 440 989 798   3
     180 561 978 767 344 317 694 195 444 841
     570 351 744 573 886 811 844 369 490 159
     408 973 790 683 892  89   2 231 768 341

yの値が表示されているが,でたらめの並び方をしている。このような数の並びは乱数と呼ばれている。
ここで521,197,109は適当に選んだ素数である。yの値は0から999の範囲で変化している。
xの値にある値をかけて,別のある値を加える作業を繰り返しているだけである。
乱数生成部だけを関数化して,0から999までの乱数を発生する関数int random1000(void)を作りなさい。(pe02ex06.c)

この関数は呼び出すたびに異なる乱数を発生するものとする。乱数生成にかかわる定数を上記のプログラムと
同じにすれば,上記と全く同じ乱数列が生成されるはずなので,次の検査用のmainを作り,
作成した関数を検査しなさい。

    int i;
    int rnd;
    for (i=0; i<100; i++) {
        rnd=random1000();
        printf("%4d",rnd);
        if (i%10==9) printf("\n");
    }


(7)テキストファイルyear.txtに,月の名前,その月の日数,1月からその月までの累積日数を表
にして出力するプログラムを作成しなさい。ただし,プログラム中に月の名前と日数を配列で与え
るものとする。
(pe02ex07.c)

    January   31    31
    February  28    59
    March     31    90
      :        :     :

このようなファイルになるはず。

 

(8)テキストファイルを読み込み,複数のスペース文字が続いたら1文字のスペース文字にする作業を行い,
別のテキストファイルに書き出しなさい。ファイル名は実行時にキーボードから入力するものとします。
以下を内容とするテキストファイルを作って動作を検査しなさい。(pe02ex08.c)

Fish is easy to prepare and quick to cook and is a healthy options for 
a wide range of      tastes and ages,           including semi-vegetarians.
It is low in calories and fat and provides protein, vitamins and minerals.

2行目に複数のスペース文字が連続しているので,次のようなファイルに変換されたら正解です。

Fish is easy to prepare and quick to cook and is a healthy options for 
a wide range of tastes and ages, including semi-vegetarians.
It is low in calories and fat and provides protein, vitamins and minerals.


(9)Cプログラムのソースファイルを読み込み,コメント部分を取り除いて,別のファイルに書き出しなさい。
ファイル名は実行時にキーボードから入力するものとします。
コメント部分は「/*」と「*/」に囲まれた部分であり,複数行にまたがっている場合もあります。(pe02ex09.c)

以下を内容とするCプログラムのソースファイルを作って,コメントが取り除けたかどうか検査しなさい。
コメントを取り除いた結果,空白行が残っても消えてもどちらでもよい。

/*   sample program level 1    */
/* for C source file testing   */

#include <stdio.h>

int main()
{
    printf("Hello world.\n");
    return 0;
}

/*   sample program level 2    *
 * for C source file testing   */

#include <stdio.h>

int main()
{
    printf("Hello world.\n");
    /* confusing example */
    printf("/* indicates starting of comments.\n");
    printf("*/ indicates ending of comments.\n");
    return 0;
}

/*   sample program level 3    *
 * for C source file testing   *
 * Compile and go anyway.      */

#include <stdio.h>

int main()
{
    printf("Hello world.\n");
    /* confusing example */
    printf("\"/*\" indicates starting of comments.\n");
    printf("\"*/\" indicates ending of comments.\n");
    return 0;
}


(10)時間(時分秒)を表す構造体を次のように定義します。
    typedef struct {
        int hour;   /* 時 */
        int minute; /* 分 */
        int second; /* 秒 */
    } time_type;
2つの時間データを受け取り,その和を返す関数
time_type addTime(time_type a, time_type b)
を作成し,検査しなさい。
検査には 2:30:15+2:31:20,2:30:45+2:29:16 の2つの計算を用いなさい。(pe02ex10.c)

(11)時間(時分秒)を表す構造体を前題のように定義します。
2つの時間データを受け取り,その差を返す関数
time_type subtractTime(time_type a, time_type b)
を作成し,検査しなさい。ただし,差とは a-b の意味である。
検査には
2:30:15-1:21:12,2:30:45+2:31:16,2:30:15-3:45:30,1:30:30-1:40:25,1:30:45-1:40:50
の5つの計算を用いなさい。(pe02ex11.c)


(12)時間(時分秒)を表す構造体を前題のように定義します。
時間データを受け取り,その定数倍を返す関数
time_type multiplyTime(time_type a, double b)
を作成し,検査しなさい。
検査には 2:20:15×2,2:31:20×3,2:30:45×(-4) の3つの計算を用いなさい。(pe02ex12.c)