关于运算符优先级的说明
Clarification about precedence of operators
我从一些练习和问题中得到了这个片段:这是以下代码的输出:
main()
{
char *p = "ayqm";
printf("%c", ++*(p++));
}
我的预期答案是 z
但实际答案实际上是 b
。这怎么可能?
稍后编辑:该片段是从练习中提取的,没有关注 printf()
代码区以外存在的字符串文字或语法问题。
您的程序有未定义的行为,因为它试图修改字符串文字 "ayqm"。根据标准,尝试修改字符串文字会导致未定义的行为,因为它可能存储在只读存储中。
指针 p
指向字符串文字 "ayqm"。这个表达式
printf ("%c", ++*(p++));
最终尝试修改指针 p
指向的字符串文字。
程序中的未定义行为包括它可能执行不正确(崩溃或静默生成不正确的结果),或者它可能偶然地完全按照程序员的意图行事。
作为 posted,该程序存在多个问题:
- 它尝试修改字符串常量
"ayqm"
,这在 C 标准中被描述为 未定义的行为。
- 它在没有正确声明的情况下使用
printf
,再次产生未定义的行为。
- 其输出未以换行符终止,导致实现定义的行为。
- 没有 return 类型的
main
原型已过时,C 标准不再支持。
- 增加字符会产生实现定义的行为。如果执行字符集是 ASCII,
'a'+1
确实会产生 'b'
,但 C 标准不保证。事实上,在老式大型计算机中仍然使用的 EBCDIC 字符集中,字母处于单个单调序列中(即:'a'+1 == 'b'
但在此字符集中为 'i'+1 != 'j'
)。
这是更正后的版本:
#include <stdio.h>
int main(void) {
char str[] = "ayqm";
char *p = str;
printf("%c\n", ++*(p++));
return 0;
}
p
是 post 递增的,这意味着 p
的当前值用于 *
运算符,而 p
的值是在下一个序列点之前递增,即调用 printf
函数。通过 p
、'a'
读取的字符然后递增,这可能会或可能不会产生 'b'
,具体取决于执行字符集。
在printf
returns到main
函数后,p
指向str[1]
并且str
包含字符串"byqm"
.
我从一些练习和问题中得到了这个片段:这是以下代码的输出:
main()
{
char *p = "ayqm";
printf("%c", ++*(p++));
}
我的预期答案是 z
但实际答案实际上是 b
。这怎么可能?
稍后编辑:该片段是从练习中提取的,没有关注 printf()
代码区以外存在的字符串文字或语法问题。
您的程序有未定义的行为,因为它试图修改字符串文字 "ayqm"。根据标准,尝试修改字符串文字会导致未定义的行为,因为它可能存储在只读存储中。
指针 p
指向字符串文字 "ayqm"。这个表达式
printf ("%c", ++*(p++));
最终尝试修改指针 p
指向的字符串文字。
程序中的未定义行为包括它可能执行不正确(崩溃或静默生成不正确的结果),或者它可能偶然地完全按照程序员的意图行事。
作为 posted,该程序存在多个问题:
- 它尝试修改字符串常量
"ayqm"
,这在 C 标准中被描述为 未定义的行为。 - 它在没有正确声明的情况下使用
printf
,再次产生未定义的行为。 - 其输出未以换行符终止,导致实现定义的行为。
- 没有 return 类型的
main
原型已过时,C 标准不再支持。 - 增加字符会产生实现定义的行为。如果执行字符集是 ASCII,
'a'+1
确实会产生'b'
,但 C 标准不保证。事实上,在老式大型计算机中仍然使用的 EBCDIC 字符集中,字母处于单个单调序列中(即:'a'+1 == 'b'
但在此字符集中为'i'+1 != 'j'
)。
这是更正后的版本:
#include <stdio.h>
int main(void) {
char str[] = "ayqm";
char *p = str;
printf("%c\n", ++*(p++));
return 0;
}
p
是 post 递增的,这意味着 p
的当前值用于 *
运算符,而 p
的值是在下一个序列点之前递增,即调用 printf
函数。通过 p
、'a'
读取的字符然后递增,这可能会或可能不会产生 'b'
,具体取决于执行字符集。
在printf
returns到main
函数后,p
指向str[1]
并且str
包含字符串"byqm"
.