问题描述:指针变量作为被调函数形参时,为什么有时候在被调函数调用结束后,main函数中作为实参的指针会发生变化,有时又不发生变化。
先上代码吧😎:
代码1:
#include <stdio.h>
int k=7;
void f(int **s)
{ int *t=&k;
*s=t;
printf("%d,%d,%d,", k, *t, **s);
}
main()
{ int i=3,*p=&i, **r = &p;
f(r); printf("%d,%d,%d\n", i, *p, **r);
}
运行结果:
7,7,7,3,7,7
Press any key to continue
代码2:
#include <stdio.h>
int k=7,m=5;
void f(int **s)
{ int *t=&k;
s=&t;
*s=&m;
printf("%d,%d,%d,", k, *t, **s);
}
main()
{ int i=3,*p=&i, **r = &p;
f(r);
printf("%d,%d,%d\n", i, *p, **r);
}
运行结果:
7,5,5,3,3,3
Press any key to continue
上述代码段1和2的main函数部分都相同,但运行结果却不同,表现在代码段1在执行完f函数之后,指针p和r所指向的内容发生了变化,而代码段2在执行完f函数之后,指针p和r所指向的内容未发生变化。仔细分析会发现,
主要区别就在第8行和第27行。
代码段1是*s=t;
,而代码段2是s=&t;
。看上去似乎没什么区别,但就是这两句的不同导致了运行结果的不同。 *s=t;
是改变指针s所指向变量的值,不改变指针s的值,即指针s原来指向哪里,现在还指向哪里,又因为s=r=p,
所以,*s=*r=p=t=&k,
故在f函数执行结束后,*p=**r=k=7。
而代码2是s=&t;
改变的是指针s的值,而不是指针所指向变量的值,,所以执行完这条语句之后,s就不等于r了,即s和r不再指向同一个变量(p),所以后续对s的任何操作都不会引起r和p的变化。
上面两段代码函数的形参都是指向指针变量的指针(指针的指针),下面再看一个简单点的例子:指向普通变量的指针作为函数形参
代码3🙃:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct stu {
char *name, gender;
int score;
} STU;
void f(char *p)
{
p=(char *)malloc(10);
strcpy(p, "Qian");
}
main()
{
STU a={NULL, 'm', 290}, b;
a.name=(char *)malloc(10);
strcpy( a.name, "Zhao" );
b = a;
f(b.name);
b.gender = 'f'; b.score = 350;
printf("%s,%c,%d,", a.name, a.gender, a.score);
printf("%s,%c,%d\n", b.name, b.gender, b.score);
}
运行结果:
Zhao,m,290,Zhao,f,350
Press any key to continue
上面代码段就是执行完被调函数后,作为实参的b. name(虽然是数组名,但编译系统在编译时会将其当作指针变量)未发生变化,还是因为这条语句:p=(char *)malloc(10);
,它让p不再等于数组b. name首地址,而是指向由malloc函数分配的一块内存区域,所以后续对p的操作不会引起b.name的任何变化。