計算機の内部にはメインメモりと呼ばれる装置が収まっている。メインメモリの役割は、数値を記録して置くことである。
メインメモリは沢山の記憶セルからなっており、個々の記憶セルは一般に1 byte ( = 8 bit )分の情報が保持できる( 0〜255 = 2^8 - 1 )あるいは、-128〜127の範囲の数値)。
個々の記憶セルはそれらを区別するために番地が付けられており、異なる番地のセルには異なる情報(数値)を記憶することができる。
セル数は、いわゆる「メインメモリのメモリサイズ」で、例えば、数学科の2008年度入学者に配布されている機種(vostro 1200)には、2 G byteのメモリが塔載されている([vostro 1200 のメインメモリのサイズを確認してみよう])。
[スタートメニュー]を開き、その中の[コンピュータ]の所で、右クリックしてみよう。すると、メニューが表示されるはずだ。この中の[プロパティ(P)]を左クリックすると[システムとメンテナンス>>システム]のウィンドウが表示される。この中の「メモリ(RAM):」の後に記載されている2038MBが、このNote-PCに塔載されているメインメモリのサイズだ。
メモリの特徴をまとめると次のようになる。
メモリの最小単位(メモリセルの記憶容量)は、byteであり、これ単独で記憶できるのは、0〜255の数値だけでである。つまり、「単独のメモリセル」では、皆さんの小遣いさえ、記憶できないことになる。
そこで、複数のメモリセルをまとめて扱い、それが一つで、大きな数を表していると考える事にする。こうしてまとめられたセルの事をワード([ワード長と表現できる数の範囲])と呼ぶ事がある。
K君:「ふむ、ふむ、なるほど、自分の10本の指で、足りなければ、友達の手の指を借りればよいわけか..」「一つのセルでは、250位ってことは、僕の月一万円の小遣いを記録するには、10000 / 250で40セルか?結構使うなぁ...、こんなんじゃ、2Gあっても足りなくならないか? 2Gって、20億位か、すると、これの250倍って、えっ?たった5000億?じゃあ、このコンピュータでは国家予算の計算もできないってこと??」
Y先生:「相変わらず、K君は慌てものだなぁ..。実はそんなことはないんだ。0〜255 ( = 256 - 1 )まで表現できるセルが二つあれば、実は、0〜65535 ( = 256 * 256 - 1 )まで表すことができる。つまり、君の御小遣いなら、セル二つで十分だってことだな。それに、我国の借金だって、1,000,000,000,000,000を越えないので、7 byteで十分だ。」
K君:「なるほど、和(256+256)ではなく、積(256*256)になるですね。」
Y先生:「そうそう、n個のセルを継いでできるワードが表現できる数の種類は、2^(8*n) = (2^8)^n = 256^nとなる。」
K君:「すると、友達の指が十の位を、自分の指が一の位を表すとすれば、なんと、0〜99の100個、すなわち、10^2 = 100個の数が表されるってことですね」
Y先生:「ふむ、その通りだ。それが位取法、十進法というわけだ。じゃあ、そこまで判ったんだったら、実は、片手でも32通り、両手なら1024通りまで表すことができることがわかるかな?」
K君:「えっ?こんな所でまで、宿題ですか?参ったなぁ..ええと..なるほど...。でも先生、普通の人は、こんな風に指を曲げることなんかできないですよねぇ..」
Y先生:「ふむ、それが『数学』というものだよ。はっはっはぁ...」
計算機が「計算を行う」ということは、どうゆう意味を持つのだろうか?実は、これは「メモリを書き換えること」という観点で意味を付けることができる。
例えば、「最初に、メモリの個々のセルに値が与えられており、プログラムを実行した後にメモリ内のセルの値がどのように変化したか」で、「プログラムを意味」を定める事ができる。
実際には、「計算結果をメモリに書き込んでいる」ので、やっぱり計算を行っているではないかと思われるが、逆に考えれば、「計算をしても、その結果がメモリに書き込まれなければ無意味」であり、また、「メモリに書き込まれた結果さえ同じであれば、その計算方法はどうでもよい」という点を考えると、実は主役が計算側にはなく、メモリ側にあることが解る。
Download : sample-001.c ( SJIS 版 )
#include <stdio.h> /* 文字列を格納する配列 */ #include <stdio.h> int main (void) { char arry_of_str[4]; /* 文字列を格納する配列 */ /* (@) str -> array_of_str */ char *str = arry_of_str; /* (@) array_of_str の別名としての str を追加 */ str[0] = 'A'; /* 代入 */ str[1] = 'B'; /* 代入 */ str[2] = 'C'; /* 代入 */ str[3] = '\0'; /* 代入 */ printf ( "文字列 str は %s です。\n", str ); /* 表示 */ return (0); }
C:\usr\c\> sample-001 char &cv = 0xbfe5a5bf sizeof(char) = 1 &cv + 1 = 0xbfe5a5c0 int &iv = 0xbfe5a5b8 sizeof(int) = 4 &iv + 1 = 0xbfe5a5bc double &dv = 0xbfe5a5b0 sizeof(double) = 8 &dv + 1 = 0xbfe5a5b8 C:\usr\c\>
Download : sample-002.c ( SJIS 版 )
#include <stdio.h> int main() { char cv; int iv; double dv; printf ( "char\n" ); printf ( "&cv = %p\n", &cv ); printf ( "sizeof(char) = %d\n", sizeof(char) ); printf ( "&cv + 1 = %p\n", &cv + 1 ); printf ( "int\n" ); printf ( "&iv = %p\n", &iv ); printf ( "sizeof(int) = %d\n", sizeof(int) ); printf ( "&iv + 1 = %p\n", &iv + 1 ); printf ( "double\n" ); printf ( "&dv = %p\n", &dv ); printf ( "sizeof(double) = %d\n", sizeof(double) ); printf ( "&dv + 1 = %p\n", &dv + 1 ); return (0); }
C:\usr\c\> sample-002 char &cv = 0xbf8d756f sizeof(char) = 1 &cv + 1 = 0xbf8d7570 int &iv = 0xbf8d7568 sizeof(int) = 4 &iv + 1 = 0xbf8d756c double &dv = 0xbf8d7560 sizeof(double) = 8 &dv + 1 = 0xbf8d7568 C:\usr\c\>
Download : sample-003.c ( SJIS 版 )
#include<stdio.h> main() { int va; printf ( "%p\n", &va ); return 0; }
C:\usr\c\> sample-003 0xbff7b8ac C:\usr\c\>
Download : sample-004.c ( SJIS 版 )
#include<stdio.h> main() { int va; printf ( "%p\n", &va ); va = 1; printf ( "va=%d\n", va ); va = 100; printf ( "va=%d\n", va ); va = va - 23; printf ( "va=%d\n", va ); printf ( "??=%d\n", *((int *)0x0012FF68) ); *((int *)0x0012FF68) = 987; printf ( "??=%d\n", *((int *)0x0012FF68) ); printf ( "va=%d\n", va ); return 0; }
C:\usr\c\> sample-004 0xbf921ffc va=1 va=100 va=77 va=77 C:\usr\c\>
Download : sample-005.c ( SJIS 版 )
#include<stdio.h> void sub(void) { int va; printf ( "va=" ); scanf ( "%d", &va ); printf ( "va = %d\n", va ); } int main() { int va; printf ( "%p\n", &va ); sub(); printf ( "%d\n", *((int *)0x0012FF5C) ); return 0; }
10
C:\usr\c\> sample-005
Download : sample-006.c ( SJIS 版 )
#include<stdio.h> int main(void) { int va; va = 2; printf ( "%d\n", va ); va = va + 3; printf ( "%d\n", va ); return 0; }
C:\usr\c\> sample-006 2 5 C:\usr\c\>
Download : sample-007.c ( SJIS 版 )
#include<stdio.h> int main() { int va; *(&va) = 2; printf ( "%d\n", *(&va) ); *(&va) = *(&va) + 3; printf ( "%d\n", *(&va) ); return 0; }
C:\usr\c\> sample-007 2 5 C:\usr\c\>
Download : sample-008.c ( SJIS 版 )
#include <stdio.h> void sub ( void ) { int va; printf ( "sub:&va = %p\n", &va ); } int main ( void ) { int va; printf ( "main:&va = %p\n", &va ); sub(); return 0; }
C:\usr\c\> sample-008 main:&va = 0xbfb1143c sub:&va = 0xbfb1140c C:\usr\c\>
Download : sample-009.c ( SJIS 版 )
#include <stdio.h> void sub ( void ) { int va; printf ( "sub:&va = %p\n", &va ); va = 100; printf ( "sub:va = %d\n", va ); } int main ( void ) { int va; printf ( "main:&va = %p\n", &va ); va = 1; printf ( "main:va = %d\n", va ); sub(); printf ( "main:va = %d\n", va ); printf ( "main:?? = %d\n", *((int *)0x0012FF5C) ); return (0); }
C:\usr\c\> sample-009
va=10 (0xbff3acdc) vb=20 (0xbff3acd8) vc=30 (0xbff3acd4) Pointer=0xbff3acd8 va=10 vb=200 vc=30
#include<stdio.h> int main() { int va = 10; int *ip = &va; char *cp = (char *)&va; printf ( "ip=%p\n", ip ); printf ( "ip + 1 = %p\n", ip + 1 ); printf ( "cp=%p\n", cp ); printf ( "cp + 1 = %p\n", cp + 1 ); va = 300; printf ( "va = %d\n", va ); *ip = 0; printf ( "va = %d\n", va ); va = 300; printf ( "va = %d\n", va ); *cp = 0; printf ( "va = %d\n", va ); }
#include <stdio.h> /* 文字列を格納する配列 */ #include <stdio.h> int main (void) { char arry_of_str[4]; /* 文字列を格納する配列 */ /* (@) str -> array_of_str */ char *str = arry_of_str; /* (@) array_of_str の別名としての str を追加 */ str[0] = 'A'; /* 代入 */ str[1] = 'B'; /* 代入 */ str[2] = 'C'; /* 代入 */ str[3] = '\0'; /* 代入 */ printf ( "文字列 str は %s です。\n", str ); /* 表示 */ return (0); }