8月24日2時間目\\ 8月24日3時間目\\ ===== メモリとアドレスと変数と ===== ==== メモリと変数 ==== 変数=メインメモリ上に確保された値を入れるための領域\\ 型=メモリ上に数値をどのように表現するかという表現形式\\ \\ 例\\ \\ **int:**\\ 整数を __4 byte__ の2進数で表現したもの。signedとunsignedがある。signedは負の数を2の補数表現で表す。\\ **char:**\\ 整数を __1 byte__ の2進数で表現したもの。signedとunsignedがある。signedは負の数を2の補数表現で表す。\\ **float:**\\ 小数点のある数を、IEEE754浮動小数点形式で表したもの。\\
{{:game-engineer:classes:game-programing-1:memory_image.png?400 }} メモリの内部のイメージ図
\\ 変数は,メモリの中に指定した型の大きさの領域を取るための規格ともいえる。\\ メモリの記憶素子には、並び順で番号づけがされており、この番号をアドレスと呼んでいる。\\ CPUはこのメモリアドレスを使って、命令やデータを読み出したり、書き込んだりしている。\\ アドレスは一般的に1byteごとに区切られてつけられている(Figure 1参照)\\ (これは、CPUのレジスタの一度にやり取りするデータ幅の最小が1byteだからであるが、詳しくはやらん!)\\ 本来はメモリアドレスを指定し、そのアドレスにデータを書き込む作業が、変数への値の代入である。\\ 高級言語では、メモリのアドレスを意識しなくてもよいように変数や型というデータの規格を用意してプログラム上で値のやり取りができる仕組みを構築している。\\
{{:game-engineer:classes:game-programing-1:memory_and_vary.png?600 }} メモリアドレスと変数
==== ポインタとアドレス ==== ポインタ=アドレスを保存する変数\\ 図では、表示領域の都合上アドレスの左16bit=4byte分はどうせ0ということで省略\\ unsigned int a; //この時点でint型(4 byte)で a 用のメモリ空間が用意される //&a で a のある4byteの領域の先頭アドレスが取得できる a = 9; //4byteの領域に、9(0x00000009)が書き込まれる int *p=nullptr; //ポインタを用意して空ポインタで初期化 //*はアスタリスク、アスタ、コメなどと呼ばれる p = &a; // p に a のアドレスを代入
{{:game-engineer:classes:game-programing-1:memory_and_pointer1.png?600 }} ポインタ変数の宣言
図より, a はアドレス**0x00000003**から4byteの領域に**0x00000003(00000000000000000000000000000101)**が書き込まれているのがわかる。\\ このaのアドレスを、先ほど用意したポインタ変数(アドレスを格納するための変数)に代入してみる。\\ p = &a; // p に a のアドレスを代入 この分によって、以下の図のようにpにaのアドレスが代入される。
{{:game-engineer:classes:game-programing-1:memory_assignm.png?600 |}} ポインタ変数へのアドレスの代入
ポインタ変数のもう一つの機能として、アドレスに格納されている値を参照するという機能がある。\\ ポインタ変数を宣言するときの様に変数に*を付けることでアドレスに格納されている値を、宣言時の型として参照する。\\ (アドレスの中に格納されている値をchar *pとするとchar型として、int *pとするとint型として取り出す) int *p; p = &a; std::cout << a << std::endl; //9が表示される std::cout << *p <9を表示 ==== ポインタと文字列と文字配列 ==== C++やC言語では組み込み型(intやfloatの様に初めから用意されている型)として文字列型がない。\\ C++/Cでは、文字列を扱うために文字配列(char型配列)を使う。\\ \\ == 文字配列の仕組み == [[game-engineer:classes:2021:game-programing-1:first-term:8:8-25-3|文字列リテラル]]で説明したように、文字列とは"ダブルクォーテーションで囲まれた文字たち"を意味している。\\ \\ 例)\\ **"Tohoku Denshi"**\\ **"I love programing"**\\ #include #include int main() { using std::cout; //using namespace std; using std::cin; //だと影響大きすぎるから using std::endl; //個別に指定するよ using std::setw; char s[] = "Time is money"; for (auto i = 0; i < 14; i++) { cout << "s[" << setw(2) << i << "]=" << s[i] << endl; } } ソースコード(いろいろ追加版) #include #include int main() { using std::cout; //using namespace std; using std::cin; //だと影響大きすぎるから using std::endl; //個別に指定するよ using std::setw; char s[20] = "Time is money"; //13文字+終端文字('\0') s[15] = 's'; s[16] = 'a'; s[17] = 't'; s[18] = 'o'; s[19] = '\0'; for (auto i = 0; i < 20; i++) { cout << "s[" << setw(2) << i << "]=" << s[i] << endl; } //char型のアドレスを入れる入れ物 p char* p; p = s + 15; cout << s << endl; cout << &(s[0]) << endl; cout << s + 15 << endl; cout << &(s[15]) << endl; cout << p << endl; cout << p + 2 << endl; cout << *(p + 2) << endl; //p = s + 15 //p + 2 = s+15 + 2 // *p = *(s+15) = s[15] // *(p+2)=*(s+17) = s[17] // cout << s[17] << endl; // = 上の繰り返しでやったやつ }