关于运算符优先级的说明

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',具体取决于执行字符集。

printfreturns到main函数后,p指向str[1]并且str包含字符串"byqm".