Upload
adriel
View
32
Download
1
Embed Size (px)
DESCRIPTION
CPU とメモリ. CPU. メモリ. 32bit. 8bit. アドレス. アドレスバス. 演算部. 0000. 整数 レジスタ. 0001. 0002. 0003. データバス. ・ ・ ・. 64bit. 書き込み. 小数レジスタ. 読み出し. データの配置. int (32bit = 4byte). double (64bit = 8byte). メモリ. メモリ. メモリは 8bit=1byte を単位に,格納する情報の大きさに合わせて使用される 読み書きは,各領域をひとまとめにして扱う 左の例: - PowerPoint PPT Presentation
Citation preview
CPUとメモリCPU
小数レジスタ
メモリ
アドレス0000000100020003
・
・
・
8bit
アドレスバス
データバス64bit
演算部整数
レジスタ
32bit
書き込み
読み出し
データの配置
メモリ
アドレス ・
012001210122
8bit
・ ・ ・
メモリ
アドレス ・
012001210122
8bit
・ ・ ・
int (32bit = 4byte)
変数 b
変数 a
double (64bit = 8byte)
変数 r
•メモリは 8bit=1byteを単位に,格納する情報の大きさに合わせて使用される
•読み書きは,各領域をひとまとめにして扱う
左の例:
•int a, b; とした場合 a は 0120 - 0123 b は 0124 - 0127
•double r; とした場合 r は 0120 - 0127
配列型アドレス ・
026202630264
8bit
・ ・ ・ a[1]
a[0]
•配列はメモリ中に順に確保される
左の例:
•int a[3]; として配列を定義した場合 確保される領域は全部で 12byte a[x] は 0262 + (x * 4) から始まる 4byte
•double d[10] のようにした場合 確保される領域は全部で 80byte d[x] は 0262 + (x * 8) から始まる 8bytea[2]
コンパイラの動作アドレス ・
026202630264
8bit
02650266 ・ b[0]
a
b[1]
main() { int a, b[2];
a = 10; b[0] = 20; b[1] = b[0] + a;}
・メモリを 12byte 確保 (開始位置: 0262 )
•「 0262 」に 10 を入れる
•「 0266+0*4 」に 20 を入れる
•「 0266+0*4 」と「 0262 」の和 を計算し,その結果を 「 0266+1*4 」に入れる
・
コンパイル
コンパイラの動作•変数に必要なメモリの総量を計算する•各変数名に実際のアドレスを対応づける•数式を,アドレスを用いた手順に変換する
ここでは,「 x 」は x から始まる 4byte であるとする
メモリのアクセス
変数のアクセスに必要な情報• 読み書きすべき変数は,どのアドレスか
ら始まるか• 変数が格納されている大きさは,いくらかコンパイラの役目・利点• アドレスを手計算しなくてよい• 変数の大きさの代わりに型( int, double
など)を用いるので,間違いにくい.また,大きさの食い違いをチェックしてくれる
ポインタの発想アドレス ・
026202630264
8bit
02650266 ・ b[0]
a
b[1]
main() { int a, b[2]; ・・・}
・
コンパイラが管理する情報•変数 a 開始: 0262 大きさ: 4 操作単位:4•変数 b 開始: 0266 大きさ: 8 操作単位:4
コンパイラが管理する情報の利用
•変数 a の開始位置(アドレス)を知りたい
•アドレスを用いてメモリ操作したい
など開始位置:変数名に対応大きさ: sizeof(..) で取得可能操作単位:型に対応
ポインタアドレス ・
026202630264
8bit
02650266 ・ b[0]
a
b[1]
main() { int a, b[2]; ・・・}
・
コンパイラが管理する情報•変数 a 開始: 0262 大きさ: 4 操作単位:4•変数 b 開始: 0266 大きさ: 8 操作単位:4
& : 変数名からのアドレス取得 &a は 0262 となる &(b[0]) は 0266 となる
* : アドレスによるメモリアクセス *(0262) で変数 a へアクセス できるか? →操作単位の情報が必要
ポインタ変数とポインタの型 ・
02620263026402650266 ・ b
a
p
main() { int a, b, *p;
a = 10; /* 1 */ p = &a; /* 2 */ b = *p; /* 3 */ *p = 20; /* 4 */} ・
1. a に 10 が入る2. p に 262 が入る3. b に a の値( 10 )が入る4. a に 20 が入る
p は int 型の ポインタ変数•p には int の変数の アドレスを代入する 事が出来る•*p で, p に格納され ているアドレスから, int の大きさで アクセスできる
型と文法
int *p;p は int 変数へのポインタ
* はポインタの前に付けると,そのポインタが指す値を意味する.つまり, int 型
p = &a;
a は int 変数
& は変数の前に付けると,その型へのポインタを意味する.つまり, int 型へのポインタ
int 型 int 型へのポインタ
int a;int *p;
p = &a; の解釈
a*p
&ap
右辺と左辺の釣り合いが取れていなければならない.
両辺は「 int 型」 両辺は「 int 型へのポインタ」
関数とポインタ
x
a
void change(int *x) { *x = 100;}
int main() { int a = 10;
change(&a);}
•a に格納された値ではなく,変数 a のポインタ(アドレス)を関数 change へ伝える事で,変数 a の内容を書き換える事が出来る(関数から値を返す事が出来る)
ポインタと配列
a[1]*(a+1)
a[0]*a
int main() { int a[2] = {10, 20}; int *y = a;
y[0] = 100; *(y+1) = 200; *a = 1000; *(a+1) = 2000;}
•ポインタ変数への加算はアドレスへの加算ではなく,操作単位(型の大きさ)を乗じた値の加算となる•ポインタは配列として,また逆に配列はポインタとして使う事が出来る
•a[0] と *a は等価•a[1] と *(a+1) は等価
y
y[0]*yy[1]
*(y+1)
ポインタの応用例
• 渡された文字列のスペースの個数を数えて返す関数
• p++ で,文字列の次の要素へ処理対象を移動する
int spacecnt(char *p) { int cnt = 0;
for( ; *p != ‘¥0’; p++) { if(*p == ‘ ‘) { cnt++; } } return cnt;}
Malloc() と free()
• 必要なときに必要なだけメモリを確保する–大きさの計算に注意( sizeof() を使う事)–型の変換(キャスト)をきちんとするのが望ましい
• 使い終わったら解放 (free) する–解放しなければどんどんメモリが浪費される
int *p;
p = (int *)malloc(100 * sizeof(int));*p = 100;p[99] = 200;free(p);
構造体
x.a
struct foo { int a; double d;};
struct foo x;
•x は大きさ 12byte
•メンバ a は大きさ 4byte で, 開始位置は x の先頭から 0
•メンバ d は大きさ 8byte で, 開始位置は x の先頭から 4
コンパイル
x.d
x •x の型は struct foo 型 ( foo はタグ名という)
•x.a の型は int
•x.d の型は double
構造体の利点
配列に対する利点• 様々な型をひとまとめに出来る• 丸ごとコピーできる
struct hoge a, b; a = b;
読みやすさ,書きやすさ• 各要素に意味のある名前を付ける事が出来る• 構造体の宣言は,タグ名により再利用できる
構造体の作り方・使い方struct st1 { int a, b;}
struct st2 { struct st1 s; double c[3];}
struct st1 x;struct st2 y;
x.a =10;y.c[0] = 10.5;y.s = x;y.s.b = 20;
作り方(宣言と定義)• 構造体を入れることが可能• 配列を入れることも可能• タグ名を用いていくつでも同
じ型の構造体を作る事が可能使い方• メンバへアクセスする演算子 .
は,続けて使う事が出来る
構造体へのポインタstruct st1 { int a, b;}
struct st1 x;struct st1 *y;
y = &x;
(*y).a = 100;y->b = 200;
構造体を指すポインタが使える
• 演算子 * の優先順位は . や[] より低いことに注意!
• 構造体へのポインタを専門に扱う演算子 -> が用意されているm->n は (*m).n と等価
複雑な変数定義• int *a[3]; int *(a[3]) と同じ
「 a は要素数 3 の配列で,その配列の各要素は int へのポインタ」
• int (*b)[3];「 b はポインタで,そのポインタが指す先は要素数 3 の配列.その配列の各要素は int 」
• struct list { int data; struct list *p1, *p2;} x;「 x は int 型の領域 data と,自分自身と同じ型の構造体を指すポインタ p をメンバに持つ構造体」
a[0]a[1]a[2]
int
intint
bintintint
datap1p2
datap1p2
datap1p2
datap1p2
datap1p2
色を塗ってある部分が実際に確保されるメモリ