我一直在学习链表和节点结构的递归定义一直困扰着我
struct node { struct node *next; int data; };
我想我总是想象自从键入指针后,它会在声明时知道起始地址和它在解除引用时可以访问的内存量.但它不可能,因为它是在任意数量的其他变量之前声明的,这些变量可以构成任何大小的结构.它是仅在取消引用时才弄明白,还是某种内存表在结构定义的末尾和指针可以使用之前被填充?
指针只是一个值,它在内存中保存一个地址.
编译器知道这些结构中结构的大小和字段的偏移量.无论何时访问引用结构中的字段,它都会添加偏移量.
看看下面的程序:
struct X { char a; int b; long c; }; void y() { struct X x; x.a = 42; x.b = 43; x.c = 44; }
函数y
转换为以下汇编代码(gcc -s
):
y: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movb $42, -16(%rbp) movl $43, -12(%rbp) movq $44, -8(%rbp) nop popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc
您可以清楚地看到值42,43,44.编译器计算结构x中字段的偏移量.它们与堆栈指针(rbp)相关,因为值x在堆栈上分配.