![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67)
【C言語】別関数でポインタの値を変えたのに変わらない。
メイン関数のポインタの値を、別関数で書き換えるプログラムを作りました。
以下がそのプログラムになります。
そのままだと、ダブルポインタを操作する必要があるので分かり辛いです。なので、ダブルポインタをシングルポインタにしてからポインタの書き換えを行うようにしました。その結果、きちんとポインタの書き換えが出来なくなってしまいました。
なぜ出来なくなってしまったのでしょうか。
2つのプログラムの違いは、
> *pp = &dummy;
が
> p = *pp; // ダブルポインタをシングルポインタにした
> p = &dummy;
に変わっただけです。
【参考】http://www.kouno.jp/home/c_faq/c4.html#8
-----------------正しいプログラム----------------
// 以下プログラムは、正しく動作する
// 実行結果は、
// p = 5
// と表示される
void func( int **pp );
int main (void){
int *p;
int a = 0;
p = &a;
func( &p );
printf("p = %d\n", *p);
return 0;
}
void func( int **pp ){
static int dummy = 5;
*pp = &dummy;
}
----------------------------------------------
-----------------間違いプログラム----------------
// 以下プログラムは、正しく動作しない
// 実行結果は、
// p = 0
// と表示される
void func( int **pp );
int main (void){
int *p;
int a = 0;
p = &a;
func( &p );
printf("p = %d\n", *p);
return 0;
}
void func( int **pp ){
static int dummy = 5;
int *p;
p = *pp; // ダブルポインタをシングルポインタにした
p = &dummy;
}
----------------------------------------
A 回答 (5件)
- 最新から表示
- 回答順に表示
No.5
- 回答日時:
参照URLの回答に答えがありますよね。
call by value であることをこのFAQで示しているだけのことです。
call by value C言語の値渡し について調べてみましょう。
まぁ
>p = &dummy;
ではなく
*p = dummy ;
で、5が表示されると思うけどC FAQの本題ではないですね。
![「【C言語】別関数でポインタの値を変えたの」の回答画像5](http://oshiete.xgoo.jp/_/bucket/oshietegoo/images/media/b/359939_5497e7f935ce1/M.jpg)
No.4
- 回答日時:
> p = *pp; // ダブルポインタをシングルポインタにした
> p = &dummy;
これを「何か変だ」と気付かないのが、わからない理由でしょうね。
これではpの中身をいじっているだけで、ppには何の影響も及ぼしません。
元コード以上に簡潔に記述する手段はありませんし、そもそも「ポインタの中身」を見る/操作する場合は*(変数名)で記述するのが当然なので元コードがわかりづらいとも思えません。
No.2
- 回答日時:
int *p は
(int *)型の変数 p だと考えてみてください。
p = *pp ;
も
p = &dummy ;
も
変数pに(int *)型の値を代入しているだけです。
ローカル変数に代入しただけでは関数外に何も影響しないのはわかりますね?
「シングルポインタ」にしたというのは
void func0( int *pp ){
static int dummy = 5;
*pp = dummy;
}
ならわかっているではないかと思います。
これは、呼び出し側で int型のアドレスを渡して、関数側でアドレスから実体を求めて(*pp)それにint型の値を代入することで、呼び出し側のint型の内容を変更するものです。
これが、double型が対象なら
void func0( double *pp ){
static double dummy = 5.0;
*pp = dummy;
}
となるのもわかると思います。
「正しいプログラム」の方では、対象が(int *)型になったものなのです。
呼び出し側で (int *)型のアドレスを渡して、関数側でアドレスから実体を求めて(*pp)それに(int *)型の値を代入することで、呼び出し側の(int *)型の内容を変更するものです。
変数dummyのアドレスを渡すのが目的なので、 *PP = &dummy ;とはなりますが、それ以外のところは int → doubleの変更と同様に int → int * の変更でよいのです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
fopne で失敗する原因
-
セグメントエラー
-
nullポインタを逆参照とは?
-
エラーの意味
-
【C言語】戻り値が構造体の関数
-
ExcelVBAでのkernel32(64bit)
-
AESのC言語による実装
-
LPSTR型の初期化について
-
init関数の意味
-
cv::Mat から vectorにコピー
-
C言語でのconstを返す関数
-
DelphiでCreateProcessがうまく...
-
戻り値で構造体を返すことは可...
-
Run-Time Check Failure #3とい...
-
PASCALとFARの意味
-
アプリを32bitから64bit移行
-
関数にポインタを渡して動的確...
-
ハンドルはポインタか
-
C++とWIN32APIとゲームプログラ...
-
Pythonの関数が全然全く分かり...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
セグメントエラー
-
C言語のポインタに直接アドレス...
-
fopne で失敗する原因
-
init関数の意味
-
Run-Time Check Failure #3とい...
-
戻り値で構造体を返すことは可...
-
C言語でのconstを返す関数
-
参照型で受け取った引数をポイ...
-
LPSTR型の初期化について
-
main(int argc,char **argv[])...
-
アプリを32bitから64bit移行
-
連結リスト 要素の入れ替え
-
Cで作成したDLL関数をVBから呼...
-
構造体とfscanf
-
CImage GetBitsメソッドについて
-
c言語で任意のファイルから読み...
-
ハンドルはポインタか
-
ExcelVBAでのkernel32(64bit)
-
基本アルゴリズムの『返す』の...
-
CWnd::EnableWindow()の扱い方
おすすめ情報