微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

K&R 中第 132 页的运算符优先级

如何解决K&R 中第 132 页的运算符优先级

我正在阅读 K&R,却被下面的句子困住了。

*p -> str++ 在访问它指向的任何内容后递增 str(就像 *s++

我同意它对 *p -> str++ 所说的话,但对于 *s++,它对我来说没有任何意义。我认为 *s++ 将在递增 s 后访问它指向的任何内容,就像 (*s)++

解决方法

-> 和后缀 ++ 都比 * 具有更高的 precedence,具有从左到右的结合性。

表达式*p->str++首先可以读作*(p->str)++,这使得语义上与*s++相同,而后者又可以读作*(s++)。所以是的,间接将发生在之后增量(expr++),但是

后缀自增和自减运算符的结果是 expr 的值。

因此,

  • p->strs,产生一个 可修改的左值,适用于 ++(本例中的指针类型)。

  • ++(后缀)然后就地递增这个值,计算表达式之前递增的值。

  • * 对该指针值执行间接操作。

然而,(*s)++ 将在增加结果值之前 执行间接操作。

,

此处重要的是 s++返回值。您需要记住 s++返回值s。因此,* 将取消引用地址 s before 增量。

所以代码 *s++ 等价于

T* temp = s; \___ These two lines is what s++ is doing
s = s + 1;   /
*temp;

*s++ 读取 s 指向的内容并将 s 加一。

注意:要在读取 s 指向的内容之前先增加它,您可以执行 *++s

,

我认为 *s++ 会在递增 s 后访问它指向的任何内容,就像 (*s)++

这会将指针增加一:

*s++;

这会将解除引用的指针(即它指向的对象)增加一:

(*s)++;

所以,这不是一回事。

示例:

#include <stdio.h>

int main() {
    char string[] = "Hello";
    
    char *s1 = string;

    printf("%c\n",*s1++);          // 'H'
    printf("%c\n",*s1);            // 'e'
    printf("%s\n",s1);             // "ello"

    char *s2 = string;

    printf("%c\n",(*s2)++);        // 'H'
    printf("%c\n",*s2);            // 'I'  ('H' + 1 = 'I')
    printf("%s\n",s2);             // "Iello"
}
,

我认为 *s++ 将在增加 s 后访问它指向的任何内容,就像 (*s)++

没有。 *s++ 被解析为 *(s++) - 您正在取消引用 s++results++ 的结果是 s 的当前值;增加 s 的副作用不会影响结果。从逻辑上讲,它的工作原理是

tmp = s
x = *tmp   // where "x =" represents any operation using the value of *tmp
s = s + 1

需要注意的是,最后两个操作可以以任何顺序发生,甚至可以同时发生(如果架构支持,可以交错或并行)。

(*s)++ 增加 *sresult - 在逻辑上等同于写

tmp = *s
x = tmp     // same as above
*s = *s + 1

与上述相同的警告。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。