C语言中的指针增量

4

请看下面的代码:

unsigned short i;
unsigned short a;
unsigned char *pInput = (unsigned char *)&i;

pInput[0] = 0xDE;
pInput[1] = 0x01;

a = ((unsigned short)(*pInput++)) << 8 | ((unsigned short)(*pInput++));

为什么a的值是0xDEDE而不是0xDE01?

1
简而言之(除其他错误外),没有保证左侧的 pInput++ 先执行,右侧的 pInput++ 后执行。换句话说,在同一表达式中修改了两次 pInput,这在技术上被称为“未定义行为”,即使你的鼻子里飞出恶魔,也不能抱怨。 - Shahbaz
3个回答

5
代码调用了未定义行为。原因是pInput在两个序列点之间被修改了多次。你可能会得到任何结果,无论是期望的还是意外的。什么也不能说。
C99规定:

在前一个和下一个序列点之间,一个对象的存储值最多只能被表达式的评估修改一次。此外,先前的值只能被访问以确定要存储的值。

阅读c-faq 3.8以获取更详细的解释。

1

这两个对 pInput 的增量之间没有序列点(sequence points),这会导致未定义的行为。

将其切分成序列,如下所示:

a = ((unsigned short)(*pInput++)) << 8;
a |= ((unsigned short)(*pInput++));

0
a = ((unsigned short)(*pInput++)) << 8 | ((unsigned short)(*pInput++));

你正在使用后置递增,++会在该行代码执行完毕后再应用。

如果执行以下操作,a将取相同的值:

a = ((unsigned short)(*pInput)) << 8 | ((unsigned short)(*pInput));

如果你想让它成为0xDE01,你需要执行以下操作:
a = ((unsigned short)(*pInput)) << 8 | ((unsigned short)(*(pInput+1)));

我认为你搞反了:a = ((unsigned short)(pInput)) << 8 | ((unsigned short)((pInput+1))); - emsworth

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