用交换函数来理解指针
来源:互联网 发布:在线订单管理系统源码 编辑:程序博客网 时间:2024/06/02 02:30
写一个函数,交换a和b的值
#include<stdio.h>
void swap1(int a,int b)
{
int tmp=a;
a=b;
b=tmp;
}
void swap1(int a,int b)
{
int tmp=a;
a=b;
b=tmp;
}
int main()
{
int a=10;
int a=10;
int b=20;
printf("%d,%d\n",a,b);
Swap1(a,b);
printf("%d,%d\n",a,b);
return 0;
}
如果调用这个函数,会交换值吗?
值并没有改变,为什么呢?
因为我们只是在交换函数内部改变了a和b的值,一旦这个函数调用结束,函数内部的变量也就销毁了,并不会传到主函数中,这就是我们经常说的值传递。相当于只是拷贝了一个副本放在交换函数中,但是这个副本的改变不会影响主函数中的值。主函数和交换函数中的a,b并不是相同的变量。所以交换函数a和b的变化并不会影响到主函数中的a和b。
如果想看是不是相同的变量,只需要看他们的地址是不是相同的,地址相同才是相同的变量。
void swap2(int *a,int *b)
{
int *tmp;
tmp=a;
a=b;
b=tmp;
}
{
int *tmp;
tmp=a;
a=b;
b=tmp;
}
既然值传递不能进行交换,那我们传递地址呢?
调用swap2函数来试一下
调用了swap2函数,还是没有改变它们的值,又是为什么呢?
因为当我们把a,b的地址传进去的时候,指针变量*a,*b 就保存了主函数a,b的地址,但是我们赋值的时候,实质上我们只是把地址互相交换了,只是改变了原来指针的指向,并不会改变a,b里面存放的值。想要改变里面的值,要对指针变量解引用,才能修改指针变量所指的地址里面的值。
void swap3(int *a,int *b)
{
int *tmp;
*tmp=*a;
*a=*b;
*b=*tmp;
}
既然没有解引用,发生了错误,那我们就解引用,看看是不是正确的
调用swap3函数,看一下是不是正确的
当我们调用这个函数的时候,不仅没有出现交换,程序还直接崩溃了,这是为什么呢?
这里要引入一个新的概念:野指针。野指针又称悬挂指针,是没有指向有效地址的指针,或者说没有访问权限的地址。
当我们定义tmp的时候,并没有初始化,所以它是一个野指针,可能随机指向了某一个地址,当我们将a解引用赋值给tmp解引用的时候,是导致系统崩溃的原因。a解引用以后是20,但是tmp由于没有初始化,它指向的地址空间并不允许它访问或者修改里面存放的值。因为没有访问权限,所以系统直接崩溃了。
但是野指针编译器不能预防,因为可能那个地址就是实际存在的。例如: int *tmp=(int *)10000; *tmp=100; 这里编译不会有错,因为这个地址就是实际存在的,但是运行的时候会崩溃,因为这个地址10000你是没有访问权限的。所以野指针防不胜防,我们使用的时候要避免使用野指针,可以加一个断言,防止野指针。
void swap(int *a,int *b)
{
int tmp;
tmp=*a;
*a=*b;
*b=tmp;
}
{
int tmp;
tmp=*a;
*a=*b;
*b=tmp;
}
去掉野指针以后能不能交换值呢?调用swap函数试一试
终于将值交换了,这个程序为什么成功了呢?
首先定义两个指针变量是没有错误的,我们想要通过指针变量去改变值,必须要解引用,当我们把a解引用时,其实就是将a指向的地址的值取出来,赋给了变量tmp;然后*a=*b 这一句就是将b指向的内存单元的值拿出来,放到a指向的内存单元。*b=tmp就是将tmp保存的变量拿出来放到b所指向的内存单元中,即a内存单元的值保存到了b内存单元,通过这个过程就可以将a,b的值进行交换了。
int main()
{
int a=10;
int b=20;
printf("%d,%d\n",a,b);
//swap1(a,b);
//swap2(a,b);
//swap3(&a,&b);
swap(&a,&b);
printf("%d,%d\n",a,b);
return 0;
}
{
int a=10;
int b=20;
printf("%d,%d\n",a,b);
//swap1(a,b);
//swap2(a,b);
//swap3(&a,&b);
swap(&a,&b);
printf("%d,%d\n",a,b);
return 0;
}
通过以上的测试,可以看出:
父函数调用子函数,子函数能修改父函数中的内容,或者子函数的改变能够影响父函数,需要两个条件:
1.传指针
2.解引用
但是有这两个条件也不一定改变值,可能会有野指针出现,要预防野指针。必要非充分条件
阅读全文
0 0
- 用交换函数来理解指针
- 用交换的程序来理解函数传递
- 指针--交换函数
- 练习3: 通过打印指针,加深对交换函数和指针的理解。
- 通过指针变量来交换值
- 运用指针,调用函数来是3个数从大到小输出(通过异或来交换大小)
- 指针与非指针的交换函数
- 用函数和指针实现两个数的交换
- 用指针将调用函数进行变量的交换
- 全局变量值交换,swap函数参数要用指针
- C++分别用指针和引用实现交换函数
- 用函数实现两个数的交换(指针)
- 用typedef来定义函数指针
- 用函数指针数组来实现计算器
- 函数指针理解-1
- 函数指针的理解。
- 理解成员函数指针
- 深入理解指针函数
- 基于c++的统计输入字符串中单词个数程序
- 基础概念
- nginx配置文件说明
- Win7开启IPV6总结
- 初学web前端,掌握这些就足够了!
- 用交换函数来理解指针
- Protobuffer和json深度对比
- Mysql中查看表的类型InnoDB
- 专访变设龙:重新定义设计 颠覆传统企业图片管理方式
- 在Centos 7 上搭建XAMPP环境
- 看中国 | 7大报告6大关键词解读双11新经济大未来
- wpa_supplicant网络配置与使用
- java.lang.NoClassDeffoundError异常处理
- 细数程序员出身的互联网大佬