集合の表現

アルゴリズムとデータ構造
補足資料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