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
数学の確率でならった,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 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点未満
|
まずは,構造体を使わないでやってみると...
#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教室
試験範囲は,前後期合わせて情報処理・演習で取り上げた内容すべてです.
これだけは,絶対に理解しておいてほしい点
これらの点を中心によく復習しておいてください.ファイルの取り扱いや構造体については,