[第12回]演習問題Ⅲ
第11回まで学習した内容を使い、演習問題を行います!
1 うるう年判定プログラム
うるう年を判定する自作関数を作ってみよう
但し、西暦を格納する変数はグローバル変数で宣言してください
結果1 2007年の場合
結果2 2004年の場合
結果3 2000年の場合
演習問題Ⅲ 第1問のヒント
1.うるう年を求める計算は「西暦年が4で割り切れるかつ100で割り切れないまたは400で割り切れる」である
2."かつ""または"を表現するには論理演算子を使います
3.グローバル変数は関数の外側で宣言します
演習問題Ⅲ 第1問の解答
1 うるう年判定プログラム
解答を隠す...
解答プログラム
#include <stdio.h>
//グローバル変数cの宣言と初期化
int c = 0;
//関数のプロトタイプ宣言
void uru();
int main()
{
printf("うるう年か判定します\n");
printf("西暦を入力してください");
scanf("%d",&c);
//関数呼び出し
uru();
// c = 0 のときうるう年 1のときは平年
if(c == 0){
printf("うるう年です\n");
} else {
printf("うるう年ではありません\n");
}
return 0;
}
//うるう年判別関数
//グローバル変数を書き換える
void uru()
{
//cが4で割り切れ
//かつcが100で割り切れないか
//400で割り切れるときうるう年
if(c%4==0 && c%100!=0 || c%400==0){
c = 0;
} else {
c = 1;
}
}
解説
さて、西暦を入力するところまでは大丈夫ですね?
このときグローバル変数cに入力された西暦が格納されます。
グローバル変数はmain関数やここではuru関数で読み出すことが可能となります。
uru関数の中身ですが、入力された西暦が4で割り切れ、かつ100で割り切れないか、400で割り切れる時がうるう年となります。
うるう年ならグローバル変数cを0に、そうでなければ1に書き換えます。
main関数に戻り、cの値が0ならうるう年と、1ならうるう年でないと表示させて終了となります。
演習問題Ⅲ 第2問
第11回まで学習した内容を使い、演習問題を行います!
2 複数文字列の格納
文字列を複数入力して、逆順に表示するプログラムを作ってみよう
但し、「END」と入力すると、プログラムを終了させるようにしてください。
また、表示を行うときには「END」を表示しないようにしよう
結果
演習問題Ⅲ 第2問のヒント
2 複数文字列の格納
1.文字列型の変数を複数使う時はchar型の2次元配列を宣言します
2.文字列の入力はscanf( )とgets( )を使います
3.「END」と入力されるのを調べるにはstrcmp( )関数を使います
演習問題III 第2問の解答
2 複数文字列の格納
解答を隠す...
解答プログラム
#include <stdio.h>
#include <string.h>
int main()
{
//2次元配列strの宣言
//配列の数は余裕を持って宣言しています
char str[256][256];
int i=0;
printf("何か入力してよね!\n");
//無限ループ
while(1){
//i番目の配列に文字列を格納
scanf("%s",str[i]);
//入力された文字列が"END"の場合
//無限ループから抜ける
if(strcmp(str[i],"END")==0){
//"END"を表示させないため
//iを減らす
i--;
break;
}
i++;
}
//このときiには入力された
//文字列の数が入っている
//iがに0なるまでiを減らす
for(i;i>=0;i--){
printf("%s\n",str[i]);
}
return 0;
}
解説
文字列を複数格納するために、2次元配列を用意します。
このとき、格納される文字列は不定になるため、多めに用意しておきましょう。
次に、入力された文字列を格納していきます。
格納する文字列の数が不定なため、whileで無限ループを作るといいですね。
scanfでstr[i]となっているのは、i番目の配列に文字列を格納するということです。
このときも格納するのは文字列なので先頭に&は必要ありませんね。
ENDが入力されたら終了なので、文字列比較のstrcmp関数を使って入力されたら終了とします。
このとき、ENDは表示させたくないので、iを1引いておきます。
そうすれば、iには格納された文字列の数が入っていますね。
表示させるにはiが0になるまで1減らしていき、表示させます。
演習問題Ⅲ 第3問
第11回まで学習した内容を使い、演習問題を行います!
3 10人分のテスト点数
10人分のテストの点数を入力し、点数と順位を表示するプログラムを作ってみよう
但し、点数の入力範囲は0~100とし、それ以外は結果の様に再入力を求めるようにすること
10人分の点数と順位を格納する下表のような2次元配列を用意しよう。
a |
[0] |
[1] |
[0] |
点数 |
順位 |
[1] |
点数 |
順位 |
[2] |
点数 |
順位 |
[3] |
点数 |
順位 |
[4] |
点数 |
順位 |
[5] |
点数 |
順位 |
[6] |
点数 |
順位 |
[7] |
点数 |
順位 |
[8] |
点数 |
順位 |
[9] |
点数 |
順位 |
1)ユーザ入力から10人分の点数を格納します。
2)配列a[x][1](xは0~9)の中身を1で初期化します。
3)順位のつけ方は、前者と後者の点数を比較し、後者が小さい場合に後者の順位を1増やします。
4)これをa[0][0]~a[9][0]まですべて比較していきます。
結果
演習問題Ⅲ 第3問のヒント
3 10人分のテスト点数
1.10人分の点数を格納する変数を宣言する時は、10個の変数を宣言するのではなく、配列を用いて宣言する
2.入力エラー時に継続条件の値をインクリメントせずに再度入力を求めさせる時は反復構造の中でcontinueを使います
3.[ 63]のように表示するにはprintf( )の指定文字列「%d」の書式を「%*d」に変える(*はどの数字を入れるか考えよう。今回は3桁使用するから・・・)
4.0~100までの入力範囲を作る方法を忘れた人はこの例題を見て確認!
演習問題Ⅲ 第3問の解答
3 10人分のテスト点数
解答を隠す...
解答プログラム
//プログラムを書くときに(1),(2),(3),(4)は書かないでください
#include <stdio.h>
int main()
{
//int型配列の宣言
(1)int a[10][2];
int b = 0 ,c = 0, d = 0 ;
printf("点数を入力してください\n");
//点数入力
for(b=0;b<10;b++){
printf("%d人目:",b+1);
(2)scanf("%d",&a[b][0]);
//0点未満、101点以上の入力で再度入力を求める
if(a[b][0]<0 || a[b][0]>100){
printf("入力エラー\nもう一度入力してください\n");
b--;
continue;
}
}
//a[b][1]をで初期化
//a[0][1]~a[9][1]までとなる
for(b=0;b<10;b++){
(3)a[b][1]=1;
}
//順位決定のfor2重ループ
/*
a[b][0]とa[d][0]を比較し後者が小さければ後者の
a[d][1]に1を足す
すべてと比較をするので、小さいほうは常に足され
順位をつけることができる
*/
(4)for(b=0;b<10;b++){
for(d=0;d<10;d++){
if(a[b][0]>a[d][0]){
a[d][1]++;
}
}
}
//点数と順位の表示
for(b=0;b<10;b++){
printf("%d人目->点数:%3d順位:%3d\n",b+1,a[b][0],a[b][1]);
}
return 0;
}
解説
8行目(1)
点数と順位を格納する2次元配列を準備します。
表にすると下のようになります
16行目(2),29行目(3)
a[b][0](下表の色がついている部分)に入力された変数を格納していきます
また、下線(3)でa[b][1]に1を格納していきます。
39~45行目(4)
ここで順位を決定しています。
a[0][0]とa[1][0]を比較し、a[1][0]が小さければa[1][1]を1足します。
この場合はa[1][0]が小さいのでa[1][1]を1足します。
![a[0][0]とa[1][0]を比較しa[1][0]が小さければa[1][1]に1足す](/pcsp/images/c_12_09.png)
次に、a[0][0]とa[2][0]を比較します。ここでもa[2][0](後者)が小さいのでa[2][1]を1足します。

a[0][0]とすべて比較すると下表のようになりましたね。
![a[0][0]と他をすべて比較](/pcsp/images/c_12_11.png)
次にa[1][0]とa[0][0]を比較します。この場合はa[0][0]のほうが大きいので値に変化はありません。

a[2][0]も同じですね。a[1][0]とa[3][0]を比べてみましょう。
今度はa[3][0]が小さいので、1足されます。

これをひたすら続けていきます。

この比較をa[9][0]まで続けていきます。
![a[9][0]まで続ける](/pcsp/images/c_12_15.png)
あとはa[b][1]で順位を表示させてあげればいいですね。
演習問題Ⅲ 第4問
第11回まで学習した内容を使い、演習問題を行います!
4 10人分のテスト点数(平均点表示付)
(3)で作ったプログラムに平均点を表示する自作関数を作ってみよう
また、余裕のある人は自作関数内に何人目が平均点以下か点数もつけて表示させてみましょう
結果
演習問題Ⅲ 第4問のヒント
4 10人分のテスト点数(平均点表示付)
1.平均値の求め方を忘れた人はこの例題を見て確認!
演習問題Ⅲ 第4問の解答
4 10人分のテスト点数(平均点表示付)
解答を隠す...
解答プログラム
#include <stdio.h>
// 関数のプロトタイプ宣言
void avg(int a[10][2]);
int main()
{
//int型配列の宣言
int a[10][2];
int b = 0 ,c = 0, d = 0 ;
printf("点数を入力してください\n");
//点数入力
for(b=0;b<10;b++){
printf("%d人目:",b+1);
scanf("%d",&a[b][0]);
//0点未満、101点以上の入力で再度入力を求める
if(a[b][0]<0 || a[b][0]>100){
printf("入力エラー\nもう一度入力してください\n");
b--;
continue;
}
}
//a[b][1]をで初期化
//a[0][1]~a[9][1]までとなる
for(b=0;b<10;b++){
a[b][1]=1;
}
//順位決定のfor2重ループ
/*
a[b][0]とa[d][0]を比較し後者が小さければ後者の
a[d][1]に1を足す
すべてと比較をするので、小さいほうは常に足され
順位をつけることができる
*/
for(b=0;b<10;b++){
for(d=0;d<10;d++){
if(a[b][0]>a[d][0]){
a[d][1]++;
}
}
}
//点数と順位の表示
for(b=0;b<10;b++){
printf("%d人目->点数:%3d順位:%3d\n",b+1,a[b][0],a[b][1]);
}
avg(a);
return 0;
}
//平均を求める関数
void avg(int a[10][2])
{
int sum = 0,avg = 0, i;
//a[0][0]~a[9][0]までsumに足していく
for(i=0;i<10;i++){
sum = sum + a[i][0];
}
//平均点を算出
avg = sum / 10;
printf("平均点は%d\n",avg);
//追加で平均点以下を表示する
for(i=0;i<10;i++){
if (a[i][0] < avg){
printf("平均点以下は%d番で\t%d点です\n",i+1,a[i][0]);
}
}
return;
}
解説
数値の入力と順位の決定方法は(3)と同じですね。
平均を求めて表示する自作関数を作ります。
このとき、引数で2次元配列を渡します。
平均値は第7回の例題5、6でやっていますね。
また、配列をforで回してあげて平均と比較し、点数が平均点以下なら表示するようにすれば、追加のプログラムの出来上がり!