回 帖 发 新 帖 刷新版面

主题:菜鸟的问题,请大牛指点:*str++的一个问题

c premier plus上11.26一个疑问:
我想问一下在C99标准里下面的两种写法是否等价?
(1)
*str=toupper(*str);
str++;
(2)
*str=toupper(*str++);
按照我的理解,(2)中的执行顺序是确定的,即先变为大写,然后赋值,最终++。
但是在code::blocks(gcc)下(2)会有warning说对str的行为未定义。
那么(2)究竟在ANSI C中是否符合标准呢?希望各位大牛能给出详细的解释?如果可以的话能否找到具体的官方说明呢?

回复列表 (共5个回复)

沙发


*str=toupper(*str++);
是应该str指针是指向str自增一后的内容
后自增的优先级为1,*的优先级为2

板凳

[quote]
*str=toupper(*str++);
是应该str指针是指向str自增一后的内容
后自增的优先级为1,*的优先级为2[/quote]

不对吧,我按照(2)的方法处理了一个字符串the one,照样显示THE ONE啊。
我的疑问是究竟按照ANSI C标准(2)的写法是否对str行为未定义呢?编译器指出[b]可能[/b]未定义,我对此有疑问。谢谢

3 楼

对这种 ++ 的问题我已经恐惧了,几乎每个论坛,几乎每隔几天,就会有人问一次这种无聊问题。
之所以说“无聊”,是因为其行为在C/C++中是“未定义”的。既然是“未定义行为”,研究它有什么意义?你换个编译器,或者同一个编译器的不同版本,其结果都可能不一样。所以你不应该写出这样的代码出来,而不是研究某某编译器为什么输出某某结果。

如果你想知道为什么是“未定义”的,可以查看C/C++,或google一下“C 序列点”。我也可以简单的话你知,C/C++标准规定:
1. "后增操作",在C/C++定义为“加1,返回原先的值”
2. 在 &&、||、?:、逗号,以及 完整声明之后、完整表达式之后、进入函数时、退出函数时 存在"序列点"
3. 两个"序列点之间",程序执行的顺序可以是任意的

所以 *str=toupper(*str++) 可能被解析成
char* tmp = str;
str = str + 1;
*str = toupper(*tmp);

也可能被解析成
*str = toupper(*str);
str = str + 1;

而这两种解析,其结果是不一样的。

4 楼

您的意思是这种行为[b]的确[/b]是未定义行为吗?编译器的warning说是[b]may be undefined[/b],我只是想确认一下。谢谢

5 楼

的确是未定义行为。

我来回复

您尚未登录,请登录后再回复。点此登录或注册