C 中的函数参数和变量地址

Function argument and variable addresses in C

我有以下程序:

#include <stdio.h>

void func(char *str) {

   int a = 4;   

   printf("\n str Address: 0x%8X\n", (unsigned int)&str);
   printf("\n a Address: 0x%8X\n", (unsigned int)&a);
}

void main()
{
    char c = 'y';
    func(&c);
}

当我运行程序时,我得到以下结果:

str Address: 0x43570EB8

a Address: 0x43570ECC

我的理解是Linux中的栈是从高地址向低地址增长的。另外 str 作为参数将首先压入堆栈。如果是这样,为什么 str 地址低于变量 a 的地址?我打印地址的方式不正确吗?

参数str很可能是在寄存器中传递的。通常,它会从该寄存器中使用,并且永远不会存在于堆栈中。因为您的代码采用 str 的地址,所以编译器被迫将它放在内存中的某个地方,以便它可以提供一个地址。看起来编译器首先在堆栈上(或至少在更高的地址)为 a 创建了 space,然后在堆栈上为 str 创建了 space 并复制了从寄存器到堆栈位置的值。

您不应该期望检查对象的地址会揭示或反映平台的其他方面,例如它的应用程序二进制接口(除其他外,它指定函数参数的传递方式)或堆栈的管理方式。只要生成的程序实现与 C 标准定义的相同 可观察行为 ,C 实现就可以自由地重新安排事物,并且现代 C 实现可以在优化程序时进行大的和意想不到的转换。可观察的行为包括程序的已定义输出,但不包括有关对象地址排序的任何规则。

顺便说一句,关于你的最后一个问题,是的,你打印的地址不正确。要打印地址,请将其转换为 void * 并使用 %p 打印,而不是 %X.