ページ 11

表の累計

Posted: 2011年6月05日(日) 13:59
by アレス
累計
50 49 48 47 46  240
45 44 43 42 41  455
40 39 38 37 36  645
35 34 33 32 31  810
30 29 28 27 26  950
25 24 23 22 21 1065
20 19 18 17 16 1155
15 14 13 12 11 1220
10  9  8  7 6 1260
5 4 3   2 1 1275
累計 275 540 795 1040 1275

このように表示するプログラムを関数縛りで作りたいのですがコンパイルすると['print_list' : 呼び出しに対する引数が少なすぎます。]と出てしまうのですがどこをどのように直せばいいのかわかりません。アドバイスください。

コード:

#include <stdio.h>

#define WIGHT 5
#define HEIGHT 10

int sum_HEIGHT(int v[][WIGHT], int sub)
{
	int i;
	int sum = 0;
	for(i=0;i<HEIGHT;i++){
		sum += v[i][sub];
	}
	return(sum);
}

int sum_WIGHT(int v[][WIGHT], int no)
{
	int i;
	int sum = 0;
	for(i=0;i<WIGHT;i++){
		sum += v[no][i];
	}
	return(sum);
}
void print_list(int v[][WIGHT],int no,int sub)
{
	int i,	j;
	puts("                           累計");
	for(i=0;i<HEIGHT;i++){
		printf("     ");
			for(j=0;j<WIGHT;j++)
				printf("%5d",50-(i*5)-j);
			printf("%5d",sum_WIGHT(v,no));
			putchar('\n');
	}
	printf("累計 ");
	for(i=0;i<WIGHT;i++)
		printf("%5d",sum_HEIGHT(v,sub));
}

int main(void)
{
	int tensu[HEIGHT][WIGHT];

	print_list(tensu);

	return (0);
}

Re: 表の累計

Posted: 2011年6月05日(日) 14:35
by a5ua
エラーになるのは、print_listは3個の引数を要求しているのに対して、
mainでは、1つの引数しか与えていないからです。

ところで、sum_HEIGHTなどの各関数がどのような処理をするか説明できますか?
以下のように、関数にコメントをつける形で答えてみてください。

コード:

// 要素数nの配列vの各要素を合計した値を返す
int sum(int v[], int n)
{
	int sum = 0;
	int i;
	for (i = 0; i < n; i++) {
		sum += v[i];
	}
	return sum;
}

Re: 表の累計

Posted: 2011年6月05日(日) 14:56
by アレス
>a5uaさん

コード:

#include <stdio.h>

#define WIGHT 5
#define HEIGHT 10

//縦列subの合計を求める。配列v[sub]の各要素の合計値で返す。
int sum_HEIGHT(int v[][WIGHT], int sub)
{
	int i;
	int sum = 0;
	for(i=0;i<HEIGHT;i++){
		sum += v[i][sub];
	}
	return(sum);
}

//横列v[no]の合計を求める。配列v[no]の各要素の合計値で返す。
int sum_WIGHT(int v[][WIGHT], int no)
{
	int i;
	int sum = 0;
	for(i=0;i<WIGHT;i++){
		sum += v[no][i];
	}
	return(sum);
}
//一覧表を出力する。
void print_list(int v[][WIGHT],int no,int sub)
{
	int i,	j;
	puts("                           累計");
	for(i=0;i<HEIGHT;i++){
		printf("     ");
			for(j=0;j<WIGHT;j++)
				printf("%5d",50-(i*5)-j);
			printf("%5d",sum_WIGHT(v,no));
			putchar('\n');
	}
	printf("累計 ");
	for(i=0;i<WIGHT;i++)
		printf("%5d",sum_HEIGHT(v,sub));
}

int main(void)
{
	int tensu[HEIGHT][WIGHT];


	print_list(tensu);

	return (0);
}
こんなかんじですかね。

Re: 表の累計

Posted: 2011年6月05日(日) 15:15
by a5ua
sum_HEIGHTとsum_WIGHTについては、問題ないと思います。

ただし、print_listについては、少し説明が足りないと思います。
引数である、v, no, subはどのように使われるのかの説明がありません


あと、プログラムとは直接関係ないですが、WIGHTはWIDTHのスペルミスですよね?

Re: 表の累計

Posted: 2011年6月05日(日) 15:41
by アレス
>a5uaさん
print_listのとこにもreturn()をつけて()内にnoやsubを用いた値で返すということですか。

Re: 表の累計

Posted: 2011年6月05日(日) 16:11
by a5ua
print_listは配列vをもとに、一覧表を作成して出力するのですよね?
でしたら、「一覧表とは何か?」を、数式もしくは言葉などで説明しなくてはなりません。

まあ、何が言いたいかというと、noやsubはprint_listの引数として本当に必要でしょうか?

Re: 表の累計

Posted: 2011年6月05日(日) 19:26
by アレス

コード:

#include <stdio.h>
#define WIDHT 5
#define HEIGHT 10

int sum_HEIGHT(int v[][WIDHT], int sub)
{
	int i;
	int sum = 0;
	for(i=0;i<HEIGHT;i++){
		sum += v[i][sub];
	}
	return(sum);
}

int sum_WIGHT(int v[][WIDHT], int no)
{
	int i;
	int sum = 0;
	for(i=0;i<WIDHT;i++){
		sum += v[no][i];
	}
	return(sum);
}
void print_list(int v[][WIDHT])
{
	int i,	j;
	int	a = 0;
	int	va[5] = {0};
	puts("                                累計");
	for(i = 0;i < HEIGHT;i++){
		printf("     ");
			for(j = 0;j < WIDHT;j++){
				printf("%5d",50 - (i * 5) - j);
				a += 50 - (i * 5)-j;
				va[j] += 50 - (i * 5) - j;
			}
			printf("%5d",a);
			putchar('\n');
	}
	printf("累計 ");
	for(i = 0;i < WIDHT;i++){
		printf("%5d",va[i]);
		if(i < 4)
		va[i + 1] += va[i];
		}
}

int main(void)
{
	int tensu[HEIGHT][WIDHT];


	print_list(tensu);

	return (0);
}
>a5uaさん
一覧表をnoとsubを使わなかったらこのようになったんですがこれでは関数を用いてないですし…。

Re: 表の累計

Posted: 2011年6月05日(日) 19:32
by h2so5
関数使ってますよ。

print_list(tensu); ← これ関数ですよね?

Re: 表の累計

Posted: 2011年6月05日(日) 19:36
by box
アレス さんが書きました: 関数縛り
一覧表をnoとsubを使わなかったらこのようになったんですがこれでは関数を用いてないですし…。
関数縛りという言葉の意味がわかりません。
関数を用いていないと判断なさった理由がわかりません。
以上2点につきまして、ご説明をお願いいたします。

Re: 表の累計

Posted: 2011年6月05日(日) 19:48
by アレス
>h2so5さん>boxさん
関数縛りというのが違ったのかもしれません。累計を求めるのに関数を用いて、一覧表を出力するのにも関数を使うという意味です。日本語おかしくてすみません。

Re: 表の累計

Posted: 2011年6月05日(日) 19:50
by box
関数を用いていないと判断なさった理由についてはいかがでしょうか?

Re: 表の累計

Posted: 2011年6月05日(日) 19:57
by a5ua
sum_HEIGHTとsum_WIGHTは、vに何らかの(意味のある)値が入っていることが前提になっていますよね?

今のコードではprint_listが
・v[j]の初期化(No: 7では引数のvすら使ってないようですが)
・累計の計算
・表示
という機能を持っていますが、初期化と累計の計算を同時に行なっているため、
sum_HEIGHTとsum_WIGHTが有効に使えません。
よって、print_listの機能のうち、初期化の処理を別の関数に分離することを考えます。

たとえば、配列の初期化用に次のような関数を用意します。

コード:

// vに値を設定する
// No: 1に書いてあるように、以下のように初期化する
// 50 49 48 47 46
// 45 44 43 42 41
// 40 39 38 37 36
// 35 34 33 32 31
// 30 29 28 27 26
// 25 24 23 22 21
// 20 19 18 17 16
// 15 14 13 12 11
// 10  9  8  7  6
//  5  4  3  2  1
void init_list(int v[][WIDHT]);
このinit_listを適切に実装したうえで、
print_listでsum_HEIGHTとsum_WIGHTを使うようなコードを考えてみましょう。

Re: 表の累計

Posted: 2011年6月05日(日) 19:59
by アレス
>boxさん
print_list(tensu)を使っていますが先ほどのソースでは

コード:

int sum_HEIGHT(int v[][WIDHT], int sub)
{
	int i;
	int sum = 0;
	for(i=0;i<HEIGHT;i++){
		sum += v[i][sub];
	}
	return(sum);
}

int sum_WIGHT(int v[][WIDHT], int no)
{
	int i;
	int sum = 0;
	for(i=0;i<WIDHT;i++){
		sum += v[no][i];
	}
	return(sum);
}
この部分がなくても起動します。つまり累計を出すのに関数を用いてないという意味です。

Re: 表の累計

Posted: 2011年6月05日(日) 20:21
by アレス
>a5uaさん
アドバイスをみてこのようにしてみたのですが、[error LNK2019: 未解決の外部シンボル _sum_WIDTH が関数 _print_list で参照されました。]とでてしまったのですが・・・。考え方てきにはこれでいいのですか?

コード:

#include <stdio.h>
#define WIDHT 5
#define HEIGHT 10

int sum_HEIGHT(int v[][WIDHT], int sub)
{
	int i;
	int sum = 0;
	for(i=0;i<HEIGHT;i++){
		sum += v[i][sub];
	}
	return(sum);
}

int sum_WIGHT(int v[][WIDHT], int no)
{
	int i;
	int sum = 0;
	for(i=0;i<WIDHT;i++){
		sum += v[no][i];
	}
	return(sum);
}

void fill(int v[][WIDHT])
{
	int i,	j;
	for(i = 0;i < HEIGHT;i++){
		for(j = 0;j < WIDHT;j++)
			v[i][j] = 50 - (i * 5) - j;
	}
}

void print_list(int v[][WIDHT])
{
	int i,	j;
	puts("                                累計");
	for(i = 0;i < HEIGHT;i++){
		printf("     ");
			for(j = 0;j < WIDHT;j++)
				printf("%d",v[i][j]);
			printf("%5d\n",sum_WIDTH(v,i));
	}
	printf("累計 ");
	for(i = 0;i < WIDHT;i++){
		printf("%5d",sum_HEIGHT(v,j));
		}
}

int main(void)
{
	int tensu[HEIGHT][WIDHT];


	print_list(tensu);

	return (0);
}

Re: 表の累計

Posted: 2011年6月05日(日) 20:27
by bitter_fox
アレス さんが書きました:>a5uaさん
アドバイスをみてこのようにしてみたのですが、[error LNK2019: 未解決の外部シンボル _sum_WIDTH が関数 _print_list で参照されました。]とでてしまったのですが・・・。考え方てきにはこれでいいのですか?

コード:

int sum_WIGHT(int v[][WIDHT], int no)
{
}
sum_WIGHTだけWIDTHに修正されていないですよ。

Re: 表の累計

Posted: 2011年6月05日(日) 20:36
by a5ua
まだ、間違っている箇所がありますが、fill関数の実装に関してはOKです。

とりあえず、以下の2点についてやってみてください。
・エラーをなくすために、WIDHT -> WIDTHに修正してください。
・fill関数を適切な場所で呼び出してください。

Re: 表の累計

Posted: 2011年6月05日(日) 21:08
by アレス
>a5uaさん
入れてみたんですけど今度はこんなエラーが・・・。[warning C4020: 'fill' : 実引数が多すぎます。]

コード:

#include <stdio.h>
#define WIDTH 5
#define HEIGHT 10

int sum_HEIGHT(int v[][WIDTH], int sub)
{
	int i;
	int sum = 0;
	for(i=0;i<HEIGHT;i++){
		sum += v[i][sub];
	}
	return(sum);
}

int sum_WIDTH(int v[][WIDTH], int no)
{
	int i;
	int sum = 0;
	for(i=0;i<WIDTH;i++){
		sum += v[no][i];
	}
	return(sum);
}

void fill(int v[][WIDTH])
{
	int i,	j;
	for(i = 0;i < HEIGHT;i++){
		for(j = 0;j < WIDTH;j++)
			v[i][j] = 50 - (i * 5) - j;
	}
}

void print_list(int v[][WIDTH])
{
	int i,	j;
	puts("                                累計");
	for(i = 0;i < HEIGHT;i++){
		printf("     ");
			for(j = 0;j <= WIDTH;j++){
				fill(v,WIDTH,sum_WIDTH(v,i));
				printf("%d",v[i][j]);
				}
	}
	printf("累計 ");
	for(i = 0;i < WIDTH;i++){
		printf("%5d",sum_HEIGHT(v,j));
		}
}

int main(void)
{
	int tensu[HEIGHT][WIDTH];
	


	print_list(tensu);

	return (0);
}

Re: 表の累計

Posted: 2011年6月05日(日) 21:15
by box
fill() とは、何をどうするための関数ですか?
fill() の機能を満たすために必要な引数は、何ですか?

fill() は、ループの中で実行する必要がある関数でしょうか?
fill() の機能から考えて、私なら、「1回だけ」実行するようなコードを書くと思います。

Re: 表の累計

Posted: 2011年6月05日(日) 21:45
by アレス
>boxさん
これでおかしいところはありますか?

コード:

#include <stdio.h>
#define WIDTH 5
#define HEIGHT 10

int sum_HEIGHT(int v[][WIDTH], int sub)
{
	int i;
	int sum = 0;
	for(i=0;i<HEIGHT;i++){
		sum += v[i][sub];
	}
	return(sum);
}

int sum_WIDTH(int v[][WIDTH], int no)
{
	int i;
	int sum = 0;
	for(i=0;i<WIDTH;i++){
		sum += v[no][i];
	}
	return(sum);
}

void fill(int v[][WIDTH])
{
	int i,	j;
	for(i = 0;i < HEIGHT;i++){
		for(j = 0;j < WIDTH;j++)
			v[i][j] = 50 - (i * 5) - j;
	}
}

void print_list(int v[][WIDTH])
{
	int i,	j;
	int	a=0,	b=0;
	puts("                                累計");
	fill(v);
	for(i = 0;i < HEIGHT;i++){
		printf("     ");
			for(j = 0;j < WIDTH;j++)
				printf("%5d",v[i][j]);
				a += sum_WIDTH(v,i);
			printf("%5d\n",a);
	}
	printf("累計 ");
	for(i = 0;i < WIDTH;i++){
		b += sum_HEIGHT(v,i);
		printf("%5d",b);
		}
}

int main(void)
{
	int tensu[HEIGHT][WIDTH];
	


	print_list(tensu);

	return (0);
}

Re: 表の累計

Posted: 2011年6月05日(日) 21:58
by box
アレス さんが書きました: これでおかしいところはありますか?
当初の仕様を満たしていれば、正しいプログラムである、ということになります。
当初の仕様を満たしているかどうかを最終的に確認する人は、質問者さん自身です。他人ではありません。

コードの書き方で気になった点があります。
print_list() の字下げの方法が首尾一貫していないため、何だか見づらく感じます。

Re: 表の累計

Posted: 2011年6月05日(日) 22:02
by アレス
アドバイスしてくださった皆様ありがとうございました。