这段代码是实现定义的吗?

5
#include<stdio.h>

int main (void)
{
  int i=257;
  int *ptr=&i;

  printf("%d%d",*((char*)ptr),*((char*)ptr+1));
  return 0;
}

以上代码的输出是否是实现定义的,并且输出是否因为小端和大端机器而有所不同?

printf("%d%d",((char*)ptr)[0],((char*)ptr)[1]); 在我看来更易读。仅此而已。 - Patrick Schlüter
3个回答

8

是的。在运行时检测字节序的经典方法如下:

uint32_t var = 1;
uint8_t *ptr = (uint8_t*)&var;

if(*ptr) puts("Little Endian");
else puts("Big Endian");

尽管257 => 0x0101,但int类型很可能是32位的,这种情况下,在大端机器上会打印00,在小端机器上会打印11。


3

没错,它会。 我总是这样写,因为我从来不确定运算符的优先级:

*(((char*)ptr)+1)

为了实现你想要的更改,将格式字符串中的%d替换为%c


@tristopia:我发现对于那些不是数组的变量进行数组索引会使代码更难读懂。这只是为了证明在这一点上意见存在分歧。 - DevSolar
内存字符数组。特别是对于指向字符的指针,[]符号表示法总是更易读的,在我看来。 - Patrick Schlüter

2

是的,这将成为实现定义行为。

当您使用(char *)强制转换ptr并访问第一个内存位置时,将访问存储在内存中的第一个字节,这将取决于系统是大端还是小端系统。

在调用printf函数之前,参数将被评估。如上所述,这种评估将在不同的系统中获得不同的值。因此,它是实现定义的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接