ポインタについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
beginner

ポインタについて

#1

投稿記事 by beginner » 13年前

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;
		}
}

	


アバター
h2so5
副管理人
記事: 2212
登録日時: 13年前
住所: 東京
連絡を取る:

Re: ポインタについて

#2

投稿記事 by h2so5 » 13年前

9行目にエラーがあると分かっているなら、
9行目を色々といじってみればいいと思います。

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

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: ポインタについて

#3

投稿記事 by softya(ソフト屋) » 13年前

とりあえず、ポインタと配列がかなり混乱しているようです。

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

と言う事で、全部の組み合わせがおかしくなっています。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

box
記事: 2002
登録日時: 13年前

Re: ポインタについて

#4

投稿記事 by box » 13年前

> change(&a[10]);

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

change() に本当に渡したいものは何でしょうか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: ポインタについて

#5

投稿記事 by softya(ソフト屋) » 13年前

関数化する前に関数なしで目的を果たせるコードを書いてもらっても良いですか?
それを元に関数化したほうが良い気がします。

[追記]
ただし、aの配列は別のポインタに渡してからソートするようにしてください。
aa ← a
でお願いします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: ポインタについて

#6

投稿記事 by ISLe » 13年前

やりたいことから考えると、change関数は
void change(int a[]);
と宣言して
change(a);
と呼び出すのが素直だと思います。

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

beginner

Re: ポインタについて

#7

投稿記事 by beginner » 13年前

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]);
}

アバター
bitter_fox
記事: 607
登録日時: 13年前
住所: 大阪府

Re: ポインタについて

#8

投稿記事 by bitter_fox » 13年前

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

beginner

Re: ポインタについて

#9

投稿記事 by beginner » 13年前

>>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]);
}


アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: ポインタについて

#10

投稿記事 by softya(ソフト屋) » 13年前

>指摘された通りにコードを書いてみたのですが以下のコードであっているでしょうか?

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

ちなみに、次のものは次の様な書き方と同義です。
aa=&a[0]; → aa=a;
a[i+1] → aa[i+1]
*aa → aa[0]
書きなおしてソースコードを眺めてみてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

box
記事: 2002
登録日時: 13年前

Re: ポインタについて

#11

投稿記事 by box » 13年前

>指摘された通りにコードを書いてみたのですが以下のコードであっているでしょうか?

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

テストとデバッグをご自分でやってみることですね。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

beginner

Re: ポインタについて

#12

投稿記事 by beginner » 13年前

>>boxさん,softya(ソフト屋)さん
ありがとうございます。無事解決しました。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: ポインタについて

#13

投稿記事 by softya(ソフト屋) » 13年前

出来ればフォーラムルールにありますとおり、解決したコードを書いていただけないでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

beginner

Re: ポインタについて

#14

投稿記事 by beginner » 13年前

解決しましたのでそのコードを載せておきます。
同じような問題で困っている人がいましたら参考にしてください。

コード:

#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];
}

アバター
bitter_fox
記事: 607
登録日時: 13年前
住所: 大阪府

Re: ポインタについて

#15

投稿記事 by bitter_fox » 13年前

コード:

    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;
        }

beginner

Re: ポインタについて

#16

投稿記事 by beginner » 13年前

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;
		}
}

閉鎖

“C言語何でも質問掲示板” へ戻る