• ベストアンサー

教えてポインタ

例えば、以下のようなソース。 関数の中で、引数のポインタに値を入れてmainに戻す。 とても簡単なものです。 void func(int *N) {  *N=0; } main {  int  *N=1;  func(N);  printf("%d",*N) } 疑問は、ここからです。 (1)void func(int  *N) (2)void func(int*  N) (3)void func(int*  &N) 上記は、何が違いますか? なお、当方のVS2010で同じソースを作ると、 (1)の場合、エラーになります。(func関数の*N=0のところでダウン) (2)だと、OKになります。 (3)は、なに?

質問者が選んだベストアンサー

  • ベストアンサー
  • wormhole
  • ベストアンサー率28% (1626/5665)
回答No.5

>funk(FILE* &fp)とfunk(FILE **fp)における概念に微妙な違いが >あるような気がしますが?詳細は分かりません・・ 前者はCにはないC++の参照渡し(call by reference)です。

NEW2010
質問者

お礼

ありがとうございます。 解決しました。

その他の回答 (4)

noname#210530
noname#210530
回答No.4

各アドレスを表示して、何がどうなっているか確認してはどうでしょうか。 func(FILE **fp)と定義し、mainではFILE *mainfpと定義し、func(&mainfp)で渡した場合、 mainでprintf("&mainfpは%p\n", (void*)&mainfp); と funcでprintf("fpは%p\n", (void*)fp); は等しくなります。 func(FILE* &fp)と定義し、mainではFILE *mainfpと定義し、func(mainfp)渡した場合、 mainでprintf("&mainfpは%p mainfpは%p\n", (void*)&mainfp, (void*)mainfp); funcでprintf("&fpは%p fpは%p\n", (void*)&fp, (void*)fp); とか試してみてください。 &mainfp と &fp が等しければ、func(mainfp)で自動的に mainfpのアドレスを渡す処理をこのコンパイラではやっている事になりそうです。 色々試して推測するしかないと思います。 どうであれfunc(FILE* &fp)のような使い方は一般的ではないので、避けたほうがいいです。

NEW2010
質問者

お礼

ありがとうございます。 すいません、回答いただいて申し訳ないのですが、 No5さんで解決に至りました。 アドレスの確認をする手法で解決の一助となるアドバイスについて、 お礼申し上げます。

  • Wap58
  • ベストアンサー率33% (29/87)
回答No.3

No.2です。自分なりに解釈してみました void funk(FILE **fp)とプロト宣言し mainでFILE *mainfpを定義して 1)funk関数に引数、&mainpを渡す 2)funk関数に引数、mainpを渡す 1)はプロトタイプどうりに受けないと 多くの方の環境下ではエラーになります 2)も素直にfunk(FILE *fp)で受ける 汎用性を考えると素直に書いた方がいい ところでvoid funk(FILE* &fp)と プロト宣言してエラーになりませんか?

NEW2010
質問者

お礼

早速の回答ありがとうございます。 最後のご質問ですが、 void funk(FILE* &fp)とプロト宣言してエラーにならないのです。 funk内でファイル書き込みもできます。 VS2010を使っています。コンパイラの性質でしょうか? funk(FILE* &fp)とfunk(FILE **fp)における概念に微妙な違いが あるような気がしますが?詳細は分かりません・・

  • Wap58
  • ベストアンサー率33% (29/87)
回答No.2

  char *name = "file.txt";   なんて、はしょたソースも良く見かけます   わかりズラいけど文字リテラル自体が配列で   *演算子に対して&演算子をはしょれます     ご存知でしょうが*と&じゃ意味が全く変わります   &はポインタ演算子(住所はここです)   *はポインタの彼参照演算子(住所はどこ?)     (1)(2)はコンパイラーで結果が変わります   (3)は頭から尻尾を食うので引数になりません     私のコンパイラーはint *N=1;の時点でダメ   No.1の方も書かれてるように   誰が見てもわかり易いソースがいいと思います  

NEW2010
質問者

お礼

ご回答ありがとうございます。 コンパイルの件は理解致しました。 (3)「int* &N」の質問の意味を以下に記します。 FILEポインタを引数として関数に渡す場合、 ダブルポインタにする必要があります。 func(FILE **fp)と定義し、 mainではFILE *mainfpと定義し、func(&mainfp)で渡す。 これが(3)のように、 func(FILE* &fp)と定義しておくと、mainではfunc(mainfp)で 渡せるのです。 これが何故なのかよくわかりません。 なお、最初の質問における内容に誤りがあり、まことに失礼しました。

  • tsunji
  • ベストアンサー率20% (196/958)
回答No.1

void func(int *N) {  *N=0; } void main() {  int N=1;  func(&N);  printf("%d",N); } ポインタの使い方が間違っています。 コードを書き直すと上記の様になります。 ポインタは配列の場所を指すものですから、 まずNを通常の変数として宣言し、渡すときに ポインタとして渡します。 func関数はそのままでOK。

NEW2010
質問者

お礼

ご回答ありがとうございます。 ポインタの使い方について、失礼しました。