【问题标题】:Why is *p++ different from *p += 1?为什么 *p++ 与 *p += 1 不同?
【发布时间】:2012-08-31 19:22:53
【问题描述】:

考虑:

void foo1(char **p) { *p++; }
void foo2(char **p) { *p += 1; }

char *s = "abcd";
char *a = s; 
foo1(&a); 
printf("%s", a); //abcd

但如果我使用foo2() 而不是:

char *a = s; 
foo2(&a); 
printf("%s", a); //bcd

谁能解释一下?

【问题讨论】:

  • 因为*p++*(p++)一样
  • 也可以试试void foo3(char **p) { (*p)++; }
  • 享受你漂亮的问题徽章:-)

标签: c


【解决方案1】:

关键是+=++ 运算符的优先级。 ++ 的优先级比+= 高(实际上,赋值运算符在 C 中的优先级倒数第二低),所以运算

*p++

表示取消引用指针,然后将指针本身加1(通常,根据指针算术规则,它不一定是一个字节,而是sizeof(*p)关于结果地址) .另一方面,

*p += 1

表示将指针所指向的值加一(不对指针本身做任何事情)。

【讨论】:

  • 您对它的解释做得很好,但请您补充一点 *p++ 将指针本身增加 1 个“单位”,因此 char 指针可能会增加 1,而 int指针可能会增加 4 等,具体取决于实现细节。
  • @EdwinBuck:我没有真正看到相关性,这只是普通的指针运算,而不是问题的重点。
  • @EdwinBuck 指针是 int 还是 char,当您增加它时,它会增加一。然而,由于指针的大小,表示该指针的实际地址可能会更改超过一个字节。
  • @RichardJ.RossIII 我们都是对的,但我们谈论的是不同的 1。一个单位,或sizeof(*p) 在某种程度上仍然是 1,但如果您查看存储在p 中的二进制值,实际值在二进制算术中并不总是“+1”。
  • 指针的表示,在许多 C 实现中是简单的内存地址,不应与它的值混淆,这是它在 C 上下文中的含义。 p++ 确实将值增加一。就本问题而言,它对该值表示的影响与此无关,就像将 1 添加到浮点 1.f 通常将表示更改为 8,388,608 一样,这无关紧要。
【解决方案2】:

优先级。后缀++ 比前缀* 绑定得更紧密,所以它递增p+= 与普通赋值运算符一起位于优先级列表的低端,因此它将 *p 加 1。

【讨论】:

    【解决方案3】:

    前缀 ++ 和 * 的优先级相同。两者的关联性是从右到左。后缀 ++ 的优先级高于 * 和前缀 ++。后缀++的结合性是从左到右的。

    【讨论】:

      【解决方案4】:

      让我们从*p += 1开始

      我会尝试从一个不同的角度来回答这个问题... 步骤 1 让我们看看运算符和操作数:在这种情况下,它是一个操作数(指针 p),我们有两个运算符,在这种情况 * 用于取消引用,+= 1 用于增量。具有更高优先级的第 2 步 * 优先于 +=


      *P++ 这个有点棘手......甚至可能是邪恶的 同样,我们有一个操作数(p 指针)和两个运算符,只是现在用于取消引用的 * 和 ++ 后增量具有相同的优先级。 (在某些表格中,帖子中的 ++ 具有更高的优先级。)

      第 1 步让我们看看运算符和操作数:在这种情况下,它是操作数,并且您有两个运算符,在这种情况下 * 用于取消引用,++ 用于递增。第 2 步哪个优先级更高? ++ 的优先级高于 * 注意:即使它们具有相同的优先级,它们也会从右到左关联,同样,++ 在 * 之前 第 3 步(棘手的部分......) ++ 在哪里?它在操作数的右侧,这意味着 POST Increment 在这种情况下,编译器会记下“心理笔记”来执行增量AFTER其他运营商... 后面是什么意思?这意味着它只会将增量应用为下一个“;”之前的最后一步。因此它将与同一“行”上的所有其他运算符一起完成 注意:如果它是 *++p ,那么它将在同一行上的任何其他运算符之前执行它,因此在这种情况下,它等同于获取两个处理器的寄存器,一个将保存取消引用的 *p 的值和另一个将保存增加的 p++ 的值,在这种情况下有两个原因,是 POST 活动......在这种情况下,这很棘手,看起来很矛盾。人们会期望 ++ 优先于 *,它确实如此,只是 POST 意味着它只会在所有其他操作数之后应用,在下一个 ';' 之前令牌...

      就像我说的,棘手的部分是操作数右侧的任何增量都将被搁置一旁,并在移至下一行之前作为 LAST 操作应用...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-07-23
        • 2022-12-04
        • 1970-01-01
        • 2019-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-29
        相关资源
        最近更新 更多