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