例えば、int foo[] = {0, 1, 2};と初期化したとき、&foo[0]は0x00E4だったとします。
その場合、&foo[1]は0x00E8と思いますが、ここがいまいち腑に落ちていません。
すなわち、アドレスを1進めることは1ビットではなく1バイト進めることになっていると思われますが、まずはそのような認識でよろしいでしょうか。
そして、メモリを説明する際は、よくハコのようなイメージが使用されると思うのですが、
アドレスを1進めることはそのハコにおいては8進めることになっているという認識でよろしいでしょうか。
すなわち、ハコとしては当然ビット単位で存在しているが、アドレスとしては最小単位をバイトとして定義しているため、アドレスとしては表示されないだけで目に見えないハコが隙間に存在しているというイメージでよろしいでしょうか。
1バイトより小さな型が存在しない?のは、アドレスの最小単位をバイトとして定義しているためでしょうか。
また、そのハコを1バイト単位ではなく1ビット単位で制御するような方法?もあったりするのでしょうか。
初歩的な質問で申し訳ございません。
また、訳の分からないことを言っているかもしれませんが、上手に調べられなかったためご教示していただけると助かります。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答7件
0
アドレスを1進めることは1ビットではなく1バイト進めることになっていると思われますが、まずはそのような認識でよろしいでしょうか。
違います。
メモリを説明する際は、よくハコのようなイメージが使用されると思うのですが、アドレスを1進めることはそのハコにおいては8進めることになっているという認識でよろしいでしょうか。
違いますが 、惜しい。
アドレスを1増やすということは、ハコ1つ分進めることに相当します。
そして、そのハコのサイズは、変数の型によって違うので、実際に変化するメモリアドレスの幅は、変数の型によって変わるのです。
int が 8ビットであれば、箱のサイズは8ビットであり、ポインタは8ビット進みます。
int が32ビットであれば、32ビット進みます。
投稿2025/02/11 06:09
編集2025/02/11 06:27総合スコア14039
0
すなわち、アドレスを1進めることは1ビットではなく1バイト進めることになっていると思われますが、まずはそのような認識でよろしいでしょうか。
それでいいです。
が、int型の変数のサイズは、1ではありません
で、foo[0]からfoo[1]ってのは、1バイト進めるという意味でもありません
投稿2025/02/11 05:17
編集2025/02/11 05:21総合スコア88126
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
&foo[0]は0x00E4だったとします。
その場合、&foo[1]は0x00E8と思います
いまの世の中の主流はそうなのですが、必ずそうなるわけではないことに注意が必要です。いわゆる8bitとか16bitCPUと呼ばれるものでは、intは16bit, 2byteであることが多いです。C言語的には、intは少なくとも-32767~32767の値を保存できること、としか決まっていません(さすがにintが8bitというのはC言語では許されない)。
アドレスを1進めることは1ビットではなく1バイト進めることになっていると思われますが、まずはそのような認識でよろしいでしょうか。
それはOKです。
アドレスを1進めることはそのハコにおいては8進めることになっているという認識でよろしいでしょうか
これも、世の99.99999%(個人の感想です)ではよろしいですが、そうでないモノは確実に存在します。アナデバのDSP、と言って分からない人が触れる機会はないでしょうが、こいつには32bitが1byteというモードが存在します。
ハコとしては当然ビット単位で存在しているが、アドレスとしては最小単位をバイトとして定義している
物理的にはビットは存在しているけれど、アドレスが振られるのはbitではなくバイト単位で、その単位でしかアクセスする手段は用意されていないのが普通、という説明がよいのかな。アドレスを定義、というのはちょっと違う気がする。大抵は物理的にそういう構造になっているので。
ハコを1バイト単位ではなく1ビット単位で制御するような方法
構造体のビットフィールド(構造体中のmビットをグループ扱いする仕組み。m=1ももちろんあり)がそれに相当することになるかと思います。余程特殊なハードとそれ用のC言語を作成するのでない限り、アクセス自体はバイト単位で行って、内部的にビット演算によってビット単位(グループ)で操作した結果を得ることになるでしょう。もちろん、それに相当する操作を自分で行うこともできます。ビットマスクとかいう言葉で調べられるかしら。
投稿2025/02/11 13:51
総合スコア7707
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
ベストアンサー
ハコとしては当然ビット単位で存在しているが、アドレスとしては最小単位をバイトとして定義しているため、アドレスとしては表示されないだけで目に見えないハコが隙間に存在しているというイメージでよろしいでしょうか。
そのたとえで使われた「ハコ」とはなんぞや?と言うことになるかと思います。
普通のCPUは、メモリーを1bit単位では読み書きできません。メモリー中の位置を示す「メモリーアドレス」は1byte単位です。
メモリーの中の1bitだけを書き換えたくても、それだけを変更できません。(少なくとも)1byteをメモリーから読み出して希望位置の1bitだけ書き換えて、その結果をまた同じ場所の1byteに上書きします。
機械語命令的には、①読み出し②1bit書き換え③書き込みの3命令かも知れないし、1命令で出来るCPUがあるかも知れません(実際あった)。後者の場合でも機械語で1命令でも内部的には3ステップです。
理由はメモリー周りのハードウェアがbit単位でアクセスできるようになっていないからです。
もちろん、そういうCPUとハードウェアを設計して作るのは可能だと思います。「演算処理の中で、1bit単位の演算処理が大多数で、8bit単位~64bit単位での演算は少ない」とかいうような想像しにくいケースでない限り効率が悪そうですね。
ということで、「機械語レベルでアドレスを+1する」は、「1バイト進む」です。
Cのポインターや配列添え字の場合だと、+1 は 「その型の1つ分のバイト数だけ進む」、つまりint
が4byteだとint
型へのポインターを+1すると、機械語レベルでは+4されます。
そのたとえで使われた「ハコ」とはなんぞや?と言うことになるかと思います。
の続きを書くと、「(今の一般的な)コンピューターのメモリーの説明」で使われたのなら1byteとか4byteとかの「1byteの整数倍」の大きさのハコになると思います。そうではなくて、「抽象的なデータの保管の仕方の説明」で使われたのなら「1bitの整数倍」のハコもあり得るかと思います。「真偽値の保管には1bitあれば十分ですよね?」は「はい」です。
ただし、メモリーの話と絡めると、Cだとstruct
でビット単位で定義できるのはご存じかと思いますが、struct { unsigned char a:1; } X;
と宣言した変数X
はメモリー上で1byteの場所を取ります。
投稿2025/02/11 12:34
総合スコア86160
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

0
アドレスの計算は内部的にはデータサイズに対する掛け算で表されます
int
のデータサイズは4byte
なので、例えばint配列
の場合、今回のfoo
のケースではfoo[0]->foo[2]
の移動量が4*2=8byte
となります
またC++
ではインスタンスのメンバとして1byte
以下のサイズのフィールド領域を定義できます
#include<stdio.h> struct A{ unsigned char c:3=0; //3bit領域 }; int main(void){ printf("%lld,sizeof(A)); }
1
データサイズはbit単位では表されないため、メモリ管理の都合からプログラム上ではこのクラスのデータサイズは1byte
となりますが、内部のメンバには1byte
以下のサイズが割り当てられます
このように、ユーザー定義型によってbit単位のデータサイズを考えられます
最もC++
以外で同様の操作が可能な言語があるかは判りません
ちなみに、1byte=8bit
は慣例的な取り決めであって絶対ではありません
8bit
というサイズにはオクテッド(octed)
という単位が与えられています
よって厳密には1byte≒1octed=8bit
となります
またアドレスも同様に1アドレス=1byte
とは限りません
かつて情報処理技術者試験用に制定されたCOMET
という仮想的なマシンでは1アドレス=16bit
と定義されていました
このように厳密な定義には齟齬があるものの、現代のコンピュータでは1アドレス=1byte=8bit
がほぼ当たり前となっています
なのでこれらを知っておく必要はありませんがアドレスの足し引きとはデータサイズの掛け算であることは意識しておくと良いでしょう
投稿2025/02/11 10:11
編集2025/02/11 10:25総合スコア93
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
C言語で決まっているのは、charが1byteのみです。あとは環境依存です。
質問者さんの環境ではintが4byteなので、&foo[0]のアドレスが0x00E4なら、&foo[1]のアドレスは4足した0x00E8になります。
アドレスはbyte単位なので、1byte=1個の箱で表現します。
これに対して、ビット演算の際は、1bit=1個の箱で表現します。
両者が混在した絵を描く場面は、考えづらいですね。
なので「目に見えないハコが隙間に存在している」なんて考えなくてよいと思います。
投稿2025/02/11 08:36
総合スコア1255
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
バイトとかビットとか、メモリサイズが依存しているのは型の方です。
intが4バイトなら次のアドレスは元のアドレスに4バイト足した値になります。
charが1バイトなら、次のアドレスとしては元のアドレスに1バイト足した値になります。
C言語のポインタが喜ばれるのは、機械語の時はこのなんバイト進めたところを次の領域とするのかをプログラマが指定したところを型という制約により、ある種自動的に指定できるところらしいです。
ハコの認識としては正しそうに見えますが、
正直いってExcelのセルをイメージした方が理解が容易だと思います。
1つのセルが1ビットだとしたら、そこに0or1しか入らないので、これが8個連続していたら2の8乗だけのデータが格納でき、その中身によってそれがなんであるか?を2の8乗分だけ表せます。
C言語に1バイトより小さい型が存在しない理由はよく知りませんが、
概念的には1ビット型で0 or 1だけを示すことも可能でしょう。
投稿2025/02/11 06:25
編集2025/02/11 06:26総合スコア524
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。