[英]Activation Record in C
void test(int p1[10], int p2) {
int l1;
int l2[10];
printf("params are at %d and %d\n", &p1, &p2);
printf("locals are at %d and %d\n", &l1, &l2[0]);
}
int main(void) {
test(5, 10);
}
我对上面的代码有些困惑...当函数已经指定了p [10]的数组时,如何为测试函数提供5的参数。 输出地址也很奇怪,p1和p2应该相隔40个地址(10个元素的数组乘以每个int 4个字节)。 但是控制台显示它们仅相隔4个单位。
5
被隐式转换为指向int的指针(即0x00000005
)。 GCC sayeth(无可鼓励错误报告的参数):
$ gcc -c z.c
z.c: In function ‘main’:
z.c:13: warning: passing argument 1 of ‘test’ makes pointer from integer
without a cast
$
zc中的代码是问题中的代码,其前面带有' #include <stdio.h>
'和空白行。
GCC在说真话-代码在C上破烂-沉迷于未定义的行为(将整数5转换为整数指针,而无需强制转换以告知编译器程序员可以做什么)。
因为p1等效于'int * p1',所以对于32位编译,p1和p2之间的距离(4)是正确的。
test()函数具有两个参数:指针p1(指向10个整数的数组)和一个整数p2。 在堆栈上,p2在较高的地址上,而p1在较低的地址上。 p2和p1的起始地址之差为p2的大小(== 4)。
该函数在堆栈上有两个局部变量:在较高地址上的整数l1和在较低地址上的数组l2(由10个整数组成)。 l1和l2的起始地址之间的差是l2数组的大小(== 4 * 10)。
当您在main()中调用'test(5,10)'时,文字'5'不会在test()函数内部解释为整数,而是作为指针(因此,编译器感到悲伤:“使用整数创建指针而没有演员”)。
您不是在传递数组作为值,而是在传递int,0x0000005或其他任何值。
您要传递两个刚刚分配的变量,即在堆栈上。 因此,您已为两个整数(每个4字节)分配了空间。 因此,当您找到他们的地址时,它们应该分开4个。
正如其他人指出的那样,您正在传递一个文字int
(5),该文字在传递给test
函数时将被转换为指针类型。 在函数参数中,所有顶级数组声明都转换为指针,因此可以等效地编写测试
void test( int* p1, int p2 )
您的printf
调用存在问题。 %d
是int
的格式说明符,而不是指针类型。 要正确地将指针传递给printf
,应将其显式转换为void*
并使用%p格式说明符。
printf("params are at %p and %p\n", (void*)&p1, (void*)&p2);
printf("locals are at %p and %p\n", (void*)&l1, (void*)&l2[0]);
您需要先执行此操作,然后才能致电告知显示的地址是否看起来“奇怪”。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.