c++ 有人能为我解释一下这个“字节序”函数吗?

xfb7svmp  于 2022-12-05  发布在  其他
关注(0)|答案(6)|浏览(157)

编写一个程序来确定计算机是big-endian还是little-endian。

bool endianness() {
     int i = 1;
     char *ptr;
     ptr  = (char*) &i;
     return (*ptr);
}

我有上面的函数,我不太明白,ptr =(char*)&i,我认为它是指向一个字符的指针,我所在的地址,如果一个int是4个字节,比如ABCD,当你在上面调用char* 的时候,我们说的是A还是D,为什么?
谁能更详细地解释一下吗?谢谢。
所以具体来说,ptr =(char*)&i;当您将它转换为char* 时,会得到&i的哪一部分?

jv4diomz

jv4diomz1#

如果你有一个小字节序的体系结构,i在内存中看起来像这样(十六进制):

01 00 00 00
^

如果你有一个big-endian体系结构,i在内存中看起来像这样(十六进制):

00 00 00 01
^

char*的强制转换为int的第一个字节提供了一个指针(我已经用^指向了它),因此如果您使用的是小端体系结构,则char*指向的值将是01;如果您使用的是大端体系结构,则00指向的值将是00
返回该值时,0将转换为false1将转换为true。因此,如果您的体系结构为小端优先,则此函数将返回true,如果您的体系结构为大端优先,则返回false

vlf7wbxs

vlf7wbxs2#

ptr是否指向字节A或D取决于机器的字节序。ptr指向整数中位于最低地址的字节(其他字节将位于ptr+1,...)。
在big-endian机器上,整数的 most 有效字节(即0x00)将存储在此最低地址,因此函数将返回零。
在litte-endian机器上则相反,整数的 least significant字节(0x01)将存储在最低地址,因此在这种情况下函数将返回1。

jqjz2hbq

jqjz2hbq3#

这是使用punning类型将整数作为字符数组进行访问。如果机器是big endian,则这将是major字节,其值为0;但如果机器是little endian,则这将是minor字节,其值为1。(不是将i作为单个整数进行访问,而是将同一内存作为四个字符的数组进行访问)。

yvt65v4c

yvt65v4c4#

*((char*)&i)是字节A还是字节D是字节序的核心。在小字节序系统中,整数0x 41424344在内存中的布局为:0x 44 43 42 41(最低有效字节优先;在ASCII中,这是“DCBA”)。在大端序系统中,它将被布局为:0x 41 42 43 44.指向该整数的指针将保存第一个字节的地址。将该指针视为整数指针,您将得到整个整数。将该指针视为字符指针,您将得到第一个字节,因为这是字符的大小。

dxxyhpgq

dxxyhpgq5#

假设int是4个字节(在C语言中可能不是)。这个假设只是为了简化这个例子...
您可以分别查看这4个字节。
char是一个字节,所以它查看的是4字节缓冲区的第一个字节。
如果第一个字节是非0,那么它告诉你最低位是否包含在第一个字节中。
我随机选择了数字42,以避免混淆值1的任何特殊含义。

int num = 42;
if(*(char *)&num == 42)
{
      printf("\nLittle-Endian\n");
}
else
{
      printf("Big-Endian\n");
}

明细:

int num = 42; 
//memory of the 4 bytes is either: (where each byte is 0 to 255)
//1) 0 0 0 42
//2) 42 0 0 0

char*p = #/*Cast the int pointer to a char pointer, pointing to the first byte*/
bool firstByteOf4Is42 = *p == 42;/*Checks to make sure the first byte is 1.*/

//Advance to the 2nd byte
++p;
assert(*p == 0);

//Advance to the 3rd byte
++p;
assert(*p == 0);

//Advance to the 4th byte
++p;
bool lastByteOf4Is42 = *p == 42;
assert(firstByteOf4Is42 == !lastByteOf4Is42);

如果firstByteOf4Is42为真,则为小端字节序。如果lastByteOf4Is42为真,则为大端字节序。

e5nqia27

e5nqia276#

当然,让我们来看看:

bool endianness() {
     int i = 1; //This is 0x1:
     char *ptr;
     ptr  = (char*) &i; //pointer to 0001
     return (*ptr);
}

如果机器是Little endian,那么 *ptr中的数据将是0000 0001。
如果机器是Big Endian,则数据将被反转,即i将为

i = 0000 0000 0000 0001 0000 0000 0000 0000

因此,*ptr将保持0x0
最后,return *ptr等效于

if (*ptr = 0x1 ) //little endian

else //big endian

相关问题