C 使用数组时后缀/前缀如何工作
下面是两个代码示例:C 使用数组时后缀/前缀如何工作,c,C,下面是两个代码示例: int k,j=1; int x[4]={5,14,25,47}; k = x[j] + ++j; printf("%d, %d",j,k); 将显示一条警告—“j”上的操作可能未定义” 但是输出是:2,16 然后我试了一下: int k,j=1; int x[4]={5,14,25,47}; k = x[j] +++j; printf("%d, %d",j,k); 这不会给出任何警告,但输出有点混乱。产出-1,15 为什么在第二
int k,j=1;
int x[4]={5,14,25,47};
k = x[j] + ++j;
printf("%d, %d",j,k);
将显示一条警告—“j”上的操作可能未定义”
但是输出是:2,16
然后我试了一下:
int k,j=1;
int x[4]={5,14,25,47};
k = x[j] +++j;
printf("%d, %d",j,k);
这不会给出任何警告,但输出有点混乱。产出-1,15
为什么在第二种情况下j没有增加
k = x[j] +++j;
与
k = (x[j]++) +j;
另外,k=x[j]+++j
是未定义的行为,因为加法的求值顺序未定义。除了允许编译器生成任何内容之外,这两个代码段都是对这一行的合理解释:
j++;
k = x[j] + j;
及
一般来说,避免“聪明”。如果您不能100%确定自己在做什么,请不要在更复杂的语句中使用++
和--
。在之前或之后在单独的行上执行递增或递减。那会帮你省去很多麻烦。例如,你能毫无疑问地在谷歌上准确地说什么吗
while(*str++) {
/* Do something */
}
意味着什么?我觉得这更清楚
while(*str) {
str++;
/* Do something */
}
当然它需要一条线,减少线的数量可能是一件好事,但在这种情况下,我认为最好是安全起见。在这个特殊的例子中,你也可以用括号把它弄清楚:*(str++)
,如果你愿意的话,但我想你明白我的意思了
我实际上回答了实际的问题:一个C程序被解析为一个令牌序列,比如
int
,+
,+
,和->
。当源文本包含++
时,这可能是标记++
和++
或标记++
和++
。C 2018第6.4节中的一条规则告诉我们:
如果输入流已解析为预处理令牌(最多可达给定字符),则下一个预处理令牌是可构成预处理令牌的最长字符序列
因此,在
++
中,下一个可能是最长的令牌是++
,因此取下该令牌,留下++
作为下一个令牌。Sox[j]+++j代码>被解析为x
[
j
+
+
注意,第一个代码片段中的语句调用了未定义的行为:k=x[j]+++j
在没有中间序列点的情况下使用和更新j
。
while(*str) {
str++;
/* Do something */
}