アルゴリズムとデータ構造 補足資料5-1 「メモリとポインタ」 横浜国立大学 理工学部 数物・電子情報系学科 富井尚志
(ASCIIコードなら’A’、10進数なら65) アドレス(32bit) 中身(1記憶単位は8bit) … 0x 40ea 0800 1101 0000 0x 40ea 0801 0000 0111 0x 40ea 0802 0100 1011 0x 40ea 0803 1011 1111 0x 40ea 0804 0100 1100 0x 40ea 0805 1000 1110 0x 40ea 0806 1010 0100 0x 40ea 0807 0x 40ea 0808 0100 0001 0x 40ea 0809 1011 0111 0x 40ea 080a 0x 40ea 080b 0x 40ea 080c 0x 40ea 080d 0110 1111 0x 40ea 080e 1010 0111 0x 40ea 080f 0101 0000 0x 40ea 0810 計算機の記憶(メモリ)の構造: すべての記憶領域には、記憶単位ごとに 連続する番号(アドレス)が付されている 記憶単位の中身には、値が書き込まれている CPUは、任意のアドレスを指定することで そのアドレスの記憶領域の中身を 読み出す/書き込む ことができる (Random Access Memory : RAM) たとえば、 アドレス0x40ea080a番地の中身は、 01000001 (ASCIIコードなら’A’、10進数なら65) (システムによって異なるがここでは) アドレスは32bit (左図では16進表記) 記憶単位は8bit (単位は[Byte]) アドレスは0x00000000~0xffffffff なので、232=4GByte の空間が限界
printf(“a:%x = %d\n”, &a, a); return 0; } アドレス(32bit) 中身(1記憶単位は8bit) … 0x 40ea 0800 1101 0000 0x 40ea 0801 0000 0111 0x 40ea 0802 0100 1011 0x 40ea 0803 1011 1111 0x 40ea 0804 0000 0000 0x 40ea 0805 0x 40ea 0806 0x 40ea 0807 0001 0100 0x 40ea 0808 0100 0001 0x 40ea 0809 1011 0111 0x 40ea 080a 0x 40ea 080b 0x 40ea 080c 0100 1100 0x 40ea 080d 0110 1111 0x 40ea 080e 1010 0111 0x 40ea 080f 0101 0000 0x 40ea 0810 int main(void) { int a; a = 20; printf(“a:%x = %d\n”, &a, a); return 0; } &a a 実行すると、以下の結果が出た。 a: 40ea0804 = 20 この場合のaは? →int型(32bitの箱)の変数aは、 中身が20 (2進数では10100) 00000000 00000000 00000000 00010100 a int 型(32bit) aは、物理的にどこに存在する? → 記憶(メモリ)の中 (OSに割り当ててもらう; 毎回変わる) aは、具体的にどこ? → 今回は0x 40ea 0804番地からの4バイト分 → &a == 0x 40ea 0804 (aのアドレス)
printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; アドレス(32bit) 中身(1記憶単位は8bit) … 0x 40ea 0800 1101 0000 0x 40ea 0801 0000 0111 0x 40ea 0802 0100 1011 0x 40ea 0803 1011 1111 0x 40ea 0804 0000 0000 0x 40ea 0805 0x 40ea 0806 0x 40ea 0807 0001 0100 0x 40ea 0808 0100 0001 0x 40ea 0809 1011 0111 0x 40ea 080a 0x 40ea 080b 0x 40ea 080c 0100 1100 0x 40ea 080d 0110 1111 0x 40ea 080e 1010 0111 0x 40ea 080f 0101 0000 0x 40ea 0810 int main(void) { int a; int *ap; ap = &a; a = 20; printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; printf(“ap:%x=%d\n”, ap, *ap); return 0; } &a a
printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; アドレス(32bit) 中身(1記憶単位は8bit) … 0x 40ea 0800 1101 0000 0x 40ea 0801 0000 0111 0x 40ea 0802 0100 1011 0x 40ea 0803 1011 1111 0x 40ea 0804 0000 0000 0x 40ea 0805 0x 40ea 0806 0x 40ea 0807 0001 0100 0x 40ea 0808 0100 0001 0x 40ea 0809 1011 0111 0x 40ea 080a 0x 40ea 080b 0x 40ea 080c 0100 0000 0x 40ea 080d 1110 1010 0x 40ea 080e 0000 1000 0x 40ea 080f 0000 0100 0x 40ea 0810 int main(void) { int a; int *ap; ap = &a; a = 20; printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; printf(“ap:%x=%d\n”, ap, *ap); return 0; } &a a 代入 0x 40ea 0804 ap ポインタ型(32bit) アドレスを「値」として保持
printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; アドレス(32bit) 中身(1記憶単位は8bit) … 0x 40ea 0800 1101 0000 0x 40ea 0801 0000 0111 0x 40ea 0802 0100 1011 0x 40ea 0803 1011 1111 0x 40ea 0804 0000 0000 0x 40ea 0805 0x 40ea 0806 0x 40ea 0807 0001 0100 0x 40ea 0808 0100 0001 0x 40ea 0809 1011 0111 0x 40ea 080a 0x 40ea 080b 0x 40ea 080c 0100 0000 0x 40ea 080d 1110 1010 0x 40ea 080e 0000 1000 0x 40ea 080f 0000 0100 0x 40ea 0810 int main(void) { int a; int *ap; ap = &a; a = 20; printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; printf(“ap:%x=%d\n”, ap, *ap); return 0; } &a a a: 0x40ea0804=20 と表示
printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; アドレス(32bit) 中身(1記憶単位は8bit) … 0x 40ea 0800 1101 0000 0x 40ea 0801 0000 0111 0x 40ea 0802 0100 1011 0x 40ea 0803 1011 1111 0x 40ea 0804 0000 0000 0x 40ea 0805 0x 40ea 0806 0x 40ea 0807 0001 0100 0x 40ea 0808 0100 0001 0x 40ea 0809 1011 0111 0x 40ea 080a 0x 40ea 080b 0x 40ea 080c 0100 0000 0x 40ea 080d 1110 1010 0x 40ea 080e 0000 1000 0x 40ea 080f 0000 0100 0x 40ea 0810 int main(void) { int a; int *ap; ap = &a; a = 20; printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; printf(“ap:%x=%d\n”, ap, *ap); return 0; } &a a &a: 変数aがメモリのどこにあるかを示す a: 0x40ea0804=20 変数aに格納されている値
printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; アドレス(32bit) 中身(1記憶単位は8bit) … 0x 40ea 0800 1101 0000 0x 40ea 0801 0000 0111 0x 40ea 0802 0100 1011 0x 40ea 0803 1011 1111 0x 40ea 0804 0000 0000 0x 40ea 0805 0x 40ea 0806 0x 40ea 0807 0001 0100 0x 40ea 0808 0100 0001 0x 40ea 0809 1011 0111 0x 40ea 080a 0x 40ea 080b 0x 40ea 080c 0100 0000 0x 40ea 080d 1110 1010 0x 40ea 080e 0000 1000 0x 40ea 080f 0000 0100 0x 40ea 0810 int main(void) { int a; int *ap; ap = &a; a = 20; printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; printf(“ap:%x=%d\n”, ap, *ap); return 0; } &a a 0x 40ea 0804 ap ポインタ型(32bit) アドレスを「値」として保持
printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; アドレス(32bit) 中身(1記憶単位は8bit) … 0x 40ea 0800 1101 0000 0x 40ea 0801 0000 0111 0x 40ea 0802 0100 1011 0x 40ea 0803 1011 1111 0x 40ea 0804 0000 0000 0x 40ea 0805 0x 40ea 0806 0x 40ea 0807 0001 0100 0x 40ea 0808 0100 0001 0x 40ea 0809 1011 0111 0x 40ea 080a 0x 40ea 080b 0x 40ea 080c 0100 0000 0x 40ea 080d 1110 1010 0x 40ea 080e 0000 1000 0x 40ea 080f 0000 0100 0x 40ea 0810 int main(void) { int a; int *ap; ap = &a; a = 20; printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; printf(“ap:%x=%d\n”, ap, *ap); return 0; } 0x 40ea 0804 ap ポインタ型(32bit) 参照先はint型
printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; アドレス(32bit) 中身(1記憶単位は8bit) … 0x 40ea 0800 1101 0000 0x 40ea 0801 0000 0111 0x 40ea 0802 0100 1011 0x 40ea 0803 1011 1111 0x 40ea 0804 0000 0000 0x 40ea 0805 0x 40ea 0806 0x 40ea 0807 0001 0100 0x 40ea 0808 0100 0001 0x 40ea 0809 1011 0111 0x 40ea 080a 0x 40ea 080b 0x 40ea 080c 0100 0000 0x 40ea 080d 1110 1010 0x 40ea 080e 0000 1000 0x 40ea 080f 0000 0100 0x 40ea 0810 int main(void) { int a; int *ap; ap = &a; a = 20; printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; printf(“ap:%x=%d\n”, ap, *ap); return 0; } *ap 参照先の大きさ(型)は 宣言で指定したとおり。 すなわち、 int *ap; より、*apはint型 *:参照 そのアドレスの 内容を見る 0x 40ea 0804 ap ポインタ型(32bit) 参照先はint型
printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; アドレス(32bit) 中身(1記憶単位は8bit) … 0x 40ea 0800 1101 0000 0x 40ea 0801 0000 0111 0x 40ea 0802 0100 1011 0x 40ea 0803 1011 1111 0x 40ea 0804 0000 0000 0x 40ea 0805 0x 40ea 0806 0x 40ea 0807 0001 0101 0x 40ea 0808 0100 0001 0x 40ea 0809 1011 0111 0x 40ea 080a 0x 40ea 080b 0x 40ea 080c 0100 0000 0x 40ea 080d 1110 1010 0x 40ea 080e 0000 1000 0x 40ea 080f 0000 0100 0x 40ea 0810 int main(void) { int a; int *ap; ap = &a; a = 20; printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; printf(“ap:%x=%d\n”, ap, *ap); return 0; } *ap = *ap +1; 参照先の中身に 1を加える *ap 参照先の大きさ(型)は 宣言で指定したとおり。 すなわち、 int *ap; より、*apはint型 *:参照 そのアドレスの 内容を見る 0x 40ea 0804 ap ポインタ型(32bit) 参照先はint型
printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; アドレス(32bit) 中身(1記憶単位は8bit) … 0x 40ea 0800 1101 0000 0x 40ea 0801 0000 0111 0x 40ea 0802 0100 1011 0x 40ea 0803 1011 1111 0x 40ea 0804 0000 0000 0x 40ea 0805 0x 40ea 0806 0x 40ea 0807 0001 0101 0x 40ea 0808 0100 0001 0x 40ea 0809 1011 0111 0x 40ea 080a 0x 40ea 080b 0x 40ea 080c 0100 0000 0x 40ea 080d 1110 1010 0x 40ea 080e 0000 1000 0x 40ea 080f 0000 0100 0x 40ea 0810 int main(void) { int a; int *ap; ap = &a; a = 20; printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; printf(“ap:%x=%d\n”, ap, *ap); return 0; } *ap ap: 0x40ea0804=21 と表示
printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; アドレス(32bit) 中身(1記憶単位は8bit) … 0x 40ea 0800 1101 0000 0x 40ea 0801 0000 0111 0x 40ea 0802 0100 1011 0x 40ea 0803 1011 1111 0x 40ea 0804 0000 0000 0x 40ea 0805 0x 40ea 0806 0x 40ea 0807 0001 0101 0x 40ea 0808 0100 0001 0x 40ea 0809 1011 0111 0x 40ea 080a 0x 40ea 080b 0x 40ea 080c 0100 0000 0x 40ea 080d 1110 1010 0x 40ea 080e 0000 1000 0x 40ea 080f 0000 0100 0x 40ea 0810 int main(void) { int a; int *ap; ap = &a; a = 20; printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; printf(“ap:%x=%d\n”, ap, *ap); return 0; } *ap ap: メモリのどこかを示す ap: 0x40ea0804=21 apの参照先(*ap)に 格納されている値
printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; アドレス(32bit) 中身(1記憶単位は8bit) … 0x 40ea 0800 1101 0000 0x 40ea 0801 0000 0111 0x 40ea 0802 0100 1011 0x 40ea 0803 1011 1111 0x 40ea 0804 0000 0000 0x 40ea 0805 0x 40ea 0806 0x 40ea 0807 0001 0101 0x 40ea 0808 0100 0001 0x 40ea 0809 1011 0111 0x 40ea 080a 0x 40ea 080b 0x 40ea 080c 0100 0000 0x 40ea 080d 1110 1010 0x 40ea 080e 0000 1000 0x 40ea 080f 0000 0100 0x 40ea 0810 int main(void) { int a; int *ap; ap = &a; a = 20; printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; printf(“ap:%x=%d\n”, ap, *ap); return 0; } &a a *ap 2つの変数(箱) 00000000 00000000 00000000 00010101 a int 型(32bit) aの中身は21 ap &ap 0x 40ea 0804 ap ポインタ型(32bit) 参照先はint型 apの中身は aのアドレス(&a)
printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; int main(void) { int a; int *ap; ap = &a; a = 20; printf(“a:%x = %d\n”, &a, a); *ap = *ap +1; printf(“ap:%x=%d\n”, ap, *ap); return 0; } aのアドレス a 21 *ap aの箱を参照 (参照先はint型) 2つの変数(箱) 00000000 00000000 00000000 00010101 a int 型(32bit) aの中身は21 ap 0x 40ea 0804 ap ポインタ型(32bit) 参照先はint型 apの中身は aのアドレス(&a) aのアドレス を代入しておく
ポインタ:まとめ int *ap; *ap int a; ap a 21 ap = &a; &a
ポインタ:まとめ int型へのポインタ変数ap *ap aの実体を参照 (参照先はint型) aの実体 ap a 21 apはaを指し示す。 存在するメモリのアドレス (注意) ※ 何型へのポインタであっても、ポインタ変数には一律、アドレスが格納される。 参照するとき(*をつけたとき)やポインタ演算を行うとき(ap+1など)に、型を適用する。 ※ ポインタをつかって参照する際には、必ず「実体」(変数や割当済み領域)が必要 → 実体のない参照を行った場合には、Segmentation Haltという実行時エラーが生じる
参照の例 Web上のドキュメント参照: ドキュメント05.pdfへのポインタ 05.pdfの実体 URL WWWサーバ www.tommylab.ynu.ac.jp 05.pdfの実体 URL http://www.tommylab.ynu.ac.jp/lecture/Algorighm/05/05.pdf pdfファイル HTMLドキュメント内での記述: <a href=“http://www.tommylab.ynu.ac.jp/lecture/Algorighm/05/05.pdf”>第5回資料</a> 参照元のHTMLドキュメントに05.pdfが埋め込まれているわけではない。 参照元にはURL(アドレス)のみが埋め込まれる。実体は参照先に存在する。
サンプルプログラム: pointer.c 関数f1のブロック内だけで有効な仮引数xと、 関数f2の仮引数xp(ポインタ変数)に渡されたポインタの違いに注目 f2からは、main関数のブロック内だけで有効な変数aに ポインタを使って参照することができる。
/**************************************************************** アルゴリズムとデータ構造 サンプルプログラム pointer.c <<アドレスとポインタ>> copyright (c) 1995,96,97 T.Mori <mori@forest.dnj.ynu.ac.jp> ****************************************************************/ #include <stdio.h> void f1(int x); void f2(int *xp); main() { int a; a = 1; printf("a == %d\n", a); printf("start: f1(a)\n"); f1(a); printf("done: f1(a)\n"); /* &a は変数aの値が保持されている番地 */ /* printfの引数の中の%uは,%dとほぼ同じだが符合なし(正の)の整数として印刷 */ printf("&a == %u\n", &a); printf("start: f2(&a)\n"); f2(&a); printf("done: f2(&a)\n"); return 0; } /* 変数の値を仮引数(自動変数)に代入し,そのデータを改変する */ /* 呼び出し側の変数の値はもちろん変わらない */ void f1(int x) { printf(" x == %d\n", x); x = x + 1; } /* 変数へのポインタ(番地)を仮引数に渡し,その番地にあるデータを改変する */ /* 呼び出し側の変数の値も変わる */ f2(int *xp) printf(" xp == %u\n", xp); printf(" *xp == %d\n", *xp); *xp = *xp + 1;
int main( void) void f2( int *xp ) 変数 int a 仮引数 int *xp xpの値(アドレス)を表示 printf("a == %d\n", a); printf("start: f1(a)\n"); f1(a); printf("done: f1(a)\n"); printf("&a == %u\n", &a); printf("start: f2(&a)\n"); f2(&a); printf("done: f2(&a)\n"); xpの値(アドレス)を表示 *xpの値(中身)を表示 *xp++ void f1( int x ) xpの値(アドレス)を表示 return 0; 仮引数 int x *xpの値(中身)を表示 戻り値なし(void) xの値を表示 x++ xの値を表示 戻り値なし(void)
int main( void) 変数 int a 1 return 0; &a==4026529420d a = 1; printf("a == %d\n", a); printf("start: f1(a)\n"); f1(a); printf("done: f1(a)\n"); printf("&a == %u\n", &a); printf("start: f2(&a)\n"); f2(&a); printf("done: f2(&a)\n"); return 0;
int main( void) 変数 int a 1 return 0; &a==4026529420d a = 1; printf("a == %d\n", a); printf("start: f1(a)\n"); f1(a); printf("done: f1(a)\n"); printf("&a == %u\n", &a); printf("start: f2(&a)\n"); f2(&a); printf("done: f2(&a)\n"); return 0; a==1 start: f1(a)
int main( void) 変数 int a 1 return 0; &a==4026529420d a = 1; printf("a == %d\n", a); printf("start: f1(a)\n"); f1(a); printf("done: f1(a)\n"); printf("&a == %u\n", &a); printf("start: f2(&a)\n"); f2(&a); printf("done: f2(&a)\n"); return 0; a==1 start: f1(a)
int main( void) 変数 int a 1 f1(1) void f1( int x ) 仮引数 int x return 0; &a==4026529420d a = 1; printf("a == %d\n", a); printf("start: f1(a)\n"); f1(a); printf("done: f1(a)\n"); printf("&a == %u\n", &a); printf("start: f2(&a)\n"); f2(&a); printf("done: f2(&a)\n"); f1(1) void f1( int x ) return 0; 仮引数 int x 1 a==1 start: f1(a) xの値を表示 x++ xの値を表示 戻り値なし(void)
int main( void) 変数 int a 1 f1(1) void f1( int x ) 仮引数 int x return 0; &a==4026529420d a = 1; printf("a == %d\n", a); printf("start: f1(a)\n"); f1(a); printf("done: f1(a)\n"); printf("&a == %u\n", &a); printf("start: f2(&a)\n"); f2(&a); printf("done: f2(&a)\n"); f1(1) void f1( int x ) return 0; 仮引数 int x 1 a==1 start: f1(a) x == 1 xの値を表示 x++ xの値を表示 戻り値なし(void)
int main( void) 変数 int a 1 f1(1) void f1( int x ) 仮引数 int x return 0; &a==4026529420d a = 1; printf("a == %d\n", a); printf("start: f1(a)\n"); f1(a); printf("done: f1(a)\n"); printf("&a == %u\n", &a); printf("start: f2(&a)\n"); f2(&a); printf("done: f2(&a)\n"); f1(1) void f1( int x ) return 0; 仮引数 int x 2 a==1 start: f1(a) x == 1 xの値を表示 x++ xの値を表示 戻り値なし(void)
int main( void) 変数 int a 1 f1(1) void f1( int x ) 仮引数 int x return 0; &a==4026529420d a = 1; printf("a == %d\n", a); printf("start: f1(a)\n"); f1(a); printf("done: f1(a)\n"); printf("&a == %u\n", &a); printf("start: f2(&a)\n"); f2(&a); printf("done: f2(&a)\n"); f1(1) void f1( int x ) return 0; 仮引数 int x 2 a==1 start: f1(a) x == 1 x == 2 xの値を表示 x++ xの値を表示 戻り値なし(void)
int main( void) 変数 int a 1 void f1( int x ) 仮引数 int x return 0; 2 &a==4026529420d a = 1; printf("a == %d\n", a); printf("start: f1(a)\n"); f1(a); printf("done: f1(a)\n"); printf("&a == %u\n", &a); printf("start: f2(&a)\n"); f2(&a); printf("done: f2(&a)\n"); void f1( int x ) return 0; 仮引数 int x 2 return a==1 start: f1(a) x == 1 x == 2 xの値を表示 x++ xの値を表示 戻り値なし(void)
int main( void) 変数 int a 1 return 0; &a==4026529420d a = 1; printf("a == %d\n", a); printf("start: f1(a)\n"); f1(a); printf("done: f1(a)\n"); printf("&a == %u\n", &a); printf("start: f2(&a)\n"); f2(&a); printf("done: f2(&a)\n"); return 0; a==1 start: f1(a) x == 1 x == 2 done: f1(a) &a==4026529420d start: f2(&a)
int main( void) 変数 int a 1 return 0; &a==4026529420d a = 1; printf("a == %d\n", a); printf("start: f1(a)\n"); f1(a); printf("done: f1(a)\n"); printf("&a == %u\n", &a); printf("start: f2(&a)\n"); f2(&a); printf("done: f2(&a)\n"); return 0; a==1 start: f1(a) x == 1 x == 2 done: f1(a) &a==4026529420d start: f2(&a)
int main( void) void f2( int *xp ) 変数 int a 1 仮引数 int *xp &a==4026529420d 仮引数 int *xp 4026529420 a = 1; printf("a == %d\n", a); printf("start: f1(a)\n"); f1(a); printf("done: f1(a)\n"); printf("&a == %u\n", &a); printf("start: f2(&a)\n"); f2(&a); printf("done: f2(&a)\n"); f2(4026529420) xpの値(アドレス)を表示 *xpの値(中身)を表示 *xp++ xpの値(アドレス)を表示 return 0; *xpの値(中身)を表示 a==1 start: f1(a) x == 1 x == 2 done: f1(a) &a==4026529420d start: f2(&a) 戻り値なし(void)
ポインタ(アドレスの値)を渡すことによって、 別の関数内の自動変数(や、確保された領域)に int main( void) 参照渡しによる 関数呼び出しに相当 Call by Reference ポインタによる参照 Reference void f2( int *xp ) 変数 int a 1 &a==4026529420d 値渡しによる 関数呼び出し Call by Value 仮引数 int *xp 4026529420 a = 1; printf("a == %d\n", a); printf("start: f1(a)\n"); f1(a); printf("done: f1(a)\n"); printf("&a == %u\n", &a); printf("start: f2(&a)\n"); f2(&a); printf("done: f2(&a)\n"); f2(4026529420) xpの値(アドレス)を表示 *xpの値(中身)を表示 *xp++ xpの値(アドレス)を表示 return 0; *xpの値(中身)を表示 a==1 start: f1(a) x == 1 x == 2 done: f1(a) &a==4026529420d start: f2(&a) 戻り値なし(void) (注意) C言語での関数呼び出しは、 値渡しによる関数呼び出しのみ Call by Value ポインタ(アドレスの値)を渡すことによって、 別の関数内の自動変数(や、確保された領域)に 直接アクセスさせる→Call by Referenceの代わり
int main( void) void f2( int *xp ) 変数 int a 1 仮引数 int *xp &a==4026529420d 仮引数 int *xp a = 1; printf("a == %d\n", a); printf("start: f1(a)\n"); f1(a); printf("done: f1(a)\n"); printf("&a == %u\n", &a); printf("start: f2(&a)\n"); f2(&a); printf("done: f2(&a)\n"); f2(4026529420) xpの値(アドレス)を表示 *xpの値(中身)を表示 *xp++ xpの値(アドレス)を表示 return 0; *xpの値(中身)を表示 a==1 start: f1(a) x == 1 x == 2 done: f1(a) &a==4026529420d start: f2(&a) 戻り値なし(void)
int main( void) void f2( int *xp ) 変数 int a 1 仮引数 int *xp &a==4026529420d 仮引数 int *xp a = 1; printf("a == %d\n", a); printf("start: f1(a)\n"); f1(a); printf("done: f1(a)\n"); printf("&a == %u\n", &a); printf("start: f2(&a)\n"); f2(&a); printf("done: f2(&a)\n"); f2(4026529420) xpの値(アドレス)を表示 *xpの値(中身)を表示 *xp++ xpの値(アドレス)を表示 return 0; *xpの値(中身)を表示 a==1 start: f1(a) x == 1 x == 2 done: f1(a) &a==4026529420d start: f2(&a) xp== 4026529420d *xp==1 戻り値なし(void)
int main( void) void f2( int *xp ) 変数 int a 2 仮引数 int *xp &a==4026529420d 仮引数 int *xp a = 1; printf("a == %d\n", a); printf("start: f1(a)\n"); f1(a); printf("done: f1(a)\n"); printf("&a == %u\n", &a); printf("start: f2(&a)\n"); f2(&a); printf("done: f2(&a)\n"); f2(4026529420) xpの値(アドレス)を表示 *xpの値(中身)を表示 *xp++ xpの値(アドレス)を表示 return 0; *xpの値(中身)を表示 a==1 start: f1(a) x == 1 x == 2 done: f1(a) &a==4026529420d start: f2(&a) xp== 4026529420d *xp==1 戻り値なし(void)
int main( void) void f2( int *xp ) 変数 int a 2 仮引数 int *xp &a==4026529420d 仮引数 int *xp a = 1; printf("a == %d\n", a); printf("start: f1(a)\n"); f1(a); printf("done: f1(a)\n"); printf("&a == %u\n", &a); printf("start: f2(&a)\n"); f2(&a); printf("done: f2(&a)\n"); f2(4026529420) xpの値(アドレス)を表示 *xpの値(中身)を表示 *xp++ xpの値(アドレス)を表示 return 0; *xpの値(中身)を表示 a==1 start: f1(a) x == 1 x == 2 done: f1(a) &a==4026529420d start: f2(&a) xp== 4026529420d *xp==1 *xp==2 戻り値なし(void)
int main( void) void f2( int *xp ) 変数 int a 2 仮引数 int *xp &a==4026529420d 仮引数 int *xp a = 1; printf("a == %d\n", a); printf("start: f1(a)\n"); f1(a); printf("done: f1(a)\n"); printf("&a == %u\n", &a); printf("start: f2(&a)\n"); f2(&a); printf("done: f2(&a)\n"); xpの値(アドレス)を表示 *xpの値(中身)を表示 *xp++ return xpの値(アドレス)を表示 return 0; *xpの値(中身)を表示 a==1 start: f1(a) x == 1 x == 2 done: f1(a) &a==4026529420d start: f2(&a) xp== 4026529420d *xp==1 *xp==2 戻り値なし(void)
int main( void) 変数 int a 2 return 0; &a==4026529420d a = 1; printf("a == %d\n", a); printf("start: f1(a)\n"); f1(a); printf("done: f1(a)\n"); printf("&a == %u\n", &a); printf("start: f2(&a)\n"); f2(&a); printf("done: f2(&a)\n"); return 0; a==1 start: f1(a) x == 1 x == 2 done: f1(a) &a==4026529420d start: f2(&a) xp== 4026529420d *xp==1 *xp==2 done: f2(&a) a==2