这个字符串文字的例子有什么问题?

What's wrong with this example with string literal?

我正在阅读来自该网站的一个回答,其中说以下是未定义的

char *fubar = "hello world";
*fubar++; // SQUARELY UNDEFINED BEHAVIOUR!

但不是先完成了fubar++,也就是把指针移到e,然后完成了*(),也就是提取了e出去。我知道这应该在聊天中被问到(我是一个善良的人)但是没有人在那里所以我在这里问以引起注意。

++ 的位置是关键:如果它是后缀(如本例),则增量发生在 after.

同样由于 operator precedence 你增加了 指针

所以发生的是指针 fubar 被取消引用(导致 'h' 然后被忽略),然后指针变量 fubar 递增指向 'e'.

简而言之:*fubar++ 很好并且有效。

如果它是 (*fubar)++ 那么它将是未定义的行为,因为那时它会尝试增加字符串的第一个字符。 C 中的文字字符串是 只读 字符的数组,因此尝试修改文字字符串中的字符将是 未定义行为.


表达式*fubar++本质上等于

char *temporary_variable = fubar;
fubar = fubar + 1;
*temporary_variable;  // the result of the whole expression

显示的代码显然不是未定义的行为,因为*fubar++有点等于char result; (result = *fubar, fubar++, result),即它增加了指针,而不是取消引用值,表达式的结果是指针递增之前的(解除引用的)值 *fubar*fubar++ 实际上给了你 fubar 最初指向的字符值,但你根本没有使用这个 "result" 并忽略它。

但是请注意,以下代码确实引入了未定义的行为:

char *fubar = "hello world";
(*fubar)++;

这是因为这会增加 fubar 指向的值,从而操纵字符串文字 -> 未定义的行为。

当用字符数组替换字符串字面量时,一切正常:

int main() {

    char test[] = "hello world";
    char* fubar = test;
    (*fubar)++;
    printf("%s\n",fubar);
}

输出:

iello world