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
.
我有以下程序:
#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
.