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个单位......
答案 0 :(得分:4)
5
被隐式转换为指向int的指针(即0x00000005
)。答案 1 :(得分:3)
$ 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
$
z.c中的代码是问题中的代码,前面是“#include <stdio.h>
”和一个空行。
因为p1等于'int * p1',所以p1和p2(4)的距离对于32位编译是正确的。
答案 2 :(得分:1)
test()函数有两个参数:指针p1(指向10个整数的数组)和一个整数p2。在堆栈上,p2位于较高地址,p1位于较低地址。 p2和p1的起始地址之间的差异是p2(== 4)的大小。
该函数在堆栈上有两个局部变量:较高地址上的整数l1和较低地址上的数组l2(10个整数)。 l1和l2的起始地址之间的差异是l2数组的大小(== 4 * 10)。
当你在main()中调用'test(5,10)'时,文字'5'将不会在test()函数内部解释为整数但是作为指针(因此编译器悲伤:“使指针来自没有强制转换的整数“)。
答案 3 :(得分:0)
您没有将数组作为值传入,只是传递一个int,0x0000005或其他任何内容。
您正在传递两个刚刚分配的变量,即在堆栈上。所以你已经分配了两个整数的空间,每个4个字节。因此,当你找到他们的地址时,它们应该相隔4个。
答案 4 :(得分:0)
并记住他们对“天使害怕踩踏”的所说的话。 C中的数组参数会自动重写为“指向数组的指针”。 5
的指针肯定是不正确的,但C会用它运行** ... **一段时间。
我记得你无法通过MS C ++获得这样的程序,所以我想你正在使用gnu。在这种情况下,我建议-Wall -Werror
。
答案 5 :(得分:0)
正如其他人已经注意到你传递了一个文字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]);
在打电话询问显示的地址是否“奇怪”之前,您需要这样做。