C 如何解释*((字符*)&a)
我看到了一种了解平台端性的方法是这个程序,但我不理解它C 如何解释*((字符*)&a),c,endianness,C,Endianness,我看到了一种了解平台端性的方法是这个程序,但我不理解它 #include <stdio.h> int main(void) { int a = 1; if( *( (char*)&a ) == 1) printf("Little Endian\n"); else printf("Big Endian\n"); system("PAUSE"); return 0; } #包括 内部主(空) { INTA=1; 如果(*((char*)&a)==1)pr
#include <stdio.h>
int main(void)
{
int a = 1;
if( *( (char*)&a ) == 1) printf("Little Endian\n");
else printf("Big Endian\n");
system("PAUSE");
return 0;
}
#包括
内部主(空)
{
INTA=1;
如果(*((char*)&a)==1)printf(“小端点”\n);
else printf(“Big-Endian\n”);
系统(“暂停”);
返回0;
}
考试做什么
a的地址
char*
char*
,这将为您提供int
1
,则它是little endian。否则-大假设
sizeof(int)==4
,则:
|........||........||........||........| <- 4bytes, 8 bits each for the int a
| byte#1 || byte#2 || byte#3 || byte#4 |
int
几乎总是大于一个字节,并且通常跟踪体系结构的字大小。例如,32位体系结构可能具有32位整数。因此,给定典型的32位整数,4个字节的布局可能是:
00000000 00000000 00000000 00000001
或先使用最低有效字节:
00000001 00000000 00000000 00000000
char*是一个字节,所以如果我们把这个地址转换成char*我们也会得到上面的第一个字节
00000000
或
因此,通过检查第一个字节,我们可以确定体系结构的终结性。程序只是将
int
占用的空间重新解释为char
s数组,并假设1
作为int将存储为一系列字节,其最低顺序为值为1的字节,剩下的是0
因此,如果最低阶字节首先出现,那么平台就是小端,否则就是大端
这些假设可能不适用于现有的每个平台。这只适用于
sizeof(int)>1
的平台。例如,我们假设它是2,并且achar
是8位
基本上,对于小尾端,数字1作为16位整数如下所示:
00000001 00000000
但对于big endian,它是:
00000000 00000001
因此,首先代码设置a=1
,然后:
*( (char*)&a ) == 1)
获取a
的地址,将其视为指向char
的指针,并取消对其的引用。因此:
- 如果
包含一个小的endian整数,那么将得到a
部分,当被解释为00000001
char
- 如果
包含一个大端整数,您将得到a
。检查00000000
将失败,代码将假定平台为big-endian==1
int16\u t
和int8\u t
而不是int
和char
来改进此代码。或者更好,只需检查htons(1)!=1
- 您可以将整数视为4字节的数组(在大多数平台上)。小端整数的值为
,大端整数的值为01 00
李>00 00 01
- 通过执行
可以获得该数组的第一个元素的地址&a
- 表达式
将其强制转换为单个字节的地址(char*)&a
- 最后,
获取该地址包含的值*((char*)&a)
00000001 -->Address 0x100
00000000 -->Address 0x101
00000000 -->Address 0x102
00000000 -->Address 0x103
分析上述演员阵容:-
同样&a=0x100
,因此<代码> *((char *)0x100)< /代码>意味着考虑一个字节(因为4字节加载int),所以在0x100的数据将被引用。
*( (char*)&a ) == 1 => (*0x100 ==1) that is 1==1 and so true,implying its little endian.
下面是它的分解方式:
a -- given the variable a
&a -- take its address; type of the expression is int *
(char *)&a -- cast the pointer expression from type int * to type char *
*((char *)&a) -- dereference the pointer expression
*((char *)&a) == 1 -- and compare it to 1
基本上,cast
(char*)&a
将表达式&a
的类型从指向int
的指针转换为指向char
的指针;当我们将解引用运算符应用于结果时,它会给出存储在a
的第一个字节中的值 @DonalFellows可能重复不确定是否在dup上,此问题已找到代码,并想知道它是如何工作的。潜在的dup只是问一个关于如何检测endianness的一般问题。可能的重复也请注意,结果不是很可靠,因为big endian和little endian不是唯一的选项,一些疯狂的硬件会以不同的方式进行整数和浮点运算,一些CPU可以在运行时进行配置。请注意,这张漂亮的图形颠覆了尾端的感觉:它移动了计算指针指向的明显位置,而不是对整数的字节进行重新排序。您似乎翻转了字节中的位顺序以及整数中的字节顺序!非常非常感谢,我可能按下了home按钮而不是end:)int
在64位Linux上是32位的。@JamesMcLaughlin我不知道,谢谢。我软化了语言。C89 2.2.4.2和C99 5.2.4.2.1要求sizeof(int)>1
,通过要求int_MIN
和int_MAX
的值超过char
的容量,所以尽管您的警告是正确的,但它却是完全正确的。更有趣的是,这段代码在不是big-endian或small-endian的middle-endian系统上工作不正确。(尽管这种系统的频率很小,如果你不得不问它们是什么,你可能不必关心它们。:-)
00000000 -->Address 0x100
00000000 -->Address 0x101
00000000 -->Address 0x102
00000001 -->Address 0x103
00000001 -->Address 0x100
00000000 -->Address 0x101
00000000 -->Address 0x102
00000000 -->Address 0x103
*( (char*)&a ) == 1 => (*0x100 ==1) that is 1==1 and so true,implying its little endian.
a -- given the variable a
&a -- take its address; type of the expression is int *
(char *)&a -- cast the pointer expression from type int * to type char *
*((char *)&a) -- dereference the pointer expression
*((char *)&a) == 1 -- and compare it to 1