第15回:復習(2)

 1年間かけて学習してきたC言語によるプログラミングの総復習第二回です.


追加 第3回の演習の答え

入力されたアルファベットの小文字の文字列をabc順に並べ替えるプログラムを,ポインタを使って書き直そう.

#include <stdio.h>

void main()
{
    char s[256], t;
    int n, i, j;
    char *p;

    p = s;

    //文字列の入力
    printf("単語を入力してください\n");
    scanf("%s", p);
    printf("入力された文字列は%sです.\n", p);

    // 文字数を数える
    for(i=0; *(p+i) != 0x00; i++);
    printf("文字数は,%d文字です.\n", i);

    n = i;

    // 並び替え
    for(i=0; i < n-1; i++){
        for(j=i+1; j < n; j++){
            if(*(p+i) > *(p+j)){
                t = *(p+i);
                *(p+i) = *(p+j);
                *(p+j) = t;
            }
        }
    }

    printf("結果 : %s\n", p);
}

後期のホームページの目次

第1回:前期の復習

第2回:ポインタ(その1)

第3回:ポインタと配列

第4回:関数

第5回:関数(2)

第6回:関数と配列

第7回:関数(4)

第8回:中間テスト

第9回:ファイル

第10回:ファイル(2)

第11回:バイナリファイル

第12回:構造体

第13回:構造体(2)

第14回:復習(1)

第15回:復習(2)


後期に学習した内容をまとめると

  • ポインタ
    • ポインタと配列の関係
  • 関数
    • 関数の定義
    • 引数 値渡しとアドレス渡し
    • 再帰関数
  • ファイル
    • ファイルの読み書き
    • バイナリファイル
  • 構造体

中間テストでは,主に関数を取り上げました.をもう一度復習してみよう.


中間テストの解答

問題1

数学の確率でならった,n個の中からr個を選ぶときの組み合わせの数 nCr を求めるプログラムを下記の手順でつくれ.

(1) forループを使って計算する

(2) 再帰関数を使って計算する

ヒント: 

(1)forループを使って計算する場合

#include <stdio.h>

long combi(int n, int r)
{
    int i;
    long p=1;

    for(i=1; i<=r; i++){
        p = p*(n-i+1)/i;
    }

    return p;
}

void main()
{
    int n, r;

    printf("nこの中からr個を選ぶときの組み合わせを計算します\n");
    printf("nを入力:");
    scanf("%d", &n);
    printf("rを入力:");
    scanf("%d", &r);

    printf("組み合わせの数は,%d通りです\n", combi(n, r));
}

(2)再帰関数を使って計算する場合

#include <stdio.h>

long combi(int n, int r)
{
    int i;
    long p;

    if(r==0){
        p=1;
    }else{
        p = (n-r+1)*combi(n, r-1)/r;
    }

    return p;
}

void main()
{
    int n, r;

    printf("nこの中からr個を選ぶときの組み合わせを計算します\n");
    printf("nを入力:");
    scanf("%d", &n);
    printf("rを入力:");
    scanf("%d", &r);

    printf("組み合わせの数は,%d通りです\n", combi(n, r));
}

問題2

アルファベットを暗号化・解読する関数を作成せよ.

暗号化のルールは,次のようにする.

暗号
A @
B A
C B
... ...
Y X
Z Y

#include <stdio.h>

int moji_nagasa(char *str)
{
    int i;
    for(i=0; str[i] != 0x00; i++);
    return i;
} 
 
void ango(char *s, int a)
{
    int i, n;

    n = moji_nagasa(s);

    for(i=0; i<n; i++){
        if(a==1){     /*暗号化*/
            s[i]--;
        }else if(a==0)}    /*解読*/
            s[i]++;
        }
    }
}

void main()
{
    char s[256];
    int a;

    printf("アルファベットを暗号化・解読するプログラムです\n");
    printf("暗号化するなら1を,解読するなら0を入力:");
    scanf("%d", &a);
    printf("暗号化・解読したい文字列を入力:");
    scanf("%s", s);

    ango(s, a);

    printf("結果:%s\n", s);
}


構造体の演習の復習

 下記の成績データをファイルから読み込んで,各学生の2回のテストの平均点を計算し,成績を判定するプログラムを,構造体を用いて作成せよ.

2 1 1 アベ 50 60
2 1 2 イトウ 70 45
2 1 3 ウエダ 90 53
2 1 4 エンドウ 75 65
2 1 5 オカダ 30 15
2 1 6 カトウ 90 76
2 1 7 キダ 80 56
2 1 8 クリタ 86 95

成績対応表
A
80点以上
B
60点以上
C
50点以上
F
50点未満

ステップ1
まずは,構造体を使わずに,データを読み込んで画面に表示するだけのプログラムを作ってみる.
ステップ2
変数を構造体を用いるように変更する.
ステップ3
構造体の配列を用いる

まずは,構造体を使わないでやってみると...

#include <stdio.h>

void ave(int ten_1, int ten_2, float *heikin)
{
    *heikin = (ten_1 + ten_2 )/2.0;  
}

void main()
{
    int i, n=8;
    int gakunen;
    int kumi;
    int bangou;
    char simei[25];
    int ten_1;
    int ten_2;
    float heikin;
    char hantei;

    FILE *fp;

    if((fp = fopen("testdata.txt", "r")) == NULL){
        printf("ファイルを開けませんでした");
        exit();
    }

   for(i=0; i<n; i++){
        fscanf(fp, "%d %d %d %s %d %d", &gakunen, 
                                        &kumi,
                                        &bangou,
                                        simei,
                                        &ten_1,
                                        &ten_2);
        ave(ten_1, ten_2, &heikin);

        if(heikin>=80){
            hantei = 'A';
        }else if(heikin>=60){
            hantei = 'B';
        }else if(heikin>=50){
            hantei = 'C';
        }else{
            hantei = 'F';
        }

        printf("%d %d %d %8s %d %d %.1f %c\n", gakunen,
                                              kumi,
                                              bangou,
                                              simei,
                                              ten_1,
                                              ten_2,
                                              heikin,
                                              hantei);
    }

    fclose(fp);
}

構造体を使わないと,関数(ave)を呼ぶ際に,引数の数が多くて面倒です.では,構造体を使ってみると...

#include <stdio.h>

struct seiseki{
    int gakunen;
    int kumi;
    int bangou;
    char simei[25];
    int ten_1;
    int ten_2;
    float heikin;
    char seiseki;
};

void ave(struct seiseki *list)
{
    list->heikin = (list->ten_1 + list->ten_2 )/2.0;  
}

void main()
{
    int i, n=8;
    struct seiseki list2002;
    FILE *fp;

    if((fp = fopen("testdata.txt", "r")) == NULL){
        printf("ファイルを開けませんでした");
        exit();
    }

   for(i=0; i<n; i++){
        fscanf(fp, "%d %d %d %s %d %d", &list2002.gakunen, 
                                        &list2002.kumi,
                                        &list2002.bangou,
                                        list2002.simei,
                                        &list2002.ten_1,
                                        &list2002.ten_2);
        ave(&list2002);

        if(list2002.heikin>=80){
            list2002.hantei = 'A';
        }else if(list2002.heikin>=60){
            list2002.hantei = 'B';
        }else if(list2002.heikin>=50){
            list2002.hantei = 'C';
        }else{
            list2002.hantei = 'F';
        }

        printf("%d %d %d %s %d %d %.1f %c\n", list2002.gakunen,
                                              list2002.kumi,
                                              list2002.bangou,
                                              list2002.simei,
                                              list2002.ten_1,
                                              list2002.ten_2,
                                              list2002.heikin,
                                              list2002.hantei);
    }

    fclose(fp);
}

後期の期末試験について 時間割り

1月29日(水) 2時限 0406教室

試験範囲は,前後期合わせて情報処理・演習で取り上げた内容すべてです.

これだけは,絶対に理解しておいてほしい点

  • 変数とは
  • 条件分岐
  • 繰り返し
  • 配列
  • 関数

これらの点を中心によく復習しておいてください.ファイルの取り扱いや構造体については,