スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Cのダブルポインターについて何か語っているのをまとめたようだけど、もう昔のものすぎてそのまま記事に投稿しておこうと思った。


-------------------------------------------------------------------
aiya_000 : /*** Warning ***/
// デバッグ中についったーはやめましょう。 [[ 19:13]]
---------------------------------------------------------------------------------------------------------------------------------------------
aiya_000 : いた。
http://t.co/wWY4OOebDh [[ 19:46]]
-------------------------------------------------------------------
aiya_000 : こういうことか。
http://t.co/HuNRlQEiiq [[ 19:52]]
-------------------------------------------------------------------
aiya_000 : 結果。
http://t.co/eRZx09Tl0A [[ 19:52]]
-------------------------------------------------------------------
aiya_000 : ああ、ダブルポインタな。
http://t.co/nJZQzHr0Mn [[ 19:56]]
---------------------------------------------------------------------------------------------------------------------------------------------
aiya_000 : …なんで?
char* str;

void func(char* str){ str = "aaa"; }
に渡したらなぜおかしくなる?
func(str);
printf("%s\n", str); // おかしい。 [[ 19:58]]
---------------------------------------------------------------------------------------------------------------------------------------------
aiya_000 : あー、メモリ確保してないじゃん。
…それでおかしくなるの…? [[ 19:59]]
---------------------------------------------------------------------------------------------------------------------------------------------
aiya_000 : えー、確かにchar*に何かを装填したいならchar*ポインタ(char**)を渡すのが当然だけど、
なにか腑に落ちない。 [[ 20:02]]
---------------------------------------------------------------------------------------------------------------------------------------------
aiya_000 : std::stringの場合(戻り値で戻せとかは考えないで)、
void func(std::string* str){ *str = "aaa"; }
std::string str; func(&str);
が普通だけどさ…うーん? [[ 20:03]]
---------------------------------------------------------------------------------------------------------------------------------------------
aiya_000 : char* str;で
メモリ領域xにstrをsizeof(char*)分確保する。 [[ 20:04]]
---------------------------------------------------------------------------------------------------------------------------------------------
aiya_000 : func(str);

メモリ領域xを…あーっ!!! [[ 20:05]]
---------------------------------------------------------------------------------------------------------------------------------------------
aiya_000 : ないじゃん。
メモリ領域xの参照先アドレスないじゃん。
結果的にfunc関数には壊れた参照先アドレスbが渡るじゃん。
あーーーっ!!わほーーいっ!!! [[ 20:06]]
---------------------------------------------------------------------------------------------------------------------------------------------
aiya_000 : void func(char**);
だと [[ 20:07]]
---------------------------------------------------------------------------------------------------------------------------------------------
aiya_000 : char* str;でsizeof(char*)を確保、
func(&str);でアドレスxをchar**に渡す。 [[ 20:07]]
---------------------------------------------------------------------------------------------------------------------------------------------
aiya_000 : で、間接アクセス演算子にて
str(char*)に参照先アドレスを格納する。
例えば
void func(char** str){ *str = "aaa"; }
char* str; func(&str);
ならデータ層のアドレスa("aaa"の先頭アドレス)が格納される。 [[ 20:09]]
---------------------------------------------------------------------------------------------------------------------------------------------
aiya_000 : あーうっ。 [[ 20:09]]
---------------------------------------------------------------------------------------------------------------------------------------------
aiya_000 : C++って型安全だねっ!?
多分char** str;とchar* str[X];を違う型だと判断してる。 [[ 20:12]]
---------------------------------------------------------------------------------------------------------------------------------------------
aiya_000 : そして襲い来るセグメント違反!!
楽しい!!! [[ 20:13]]
---------------------------------------------------------------------------------------------------------------------------------------------
aiya_000 : やっほーいできたあっ!!!
const unsigned char*からconst char*へのキャストっ!!
さすが再解釈キャストだっ!!
http://t.co/mDyM19E89k [[ 20:52]]
---------------------------------------------------------------------------------------------------------------------------------------------
スポンサーサイト

あいやがポインタについてなんか言ってます。


いつも「*p」←をポインタって言ってるけど、 *←がポインタなのではなくて、 pがポインタ変数なんだよね。 「*」は間接アクセス演算子、ポインタ自体ではない。
返信
リツイート
お気に入りに登録
開く
ポインタスター☆あいや ‏@aiya000 11月18日


これがわかってればポインタは友達だね。
返信
リツイート
お気に入りに登録
開く
ポインタスター☆あいや ‏@aiya000 11月18日


「p」は他の場所のアドレスを格納する変数、 他の場所のアドレスを表すものに 他の場所へアクセスするためのものを付加すると 他の場所へアクセスできる。
返信
リツイート
お気に入りに登録
開く
ポインタスター☆あいや ‏@aiya000 11月18日

つまり*p1と*p2があったとして、 p1の値がアドレス0x0001、 p1の値がアドレス0x0002。 0x0002にあるデータが「10」だとすると、 *p1 = *p2 で行っていることは 0x0001 = 10。
返信
リツイート
お気に入りに登録
開く
ポインタスター☆あいや ‏@aiya000 11月18日

そして p1 = p2とすると、 p1 = 0x0002になる。
返信
リツイート
お気に入りに登録
開く
ポインタスター☆あいや ‏@aiya000 11月18日

aという変数が0x0003にあったとして、 *pに0x0003を入れたいならば、 p = &aとする。 そうすると&aが0x0003に変換されて代入される(イメージ)。
返信
リツイート
お気に入りに登録
開く
ポインタスター☆あいや ‏@aiya000 11月18日

ところがポインタ宣言と混ざると段階層がズレるから最初の頃は混乱する。 int型ポインタpを宣言しつつ代入しようとすると int *p = &a になる。
返信
リツイート
お気に入りに登録
開く
ポインタスター☆あいや ‏@aiya000 11月18日

これ、そもそも int* p = &a; と書いておけばわかるかもしれない。 int*「p = &a」; int型pにaのアドレスを代入、と。
返信
リツイート
お気に入りに登録
開く
ポインタスター☆あいや ‏@aiya000 11月18日

あとは&aつまりpの持つ場所に値を書き込みたいならば、 間接的にアドレスにアクセスするための演算子「*」を付加するだけ。 *p = 10; printf("%d\n", a); // 10
返信
リツイート
お気に入りに登録
開く
ポインタスター☆あいや ‏@aiya000 11月18日

ダブルポインタはポインタ変数のアドレスの値が持つアドレスにアクセスするための演算子、 つまりダブルポインタはpのアドレス(仮に0x0004とでも)を受け入れる箱。
返信
リツイート
お気に入りに登録
開く
ポインタスター☆あいや ‏@aiya000 11月18日

int** pp = &p; printf(**pp);
返信
リツイート
お気に入りに登録
開く
ポインタスター☆あいや ‏@aiya000 11月18日

トリプルポインタでアドレスppなら ppp = &pp;
返信
リツイート
お気に入りに登録
開く
ポインタスター☆あいや ‏@aiya000 11月18日

いえすっ!!おーけー!! 。
返信
リツイート
お気に入りに登録
開く
ポインタスター☆あいや ‏@aiya000 11月18日

関数ポインタ

関数ポインタにて色々学べることがあったので書きます。

まず普通のポインタ型と関数ポインタ型は別の扱いとなっているようです。(多分?)
具体例としては
「void *pointer」と
「void (*method)()」です。

ですので関数構造体を作るときは「関数用のポインタ」となるようです。

だから構造体メンバに関数ポインタを作るときはこう!
typedef struct{
 void (*method)();
} Method;


関数ポインタ配列はこう!
void (*method[])();


です!
初期化はこう!
Method method = { hogeMethod, fooMethod };
void (*method[])() = { hogeMethod, fooMethod };

です!

ここのサイトを参考にさせていただきました!
http://uguisu.skr.jp/Windows/c_interface.html
http://www5c.biglobe.ne.jp/~ecb/c/16_04.html

なお、
void (*method)();

は引数ありの関数も代入できるようです。


ループによる構造体メソッド実行はできてない…。
構造体ポインタ変数にすればポインタをインクリメントしてアクセスできるんじゃないかと思ったんだけどな…。

キャストして実行すればいいのか…?
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。