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