实施例7表达的分组并不完全决定其评估.在以下片段中:
Run Code Online (Sandbox Code Playgroud)#include <stdio.h> int sum; char *p; /* ... */ sum = sum * 10 - '0' + (*p++ = getchar());表达式语句被分组,就好像它被写为
Run Code Online (Sandbox Code Playgroud)sum = (((sum * 10) - '0') + ((*(p++)) = (getchar())));但是p的实际增量可以在前一个序列点和下一个序列点(;)之间的任何时间发生,并且对getchar的调用可以在需要其返回值之前的任何点发生.
所以基本上我把它理解为未指明的行为 - 要么是*p = getchar(); p++;OR p++; *p = getchar().请注意,这;意味着一个序列点,但整个表达式中没有其他序列点.
所以这种语法没用.而且,几乎,++和 - 用于指针分配是没用的.对?
词汇分组是无关紧要的.要紧的是值的p++.
该陈述与以下两个陈述相同:
sum = sum * 10 - '0' + (*p = getchar());
++p;
Run Code Online (Sandbox Code Playgroud)
或者
*p = getchar(); p++;ORp++; p* = getchar()[原文如此]
好吧,没有.它是:
*p = getchar(); p++
Run Code Online (Sandbox Code Playgroud)
要么
old_p = p++; *old_p = getchar()
Run Code Online (Sandbox Code Playgroud)
在你的解释中,你可以写*p或*(p + 1)不是真的.在这两种解释p中,无论编译器何时决定放置更改的指令,都要写入最初指向的位置p.如果它决定将它放在write to之前*p,则必须确保它保留旧值以便稍后写入(*old_p).
后缀--和++运算符实际上是非常好的快捷方式.举个例子:
size_t strlen(const char *str)
{
size_t len = 0;
while (str[len++]);
return len - 1;
}
Run Code Online (Sandbox Code Playgroud)
这是strlen使用后缀的非常简洁的实现++.
从C11,6.5.2.4.2(强调我的):
postfix ++运算符的结果是操作数的值.作为副作用,操作数对象的值递增(即,将相应类型的值1添加到其中).有关约束,类型和转换以及操作对指针的影响的信息,请参阅加法运算符和复合赋值的讨论.在更新操作数的存储值的副作用之前,对结果的值计算进行排序.对于不确定顺序的函数调用,后缀++的操作是单个评估.具有原子类型的对象上的Postfix ++是具有memory_order_seq_cst内存顺序语义的读取 - 修改 - 写入操作.