ポインタの憂鬱

目次

はじめに

現在、私は、C言語で実用的なプログラムを書いているところです。はじめに学んだ言語がJavaなのでポインタでハテ?と思ってしまうところがあります。正確にはハテ?というよりも"なんじゃこりゃ?"という部分がたまにあります。特にポインタ関連です。ある程度積み重ねていけば経験となり、問題ない部分なのですが、初心者用のC言語の書籍などに頼っているとどうしてもポインタを読む事にt止まってしまいます。なのでちょっと引っかかった部分を書き留めました。同じ疑問をもった初心者の方がここで解決できれば幸いと思います。

動作環境

私が、実際に動かしている環境です。C言語の基礎部分なのでどんなコンパイラでも問題なく動くでしょう。

お題

(void **)(&pApp->m_pMenu)を理解する。
	if (function(arg1, arg2, (void **)(&pApp->m_pMenu), arg4) != 0) 
実際には上記のようなソースだったのですが、C言語入門書レベルとはさすがに違います。噛み砕いて理解してしまえば、あ!っそういうこと...と納得できますがポインタの難しさを感じます。

理解するためにやった事

とりあえず、すくないC言語の知識を活用して解析しました。

1.関数は、引数の型として void **(ボイドのポインタのポインタ)を要求しているな。 また、演算の順序があるので括弧で括っているのだろう。

(void **)

2.(&pApp->m_pMenu)とは、構造体のアドレスのm_pMenuメンバ?構造体のポインタでそのメンバのm_pMenuのアドレス?なんじゃこりゃ?

調べてみるとアロー演算子(->)の方が結合度が高いそうですので、
pApp->m_pMenuを先に読んで"pApp構造体ポインタのm_pMenuメンバポインタ"
最後に&はアドレス参照を意味するので"XXのアドレス"を加えると &pApp->m_pMenuは

"pApp構造体ポインタのm_pMenuメンバポインタのアドレス"

と読めると思います
でも下記の文は正しいのでしょうか?ポインタのポインタ=(void **)は 正しい気がしますが"XXのアドレス"がついているので私の解釈は間違っていそうです。

"pApp構造体ポインタのm_pMenuメンバポインタのアドレス" = (void **)

実際にソースを書いていろいろ確認してみたいと思います。


#include 

typedef struct _hoge {
        char *name;
} HOGE;

int main(int argc, char * argv[]) {
        HOGE a;
        HOGE *pa;
        pa = &a;
        printf("%p\n", &pa);
        printf("%p\n", pa);
        printf("%p\n", &pa->name);
        printf("%p\n", pa->name);
        return 0;
}

結論

ポインタは難しい!