ここでポインタ変数を導入してみます
メモリとアドレスと変数の関係について学んでみましょう
こんにちは アレサです。
午前は
現在、このカクヨムでも連載されている
プレミアム ミリオンセラー作家
佐月 詩 さん原作の
長編映画 「ft王」
~そして、清らかさの意味を知る~
時の涙 前編
をソーラーさん達みんなで見に行ってきました。
わくわくと感動で涙が止まりませんでしたの。
その余韻がまだ残っています。
午後からは
今日は、しとやかにメモリとアドレスのお話をしてみたいとおもいます。
アドレスとはコンピュータ内のメモリにデータを保存するときに
そのデータを格納するメモリに
もとからつけられている番号(住所)のことです。
番号(住所)がわかれば、
そこに保存されているデータを
その番号(住所)をつかって呼び出すことができるわけなんです。
いままで
コンピュータのメモリに
変数を用いてデータを格納してきました。
変数とデータを格納するメモリにつけられているアドレスには
対応関係があります
例えば int型(4バイト)の変数aならば
変数aに格納される数値は
数値1なら
00000000 00000000 00000000 00000001
👆 👆 👆 👆
1バイト 1バイト 1バイト 1バイト
数値2147483647なら
11111111 11111111 11111111 11111111
👆 👆 👆 👆
1バイト 1バイト 1バイト 1バイト
のように
4バイトのメモリにわたって格納されることになります
コンピュータは
1バイトを基準としてデータを管理する仕組みとなっており
その1バイトごとにアドレスが割り当てられていますので
変数aは
例えば
0019FF54
0019FF55
0019FF56
0019FF57
のような4つのアドレスをもっていることになります
変数aのアドレス(データを格納するメモリにつけられている番号(住所))
は
アドレス演算子&を変数aにもちいて&aのように表記されますが
&aは
変数aが持っている4つのアドレス
0019FF54
0019FF55
0019FF56
0019FF57
のうち
先頭のアドレス0019FF54だけを表しています。
この&aが
変数aが持っている4つのアドレス
0019FF54
0019FF55
0019FF56
0019FF57
のうち
先頭のアドレス0019FF54だけを表すというシステムは
C言語のなかでいたるところで見られます。
ですので
おぼえておられるとC言語の理解がより深まることになると思われますの😊
実際にプログラムを組んで
変数aのアドレス &aがどのような数値になっているか
確かめてみましょう。
#include <stdio.h>
int main(void){
int a=1;
printf("変数aに格納された値は%dです。\n",a);
printf("変数aのアドレスは%pです。\n",&a);
/*ここで変数aのアドレス情報を知るために
変数aに
アドレス演算子&がつかわれています。
&aはコンピュータのメモリに2進数数値で格納されています。
2進数数値でメモリに格納されている
アドレス&aを16進数でprintf出力表示させるために
%p出力変換指定子がもちいられています*/
return 0;
}
コンパイル結果
EAZY IDECの場合
変数aの値は1です。
変数aのアドレスは0019FF54です。
Visual Studioの場合
ビルド実行結果
変数aの値は1です。
変数aのアドレスは00CFFC7Cです。
まず、変数宣言、初期化
int a=1;
をおこない,
そのあと変数aのアドレスである&aをprintf出力表示しています。
Visual Studioの場合
では
初期化
int a=1;
あるいは
変数aに数値データを代入しなければ
変数aのアドレス&aを取得することはできません。
統合開発環境EAZY IDECでは
初期化
int a=1;
を行わなくても
あるいは
変数aに数値データを代入しなくても
変数aのアドレス&aを取得することはできます。
#include <stdio.h>
int main(void){
int a;
printf("変数aの値は%dです。\n",a);
printf("変数aのアドレスは%pです。\n",&a);
return 0;
}
コンパイル結果
変数aの値は4198543です。
変数aのアドレスは0019FF54です。
Visual Studioの場合
エラー C4700 初期化されていないローカル変数 'a' が使用されます
と表示されビルドエラーになります。
変数aの初期化を行わないと
いつも通りお馴染みのモンスター数値さん
4198543が変数aに格納されていますね。
ですが、
変数aのアドレスは
(EAZY IDECの場合のみ)
変数aが初期化されるされないにかかわらず0019FF54となっています。
もうすこし試してみたいと思います
int a=5;
と
aに数値5を代入して初期化した場合
変数aのアドレスはどうなっているのでしょうか?
#include <stdio.h>
int main(void){
int a=5;
printf("変数aの値は%dです。\n",a);
printf("変数aのアドレスは%pです。\n",&a);
return 0;
}
コンパイル結果
EAZY IDECの場合
変数aの値は5です。
変数aのアドレスは0019FF54です。
ビルド結果
Visual Studioの場合
変数aの値は5です。
変数aのアドレスは00EFFBDCです。
EAZY IDECの場合では
変数aのアドレスは0019FF54ですね。
変数aに格納される数値の値にかかわらず
変数aのアドレスは同じということになります。
ですが
Visual Studioの場合
変数aに5が代入されているときのビルド実行結果
変数aの値は5です。
変数aのアドレスは00EFFBDCです。
と
変数aに1が代入されているときのビルド実行結果
変数aの値は1です。
変数aのアドレスは00CFFC7Cです。
の時と
変数aのアドレスは違ってきています。
コンパイラがことなるので
違った命令がコンピュータに与えられているというわけです
この辺りはコンパイラの仕様の違いとなっています。
EAZY IDECの場合
この変数aはint型なので4バイトの容量をもち
その連続した4バイトのうちの
先頭の1バイトのアドレスが0019FF54となっています。
Visual Studioの場合
この変数aはint型なので4バイトの容量をもち
その連続した4バイトのうちの
先頭の1バイトのアドレスが00CFFC7Cとなっています。
それでは3つの変数a,b,cの変数宣言、初期化をおこなうと
そのアドレスはどのように表示されるでしょうか?
#include <stdio.h>
int main(void) {
int a = 5;
printf("変数aの値は%dです。\n", a);
printf("変数aのアドレスは%pです。\n", &a);
int b = 10000;
printf("変数bの値は%dです。\n", b);
printf("変数bのアドレスは%pです。\n", &b);
int c = 12;
printf("変数cの値は%dです。\n", c);
printf("変数cのアドレスは%pです。\n", &c);
return 0;
}
EAZY IDECの場合
コンパイル結果
変数aの値は5です。
変数aのアドレスは0019FF54です。
変数bの値は10000です。
変数bのアドレスは0019FF50です。
変数cの値は12です。
変数cのアドレスは0019FF4Cです。
アレサ「
3つの
変数a
変数b
変数c
を作製すると
その
変数a
変数b
変数c
に対応する3つのアドレスが存在することになります。
このときメモリ内では
0019FF54👈変数aと名づけられ管理されている4つのアドレス
0019FF53
0019FF52
0019FF51
0019FF50👈変数bと名づけられ管理されている4つのアドレス
0019FF4F
0019FF4E
0019FF4D
0019FF4C👈変数cと名づけられ管理されている4つのアドレス
0019FF4B
0019FF4A
0019FF49
と
仲良く
変数aの管理している4つのアドレス
と
変数bの管理している4つのアドレス
と
変数cの管理している4つのアドレス
が連続してならんでいます。
変数aよりあとに変数bを作製したのに
なぜか
変数bのアドレスの番号は
変数aのアドレスの番号よりちいさくなっています
つまり
下の図のように
新しい変数を作成するたびに
0019FF54👈変数aと名づけられ管理されている4つのアドレス
0019FF53
0019FF52
0019FF51
0019FF50👈変数bと名づけられ管理されている4つのアドレス
0019FF4F
0019FF4E
0019FF4D
0019FF4C👈変数cと名づけられ管理されている4つのアドレス
0019FF4B
0019FF4A
0019FF49
と
だんだん小さいアドレスのメモリが
新たに作成された変数に
割り当てられています。
この場合は
新しい変数を作成するたびに
新しい変数には
だんだん小さいアドレスのメモリが割り当てられていますが
場合によっては
これとは逆に
新しい変数を作成するたびに
0019FF4C👈変数aと名づけられ管理されている4つのアドレス
0019FF4D
0019FF4E
0019FF4F
0019FF50👈変数bと名づけられ管理されている4つのアドレス
0019FF51
0019FF52
0019FF53
0019FF54👈変数cと名づけられ管理されている4つのアドレス
0019FF55
0019FF56
0019FF57
と
だんだん数値の大きいアドレスのメモリが新たに作製される変数に
割り当てられることもあります。
ここでは
0019FF54👈変数aと名づけられ管理されている4つのアドレス
0019FF53
0019FF52
0019FF51
0019FF50👈変数bと名づけられ管理されている4つのアドレス
0019FF4F
0019FF4E
0019FF4D
0019FF4C👈変数cと名づけられ管理されている4つのアドレス
0019FF4B
0019FF4A
0019FF49
のように
だんだん数値の小さいアドレスのメモリが新たに作製される変数に
割り当てられているとします。
このとき
int型の変数aに格納される数値は
0019FF54👈
0019FF53👈変数aという名前で
0019FF52👈この4つのアドレスのメモリは管理されています
0019FF51👈
この4つのアドレス番号のついたメモリに格納されます。
この状態の
int型の変数aに数値1234567を格納するとしましょう。
数値1234567は2進数に変換されて
コンピュータのメモリに
2進数で
00000000000100101101011010000111(32ビット)
と格納されます
そのとき
2進数数値
00000000000100101101011010000111(32ビット)
は
0019FF54👈
0019FF53👈変数aという名前で
0019FF52👈この4つのアドレスのメモリは管理されています
0019FF51👈
のアドレス番号のついたメモリに
0019FF54のアドレス番号のついたメモリに10000111
0019FF53のアドレス番号のついたメモリに11010110
0019FF52のアドレス番号のついたメモリに00010010
0019FF51のアドレス番号のついたメモリに00000000
と格納されていきます
そのとき
0019FF54のアドレス番号のついたメモリに00000000
0019FF53のアドレス番号のついたメモリに00010010
0019FF52のアドレス番号のついたメモリに11010110
0019FF51のアドレス番号のついたメモリに10000111
ではなく
0019FF54のアドレス番号のついたメモリに10000111
0019FF53のアドレス番号のついたメモリに11010110
0019FF52のアドレス番号のついたメモリに00010010
0019FF51のアドレス番号のついたメモリに00000000
と格納されていきます。
つまり
2進数数値
00000000000100101101011010000111(32ビット)
の小さな位から8つずつ
0019FF54のアドレス番号のついたメモリに10000111
0019FF53のアドレス番号のついたメモリに11010110
0019FF52のアドレス番号のついたメモリに00010010
0019FF51のアドレス番号のついたメモリに00000000
格納されていきます。
次に
0019FF4C👈変数aと名づけられ管理されている4つのアドレス
0019FF4D
0019FF4E
0019FF4F
0019FF50👈変数bと名づけられ管理されている4つのアドレス
0019FF51
0019FF52
0019FF53
0019FF54👈変数cと名づけられ管理されている4つのアドレス
0019FF55
0019FF56
0019FF57
と
新たに作製される変数にだんだん数値の大きいアドレスのメモリが
割り当てられているとします。
この状態の
int型の変数aに数値1234567を格納するとしましょう。
数値1は2進数に変換されて
コンピュータのメモリに
2進数で
00000000000100101101011010000111(32ビット)
と格納されます
そのとき
2進数数値
00000000000100101101011010000111(32ビット)
は
0019FF4C👈変数aと名づけられ管理されている4つのアドレス
0019FF4D
0019FF4E
0019FF4F
のアドレス番号のついたメモリに
0019FF4Cのアドレス番号のついたメモリに10000111
0019FF4Dのアドレス番号のついたメモリに11010110
0019FF4Eのアドレス番号のついたメモリに00010010
0019FF4Fのアドレス番号のついたメモリに00000000
と格納されていきます
そのとき
0019FF4Cのアドレス番号のついたメモリに00000000
0019FF4Dのアドレス番号のついたメモリに00010010
0019FF4Eのアドレス番号のついたメモリに11010110
0019FF4Fのアドレス番号のついたメモリに10000111
ではなく
0019FF4Cのアドレス番号のついたメモリに10000111
0019FF4Dのアドレス番号のついたメモリに11010110
0019FF4Eのアドレス番号のついたメモリに00010010
0019FF4Fのアドレス番号のついたメモリに00000000
と格納されていきます。
つまり
2進数数値
00000000000100101101011010000111(32ビット)
の小さな位から8つずつ
0019FF4Cのアドレス番号のついたメモリに10000111
0019FF4Dのアドレス番号のついたメモリに11010110
0019FF4Eのアドレス番号のついたメモリに00010010
0019FF4Fのアドレス番号のついたメモリに00000000
と
格納されていきます。」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます