指针作为C语言的一个重要概念,是C语言的精华之一。
其 优点如下:
1. 使用指针可以实现函数参数的引用传递,减少传参的开销,更能直接操作内存,实现动态存储管理;
2. 可以使程序简洁,紧凑,灵活,高效;
但万事万物都有双面性,指针也不例外,它也有缺点:
1. 系统对指针浮动,越界,内存泄漏都不检查,所以初学者往往容易出错。
今天我写一些自己学习指针的心得。首先我试着阐明一些相关概念,相信理解了这些概念,会对我们学习指针有一些帮助。
C语言中的左右值
左右值大家或许听说过,或许没有,但大家一定知道 =( 赋值运算符)!
简而言之,左值指的是赋值运算符 = 左边的东西,右值指的是赋值运算符 = 右边的东西。
举个栗子:
int a = 0;
int b = 1;
a = b;
在这里,一定要对int a = 0;
有一个明确的认知。
这句代码的准确意思为(注意有先后顺序):
申请一个整型变量存储空间命名为a,再把数字0放入这个变量a的空间。
int b = 1;
也是一样的道理,大家可以在心里自己说一下这句话的意思。
注意注意!重点来了
a = b;
这句代码的准确意思:
将变量b的数据放入变量a的空间。
好了,好好理解一下。我简单总结一下:
左值往往指的是变量的空间,其本质是空间
右值往往指的是变量的数据,其本质是数据
假若我就要这样写呢?
1 = b;
在编译阶段程序就会报错!
这是为什么呢?那利用上面的结论就能解释了。
1是空间吗?当然不是!既然不是空间,你当然不能把数据往里放。那万一有人说那我要定义一个名为1的变量空间存储数据,抱歉C语言不支持你用数字命名变量。
上面左右值的结论只要是在赋值运算符 = 情况下,你干啥都成立,逻辑是自洽的。
当然你不要用比较符 == 来搞这个结论,这两符号不一样哦。
直接访问与间接访问
我们知道,程序运行期间。所有东西都在内存上放着,包括但不限于程序代码、常量、变量、数组。东西放在内存上,那当然都有对应地址。
我们把直接用变量名从对应的地址存取变量的值,叫作直接访问;
既然有直接访问,那么是不是还存在一个与其相对的访问方式?是的,这个方式叫间接访问。我举个栗子解释一下间接访问:
现定义了2个整型变量a与b,a里存储的数据为1,a的空间地址为xxxx。我将a的地址存入b。
我现在从b中拿到a的地址,然后通过这个地址去找a,找到a后我再操作a的内容。
通过这个操作我实现了访问b操作a,这种访问方式叫作间接访问。
类比一下,直接访问就像你去酒店找朋友玩,你朋友告诉了你他的房间号,你直接根据房间号找到朋友;
间接访问就像朋友没有告诉你房间号,你也联系不上他。然后你先去前台问他的房间号,然后再根据这个房间号去找到朋友。此处的前台相当于刚才讲的变量b。
指针和指针变量
在C语言中,地址被形象地称为指针,为啥?大家想想,有了地址,我是不是可以迅速找到该地址存储的内容?地址就像一个指向装置一样,直接指出目标位置,因此被称为指针。
而存储指针(地址)的变量被称为指针变量。
指针与指针变量并不是一个东西,指针是地址,指针变量是变量。
那大家都知道只要是变量就会有地址,那么指针变量当然也会有地址,所以就存在高级指针。我们把存储变量地址的变量称为一级指针,存储指针变量的地址的变量就被叫作二级指针,后续还有高级指针,不过越高级越复杂,我们不谈高级指针,高级指针应用场景不多。
大家还知道只要是变量就有类型,那么指针变量当然也会有类型。如果该指针变量存储的是整型变量的地址,那么它就是整形指针;
类似的,它存储的是字符型变量的地址,它就是字符型指针,我就不一一列举了。
int a = 1, * pa = &a;//定义一个整型变量a,定义一个整形指针变量存储a的地址;
char a = b, * pb = &b;//定义一个字符型变量b,定义一个字符型指针变量存储b的地址;
参考文献
《C语言程序设计(第二版)》,王曙燕。