今天刷到一个题,对答案百思不得其解。求大佬指点...
题:
#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开头?
这里有未定义行为。先去看一下 sequence point 吧。
然后,C11 6.5 Expressions/2
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 及之前,依然是一个未定义行为。
未定义行为,什么都可能发生。