Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


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

1 メモリとポインタ

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

3 メモリを学ぶ前に 2進数について学ぶ 箱が一つあり、箱の中には0か1が入る。 箱一つで数をいくつ表現できるか 解 0、1

4 メモリを学ぶ前に では、箱2つでは、数をいくつ表現できる か 解 00 ( 0 ) 01 ( 1 ) 10 ( 2 ) 11 ( 3 ) つまり箱一つで4つの数を表現できる。 ()内は10進数

5 メモリの考え方 イメージとして メモリは箱が並んだ長い一列のロッカーの 構造 箱1つを1ビットとして考えられる。 (0か1だから) 0 or 1 ・・・・・・

6 1ビットと1バイト 1 ビット・・・0 or 1・・・2の1乗 1バイト・・・8ビット・・・2の8乗 つまり、箱が8個集まったものを 1バイトとしている。

7 int 型での宣言とは int 型は4バイト使う つまり32ビット使っている 計32個 上の箱を使って数を表現している 例えば int a = 450; と宣言すれば、 メモリ上では (00000000000000000000000111000010)

8 ポインタへの導入 メモリは1バイトごとに番号がついている この番号のことをアドレスと呼ぶ。 0001番 0002番 0003番0004番

9 アドレスの確認 プログラムは下の通り 番号を調べるには %p を使う。 #include int main(void) { int i; printf(“%p\n”,&i); return 0; } 結果は16進数で表示される

10 複数のアドレスを調べると #include int main(void) { int i1,i2,i3; printf("i1(%p)\n",&i1); printf("i2(%p)\n",&i2); printf("i3(%p)\n",&i3); return 0; } 結果は各自で 結果は一桁目が4つず つ ずれているはず これは変数の宣言に int 型 ( 4バイト)を 用いたから

11 配列とアドレス #include int main(void) { int array[10]; printf("array(%p)\n",array); printf("array[0](%p)\n",&array[0]); printf("array[1](%p)\n",&array[1]); printf("array[2](%p)\n",&array[2]); return 0; } array(0012FF5C) array[0](0012FF5C) array[1](0012FF60) array[2](0012FF64) 配列を使う場合 array に & を使う 必要がない

12 ポインタ ポインタとは ポインタ型、ポインタ値、ポインタ変数の 総称 するアドレスを扱うもの

13 ポインタ型について 特徴 int 型や double 型といった型と合体すること で ポインタ型は扱える。 (例) int *a; ポインタ型はアドレスを記憶する変数の型

14 ポインタ値とポインタ変数 ポインタ型とは 変数のアドレス値 ポインタ変数 ポインタ型で宣言された実際の変数 この変数には、その元となった型の変数の アドレスを自由に代入できる

15 ポインタ変数の宣言とアドレス代 入 int main(void){ int *p; //int 型のポインタ型の宣言 int i; p = &i; // アドレスの代入 return 0; }

16 ポインタ変数のモードの話 通常変数モード int 型と同じように値を扱える (例) *p = 10; ポインタ型変数モード アドレスを扱う (例) p = &i; //i のアドレスを p に格納する

17 ポインタ変数のモードの話 #include int main(void){ int *p,i; p = &i;//p はアドレスを格納する *p = 10; //*p は値を格納する printf(“*p=%d\n”,*p); printf(“i = %d\n”,i); return 0; }

18 ポインタ変数のモードの話 #include int main(void){ int *p,i; p = &i; *p = 10; printf(“*p=%d\n”,*p); printf(“i = %d\n”,i); return 0; } *p は、通常変数モード に切り替わった変数p 結果 *p=10; i = 10;

19 今日の演習 今回はサイト:演習問題一覧をお借りしま す。 http://www9.plala.or.jp/sgwr- t/c_sub/index_en.html

20 メモリとポインタ( 2 回目)

21 復習問題 a = 10 を表示せよ。(ただし a = 10; としない) int main(void){ int a; int *p; // ここにかく // ここにかく (最高 2 行だと思われる) printf(“a = %d\n”,a); return 0; }

22 ポインタ型の引数 自作関数の引数にポインタ型を使用する 今までは int value(int a){ 処理 ; }

23 ポインタ型の引数 #include void func(int *pvalue); int main(void) { int value = 10; printf("&value = %p\n",&value); func(&value); printf("value = %d\n",value); return 0; } void func(int *pvalue) { printf("pvalue = %p\n",pvalue); *pvalue = 100; return; }

24 自作関数を実行する前 アドレス 0018FF5C 値 10 変数名 value

25 自作関数を実行した後 アドレス 0018FF5C 値 100 変数名 value 関数で行われていること 1.自作関数に value のアドレスを渡す 2.アドレスの値に 100 を代入する

26 ポインタと配列の話 自作関数の引数に配列を用いる #include int getaverage(int data[10]); int main(void) { int average,array[10] = {15,78,98,15,98,85,17,35,42,15}; average = getaverage(array); printf(“%d\n”,average); return 0; } int getaverage(int data[10]) { int i,average = 0; for (i = 0;i < 10;i++) { average += data[i]; } return average / 10; } // 結果 49

27 関数に配列を用いても問題ないようにみえ る しかし、配列の要素数が変わると問題が発 生する。

28 要素数が 5 の場合 #include int getaverage(int data[10]); int main(void) { int average,array[5] = {15,98,98,17,42}; average = getaverage(array); printf(“%d\n”,average); return 0; } int getaverage(int data[10]) { int i,average = 0; for (i = 0;i < 10;i++) { average += data[i]; } return average / 10; } // 結果 おかしいことに

29 配列の引数は配列の要素数は無視されている。実際、 int getaverage(int data[]); としても問題ない。 実は配列を関数渡すというのは アドレスを関数に渡しているのと同じである int getaverage(int data[10]); int getaverage(int *data); // アドレスの先頭番地を渡 す 上の二つは同じように扱える。

30 問. おかしい点を探せ #include int getaverage(int *data); int main(void) { int average,array[10] = {15,78,98,15,98,85,17,35,42,15}; average = getaverage(array); printf("%d\n",average); return 0; } int getaverage(int *data) { int i,average = 0; for (i = 0;i < 10;i++) { average += data[i]; return average / 10; }

31 [] は配列の要素を選択するという意味もある が data[i] は data というアドレスと i を足している という意味でもある。

32 参考文献 苦しんで覚える C 言語 http://9cguide.appspot.com/15-07.html アカバス http://akabas.net/lib/CExercise.aspx?id=8


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

Similar presentations


Ads by Google