15

次のコードがある場合:

int i = 5;
void * ptr = &i;
printf("%p", ptr);

i の LSB アドレスまたは MSB を取得しますか?
プラットフォーム間で異なる動作をしますか?
ここで C と C++ に違いはありますか?

4

6 に答える 6

21

intのサイズが 4 バイトであることを考慮してください。常に&iこれらの 4 バイトの最初のアドレスを提供します。

アーキテクチャがリトル エンディアンの場合、下位アドレスの LSB は次のようになります。

        +-----+------+------+------+
住所 | 1000 | 1001 | 1002 | 1003 |
        +-----+------+------+------+
値 | 5 | 0 | 0 | 0 |
        +-----+------+------+------+

アーキテクチャがビッグ エンディアンの場合、下位アドレスの MSB は次のようになります。

        +-----+------+------+------+
住所 | 1000 | 1001 | 1002 | 1003 |
        +-----+------+------+------+
値 | 0 | 0 | 0 | 5 |
        +-----+------+------+------+

リトルエンディアンの場合&iは LSB アドレスを指定し、ビッグ エンディアンの場合は MSB アドレスを指定します。ii

混合エンディアン モードでも、タスクごとにリトルエンディアンまたはビッグ エンディアンが動的に選択されます。

以下のロジックは、エンディアンを示します

int i = 5; 
void * ptr = &i; 
char * ch = (char *) ptr;

printf("%p", ptr); 
if (5 == (*ch))
    printf("\nlittle endian\n");
else
    printf("\nbig endian\n");

この動作は、 と の両方で同じですcc++

于 2012-08-17T11:01:28.970 に答える
11

i の LSB アドレスまたは MSB を取得しますか?

これはプラットフォームに依存します。プラットフォームのエンディアンに応じて MSB または LSB になる可能性がある最下位のアドレス バイトになります。

これは標準に直接書かれていませんが、これはセクション 6.3.2.3.7 で暗示されているものです:

オブジェクトへのポインターが文字型へのポインターに変換されると、結果はオブジェクトの最下位アドレスのバイトを指します。


プラットフォーム間で異なる動作をしますか?

はい


ここで c と c++ に違いはありますか?

いいえ: C と C++ の両方でプラットフォームに依存します。

于 2012-08-16T10:41:48.627 に答える
8

プラットフォームのエンディアンに依存します。リトルエンディアン プラットフォームの場合は LSB へのポインタを取得し、ビッグ エンディアン プラットフォームの場合は MSB をポイントします。混合エンディアンのプラットフォームもいくつかあります。その場合、神があなたの魂を憐れんでくださるかもしれませんが、コンパイラ/CPUの特定のドキュメントを確認してください。

それでも、実行時に簡単なチェックを実行できます。

uint32_t i=0x01020304;
char le[4]={4, 3, 2, 1};
char be[4]={1, 2, 3, 4};
if(memcmp(&i, le, 4)==0)
    puts("Little endian");
else if(memcmp(&i, be, 4)==0)
    puts("Big endian");
else
    puts("Mixed endian");

ちなみに、ポインターを出力するには%p、 ではなくプレースホルダーを使用する必要があります%d

于 2012-08-16T10:42:25.550 に答える
6

ptr は、整数オブジェクトの開始バイトのアドレスを格納します。これが最上位バイトまたは最下位バイトのどちらに格納されるかは、プラットフォームによって異なります。一部の奇妙なプラットフォームでは、混合エンディアンを使用することさえあります。その場合、MSB でも LSB でもありません。

その点では、C と C++ の間に違いはありません。

于 2012-08-16T10:42:19.387 に答える
3

それが指しているのは、VC++ 2010 と Digital Mars の MSB です。しかし、それはエンディアンに関連しています。

この質問の回答は、あなたにいくつかの情報を提供します: Detecting endianness in a C++ programmatically .

ここで、ユーザー「なし」は次のように述べています。

#define BIG_ENDIAN      0
#define LITTLE_ENDIAN   1
 int TestByteOrder()
{
   short int word = 0x0001;
   char *byte = (char *) &word;
   return(byte[0] ? LITTLE_ENDIAN : BIG_ENDIAN);
}

これにより、いくつかのエンディアン情報が得られます

于 2012-08-16T10:42:37.750 に答える
1

i の LSB アドレス、または MSB を取得しますか?

機種やOSによって異なります。ビッグ エンディアンのマシンと OS では MSB を取得し、リトル エンディアンのマシンと OS では LSB を取得します。

Windows は常にリトル エンディアンです。x86 上の Linux/Unix のすべての (ほとんどの?) フレーバーはリトル エンディアンです。Motorola マシン上の Linux/Unix はビッグ エンディアンです。x86 マシン上の Mac OS はリトル エンディアンです。PowerPC マシンではビッグ エンディアンです。

プラットフォーム間で動作が異なるのですか?はい、そうなります。

ここにcとc ++の違いはありますか? おそらくそうではありません。

于 2012-08-16T10:58:43.647 に答える