とても簡単です。私が持っているとしましょう:
char x = -1;
それから記憶に、私は(おそらく?)
11111111
(01234567)
だから私の質問は、私が書く場合、私&x
はビット0またはビット7のアドレスを取り戻します、そしてこれは最上位ビットですか、それとも最下位ビットですか?
32ビット整数の場合はどうですか?
メモリアドレスはビットアドレスではなくバイトアドレスです。つまり、アーキテクチャのタイプ(ビッグエンディアンまたはリトルエンディアン)に応じて、特定のビットではなく最上位バイトまたは最下位バイトを取得します。
WhozCraigのおかげで、そうです。変数はaなので、またはバイト自体char
のアドレスです。char
ビットは個別にアドレス指定できません。アドレス可能な最小のメモリ単位はバイトです。したがって、の場合、char
そのアドレスを取得すると、そのバイトへのポインタを取得します。そのバイト内の特定のビットではなく、バイト全体です。そのバイト内の個々のビットにアクセスする唯一の方法は、マスキングやシフトなどのビット単位の演算を使用することです。
32ビット整数の場合、4バイトを個別にアドレス指定できます。その場合、そのアドレスが最下位バイトと最上位バイトのどちらのアドレスであるかは、アーキテクチャのエンディアンに依存します。ビッグエンディアンシステムでは、アドレスは最上位バイトのアドレスになります。リトルエンディアンシステムでは、最下位バイトになります。
uint32_t n = 0x11223344;
uint8_t *p = (uint8_t *) &n;
if (*p == 0x11) {
// big endian
}
else if (*p == 0x44) {
// little endian
}
Cでは、メモリはバイトアドレス可能であり、charの解釈もバイトです。charは1バイトで構成され、たとえばintは4バイトで構成されているためchar x;
、&x;
文字のアドレスはビット/バイトではありません。youeが取るint i
場合&i
は、intオブジェクトのアドレスです。変数/完全なオブジェクトを更新しています。
メモリアドレス方式では、各バイトが記憶されます(アドレスが格納されます)。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+----+----+----+---+---+----+----+----+----+----+----+---+---+----+----+----+
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 0 | 1 | 1 | 2 | 3 | 4 | 5 | 6 |
+----+----+----+---+---+----+----+----+----+----+----+---+---+----+----+----+
^ ^
| |
+----+----+ | |
| add1 |--| |
+----+----+ |
| add2 |-----------------------------|
+----+----+
この図addr1
では、charの場合はビット0〜7をaddr2
表し、ビット8〜15を表します。つまり、ofcouserビットには番号(0〜15)を付けることができますが、効率的なのは、一度に1バイトにアクセスすることです。また、1ビットの情報が必要な場合でも、完全なバイトを読み取るのは良いことです。
この質問を読んだことがありますか:メモリアドレスでない場合、Cポインタとは正確には何ですか?。Cについて質問する場合:ポインター値は、ある種のIDまたはハンドル、あるいは複数のIDの組み合わせにすることができます。
つまり、Cでの参照
&x
にすぎません。1バイトを参照し、4バイトを参照します。char
int
さらに、
メモリはバイトアドレス可能ですが、幸いなことに、ビット単位の演算子とビット単位の構造を考えたビットレベルでアクセスできます。
アドレスはメモリ内のバイトを参照します。ビットには独自の個別のアドレスはありません。
そうは言っても、値が1バイトより大きいと仮定しましょう。
long x = -1;
その場合、値は32ビットまたは4バイトを占めます。これらのビットが最上位バイトを最初に格納するか、最下位バイトを最初に格納するかは、関連するハードウェアによって異なります。具体的には、ハードウェアがリトルエンディアンかビッグエンディアンかによって異なります。いずれにせよ、x
上記の例ののアドレスは、メモリ内の最初の(最下位の)バイトのアドレスになるため、次のようになります。
char p[4] = (char*)&x;
次にp[0]
、最初のバイト、p[1]
2番目のバイトというようになります。エンディアンは、最初のバイトが最上位か最下位かを示します。
アドレスはバイト全体を参照するため、ビットのアドレスについて尋ねるのは意味がありません。最近のほとんどのコンピューターはリトルエンディアンであるため(この質問を参照)、最下位バイトのアドレスを取得する必要があります。
ほとんどの人が指摘しているように、メモリはバイトアドレス可能であり、ビットには個別のアドレスがありません。それでも、ビットにアクセス(ビットへの読み取り/書き込み)する場合は、ビット単位の論理演算でビットシフト演算を使用できます。