アルゴリズムとデータ構造 補足資料5-1 「メモリとポインタ」

Slides:



Advertisements
Similar presentations
メモリとポインタ. プログラムの前提 コンピュータは、0と1で計算をし、 0と1でデータを保存している。 メモリを学ぶのに必要な知識である。
Advertisements

第6章 ポインタ ポインタが分からずにC言語を投げ出す人が数多くいます。 その半面、使いこなせば強力な武器となります。 しっかりと学習していきましょう C 言語 最難関文法 C 言語 最難関文法 1 第 6 章 ポインタ.
C 言語講座 第 7 回 ポインター. メモリとアドレス(ポインターの前 に) コンピュータのメモリには 1 バイトずつ 0 番地、 1 番地、 2 番地・・・というように 住所が割り当てられている この住所をアドレスという。 メモリはデータをしまうもので それを引き出すためには メモリに番号(アドレス)を振っておけばよいな.
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
データ構造とアルゴリズム 第10回 mallocとfree
プログラミング演習Ⅱ 第12回 文字列とポインタ(1)
地理情報システム論 第3回 コンピュータシステムおける データ表現(1)
システムプログラミング 第11回 シグナル 情報工学科  篠埜 功.
情報処理Ⅱ 2005年12月9日(金).
C言語講座 第4回 ポインタ.
構造体.
アルゴリズムとデータ構造 補足資料4-2 「線形探索」
アルゴリズムとデータ構造 補足資料6-3 「サンプルプログラムcat3.c」
第4回放送授業.
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
システムプログラミング 第11回 シグナル 情報工学科  篠埜 功.
岩村雅一 知能情報工学演習I 第8回(後半第2回) 岩村雅一
C言語講座 第3回 ポインタ、配列.
プログラミング論 関数ポインタ と 応用(qsort)
ちょっとした練習問題① 配列iroを['R', 'W', 'R', 'R', 'W' , 'W' , 'W']を宣言して、「W」のときの配列の番号をprintfで表示するようなプログラムを記述しなさい。
プログラミング論 ファイル入出力
関数とポインタ 値呼び出しと参照呼び出し swapのいろいろ 関数引数 数値積分
関数と配列とポインタ 1次元配列 2次元配列 配列を使って結果を返す 演習問題
関数の定義.
アルゴリズムとデータ構造 補足資料11-1 「mallocとfree」
2005年度 データ構造とアルゴリズム 第3回 「C言語の復習:再帰的データ構造」
プログラミング演習I 2003年5月7日(第4回) 木村巌.
第10章 これはかなり大変な事項!! ~ポインタ~
プログラミング入門2 第8回 ポインタ 情報工学科 篠埜 功.
アルゴリズムとデータ構造 補足資料5-2 「サンプルプログラムsetop.c」
第7回 プログラミングⅡ 第7回
復習 前回の関数のまとめ(1) 関数はmain()関数または他の関数から呼び出されて実行される.
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
アルゴリズムとデータ構造 補足資料4-1 「メモリと配列」
高度プログラミング演習 (08).
地域情報学 C言語プログラミング 第5回 ポインタ、関数、ファイル入出力 2017年11月17日
プログラミング論 ファイル入出力
アルゴリズムとデータ構造 補足資料6-2 「サンプルプログラムcat2.c」
第11回 プログラミングⅡ 第11回
関数への道.
オブジェクト指向プログラミングと開発環境
配列変数とポインタ 静的確保と動的確保 ポインタ配列 2次元配列 時間計測 第1回レポートの課題
プログラミング演習I 2004年5月19日(第5回) 理学部数学科・木村巌.
メモリとメモリアドレス, ポインタ変数,関数へのポインタ渡し
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
プログラミング入門2 第9回 ポインタ 情報工学科 篠埜 功.
ポインタとポインタを用いた関数定義.
情報基礎演習B 後半第2回 担当 岩村 TA 谷本君.
第13回 ポインタ 1 1.
プログラミング論 ポインタ
11.1 標準ライブラリ関数 11.2 関数呼び出しのオーバーヘッド 11.3 大域変数 11.4 プロトタイプ宣言 11.5 関数引数
アルゴリズムとデータ構造1 2009年6月15日
第5回 プログラミングⅡ 第5回
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
アルゴリズムとデータ構造 補足資料7-1 「メモリでの『構造体の配列』」
コンパイラ 第12回 実行時環境 ― 変数と関数 ― 38号館4階N-411 内線5459
アルゴリズムとデータ構造 補足資料6-1 「サンプルプログラムcat1.c」
アルゴリズムとデータ構造 2010年6月17日
アルゴリズムとデータ構造 補足資料5-3 「サンプルプログラムstrcat.c」
プログラミング演習I 2003年6月11日(第9回) 木村巌.
2005年度 データ構造とアルゴリズム 第2回 「C言語の復習:配列」
システムプログラミング 第11回 シグナル 情報工学科  篠埜 功.
プログラミング演習II 2004年11月 2日(第3回) 理学部数学科・木村巌.
プログラミング入門2 第5回 配列 変数宣言、初期化について
値渡しと参照渡しについて.
モバイルプログラミング第3回 Cプログラミングの基礎( 2 )
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング 3 ポインタ(1).
Presentation transcript:

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