我遇到了这段代码:
#include <stdio.h>
void foo(int* p1, int* p2)
{
p1 = p2;
*p1 = *p2 + 1;
}
void bar(int** p1, int** p2)
{
p1 = p2;
*p1 = *p2 + 1;
**p1 = **p2 + 2;
}
void main (void)
{
int n[] = {1,2,3};
int m[] = {4,5,6};
int *p1 = n;
int *p2 = m;
foo(p1,p2);
bar(&p1,&p2);
printf("%d %d\n",*p1,*p2);
}
我认为输出将是[1,5],而它是[1,7]。 有人可以解释原因吗?
非常感谢
答案 0 :(得分:3)
首先,您需要区分main中的p1
和p2
以及函数中的p1
,p2
,这些不相同。因此,我会将foo和bar的参数重命名为fp1
,fp2
,bp1
,fp2
,以便能够更清楚地区分。这不会改变任何行为。
所以主要首先调用foo(p1, p2);
。 fp1
和fp2
则是指针p1
和p2
的副本。在foo中:
fp1 = fp2;
fp2被分配给fp1。所以fp1和fp2都保持了数组p2的地址被分配给(即主要的m
)。*p1 = *p2 + 1;
因为p1和p2都保存m(或m [0]的地址,这对于数组是相同的),m [0]递增(是4,现在是5)。然后拨打bar(&p1, &p2);
。所以bp1
和bp2
现在在main中保存了两个指针p1
和p2
的地址(即你可以从bar中修改p1和p2!),这是然后也会发生:
bp1 = bp2;
两个指针再次保持相同的地址,即main中的p2之一(地址为m [0])。*bp1 = *bp2 + 1;
因为bp1和bp2都指向同一个指针,导致这个指针递增,所以有效地递增p2,现在指向m [1]。**bp1 = **bp2 + 2;
bp1和bp2都指向p2,指向m [1]。所以m [1]增加2(m [1]为5,现在是7!)。最后打印值。请记住,p2本身在bar内被修改,现在指向m [1],再次被修改为7,所以结果你没想到......