[ create a new paste ] login | about

Link: http://codepad.org/ZfzFv1Cy    [ raw code | output | fork ]

C, pasted on Jun 4:
// 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;
}


Output:
function にて → 133 
親の関数 にて → 123 

-----------------------------------------------------

仮引数のアドレス → BFB46DC4 
実引数のアドレス → BFB46DF0 

-----------------------------------------------------

a の値 = 10
p の値 = BFB46DF0
p の値その2 = BFB46DF4
pのアドレスが指す先にある値 = a と同じ … 10

-----------------------------------------------------

とある構造体のサイズ(byte) = 8
とある構造体のアドレス+0 = BFB46DEC
とある構造体のアドレス+1 = BFB46DF4

-----------------------------------------------------



Create a new paste based on this one


Comments: