c-big-endian系统上的地址运算符



许多人都知道下面的例子来判断系统是小端还是大端:

#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;
}

我想问一下接线员的地址;,在big-endian和little-endian系统上的工作原理相同。当指向对象的指针转换为指向字符类型的指针时,在这两种情况下,它都会指向对象的最低寻址字节吗?

我的担忧如下。假设你没有像上面那样进行类型转换,并且假设一个big-endian系统向你返回最高位地址(基本上是int的起始位置(,那么这段代码仍然会打印";Little endian"尽管您实际处理的是一个big-endian系统。

对此发表任何评论都会非常有帮助。提前谢谢:D。

分配char *c = &i;违反了C 2018 6.5.16.1 1中的约束。这段话说"以下其中一项将成立",选项列表中最接近的匹配项是:

  • 左操作数具有原子、限定或非限定指针类型,并且(考虑到左操作数在左值转换后的类型(两个操作数都是指向兼容类型的限定或不限定版本的指针,并且左边指向的类型具有右边指向的类型的所有限定符

char *int *不兼容,因此分配未通过约束。

也就是说,如果编译器确实接受了这个语句(它可能接受,因为C标准允许扩展(,并将右边的指针转换为左边的类型(正如赋值所应该的那样(,那么结果应该是指向对象的最低寻址字节的指针,而不考虑端序。根据C 2018 6.3.2.3 7:,指针转换是正常的

…当指向对象的指针转换为指向字符类型的指针时,结果指向对象的最低寻址字节。

第二个示例将向您发出编译器警告,如果没有强制转换,则赋值无效。如果您忽略警告,您可能会得到相同的结果,或者不会,就像在尝试未定义的行为时一样。

最新更新