• 締切済み

ポインタ参照すると変数が正しく見れない

なぜdata = &array;がNGなのかがわかりません。 NGの場合、read関数コール前後でdataのアドレスは変更されないようです。 #include <stdio.h> int array = 100; void read( int* data ){   data = &array; // NG   *data = array; // OK } int main(){   int data;   read( &data );   printf(" d : %d\n",data);   return 0; } * 再現環境を簡易化したためこのプログラム自体の有効性はありません

みんなの回答

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.5

#4さんがアドレスの遷移をすごく丁寧に説明していますね。 >data1そのものをdata2が指しているとばかり思っていました。 C言語的には、data2はdata1そのものを指していると言えます。 #指しているからdata1の値を変える事ができる訳ですから 問題はここでの、引数に指定された「&data1」というものと read関数の引数「data2」というものは、『同じ値を持った別のモノ』 という認識が必要です。

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.4

まず、 (1)void read( int* data ) のdataと (2)int data; のdataはメモリアドレスの違う別の変数という点は理解していますか? 仮にアドレスを割り当てて説明してみますね。 書き方は、 アドレス 名前<中身の値> とします。 まずint data;で、 0x0100 data<値は不定> 初期化していないので値は不定です。 次にread( &data );で関数を呼び出しvoid read( int* data )にパラメータを受け渡しています。 0x0104 data<0x0100> ←mainのdataのアドレスが格納されています。 ってことでこのdataは別のアドレスを持つ別の変数です。 data = &array; // NG は、どうなるかというとarrayは 0x0200 array<100> ← 値は100で初期化されています。 で&arrayはアドレスのことなので、0x0200ですね。 それをパラメータのdataに代入しているので 0x0104 data<0x0200> となります。 *data = array; // OK この*dataはアドレス0x0200を変数とみなして代入しますので、 0x0200 array<100> にarrayの値100を代入する。つまり変化無しです。 でprintfされる値は不定です。 もしNGとOKのソース順番が逆だった場合には、 *dataはアドレス0x0100ですので、これを変数とみなして代入します。 0x0100 data<値は不定> にarrayの値100を代入します。 ってことで 0x0100 data<100> となりますので、printfされるのは100です。 あと#1の方の *data = 0; は不定アドレスに代入しているので間違いです。 data = 0; が狙っていた書き方だと思います。

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.3

#include <stdio.h> int array = 100; void read( int* data2 ) {   //ここでのdeta2はmainのdata1のアドレスの『コピー』   //コピーしたアドレスの中身に対して   //値を格納するのでdata1の中身が変わる   *data2 = array; // OK   //コピーしたアドレス自身を塗りつぶすので無意味   data2 = &array; // NG   //この関数を抜けるとdata2は破棄される } int main( int argc, char*argv[] ) {   int data1;   //data1のアドレスを渡す   read( &data1 );   printf(" d : %d\n",data1);   return 0; } C言語では値そのものを渡した場合を値渡し、 ポインタを渡した場合を参照渡しなどと呼びます。 Cでは厳密にはポインタを値渡ししています。 ちなみにNo1さんのコードでは、mainのdataポインタが 不定値なのでいきなりわけの分からない場所に0を書こうとして アクセス違反が起こりますのであしからず。

cafe2cafe
質問者

お礼

”ここでのdeta2はmainのdata1のアドレスの『コピー』” という所をきちんと理解していませんでした。 data1そのものをdata2が指しているとばかり思っていました。 ありがとうございました。

  • a-saitoh
  • ベストアンサー率30% (524/1722)
回答No.2

引数というのは実質的には、呼び側で渡された値で初期化されたローカル変数に過ぎません。 dataを書き換えても、とくにNGなことは何もありません。が、ローカル変数dataの値が変わるだけです。 一体何をもっと「NG」と言ってるのでしょうか。 ちゃんとコンパイルは出来て保護例外エラーにもならずに実行出来ると思いますが。

回答No.1

===========多言語経験者ですがC/C++は初心者同然の者です======= #include <stdio.h> int array = 100; void read( int** data ){ /* 多言語で言う「値渡し」された引数はオリジナルのものが別の領域にコピーされている */ *data = &array; } int main(){ int* data; *data = 0; read( &data ); printf(" d : %d\n",*data); return 0; }

cafe2cafe
質問者

お礼

やりたい事はまさに書いていただいた記述内容です (arrayをポインタ参照したい)。 実際には、変数arrayはとても巨大な配列になっており、 memcpyや配列要素一つ一つの代入を使わずに参照したいと思っていました。 *dataを初期化して使用すると問題なく実行できる事を確認しました。 ありがとうございました。

関連するQ&A

専門家に質問してみよう