【问题标题】:What's wrong with this example with string literal?这个字符串文字的例子有什么问题?
【发布时间】:2019-04-23 20:32:02
【问题描述】:

我正在阅读来自该网站的答案,其中说以下内容未定义

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

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

【问题讨论】:

  • 是增加地址还是增加内容,对于内容:(*fubar)++;对于地址 fubar++;
  • @SPlatten:我都不想要,我只想知道答案是否会导致未定义的行为......
  • 你没有分配,所以'*'没有意义。
  • 糟糕。我不知道这一点。 ;-)
  • 经验教训:遵守在同一个表达式中永远不要将 ++ 与其他运算符混合的规则。出于多种原因,这是一件坏事:可读性、可维护性、潜在的未定义行为,

标签: c string increment


【解决方案1】:

++ 的位置是关键:如果它是一个后缀(如本例所示),那么增量发生在之后

同样由于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

【讨论】:

  • @ptr_user7813604 *fubar++ 等于 *(fubar++)。答案中也对此进行了解释。请注意,由于它是一个后缀运算符,因此指针在递增之前被取消引用,然后指针递增。
  • @ptr_user7813604, ++(postfix) 没有意义,也没有任何意义,因为括号中没有额外的操作数。
  • *fubar++ 等于*(fubar++) (大部分)等于*fubar; fubar++;
  • @Osiris:我记得 ++(postfix) 返回旧值什么的,但我现在很困惑哈哈。
【解决方案2】:

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

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

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

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

当用字符数组替换字符串文字时,一切都OK了:

int main() {

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

输出:

iello world

【讨论】:

    猜你喜欢
    • 2015-12-04
    • 1970-01-01
    • 2010-12-31
    • 2013-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多