codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
// C(/C++)言語のポインタとアドレスの話・初心者向け --------------------------------------------------------------- // // 「引数の話」の中で、「実引数」と「仮引数」は別物という話をしたけど、この // // 「別物って、何?どういう事?」。 これがテーマ。 // void function_1(int a) // 仮引数の a { a += 10; printf("function にて → %d \n", a); } void proc_A() { int a = 123; function_1(a); // 実引数の a printf("親の関数 にて → %d \n", a); } // // ↑上の2つの「a」。これの正体を暴いてみる↓ // void function_2(int a) { // ↓コピー先 = &変数 は「その変数が置かれているメモリのアドレス」を取得する printf("仮引数のアドレス → %X \n", &a); } void proc_B() { int a = 123; function_2(a); printf("実引数のアドレス → %X \n", &a); } // // ↑表示される両者の「アドレス」。先に変数は「メモリ上のどこかに名前を付けただけ」って話をしたが、 // これ。「コピーされて渡されてるので、当然別のアドレスが表示される」 // // int a1 = 123; // int a2 = a1; // a2 += 10; // これなら当然 a1 が変わる事は無いってのと、同じ。で、このアドレス。 // // 全てはこの「アドレス」に、本当の本物の値が格納されていると(とりあえず)思っておけばおk。 // // で、ポインタ。ポインタ変数は、 void proc_C() { int a = 10; // ← メモリ上の a と名前が付けられたどこかに 「符号あり整数値を」格納している。 int *p = &a; // ← メモリ上の p と名前が付けられたどこかに 「符号なしアドレス整数値を」格納している。 printf("a の値 = %d\n", a); printf("p の値 = %X\n", p); // ↑この時、上の例で言うと、p は 「変数 a のアドレスを受け取っている」。 // // ポインタ変数は、特にこの「アドレスを受け取って」その「アドレス整数値を計算したり」 // ↓ pの持っているアドレス整数に1を足す = 1つ先のアドレスを指す p += 1; printf("p の値その2 = %X\n", p); // ↓1つ前のアドレスに戻す=元通りのアドレス整数値 p -= 1; // 「そのアドレスの内容を触ったり」出来る。 printf("pのアドレスが指す先にある値 = a と同じ … %d\n", *p); } // // で、ここで大事な事。 // >↓ pの持っているアドレス整数に1を足す = 1つ先のアドレスを指す // // Q)1つ先のアドレスって、A0000000 に対して、A0000001 でいいの? // A)違う // // int *p を p += 1 すると、「int のサイズ分移動した先のアドレス」を指す。 // // ※具体的にサイズがいくつか?については正確には sizeof(int) のようにして求めるが、 // 32bitのWindowsだと、大抵32bit = 4バイト。単純に sizeof(型) 分移動するとだけ覚えておけばおk // // という事は、当然「別の型 *p = &変数」のようにしたら、そのポインタ変数が持つアドレスの1つ先は… // 具体例↓ // void proc_D() { typedef struct { int a; int b; } DATA; DATA s = {10, 20}; DATA *p = &s; printf("とある構造体のサイズ(byte) = %X\n", sizeof(DATA)); printf("とある構造体のアドレス+0 = %X\n", p); p += 1; printf("とある構造体のアドレス+1 = %X\n", p); } // // ↑ sizeof(DATA) 分、アドレスが移動しているはず // // // この「アドレスの先にある値」という考え方が出来るようになったり、 // 「そのアドレス整数値そのもの」を扱える「ポインタ(型変数)」という存在がわかると、 // // ・「配列変数」 // ・「複数の値を返す関数」 // ・などいろいろ // // が見えてくる。とりあえずここまで // #define HR() printf("\n-----------------------------------------------------\n\n") int main() { proc_A(); HR(); proc_B(); HR(); proc_C(); HR(); proc_D(); HR(); return 0; }
Private
[
?
]
Run code
Submit