ポインタについて

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

ポインタについて

#1

投稿記事 by pokka » 15年前

ポインタについて疑問に思ったことがあるので教えてください。
func1(int *a)
{
 func2(&a);
}
func2(int *a)
{
 *a++;
}

main()
{
 int x = 0;
 func1(&x);
}
こうするとエラーになります。
func2(&*a);
とするとエラーは出なくなり、きちんと動作するようになりましたが、この書き方はどうなんでしょうか?
解説サイトとかを見てもあまりこういうことは書いておらず、あまり良くない書き方をしているのかと気になってしまい、投稿しました。
よろしくおねがいします。

non

Re:ポインタについて

#2

投稿記事 by non » 15年前

まず、環境はなんでしょう?
次に、エラーはどの行で何というエラーなのでしょうか?警告ではないのですね。
きちんと動作するとありますが、何をしたいのでしょうか?

特に *a++; は何をしたかったのでしょうか?

pokka

Re:ポインタについて

#3

投稿記事 by pokka » 15年前

すみません。環境を書き忘れていました・・・
VisualC++2008で、OSはXPです。

エラー内容は
引数を 'int **' から 'int *' に変換できません
といったもので、上のソースでは3行目になります。

動作の方は、mainの中でprintfを用いてaの数字を表示させようとしたものです。省略してしまい、すみません。
*a++ ではなく、 *a = 1; として見てください。すみません。

あまち

Re:ポインタについて

#4

投稿記事 by あまち » 15年前

すみません、通りすがりです。

> 引数を 'int **' から 'int *' に変換できません
func1の引数が int * ですので
func1の関数内では引数 a の型は int * です。

func2の引数も int * 型なので
func2(&a) ではなく func2(a)とすればエラーはなくなります。
func2(&*a) だとエラーが出ない件ですが
&*a と a は同じなので結局 func2(a)を実行していることど同じです。
なのでエラーが出ないのです。
& と * の違いをよく確認してみてください。

これで疑問は解決したでしょうか?

Mist

Re:ポインタについて

#5

投稿記事 by Mist » 15年前

そのプログラムだと普通は以下のように書きますね。
func1(int *a)
{
    func2(a);   // aはxのアドレス値であるので&も*も不要
}

func2(int *a)
{
    *a = 1;

}

main()
{
    int x = 0;

    func1(&x);
}
&*aは、aの指すアドレスの変数(つまりx)のアドレスって意味なので間違ってはいませんけど、そんな面倒なことはしないでしょうね。

Tatu

Re:ポインタについて

#6

投稿記事 by Tatu » 15年前

あまちさんとMistさんが書いているとおりです。

ところで、なぜ、C言語のポインタを解説するときに

ポインタを宣言するときは
int *p;
のように変数名の前に*をつけてください。
という書き方をするのでしょうか。

ポインタを宣言するときは
int* p;
のように型の後ろに*をつけてください。
と書いたほうがよいのではないでしょうか。

こちらのほうが
void func(int* p){}
というように関数の引数にポインタを用いるときに
*がつくことが分かりやすいと思うのですが。

Mist

Re:ポインタについて

#7

投稿記事 by Mist » 15年前

> ポインタを宣言するときは
> int *p;
> のように変数名の前に*をつけてください。

それは

int* p1, p2;

と書いたとき、p1はintのポインタ変数になりますがp2はただのint型変数として宣言されてしまうからです。
だからといって

int* p1, *p2;

と書くと変な感じがしますよね。
だから*を変数名に付けて書くスタイルが主流になってしまったのです(^-^;
余談ですがD言語ではこの辺を踏まえて

int* p1, p2;

と書けばp1もp2もポインタとして宣言されます。

non

Re:ポインタについて

#8

投稿記事 by non » 15年前

こういうことだって考えられるのです。
void func1(int *a)
{
	func2(&a);
}
void func2(int **a)
{
	*a=(int *)1;
}
だから、何がしたいのかが、重要です。

>ポインタを宣言するときは
>int* p;
>のように型の後ろに*をつけてください。
>と書いたほうがよいのではないでしょうか。

そう仰る方も多いですね。
でも、初期値を入れるときは、*が後ろの方がしっくりいくかも。

Tatu

Re:ポインタについて

#9

投稿記事 by Tatu » 15年前

>Mistさん
なるほど、確かに
int* p1,p2;だと
p1はint*変数、p2はint変数になりますね。

例では変数が2つしかないので

int* p1;
int* p2;

と書けばよいだけだと思いますが、
数が多い場合、一つの変数の宣言ごとに
int*をかくのは面倒ですね。

pokka

Re:ポインタについて

#10

投稿記事 by pokka » 15年前

皆さんありがとうございました。
func2(a);にしたらエラーが出ないようになりました。

そこで、このソースを見たら疑問に思ったんですが、
main()
{
 int x = 0;
 int *px = &x
 func1(px);
}
これでも同じことになると思うんですが、プログラムかく上でどちらが好まれるんでしょうか?
わざわざポインタを宣言しないで済むので、func1(&x)とやった方がいいと思うんですが、人それぞれですか?

non

Re:ポインタについて

#11

投稿記事 by non » 15年前

これだけのためなら、わざわざポインタ変数を用意する人はいないでしょう。

pokka

Re:ポインタについて

#12

投稿記事 by pokka » 15年前

分かりました。
皆さんありがとうございました。

閉鎖

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