主函数调用子函数,子函数的改变要想影响影响主函数,必须:
1:传指针
2:解引用
以下有三个案例是指针学习中最容易出现的问题(前提:交换两个变量a、b的值)
(一)第一种情况是没有传指针,也没有解引用。
#include <stdio.h>
void Swap_error1(int a,int b)
{
int tmp;
tmp = a;
a = b;
b = tmp;
}
int main()
{
int a = 10;
int b = 20;
Swap_error1(10,20);
printf("%d,%d\n",a,b);
return 0;
}
该函数执行完成后,变量a和b的值只在子函数中交换成功,主函数中执行printf操作时,依然是a = 10;b = 20,详细情况如下图所示:
(二)第二种情况是传指针,但只改变两个指针变量的指向,并没有解引用
#include <stdio.h>
void Swap_error2(int *p1,int *p2)
{
int *tmp = p1;
p1 = p2;
p2 = tmp;
}
int main()
{
int a = 10;
int b = 20;
Swap_error2(&a,&b);
printf("%d,%d\n",a,b);
return 0;
}
在执行子函数里的语句块前,指针变量p1和p2的指向详细情况如下图所示::
指针变量p1指向变量a,保存变量a的地址f854,指针变量p2指向变量b,保存变量b的地址f848。
接下来执行子函数里的语句块,结果如下图所示:
可以看到,在交换完成后,指针变量p1指向变量b,指针变量p2指向了变量a,不过在主函数里执行完printf后,变量a和b的值并没有交换,这是因为指针变量p1和p2只是交换了变量a和b的地址,并不会对主函数里的值产生影响,故该方法错误
(三)第三种错误是,定义了一个野指针\悬挂指针
#include <stdio.h>
void Swap_error3(int *p1,int *p2)
{
int *tmp;
*tmp = *p1;
*p1 = *p2;
*p2 = *tmp;
}
int main()
{
int a = 10;
int b = 20;
Swap_error3(&a,&b);
printf("%d,%d\n",a,b);
return 0;
}
前面提到过,子函数的改变要想影响主函数,必须1:传指针、2:解引用,在这段代码里,前面两个条件都达成了,我们来试试结果是否符合预期。
结果出现了如下所示debug error:
即变量tmp未被初始化。经过了解,这样定义的指针变量,被称为野指针或悬挂指针,由于未给tmp赋值,所以它指向的内存单元无法确定,向这样的未知单元赋值是不合法的,它有可能会对系统的正常工作带来影响。
(四)那么重新定义tmp为整型变量如下所示
#include <stdio.h>
void Swap(int *p1,int *p2)
{
int tmp;
tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
int main()
{
int a = 10;
int b = 20;
Swap(&a,&b);
printf("%d,%d\n",a,b);
return 0;
}
执行子函数语句块前的情况如图:
执行后的情况为:
指针变量p1指向变量a,*p1为20,指针变量p2指向变量b,*p2为10,执行完子函数的语句块后,主函数里的a和b成功重新赋值。