main函数内外'&arrayname + n'的输出不同
Different outputs of '&arrayname + n' in and outside the main function
表达式 &arrayname + n
应该给出 base address + (number of elements * size of type of elements) * n
并且它在 main()
函数中按预期工作。
但是如果我在不同的函数中使用相同的函数,它会被不同地解释并产生不同的输出。
代码(32位编译器):
#include <stdio.h>
void arrf(int A[],int n)
{
printf("\n\nInside arrf()");
printf("\n&A ---> %p",A);
for(int i=0;i<n;i++)
printf("\n&A + %d ---> %p",i,(&A+i));
}
int main()
{
int A[]={1,2,3,4,5};
int n=5;
printf("Inside main()");
printf("\n&A --->%p",A);
for(int i=0;i<n;i++)
printf("\n&A + %d ---> %p",i,(&A+i));
arrf(A,n);
return 0;
}
示例输出:
Inside main()
&A --->0x7ffed323eac0
&A + 0 ---> 0x7ffed323eac0
&A + 1 ---> 0x7ffed323ead4
&A + 2 ---> 0x7ffed323eae8
&A + 3 ---> 0x7ffed323eafc
&A + 4 ---> 0x7ffed323eb10
Inside arrf()
&A ---> 0x7ffed323eac0
&A + 0 ---> 0x7ffed323ea88
&A + 1 ---> 0x7ffed323ea90
&A + 2 ---> 0x7ffed323ea98
&A + 3 ---> 0x7ffed323eaa0
&A + 4 ---> 0x7ffed323eaa8
在 main()
内,&A+1
给出 0x7ffed323eac0 + Hex(5*4*1) = 0x7ffed323eac0 + 0x14 = 0x7ffed323ead4
,正如预期的那样,所有 &A+i
的输出也是如此
但是在arrf()
函数中,输出并不像预期的那样,甚至&A+0
产生了与基地址不同的输出。更奇怪的是,地址在减少而不是增加。这是为什么?
将数组传递给函数时,它会转换为指向其第一个元素的指针。所以 main
中的 A
是一个数组,而 arrf
中的 A
是一个指针。
这也意味着在 arrf
中,&A
的类型为 int **
,因此指针运算是以 int *
为单位完成的,其大小在您的计算机上显然是 8系统.
此外,arrf
中的 A
是一个独立于 main
中的 A
的变量,因此它的地址将不同(很可能在程序的堆栈上)。
当您将数组的地址传递给函数时,它没有(数组元素数量的)信息表明先前的指针递增是如何工作的。为了克服这个问题,您可能需要明确地告诉编译器指针的算法应该如何表现。
我已经为您修改了示例以使其正常工作。
#include <stdio.h>
void arrf(int (*A)[5],int n)//Here
{
printf("\n\nInside arrf()");
printf("\n&A ---> %p",A);
for(int i=0;i<n;i++)
printf("\n&A + %d ---> %p",i,(A+i));
}
int main()
{
int A[]={1,2,3,4,5};
int n=5;
printf("Inside main()");
printf("\n&A --->%p",A);
for(int i=0;i<n;i++)
printf("\n&A + %d ---> %p",i,(&A+i));
arrf(&A,n);//Here
return 0;
}
另请阅读:c-pointer-to-array-array-of-pointers-disambiguation
表达式 &arrayname + n
应该给出 base address + (number of elements * size of type of elements) * n
并且它在 main()
函数中按预期工作。
但是如果我在不同的函数中使用相同的函数,它会被不同地解释并产生不同的输出。
代码(32位编译器):
#include <stdio.h>
void arrf(int A[],int n)
{
printf("\n\nInside arrf()");
printf("\n&A ---> %p",A);
for(int i=0;i<n;i++)
printf("\n&A + %d ---> %p",i,(&A+i));
}
int main()
{
int A[]={1,2,3,4,5};
int n=5;
printf("Inside main()");
printf("\n&A --->%p",A);
for(int i=0;i<n;i++)
printf("\n&A + %d ---> %p",i,(&A+i));
arrf(A,n);
return 0;
}
示例输出:
Inside main()
&A --->0x7ffed323eac0
&A + 0 ---> 0x7ffed323eac0
&A + 1 ---> 0x7ffed323ead4
&A + 2 ---> 0x7ffed323eae8
&A + 3 ---> 0x7ffed323eafc
&A + 4 ---> 0x7ffed323eb10
Inside arrf()
&A ---> 0x7ffed323eac0
&A + 0 ---> 0x7ffed323ea88
&A + 1 ---> 0x7ffed323ea90
&A + 2 ---> 0x7ffed323ea98
&A + 3 ---> 0x7ffed323eaa0
&A + 4 ---> 0x7ffed323eaa8
在 main()
内,&A+1
给出 0x7ffed323eac0 + Hex(5*4*1) = 0x7ffed323eac0 + 0x14 = 0x7ffed323ead4
,正如预期的那样,所有 &A+i
但是在arrf()
函数中,输出并不像预期的那样,甚至&A+0
产生了与基地址不同的输出。更奇怪的是,地址在减少而不是增加。这是为什么?
将数组传递给函数时,它会转换为指向其第一个元素的指针。所以 main
中的 A
是一个数组,而 arrf
中的 A
是一个指针。
这也意味着在 arrf
中,&A
的类型为 int **
,因此指针运算是以 int *
为单位完成的,其大小在您的计算机上显然是 8系统.
此外,arrf
中的 A
是一个独立于 main
中的 A
的变量,因此它的地址将不同(很可能在程序的堆栈上)。
当您将数组的地址传递给函数时,它没有(数组元素数量的)信息表明先前的指针递增是如何工作的。为了克服这个问题,您可能需要明确地告诉编译器指针的算法应该如何表现。
我已经为您修改了示例以使其正常工作。
#include <stdio.h>
void arrf(int (*A)[5],int n)//Here
{
printf("\n\nInside arrf()");
printf("\n&A ---> %p",A);
for(int i=0;i<n;i++)
printf("\n&A + %d ---> %p",i,(A+i));
}
int main()
{
int A[]={1,2,3,4,5};
int n=5;
printf("Inside main()");
printf("\n&A --->%p",A);
for(int i=0;i<n;i++)
printf("\n&A + %d ---> %p",i,(&A+i));
arrf(&A,n);//Here
return 0;
}
另请阅读:c-pointer-to-array-array-of-pointers-disambiguation