为什么* p ++不同于* p + = 1?
考虑:
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
有人可以解释吗?
关键是+=
和++
运算符的优先级。 ++
比+=
具有更高的优先级(事实上,赋值运算符在C中具有第二低优先级),所以操作
*p++
意味着对指针进行解引用,然后将指针本身增加1(通常,根据指针算术规则,它不一定是一个字节,而是关于结果地址的sizeof(*p)
)。 另一方面,
*p += 1
意味着将指针指向的值递增1(对指针本身不做任何事情)。
优先级。 后缀++
绑定比前缀*
更紧密,所以它增加了p
。 +=
在优先级列表的低端,与普通赋值运算符一起,因此它将*p
1。
前缀++和*的优先级是相同的。 两者的联系是从右到左的。 postfix ++的优先级高于*和prefix ++。 后缀++的关联性从左到右。
我们从*p += 1
我将尝试从另外一个angular度来回答这个问题。步骤1让我们看看运算符和操作数:在这种情况下,它是一个操作数(指针p),并且我们有两个运算符,在这种情况下*取消引用,+ = 1表示增量。 具有更高优先级*的步骤2具有比+ =更高的优先级
*P++
这一个是有点棘手…也许甚至邪恶再次,我们有一个操作数(p指针)和两个运算符,只有现在的*取消引用和++后增量具有相同的优先级。 (在某些表中,文章中的++是更高的优先级。)
第1步让我们看看运算符和操作数:在这种情况下,它是操作数,并且您有两个运算符,在这种情况下,*用于取消引用,++用于增量。 步骤2具有更高的优先级? ++比*有更高的优先级注意:即使它们具有相同的优先级,它们也是从右到左,再次,++在*步骤3之前(棘手的部分…)++是哪里? 它是在操作数的右侧,这意味着POST递增在这种情况下,编译器在所有其他操作符完成之后执行增量的“心理注释”。 这意味着它只会将增量作为下一个“最后一步”的最后一步; 所以它将与所有其他在同一行上的操作符一起完成:如果它是* ++ p,那么它将在同一行上的任何其他操作符之前执行,因此在这种情况下,两个处理器的寄存器,一个将保存解除引用的* p的值,另一个将保存递增的p ++的值,原因在这种情况下有两个,是POST活动…在这种情况下这是棘手的,它看起来像一个矛盾。 我们可以期望++优先于*,它只是表示它将在所有其他操作数之后应用,在下一个'之前'被应用。 令牌…
就像我说的那样,棘手的部分是任何在操作数右边的增量都将被放在一边,并且在它移动到下一行之前将被用作LAST操作。