• ベストアンサー

ポインタのポインタが引数にある関数の使い方。

ポインタのポインタが引数にある関数の使い方。 現在、このポインタのポインタが引数にある関数の動きがわからず困っています。 int test(int ** head) { int * pTail = (int *)*head; pTail = pTail + 1; } もし、この関数を呼び出して使用した場合どのような動きをするのでしょうか? int * comm_msg; これをグローバルポインタ変数として宣言させて、 test((void **)&comm_msg); このように呼び出したとした場合とさせていただきます。

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

  • ベストアンサー
回答No.1

ローカル変数pTailをincrementしているだけで、それ以外は何もしないんじゃないですか? 以下の関数ならcomm_msgをincrementします。 int *comm_msg; test(&comm_msg); int test(int ** head) { *head = *head + 1; }

techhouse
質問者

お礼

回答頂きありがとうございます。 今ちょっと動作がわからない関数プログラムというのがありまして、 int count_list(void ** head) { int cnt = 0; list_t * pTail = (list_t *)*head; if(*head != NULL) { while (1) { cnt++; if(pTail->next == NULL) break; pTail = pTail->next; } } return cnt; } linked listっていうプログラムらしいのですが、 このプログラムを comm_msg_t * comm_msg;  このポインター変数をグローバル宣言して、 int comm_msg_count() { return count_list((void **)&comm_msg); } この関数で呼び出すというプログラムがあるのですが、動作がいまいちわからないのです。 特になんですが、グローバルポインタ変数の”comm_msg”というのを count_list((void **)&comm_msg); この引数で呼び出すと、 count_list関数内で、 list_t * pTail = (list_t *)*head; このプログラムでpTailに”comm_msg”のアドレス番地をポイントするデータがメモリアドレスにポイントされると思うので、 ”pTail = pTail->next;”このプログラムで、グローバル変数内が書き換わってしまうと思うのですが、 プログラム動作としてはグローバル変数は書き換えないと聞いたのですが、本当にそのような動作なのでしょうか?

その他の回答 (2)

回答No.3

#2です。 pTailそのものはローカル変数であって、あくまでその値がglobal変数の内容を指しているだけです。 したがって、pTailを書き換えてもcomm_msgの内容は変わりません。 comm_msg_t型のデータがアドレス、ADR_AAA にあるとします。 comm_msgのアドレスを ADR_MSG とすると、 ADR_MSGのメモリ番地にADR_AAAというアドレス値が入っています。 count_list()を呼び出した時点で headには ADR_MSGというアドレス値が入っています。 pTaliは初期値でポインタ変数headの指す先の値が入るので、ADR_AAAが入ります。 この時、pTailはスタック上に作られたローカル変数なので、ADR_MSGとは違う場所のADR_PTAILとかいうアドレスに存在します。 ここでcmm_msg_t型の構造体の要素nextはcmm_msg_t型へのポインタになっていると思われますが、 ADR_AAAに存在する構造体のnextの値をADR_NEXTとすると  pTail = pTail->next; で書き換わるのはpTailだけです。 つまり  ADR_MSGの内容:ADR_AAAのまま  ADR_PTAILの内容:ADR_AAA -> ADR_NEXT となります。 あくまでローカル変数の値を書き換えてるだけで、ポインタの指す先を書き換えたりしてるわけじゃありません。

回答No.2

とりあえず関数の定義と呼び出しの型が違うので、エラーかワーニングが出ます。 int型のポインタ comm_msg が指すアドレスを ADR_AAA とします。 この comm_msg のアドレスをint型のポインタへのポインタとして関数に渡されています。 初期状態では head はポインタ変数 comm_msg のアドレスを指しています。  head -> &comm_msg 次にint型のポインタ変数 pTail に head の差すポインタの中身が渡されているわけですから、 pTali には comm_msg が指していたアドレス ADR_AAA が入ります。  pTail -> comm_msg (== ADR_AAA) 次にこのint型ポインタ変数をインクリメントしているので、 pTail の値は int型のデータ1つ分のサイズだけアドレスが加算されます。  pTail -> ADR_AAA + sizeof(int)

techhouse
質問者

お礼

回答頂きありがとうございます。 今ちょっと動作がわからない関数プログラムというのがありまして、 int count_list(void ** head) { int cnt = 0; list_t * pTail = (list_t *)*head; if(*head != NULL) { while (1) { cnt++; if(pTail->next == NULL) break; pTail = pTail->next; } } return cnt; } linked listっていうプログラムらしいのですが、 このプログラムを comm_msg_t * comm_msg;  このポインター変数をグローバル宣言して、 int comm_msg_count() { return count_list((void **)&comm_msg); } この関数で呼び出すというプログラムがあるのですが、動作がいまいちわからないのです。 特になんですが、グローバルポインタ変数の”comm_msg”というのを count_list((void **)&comm_msg); この引数で呼び出すと、 count_list関数内で、 list_t * pTail = (list_t *)*head; このプログラムでpTailに”comm_msg”のアドレス番地をポイントするデータがメモリアドレスにポイントされると思うので、 ”pTail = pTail->next;”このプログラムで、グローバル変数内が書き換わってしまうと思うのですが、 プログラム動作としてはグローバル変数は書き換えないと聞いたのですが、本当にそのような動作なのでしょうか?

関連するQ&A