一、父函数和子函数的概念
A函数调用B函数,则A称为父函数,B称为子函数。
二、野指针
也即悬挂指针,是没有访问权限的指针。需要注意的是,操作系统预防不了野指针,所以在日常编程学习过程中,我们要注意判断野指针的使用。
三、修改指针的指向不会影响父函数,子函数的改变要能影响到父函数,必须传指针和解引用。
三种交换函数
1.
#include<stdio.h>
void Swap(int *p1,int *p2)
{
int *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;
}
以上程序有bug,通过单步调试发现,在子函数中,仅仅是修改了指针的指向,并没有影响到父函数。现用语言总结该程序交换出错原因:若操作系统赋予a地址为fb22,b地址为fb20,即父函数在程序运行过程中向子函数传递了a与b的地址,而在子函数中指针tmp交换的仅仅是a与b的地址,并未修改其值,所以该程序段不能交换a与b的值。
2.
#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;
}
在以上代码中,由于存在野指针tmp的存在,其并未被初始化,操作系统为其赋予了随机值,导致程序崩溃。
3.
#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;
}
以上程序完全体现了子函数的改变要能影响到父函数,必须传指针和解引用。因为在父函数向子函数传地址的同时,子函数进行了解引用操作,所以a与b能够进行正确交换。
最后,我附上最近学习的关于数组逆置(即数组的第一个数和最后一个数交换位置,第二个数和倒数第二个数进行交换,以此类推)程序代码。
#include<stdio.h>
void Show(int *arr,int len)
{
for(int i=0;i<len;i++)
{
printf("%d ",arr[i]);
}
printf("\n");
}
void Reverse(int *arr,int len)
{
int tmp;
for(int i=0;i<len/2;i++)
{
tmp = arr[i];//arr[i] == *(arr+i)
arr[i] = arr[len-1-i];
arr[len-1-i] = tmp;
}
}
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,10};
int *p = arr;
Reverse(arr,sizeof(arr)/sizeof(arr[0]));
Show(arr,sizeof(arr)/sizeof(arr[0]));
return 0;
}