C语言字符串刷题

今天刷到一个题,对答案百思不得其解。求大佬指点...
题:

#include <stdio.h>
#include <math.h>
main()
{
    int n=0;
    char str[80]="Abc+mNp-xyZ";
    while(str[n]!='\0')
        str[n++]=str[n]>='a'&& str[n]<='z'? str[n]-'a'+'A':str[n];
    printf("%s\n",str);
    //大写字母65-90, 小写字母97-122
}

答案输出是BC+MNP-XYZ
请问为什么前面没有A啊?难道不是应该ABC+MNP-XYZ吗? 第一个元素是A,走三元运算符的后面,应该原样输出啊.为什么结果是BC开头?

阅读 1.5k
1 个回答

这里有未定义行为。先去看一下 sequence point 吧。

然后,C11 6.5 Expressions/2

If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.

str[n++]str[n]<='z'? str[n]-'a'+'A':str[n] 的求值顺序是不确定的,其中包含的对 n 的求值(取 n 的值)与副作用(写 n 的值)的顺序是不确定的,于是这是一个未定义行为。

未定义行为,什么都可能发生。

==========
把 n++ 拿出来作为一个单独的语句吧。

===========
再说 C++ 。

C++ 想在用了一个和 C 不同的确定表达式求值顺序的方案,使用 sequenced before 关系表示求值顺序。

而且,在 C++17 开始,标准增加了几个以前不存在的求值顺序运输,其中一个就是,对赋值运算符,右操作数 sequenced before 左操作数。

所以,这句话在 C++17 之后将不再是未定义行为。但是在 C++14 及之前,依然是一个未定义行为。

未定义行为,什么都可能发生。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题