第6週 配列変数
INDEX

目標

  • 配列を宣言して、その配列の要素に値を代入したりその内容を参照することができる。
  • for文を使って配列の各要素に順番に値を代入したりその内容を参照することができる。
  • 配列を初期化して各要素に値を設定することができる。
  • 配列の内容を別の配列にコピーすることができる。

予習・復習

 以下のスライドを利用して、予習と復習をしよう。復習では、自分の理解度を確認するために、実際にプログラムを作成し、意図する結果が得られるか確認しよう。
  1. 配列変数

本日の講義・演習予定

  1. 配列
  2. 配列の初期化
  3. 配列と繰り返し処理
  4. 配列のコピー
  5. マクロ定義
  6. 2次元配列
  7. 演習問題
  8. 提出課題
内 容
  1. 配列
  2. 配列の初期化
  3. 配列と繰り返し処理
  4. 配列のコピー
  5. マクロ定義
  6. 2次元配列

配列

 1000個、2000個といった大量のデータを高速に処理することはコンピュータの得意とするところです。では、この大量のデータをプログラムの中でどのように表現したらよいでしょうか。
 例えば、ある学校の全生徒1200人分の成績を管理するプログラムを作ろうと思います。各生徒の試験結果を変数に格納して処理するためには、1200個分の変数を用意する必要があります。変数名は、m1, m2, m3、・・・、m1200としました。1200個分の変数をコーディングするのも大変ですが、データの追加や削除などはそれ以上に面倒なプログラムを書かなければならなくなりそうです。数万人の市民や通販サイトの顧客を扱うデータを処理するプログラムならば、実現すること自体、現実的ではなさそうです。

 このような大量のデータをまとめて扱うために、配列(Array)と呼ばれる仕組みが用意されています。配列は、同じ型の変数がいくつも一列に連なった構造をしたもので、一つの名前、配列名を使ってまとめて操作することができます。
 例えば、100個の整数値からなるデータを配列を使って表わしてみましょう。
int m[100];
と記述すると、int型の値100個分を格納することができる配列mが用意されます。配列mの一つ一つ変数を参照するときには、次のように記述します。一つ目の変数は、
m[0]
2つ目の変数は、
m[1]
3つ目の変数は、
m[2]
・・・
100個目の変数は、
m[99]
として指定することができます。
 一つ一つの変数を配列要素もしくは単に要素(element)と呼びます。配列要素を参照する場合は、配列名の後に角カッコ[ ]とその中に先頭から何番目の要素かを記します。この先頭から何番目を示す数値を添字(index)と言います。添字は0からはじまります。例えば、100個分の配列を宣言したときは、添字の範囲は0から99になります。
配列は、同じデータ型の変数が一列に並んだもの。
Array
添字は0から始まる。
 次のプログラムc7-1a.cは、5人の生徒のテストの得点を扱うために配列を使った例です。
c7-1a.c
#include <stdio.h>

int main(void)
{
	int m[5];		// 5個の得点を格納する配列の宣言
	int sum = 0;		// 合計点
	double avg;		// 平均点
	
	m[0] = 70;		//0番目の要素に値を代入
	m[1] = 90;
	m[2] = 85;
	m[3] = 75;
	m[4] = 95;
	
	sum = m[0] + m[1] + m[2] + m[3] + m[4];
	avg = (double)sum/5;
	
	printf("合計点 %d¥n", sum);
	printf("平均点 %.1f¥n", avg);
	
	return 0;
}
Array
配列を宣言するときの角カッコ[ ]の中の数字は、配列の個数を、
配列を参照するときの角カッコ[ ]の中の数字は、何番目の要素であるかを示す。

配列の初期化

配列の初期化

 配列の宣言と同時に各要素に値を設定することができます。これを配列の初期化と言います。左辺に各要素の値をカンマ(,)で区切って並べ、それを波カッコ{}で囲います。
 先の5人の生徒の得点を扱うプログラム例の配列を初期化で書き直した例を以下に示します。
例 c7-1b.c
#include <stdio.h>

int main(void)
{
	int m[5] = {70, 90, 85, 75, 95};	// 得点を格納する配列の宣言
	int sum = 0;						// 合計点
	double avg;							// 平均点
		
	sum = m[0] + m[1] + m[2] + m[3] + m[4];
	avg = (double)sum/5;
	
	printf("合計点 %d¥n", sum);
	printf("平均点 %.1f¥n", avg);
	
	return 0;
}

配列の初期化のいろいろ

  1. すべての要素を0で初期化する例
  2. int m[5] = {0};
  3. 残りの要素だけ0で初期化する例
  4. int m[10] = {0, 1, 2, 3, 4, };

※ 変数宣言した後で、まとめて値を代入することはできない
m[] = {10, 20, 30, 40, 50};  ×これは誤り
m = {10, 20, 30, 40, 50};    ×これも誤り
変数宣言してもその値は0にはならない。

注) C言語の仕様では、変数宣言をした時点でコンパイラがメモリをクリアしなければならないとは規定されていません。それ以前に実行したプログラムが同じメモリ領域を使っていてその残骸が残っていることもあります。変数が0であることを前提とする手続きの場合は、それ以前に0を代入しておくか、0で初期化しておかなければなりません。

配列とくり返し処理

くり返し処理を利用しないで配列を扱う

 5人の生徒のテストの得点を入力して、得点一覧とその合計と平均を表示するプログラムを配列を使って実現してみます。
例 c7-2a.c

#include <stdio.h>

int main(void)
{
	int m[5];			// 得点
	int sum = 0;			// 合計
	double avg;			// 平均
	
	// 得点の読み込み
	printf("1人目の得点>> ");	scanf("%d", &m[0]);
	printf("2人目の得点>> ");	scanf("%d", &m[1]);
	printf("3人目の得点>> ");	scanf("%d", &m[2]);
	printf("4人目の得点>> ");	scanf("%d", &m[3]);
	printf("5人目の得点>> ");	scanf("%d", &m[4]);
	
	// 得点の表示
	printf("1人目 %d点¥n", m[0]);
	printf("2人目 %d点¥n", m[1]);
	printf("3人目 %d点¥n", m[2]);
	printf("4人目 %d点¥n", m[3]);
	printf("5人目 %d点¥n", m[4]);

	sum = m[0] + m[1] + m[2] + m[3] + m[4];			// 合計を求める
	avg = (double)sum/5;					// 平均を求める
	
	printf("合計点 %d¥n", sum);
	printf("平均点 %.1f¥n", avg);
	
	return 0;
}

繰り返し処理を使った配列

 5人分の得点を読み込み、表示をするためにprintfやscanfが繰り返し登場してきます。1人目の得点、2人目の得点、・・・、5人目の得点と入力するに従い、配列の添字も0、1、・・・、4と1ずつ増えています。この添字に、繰り返し構文のカウンタ変数を当てはめれば、生徒の人数に関係なく配列に値を読み込んだり、配列の値を表示するプログラムができそうです。
 下記のプログラム例では、繰り返し処理にfor文を使い、そのカウンタ変数iを配列の添字に使っています。
例 c7-2b.c
#include <stdio.h>

int main(void)
{
	int m[5];			// 得点
	int sum = 0;		// 合計
	double avg;			// 平均
	int i;
	
	// 得点の読み込み
	for (i=0; i<5; i++) {
		printf("%d人目の得点>> ",i);	scanf("%d", &m[i]);
	}
	
	// 得点の表示
	for (i=0; i<5; i++) {
		printf("%d人目 %d点¥n", m[i]);
		sum += m[i];					// 合計 sum=sum+dt[i]と同じ
	}
	avg = (double)sum/5;				// 平均
	
	printf("合計点 %d¥n", sum);
	printf("平均点 %.1f¥n", avg);
	
	return 0;
}


配列のコピー

 配列maとmbがあり、配列maの内容を配列mbにコピーしたいと思い、次のように記述しました。
mb = ma ×これは誤り
しかし、これは正しくありません。面倒でも各要素を一つずつコピーする必要があります。
mb[0] = ma[0];
mb[1] = ma[1];
・・・
c7-3.c
#include <stdio.h>

int main(void)
{
	int ma[10]={1,2,3,4,5,6,7,8,9,10};	//コピー元
	int mb[10];							//コピー先
	int i;
	
	for (i=0; i<10; i++) {
		mb[i] = ma[i];					//要素のコピー
	}
	
	for (i=0; i<10; i++) {
		printf("ma[%d]=%2d  mb[%d]=%2d¥n", i,ma[i],i,mb[i]);
	}
	
	return 0;
}
配列の内容をコピーするためには、各要素を一つずつコピーする。


マクロ定義

 配列を利用したプログラムでは、その要素数の変更が生じると複数箇所の書き換えが必要になる可能性があります。また、変更作業が面倒なだけはなくバグを発生させる原因にもなります。このような場合は、プリプロセッサを利用して要素数を定数として事前に定義して利用することができます。変更が生じてもこの部分のみの変更で済ますことができます。
#define マクロ名 文字列
マクロ名はコンパイル前に自動的にプログラム中のマクロ名を文字列に置き換えます。マクロ名には慣習的に半角大文字を使います。 下記は前節のプログラムc7-3.cをマクロを使って書き換えたものです。
c7-4.c
#include <stdio.h>
#define N 10			// マクロ定義

int main(void)
{
	int ma[N]={1,2,3,4,5,6,7,8,9,10};		//コピー元
	int mb[N];						//コピー先
	int i;
	
	for (i=0; i<N; i++) {
		mb[i] = ma[i];				//要素のコピー
	}
	
	for (i=0; i<N; i++) {
		printf("ma[%d]=%2d  mb[%d]=%2d¥n", i,ma[i],i,mb[i]);
	}
	
	return 0;
}

2次元配列

2重ループと2次元配列

 1次元配列は変数を一列に並べた構造をしていましたが、更にこれを何段かに重ねた構造をした配列を2次元配列と言います。 例えば、3つの要素を持つ1次元配列を2段重ねた2次元配列の場合は、
int m[2][3];
と宣言します。
2次元配列
これを、2行3列の2次元配列と呼びます。 それぞれの要素は2つの添え字を使って行と列を指定することでを参照することができます。例えば、左上の1行1列目の要素ならば、
m[0][0]
2行3列目の要素ならば
m[1][2]
となります。

2次元配列の初期化

 2次元配列の初期化は、各要素をカンマで区切りそれを行ごとに波カッコで囲い、さらに、その各行をカンマで区切り、全体を波カッコ{}で囲います。
例1)int m[2][3] = {{11,12,13}, {21,22,23}};
例2)int m[3][2] = {{11,12}, {21,22}, {31,32}};

以下は、2行3列の2次元配列を整数値で初期化し、その各要素の内容を表示するプログラム例です。
c7-2.c
#include <stdio.h>

int main(void)
{
	int m[2][3] = {{10,11,12},		//1行目の初期化
			  {21,22,23}};		//2行目の初期化
	int i,j;
	
	for (i=0; i<2; i++) {
		for (j=0; j<3; j++) {
			printf("m[%d][%d]=%d", i,j,m[i][j]);
		}
	}
	
	return 0;
}
二次元配列の宣言 データ型 配列名[行の要素数][列の要素数]
二次元配列の要素の参照 配列名[行位置][列位置]


expand_lessBack to TOP
内 容
  1. 探索
  2. モード探索

探索

特定の値を探索する

 配列の要素の中に、特定の値がないか。配列の先頭要素から順次、探索した値と同じかどうかを調べます。

最大値・最小値を探索する

最大値を格納する変数を用意して、配列の先頭の要素から順次、現行の最大値と比較し、もし現在の最大値よりも大きな要素が見つかった場合は、その変数を更新することで、最大値を保持します。

モード探索

最頻値を探索する

配列の要素の中で最も頻繁に出現する値を探し出します。

expand_lessBack to TOP

演習問題

  1. 次は、全ての要素を0で初期化した配列mに対して、変更したい要素の番号と値を入力してその要素の値を書き換え、その結果を表示するプログラムex6-1.cです。空欄を埋めて完成させなさい。
  2. ex6-1.c
    #include <stdio.h>
    #define N 5
    
    int main(void)
    {
    	int m[[空欄ア]];
    	int i,x;
    
    	printf("変更する要素番号と値(i,x)>> ");	
    	scanf("%d,%d",&i,&x);
    	[[空欄イ]]
    
    	for(i=0; i<N; i++){
    		printf("m[%d]=%d\n", [[空欄ウ]]);			//結果表示
    	}
    	return 0;
    }

  3. 次は、 それぞれの要素数が10個の配列ma、mb、mcの各要素を次の手順に従って操作し、その結果を表示するプログラムex6-2.cです。空欄を埋めて完成させなさい。操作1)配列maの先頭の要素から順番に1から10までの整数を代入し、配列mbには先頭の要素から順番に10から1までの整数を代入する。操作2)。配列mcには配列maと配列mbの各要素の和を代入する。
  4. ex6-2.c
    #include <stdio.h>
    #define N 10
    
    int main(void)
    {
    	int ma[N],mb[N],mc[N];
    	int i;
    
    	// 1) 配列maの先頭の要素から順に整数1から10までを代入
    	//    配列mbの先頭の要素から順に整数10から1までを代入
    	for (i=0; i<N; i++) {
    		ma[i] = [[空欄ア]];
    		mb[i] = [[空欄イ]];
    	}
    
    	// 2) 配列mcに配列maと配列mbの各要素の和を代入
    	for (i=0; i<N; i++) {
    		mc[i] = ma[i] + mb[i];
    	}
    	
    	for (i=0; i<N; i++) {
    		 printf("ma[%d]=%2d\t mb[%d]=%2d\t mc[%d]=%2d\n", [[空欄ウ]]);
    	}
    	return 0;
    }

  5. 次は、5人の生徒の国語、数学、英語の各点数を以下のような表にまとめて表示するプログラムです。空欄を埋めてプログラムex6-3.cを完成させなさい。
  6. No.|  国語 | 数学 |  英語 |
    ---+------+------+------|
     1 |   65 |   70 |   85 | 
     2 |   80 |   86 |   90 | 
     3 |  100 |   86 |   85 | 
     4 |   95 |   82 |  100 | 
     5 |   90 |   86 |   80 |
     
    *環境によっては表の列が揃って表示されないかもしれません。実際の実行結果は書式指定子を利用して揃えて表示させてください。
    ex6-3.c
    #include <stdio.h>
    int main(void)
    {
    	int score[5][3] = {
    		{65,70,85},{80,86,90},{100,86,85},{95,82,100},{90,86,80}};
    	int i,j;
    
    	printf("No.| 国語 | 数学 | 英語 |\n");
    	printf("---+------+------+------|\n");
    	for(i=0; [[空欄ア]]; i++){
    		[[空欄イ]];
    		for(j=0; [[空欄ウ]]; j++){
    			printf([[空欄エ]]);
    		}
    		printf("\n");
    	}
    	return 0;
    }

  7.  下記は、10個の要素を持つ配列mに1から10までの値を代入して、その合計値を求めるプログラムex6-4.cです。ただし、5個の間違い(修正方法によっては6個)が含まれたまま修正がされていません。正しく動作するように間違いを見つけて修正しなさい。
  8. ex6-4.c
    #include <stdio.h>
    #define N 10
    
    int main(void)
    {
    	int m[N];
    	int i,sum;
    	
    	for (i=1; i<=N; i++) {
    		m[i-1] = i;				//1〜10を代入
    	}
    	for (i=1; i<=N; i++) {
    		printf("m[%d] = %2d¥n", m[i-1]);
    		sum += m[i-1];				//変数sumに各要素を加算
    	}
    
    	printf("合計値 %d¥n", m);
    	
    	return 0;
    }
    

  9.  下記の1から10までの10個の整数で初期化された配列maの内容を逆順に配列mbに格納するプログラムex6-5.cを完成させなさい。
  10. ex6-5.c
    #include <stdio.h>
    #define N 10
    
    int main(void)
    {
    	int ma[N] = [[空欄ア]];
    	int mb[N];
    	int i;
    	
    	for(i=0; i<N; i++){
    		[[空欄イ]];				//逆順に代入
    	}
    	for(i=0; i<N; i++){
    		printf("ma[%d]=%2d ¥t mb[%d]=%2d\n", [[空欄ウ]]);
    	}
    	
    	return 0;
    }
    
    reverse copy


  11. はじめに人数とその各人の得点を入力して、60点以上の合格者の番号と点数の一覧を表示するプログラムex6-6.cを完成させなさい。
  12. ex6-6.c
    #include <stdio.h>
    
    int main(void)
    {
    	int score[64]={0}, pass[64]={0};	//点数、合格者番号(各最大64名まで)
    	int n, npass=0;				//人数、合格者数
    	int i;
    	
    	printf("入力する人数(max:64)>> ");
    	scanf("%d", &n);
    
    	for (i=0; i<n; i++) {
    		printf("%2d番>> ", i+1);
    		scanf("%d", [[空欄ア]]);		//得点の読み込み
    		if([[空欄イ]]){
    			[[空欄ウ]]			//合格者の記録
    			npass++;
    		}
    	}
    
    	printf("\n--- 合格者一覧 ---\n");
    	for(i=0; i<npass; i++){
    		printf("%2d番 %3d点\n", [[空欄エ]], [[空欄オ]]);
    	}
    	return 0;
    }
    

  13.  下記は、0番目から40番目までの41個のフィボナッチ数を表示するプログラムex6-7.cです。空欄(ア)〜(エ)を埋めて完成させなさい。
  14.  n番目のフィボナッチ数をFnとすると、最初の二項は、
    F0 = 0
    F1 = 1
    と定義されます。以降は前の項との和として求められます。
    F2 = F0 + F1 = 1
    F3 = F1 + F2 = 2
    ・・・
    Fn = Fn-2 + Fn-1
    ex6-7.c
    #include <stdio.h>
    #define N 41
    
    int main(void)
    {
    	int f[[空欄ア]];
    	int i;
    	
    	f[0] = 0;
    	f[1] = 1;
    
    	for (i=2; i<[[空欄イ]]; i++) {
    		[[空欄ウ]];
    	}
    	for (i=0; i<[[空欄エ]]; i++) {
    		printf("f[%d] = %d¥n", i, f[i]);
    	}
    	
    	return 0;
    }
    

  15. 次の数列anのn=1〜10までの10個の数列を配列で扱い、表示しなさい。
  16. a1 = 2
    a2 = 6
    an+2 = an+1 + 2an - 3

  17. 検索したい整数とその値を書き換える整数を入力して、次の与えられた10個の整数 {2, 8, 12, 5, 12, 8, 9, 3, 7, 1} の要素を書き換えるプログラムを作成しなさい。もし、見つからなかった場合は「見つかりませんでした。」と表示すること。また、書き換えた要素番号も合わせて表示すること。

  18. 以下の実行結果のように、10個のデータを入力して、その結果を横向きの棒グラフで示すプログラムを作成しなさい。ただし、入力可能なデータ値は0以上10以下とし、それ以外の値の時には再入力できるものとする。
  19. データ 1>> 2
    データ 2>> 3
    データ 3>> 4
    データ 4>> 5
    データ 5>> 12
    データ 5>> 7
    データ 6>> 3
    データ 7>> 9
    データ 8>> 8
    データ 9>> 1
    データ10>> 5
     1|**
     2|***
     3|****
     4|*****
     5|*******
     6|***
     7|*********
     8|********
     9|*
    10|*****
    

  20. 以下の実行結果のように、10個のデータを入力して、その結果を下向きの棒グラフで示すプログラムを作成しなさい。ただし、入力可能なデータ値は0以上10以下とし、それ以外の値の時には再入力できるものとする。
  21. データ 1>> 5
    データ 2>> 6
    データ 3>> 9
    データ 4>> 8
    データ 5>> 0
    データ 6>> 1
    データ 7>> 2
    データ 8>> 3
    データ 9>> 6
    データ10>> 5
     1 2 3 4 5 6 7 8 9 10
    ---------------------
     * * * *   * * * * *
     * * * *     * * * *
     * * * *       * * *
     * * * *         * *
     * * * *         * *
       * * *         *  
         * *            
         * *            
         *  
    

  22. 以下の実行結果のように、10個のデータを入力して、その結果を上向きの棒グラフで示すプログラムを作成しなさい。ただし、入力可能なデータ値は0以上10以下とし、それ以外の値の時には再入力できるものとする。
  23. データ 1>> 1
    データ 2>> 2
    データ 3>> 3
    データ 4>> 4
    データ 5>> 5
    データ 6>> 9
    データ 7>> 8
    データ 8>> 5
    データ 9>> 2
    データ10>> 7
               *        
               * *      
               * *     *
               * *     *
             * * * *   *
           * * * * *   *
         * * * * * *   *
       * * * * * * * * *
     * * * * * * * * * *
    ---------------------
     1 2 3 4 5 6 7 8 9 10
     

  24. 学生80人分の得点を与えて、10点刻み(0〜9、10〜19、20〜29、...、90〜99、100は90〜99のランクに含めるものとする)の横向きのヒストグラムを描くプログラムを作成しなさい。各得点は乱数を使って生成して良い。
  25. 得点: 39 73 68 64 27 38 19 97 2 79 83 37 43 86 89 81 83 55 9 90 33 37 97 48 11 49 86 18 1 57 50 84 70 82 84 23 74 71 25 94 23 9 91 45 93 0 12 72 98 21 87 26 74 98 97 89 80 43 75 80 57 24 81 9 21 86 12 55 52 65 28 36 6 20 3 55 75 1 99 20
    
     0-  9|*********
    10- 19|*****
    20- 29|***********
    30- 39|******
    40- 49|*****
    50- 59|*******
    60- 69|***
    70- 79|*********
    80- 89|***************
    90-100|**********
    

演習問題解答

OPEN ANSWER
  1. 回答 ア.[N]={0} イ.m[i] = x; ウ. i,m[i]

  2. 回答 ア.i+1 イ.10-i ウ.i,ma[i],i,mb[i],i,mc[i]

  3. 回答 ア.5 イ.printf("%2d | ",i+1) ウ. 3 エ.printf("%4d | ",score[i][j])

  4. 修正箇所 1. 7行目 sum=0、2. 9行目 i=0; i<N; 3.10行目 i+1、5. 12行目 i=0; i<N;、6.17行目 sum

  5. 回答 ア.{1,2,3,4,5,6,7,8,9,10} イ.mb[i] = ma[N-i-1] ウ.i,ma[i],i,mb[i]

  6. 回答 ア.&score[i] イ.score[i]>=60 ウ.pass[npass]=i エ.pass[i]+1 オ. score[pass[i]]

  7. 回答 ア. [N] イ. N ウ. f[i] = f[i-2] + f[i-1] エ. N

  8. 回答例
  9. code/6/ex6-8.c

  10. 回答例
  11. code/6/ex6-9.c

  12. 回答例
  13. code/6/ex6-11.c

  14. 回答例
  15. code/6/ex6-12.c

  16. 回答例
  17. code/6/ex6-13.c

expand_lessBack to TOP
以下の演習問題に取り組みなさい。リンク先のideone.comの未完成プログラムをforkして、プログラムを完成させなさい。空欄は必ずしも1行もしくは1文とは限りません。
  • 10個の要素からなる配列があります。この配列の要素の最大値を求めるプログラムを完成させなさい。
  • https://ideone.com/3ntVJP

  • 10個の要素からなる配列があります。この配列の要素を逆順に並べ替えるプログラムを完成させなさい。
  • https://ideone.com/xi7Rdo

  • 10人分の学生の得点が格納された配列があります。各学生の得点の順位を表示するプログラムを完成させなさい。
  • https://ideone.com/LJOWNK

本日の提出課題

以下の各プログラムを作成しなさい。ただし、配列を利用すること。
  • 1. 10個の正の整数を配列aに読み込んで、その配列aに格納された整数の最大値と最小値の差を表示するプログラム。

  • 2. 10進数である正の整数を読み込んで、2進数へ変換した結果を表示するプログラム。

  • 3. 10個の整数を配列aに読み込んで、その配列aに格納された整数の大きいほうから順に3つの値を表示するプログラム。同じ整数はないものとします。

  • 4. 0から9までの30個の整数を乱数として用意し、これを配列aに読み込みます。この配列aについて、0から9までの各整数の度数を調べて下記の実行例のようにグラフで表示するプログラム。
    4 6 1 8 6 4 8 1 5 4 7 7 3 5 3 6 5 3 9 5 8 6 5 1 3 4 1 7 4 7 1 8 5 2 7 3 8 7 6 4 1 4 3 7 1 7 5 9 0 4 
    0: *
    1: *******
    2: *
    3: ******
    4: ********
    5: *******
    6: *****
    7: ********
    8: *****
    9: **
    

  • 5. 下図の例のようにバーコードには13桁の数字が書かれています。このうち右端の数字はチェックデジットと呼ばれ、読み込まれた数字に誤りがないかを調べるために利用されます。チェックデジットは下図の例の手順で求められます。バーコードに書かれた13桁の数字を入力して、その数字に間違いがなければ「適切なコードです」、そうでなければ「入力しなおしてください」と表示するプログラム。


  •   ※ 手順5の結果が10となった場合は、チェックデジットは下1桁の0となります。

    13桁の整数はint型では範囲外となるため、long型を使います。long型の使い方については、以下のプログラム例を参考にしてください。
    #include <stdio.h>
    int main(void){
    	long int n;		// longのみでも可
    	
    	scanf("%ld", &n);		//変換指定子には%ldを使う
    	
    	printf("%ld\n", n);
    	printf("最下位桁は%ld", n%10L);		//long型の整数リテラルにはLを付ける
    	
    	return 0;
    }
    	

 0から9までの番号のついた10封の封筒があり、番号0から順番に1円、2円、4円、8円、16円、32円、64円、128円、256円、512円分のお金が入っています。下記の実行例のように1000円までの金額を入力して、その金額分の封筒の番号を表示するプログラムkadai6.cを作成しなさい。

[実行例]
必要な金額は(1〜1000)?>> 200
用意した封筒: 7 6 3
 

[考え方]
 10枚の封筒を配列として、封筒の番号を配列の添字とします。必要な金額ために用意する封筒が何番なのかわかるように、封筒(の番号)を入れる(記録する)ための入れ物(配列)を用意します。必要な封数は事前には分からないので、全ての封筒を収めることができるように(要素数10の配列を)準備します。例えば、必要な金額が200円ならば、まず大きい金額の入った封筒から調べて行きます。封筒9番の512円、封筒8番の256円では金額が大きすぎます。封筒7番目の128円ならば200円内に納まります。この封筒(の番号)を用意した入れ物に移します(記録します)。残金の72円についても同様に調べて封筒6番64円を入れ物に、さらに残金8円についても調べて封筒3番8円を入れ物に移します。残金が0となり、入れ物に移した封筒(の番号)からその封数(の番号)がわかります。


  • [提出方法]
    1. ideone.comを利用して作成した課題プログラムのURLをCoursePowerへ提出のこと。
    2. 適切な実行結果を含むこと
    3. 詳細はスライド「ideoneの使い方」参照のこと。

  • [評価について]
  • プログラムの内容の評価とは別に以下の要件を満たすことを評価の前提とする。
    1. C言語で記述されていること。
    2. ソースコードファイルのコンパイル結果に、ワーニングやエラーが出力されていないこと。
    3. 所定の実行結果が得られるていること。
    4. ソースコードは、インデントや適当な改行が施された見やすい状態であること。

  • [提出期限]
  • 2023年 5月29日(月)までとする。ただし、以降の提出も受け付ける。