ページ 11

ソースコード問題点指摘をお願いします

Posted: 2008年10月26日(日) 00:18
by ivas
C言語を初めて間もない初心者です
0~100の範囲で入力された複数の数値の中から、
最大値と最小値を求めて表示するプログラムを作成せよ。
-1が入力された場合は入力の終わりと判定する。
ただし、最大値と最小値はmain関数以外の一つの関数の中で求める。
また、入力された数値を記憶する配列の要素数は10とし、
それ以上入力された場合はエラーが起きても仕方ないこととする。

という問題に対し、
#include <stdio.h>
int maxi(int*,int*);

int main(void){
  int o,c;
  maxi(&o,&c);
  printf("%d,%d",o,c);
  return 0;
}
void maxi(int *po,int *pc){
	int max,min,i,array[10];
	printf("type 10 number between 0 and 100\n");
	for(i=0;i<10;i++){
		scanf("%d",&array);
		if(array==-1){break; 
		}else if(i==0){
		max=array,min=array;
		}else if(array[i-1]<=array){
			max=array,min=array[i-1];
			}
		else max=array[i-1],min=array;
		;
		printf("\n");
	}
	po=&max,pc=&min;
	;
}

というコードを書いてコンパイルしたところ、どんな値を打ち込んでもでたらめな
値が最大値及び最小値として返されてしまいます。
ソースコードの問題点指摘をお願いします。
コンパイラはLSI C-86で、OSはWindows Vistaです

Re:ソースコード問題点指摘をお願いします

Posted: 2008年10月26日(日) 00:45
by box
0~100のいずれかの数字が書いてある10枚のカードから、
最大値が書いてあるカードと最小値が書いてあるカードを
手で選ぶときにどういう手順を踏むかを想像してみてください。
カードに書いてある数字を1枚ずつ見ていくとき、

> 		}else if(i==0){
> 		max=array,min=array;

先頭(0枚目)のカードに書いてある数字を
仮の最大値・仮の最小値としていますので、ここはいいですね。
さて、次のカード以降は、どうしますか?

カードに書いてある数字(array)をその時点での最大値(max)と比べて大きければ、
そのカードに書いてある数字を新たな最大値とするのではありませんか?
最小値の場合もおなじですね。
そして、すべてのカードの数字を見終わったとき、
その時点の最大値・最小値が求める答えです。

また、main関数の変数o, cに、最大値・最小値を入れたいのですよね。
変数名の意味がつかみきれませんが…。
だとすると、maxi関数のmax, minは不要で、*po, *pcと書けばよいです。

>	po=&max,pc=&min;

この行も不要です。
それから、セミコロンだけの行も不要です。どういう意味で書かれましたか?

Re:ソースコード問題点指摘をお願いします

Posted: 2008年10月26日(日) 01:39
by tk-xleader
ポインタ変数に格納されている値を読み書きするには、こうします。

*po=max;

po=&max;
とした場合、引数の格納されている変数を書き換えることになります。つまりpoに入っているアドレスを書き換えてしまうのです。
C言語では引数は値で渡されているので、poそのものを書き換えても呼び出した関数(main()関数)には影響しません。ですから、main関数の中の o や c は変化しません。

変数名の意味は、「大きい(oki)」と「小さい(chisai)」という事ですよね? 読みやすさのところからも、ローマ字でもいいので、もうちょっと長めの名前を付けたほうがいいと思います。

Re:ソースコード問題点指摘をお願いします

Posted: 2008年10月26日(日) 15:16
by ivas
boxさん、tkmakwins15さん助言ありがとうございます。
指摘に基づきソースコードを修正したところ、良い結果が得られました。
どうも自分はまだポインタについて正しく理解をできていないように思います。
ただ精進あるのみです。