0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

変数とは(低レイヤーの理解)

0
Posted at

今回は変数について、深堀してくので見てってください。
低レイヤーのために。

メモリアドレスとは?

 まず、メモリは連続した大量の箱が並んでいます。その箱は1バイトごとに区切られてその箱の位置を表す アドレス が定義されています。
下の表では1段目がアドレス、2段目が1バイト分のデータです。

0x0000 0x0001 0x0002 0x0003 0x0004 0x0005 0x0006 0x0007
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

PCなどでは、メモリ16GBであれば、16ギガ個のアドレスがある感じです。

例えばint型であれば4バイトなので、メモリの箱を4つ使って値を保持していますね。
試しに 0x0002番~0x0005番の4バイトに1億の値を保存した場合 どうなるか...

0x0000 0x0001 0x0002 0x0003 0x0004 0x0005 0x0006 0x0007
0x00 0x00 0x05 0xF5 0xE1 0x00 0x00 0x00

変数は箱ではない

 先ほどのメモリについてを踏まえたうえで、変数はこの メモリアドレス に名前を付けたものプログラマーがわかりやすく名前を付けたものです。
それも使っているすべてのメモリアドレスではなく、開始地点のメモリアドレスに名前を付ける感じです。

先ほどの1億のint型、このようにコードがある場合、変数numは0x0002のことを指します。

int num = 100000000;
0x0000 0x0001 変数num 0x0003 0x0004 0x0005 0x0006 0x0007
0x00 0x00 0x05 0xF5 0xE1 0x00 0x00 0x00

変数は箱ではなく、メモリアドレスに名前を付けたもの

型は "読み方のルール"

ここまでで「変数はメモリアドレスに付けた名前」という理解ができたと思います。
では 型(int, char, float など) は何をしているのでしょうか?

結論から言うと、 型は「そのアドレスから何バイトを、どう解釈するか」 を示しています。
先ほどのメモリ状態をもう一度見ます。

0x0000 0x0001 0x0002 0x0003 0x0004 0x0005 0x0006 0x0007
0x00 0x00 0x05 0xF5 0xE1 0x00 0x00 0x00

この0x0002をint型で読むと 0x0002~0x0006 の4バイトをまとめて読み、
int型0x0002番 → 100000000
ですが、もし、0x0002をchar型で読むと 0x0002 の1バイトを読むことで、
char型0x0002番 → "5"
といった感じで値が読み取れます。

大事なのは メモリの中身は同じでも、型が違うと「見える値」が変わる ということ。

配列は変数の並び

配列は先ほどの変数が並びます。
メモリアドレスが長くなるので、4バイトでまとめたら下記

0x0000 0x0004 0x0008 0x000C 0x0010 0x0014 0x0018 0x001C
0 0 0 0 0 0 0 0

このコードのように配列を定義した場合、numの指すアドレスが0x0004であれば...

int num[4] = {10, 20, 30, 40};
0x0000 0x0004 0x0008 0x000C 0x0010 0x0014 0x0018 0x001C
0 10 20 30 40 0 0 0

言語ごとの違い

共通の事実

  • どの言語でも最終的には、
  • メモリは アドレス付きの連続領域
  • CPUは アドレスを指定して読み書き

という点は同じです。
違うのは「プログラマがどこまで直接触れるか」 です。

C言語:ほぼ制限なし

特徴

  • メモリアドレスをそのまま扱える
  • 型変換(キャスト)が自由
  • 境界チェックなし
    低レイヤー部分
  • 「配列」「変数」という概念は ほぼ存在しない
  • あるのは アドレス + 読み方(型)

👉 OS・組み込み・ドライバ向き
👉 人間が責任を負う前提の言語

C++:自由だが「自己防衛用の仕組み」が増えた

特徴

  • Cと同じことができる
  • しかし std::array, std::vector など安全な抽象がある

低レイヤー部分

  • 危険な操作は可能
  • だが「安全に書く道」も用意されている

👉 パフォーマンスと安全性の折衷

Rust:メモリは触れるが「条件付き」

特徴

  • 配列境界チェックあり
  • 生ポインタは unsafe が必要
  • 所有権・借用で書き換えを制御

低レイヤー部分

  • 安全な世界と危険な世界が明確に分離
  • 「壊すなら、ここから先は自己責任」と明示される

👉 現代的な低レイヤー言語

Java / C#:メモリを「概念として」扱う

特徴

  • アドレスを直接扱えない
  • 配列は必ず境界チェック
  • GCがメモリ管理

低レイヤー部分

  • プログラマは アドレスの存在を忘れてよい
  • 代わりに、細かい制御はできない

👉 業務・安全・生産性重視

Python / JavaScript:変数は「箱ですらない」

特徴

  • 変数は参照
  • 配列(list)は実体ではなくオブジェクト
  • メモリ配置は言語処理系依存

低レイヤー部分

  • 「連続メモリ」という保証すらない
  • CPUキャッシュ効率などは 完全にブラックボックス

👉 低レイヤー理解は概念止まり

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?