许多人都知道以下示例,以了解系统是小端还是大端:
#include <stdio.h>
int main()
{
unsigned int i = 1;
char *c = (char*)&i;
if (*c)
printf("Little endian");
else
printf("Big endian");
getchar();
return 0;
}
但是,我想知道以下代码是否仍然有效并且可以正常工作:
#include <stdio.h>
int main()
{
unsigned int i = 1;
char *c = &i;
if (*c)
printf("Little endian");
else
printf("Big endian");
getchar();
return 0;
}
这基本上是关于在大字节序系统上如何解释地址运算符&的问题。
假设您不执行上述类型转换,并且还假设一个大字节序系统将向您返回最高位地址(基本上是int的起始位置),那么尽管您已经执行了以下操作,但这段代码仍将显示“ Little endian”真正处理大型字节序系统。
任何对此的评论将非常有帮助。预先谢谢你:D。
答案 0 :(得分:3)
赋值char *c = &i;
违反了C 2018 6.5.16.1 1中的约束。该段显示“以下内容之一将成立”,并且选项列表中最接近的匹配项是:
char *
和int *
不兼容,因此分配没有约束。
也就是说,如果编译器确实接受了该语句(因为C标准允许扩展),并且可以将右侧的指针转换为左侧的类型(如应分配的那样),则结果应为指针不管字节序如何,都将保留到对象的最低寻址字节。对于按照C 2018 6.3.2.3 7进行的指针转换,这是正常的:
…当将对象的指针转换为字符类型的指针时,结果指向该对象的最低寻址字节。
答案 1 :(得分:-1)
第二个示例将向您提供一个编译器警告,如果不进行强制转换,则该分配无效。 如果忽略该警告,则尝试尝试未定义的行为时,您可能会始终获得相同的结果。