ページ 11

ポインタについて

Posted: 2011年1月16日(日) 17:34
by beginner
10個の整数を入力してその中で一番大きい数字をa[9]に移動させる関数をつくっているのですが9行目に以下のようなエラーが出てしまいます。
warning C4047: '関数' : 間接参照のレベルが 'int **' と 'int *' で異なっています。
warning C4024: 'change' : の型が 1 の仮引数および実引数と異なります。
エラーの解決方法を教えてください。

コード:

#include<stdio.h>
void change(int *[]);
int main(void) {
	int i,a[10];
	printf("10個の整数を入力してください\n");
	for(i=0;i<10;++i) {
	scanf("%d",&a[i]);
	}
	change(&a[10]);
	printf("%d\n",a[9]);
	return 0;
}
void change(int *a[10]) {
	int j,b=0;
	for(j=0;j<9;++j)
		if(*a[j+1]<*a[j]) {
			b=*a[j+1];
			*a[j+1]=*a[j];
			*a[j]=b;
		}
}

	


Re: ポインタについて

Posted: 2011年1月16日(日) 17:37
by h2so5
9行目にエラーがあると分かっているなら、
9行目を色々といじってみればいいと思います。

例えば&を外すとか...

Re: ポインタについて

Posted: 2011年1月16日(日) 17:52
by softya(ソフト屋)
とりあえず、ポインタと配列がかなり混乱しているようです。

int a[10]; aはint型の10個の要素の配列です。添字は0~9です。
&a[10] 配列aの添字10番目の要素のint型ポインタです。
int *a[10] aはint*型の10個の要素の配列です。

と言う事で、全部の組み合わせがおかしくなっています。

Re: ポインタについて

Posted: 2011年1月16日(日) 17:55
by box
> change(&a[10]);

a[10] という、配列の定義範囲外の領域のアドレスを
わざわざ渡しているのはなぜでしょうか?

change() に本当に渡したいものは何でしょうか?

Re: ポインタについて

Posted: 2011年1月16日(日) 17:57
by softya(ソフト屋)
関数化する前に関数なしで目的を果たせるコードを書いてもらっても良いですか?
それを元に関数化したほうが良い気がします。

[追記]
ただし、aの配列は別のポインタに渡してからソートするようにしてください。
aa ← a
でお願いします。

Re: ポインタについて

Posted: 2011年1月16日(日) 18:06
by ISLe
やりたいことから考えると、change関数は
void change(int a[]);
と宣言して
change(a);
と呼び出すのが素直だと思います。

int[10]型以外はコンパイルエラーにしたいのでしょうか?

Re: ポインタについて

Posted: 2011年1月17日(月) 01:02
by beginner
ISLeさん,softya(ソフト屋)さん,boxさん,h2so5さんコメントありがとうございます。
>>softya(ソフト屋)さん
関数を用いずにコードをつくったのですが、うまくいきません。
具体的にどこが間違っているか教えてください。

コード:

#include<stdio.h>
int main(void) {
	int a[10],*aa,b=0,i;
	printf("10個の整数を入力してください\n");
	for(i=0;i<10;++i) {
	scanf("%d",&a[i]);
	aa=&a[i];
	if(&a[i+1]<aa) { 
		b=a[i+1];
		a[i+1]=*aa;
		*aa=b;
	}
	}
	printf("一番大きな数は%d\n",a[9]);
}

Re: ポインタについて

Posted: 2011年1月17日(月) 01:38
by bitter_fox
beginner さんが書きました: >>softya(ソフト屋)さん
関数を用いずにコードをつくったのですが、うまくいきません。
具体的にどこが間違っているか教えてください。

コード:

	aa=&a[i];
	if(&a[i+1]<aa) { 
		b=a[i+1];
		a[i+1]=*aa;
		*aa=b;
	}
softyaさんではないですが・・・

1.&を付けるとアドレスになります。
ですので、if(&a[i+1] < aa)は常に偽。
比較対象は、アドレスではなく値ではないでしょうか?

2.a[i+1]はiが9の時、i+1が10になり配列外を参照することになる。

PS:多分softyaさんがおっしゃってるのは、一項目ごとにアドレスをコピーするのではなく、「先頭のアドレスをコピーしてそれをもとに最大値を探索してみてください」という意味では無いでしょうか・・・?

Re: ポインタについて

Posted: 2011年1月17日(月) 02:36
by beginner
>>bitter_foxさん
ご指摘ありがとうございます。
指摘された通りにコードを書いてみたのですが以下のコードであっているでしょうか?
もし間違いを発見されましたらもう一度どこが間違っているか教えてください。

コード:

#include<stdio.h>
int main(void) {
	int a[10],*aa,b=0,i;
	printf("10個の整数を入力してください\n");
	for(i=0;i<10;++i) {
	scanf("%d",&a[i]);
	}
	aa=&a[0];
	for(i=0;i<9;++i) {
	if(a[i+1]<*aa) 
		a[i+1]=*aa;
	}
	printf("一番大きな数は%d\n",a[9]);
}


Re: ポインタについて

Posted: 2011年1月17日(月) 09:56
by softya(ソフト屋)
>指摘された通りにコードを書いてみたのですが以下のコードであっているでしょうか?

自分で試されてテストは合格でしたか?
元のソースコードと入れ替え法を変更した理由はなんでしょうか?

ちなみに、次のものは次の様な書き方と同義です。
aa=&a[0]; → aa=a;
a[i+1] → aa[i+1]
*aa → aa[0]
書きなおしてソースコードを眺めてみてください。

Re: ポインタについて

Posted: 2011年1月17日(月) 22:32
by box
>指摘された通りにコードを書いてみたのですが以下のコードであっているでしょうか?

合っているかどうかを確認するのが「テスト」という工程です。
テストで間違いが見つかったら、「デバッグ」という工程でプログラムの間違いを正します。
そして、またテストします。

テストとデバッグをご自分でやってみることですね。

Re: ポインタについて

Posted: 2011年1月18日(火) 19:38
by beginner
>>boxさん,softya(ソフト屋)さん
ありがとうございます。無事解決しました。

Re: ポインタについて

Posted: 2011年1月18日(火) 20:07
by softya(ソフト屋)
出来ればフォーラムルールにありますとおり、解決したコードを書いていただけないでしょうか?

Re: ポインタについて

Posted: 2011年1月19日(水) 16:48
by beginner
解決しましたのでそのコードを載せておきます。
同じような問題で困っている人がいましたら参考にしてください。

コード:

#include<stdio.h>
void change(int []);
int main(void) {
	int i,a[10];
	printf("10個の整数を入力してください\n");
	for(i=0;i<10;++i) {
	scanf("%d",&a[i]);
	}
	change(a);
	printf("一番大きい数字は%d\n",a[9]);
	return 0;
}
void change(int *a) {
	int j;
	for(j=0;j<9;++j)
		if(a[j+1]<a[j])
			a[j+1]=a[j];
}

Re: ポインタについて

Posted: 2011年1月19日(水) 17:06
by bitter_fox

コード:

    int j;
    for(j=0;j<9;++j)
        if(a[j+1]<a[j])
            a[j+1]=a[j];
これだと、データを駄々壊しにして最大値を後方へずらすのでよろしくありません、
softya(ソフト屋) さんが書きました: 元のソースコードと入れ替え法を変更した理由はなんでしょうか?
softyaさんがこう聞いたのも、データを壊してしまっているためです。

ですので、ちゃんと「入れ替える」ように戻しましょう。

コード:

    int j, buf;
    for(j=0;j<9;++j)
        if(a[j+1]<a[j])
        {
            buf = a[j+1];
            a[j+1]=a[j];
            a[j] = buf;
        }

Re: ポインタについて

Posted: 2011年1月19日(水) 17:45
by beginner
bitter_foxさんご指摘ありがとうございます。
修正したコードを載せておきます。

コード:

#include<stdio.h>
void change(int []);
int main(void) {
	int i,a[10];
	printf("10個の整数を入力してください\n");
	for(i=0;i<10;++i) {
	scanf("%d",&a[i]);
	}
	change(a);
	printf("一番大きい数字は%d\n",a[9]);
	return 0;
}
void change(int *a) {
	int j,b;
	for(j=0;j<9;++j)
		if(a[j+1]<a[j]) {
			b=a[j+1];
			a[j+1]=a[j];
			a[j]=b;
		}
}