关于" - >"和"."的真实情况.

fsd*_*dfa 16 c compiler-construction struct

我一直想知道编译器如何看到指向结构的指针(在C中假设)和结构本身的真正区别.

struct person p;
struct person *pp;
Run Code Online (Sandbox Code Playgroud)

pp->age,我总是想象编译器会这样做:"pp的值+结构中的属性"age"的偏移量".

但它的作用是person.p什么?它几乎是一样的.对我来说,"程序员",p不是内存地址,它就像"结构本身",但当然这不是编译器如何处理它.

我的猜测是它更像是一种语法,而编译器总是如此(&p)->age.

我是对的?

Amb*_*ber 28

p->q本质上是语法糖(*p).q,因为它取消引用指针p然后转到其中的适当字段q.它为一个非常常见的情况(指向结构的指针)节省了类型.

从本质上讲,->不会2个 deferences(指针引用,字段解除引用),而.只做一(场解引用).

由于多重引用因子,->编译器不能完全用静态地址替换,并且总是至少包括地址计算(指针可以在运行时动态改变,因此位置也会改变),而在某些情况下,.编译器可以通过访问固定地址来替换操作(因为基本结构的地址也可以修复).

  • @Fabiano PS:"语法糖"是一个非常标准的术语(Dijkstra说它可能导致"分号癌症").请记住,有些人不喜欢糖(你真的更喜欢`(*p).`到'p->`?). (2认同)

e.J*_*mes 5

更新(见评论):

您有正确的想法,但仅对全局变量和静态变量有重要区别:当编译器p.age查找全局变量或静态变量时,它可以在编译时将其替换age为结构中字段的确切地址.

相反,pp->age 必须编译为"pp的值+ age字段的偏移量",因为pp的值可以在运行时改变.

  • 如果它在堆栈上声明,它在编译时不知道确切的地址,只知道堆栈指针的偏移量. (2认同)