我得到一个警告,而不是一个错误,并且当我忽略警告并继续构建/运行时,我的代码似乎运行良好。不过,由于警告,我还是很担心,或者也许我只是想了解它。
此函数将单个char附加到字符串的开头。
void s_pfx(char pf, char *s){
i = -1;
while(s[++i]);
s[i + 1] = '\0';
while(i)
s[i] = s[--i];
s[i] = pf;
}
当我预先减少i时,警告在while循环中。 (我将i作为全局变量。)
警告是“警告:'i'上的操作可能未定义[-Wsequence-point]”
我可以通过使用
进行修复while(i){
s[i] = s[i - 1];
i--;
}
但是为什么我必须那样做呢?似乎会吃掉时间,也许是十亿分之一秒,但它会累加起来。
我不明白为什么编译器无法理解代码。对我来说,这似乎很明确。我查看了其他一些类似的问题/答案,但这似乎简单得多。
帮助!谢谢。
答案 0 :(得分:3)
错误确实存在于表达式s[i] = s[-- i]
中。
C规范要求某些运算符充当“序列点”,也就是说,它们的第一个操作数要在第二个操作数之前得到完全评估。 =
运算符不是-意味着编译器可以按任何顺序求值。
当您执行i = i + 3
之类的操作时,这不是问题,因为未评估分配的左手符号(将其写入,而不读取)。但是您在那里使用指针。 s[i]
在C中的真正含义是*(s + i)
;方括号是语法糖。
因此,您确实有*(s + i) = *(s + --i)
。该表达式在左侧读取i
(它必须求和以计算出要存储数据的地址),并在右侧写入i
({{1} }。而且没有固定的求值顺序,因为--i
不是序列点。
这意味着读取可以在写入之前或之后进行。在这种情况下,C标准说该操作是 undefined ,这意味着编译器可以使该代码的分支实际上可以执行任何操作。