目录
💮前言
上期,我们对操作符进行了分析,这期我们将会对C语言中最难最重要的知识点指针进行分析。将会从几大方面讲到指针:什么是指针,指针的类型,野指针,指针运算,指针与数组,二级指针,指针数组。相信将这些讲清楚后大家对指针就有了一个初步的认识,消除对指针的恐惧了。话不多说,我们现在就开始叭。
🪷什么是指针
理解指针有两个要点:1. 指针是内存中一个最小单元的编号,也就是地址。2. 平常口语中说的指针,通常指的是指针变量,是用来存放地址的变量。所以,总结就是:指针就是地址,口语中的指针就是指针变量。
指针变量我们我们可以这么理解:我们通过 & 取出变量的内存起始地址,把地址放入一个变量中,这个变量就是指针变量。
总结:指针变量就是用来存放地址的变量。(存放在指针变量中的值都被当做地址处理)。
在这里有两个问题:1. 一个小的单元到底有多大?(1个字节) 2. 如何编址经过仔细的计算和权衡我们发现一个字节给一个对应的地址是比较合适的。
我们明白:在32位机器上,地址是32个1到32个0组成的二进制序列,地址就得用4个字节的空间来储存,所以一个指针变量的大小就应该是4个字节大小。在64位机器上,就是64个二进制序列,一个指针变量就是8个字节大小,才能存放一个地址。
总结:
指针变量是用来存放地址的,地址是唯一标示一个内存单元的。
指针的大小在32位机器上是4个字节,在64位机器上是8个字节。
2. 指针与指针的类型
大家都知道,变量中有不同的类型,整型,浮点型,长整型等等,那指针有没有类型呢?那当然是有的。那指针的类型是什么样的呢?下面我们给出指针变量相应的类型:
char *pa = NULL; int *pb = NULL; short *pc = NULL; long *pd = NULL; float *pe = NULL; double *pf = NULL;
我们可以看到,指针定义的方式是: type + *。其实:
char *是为了放char类型变量的地址。short * 是为了放short变量的地址。int * 是为了放int类型给变量的地址。那问题来了,那这些指针类型的意义在哪里?它们有什么作用?
指针+-正数
指针的类型决定了指针向前或者向后走一步多大
指针的解引用
指针的类型决定了对指针解引用的时候有多大权限(能操作几个字节)。
比如:char*解引用只能操作一个字节,int*能操作四个字节
🏵野指针
野指针的含义就是:指针指向的位置是不可知的(随机的,不正确的,没有明确限制的)
🌹野指针成因
1.指针为初始化
2. 指针越界访问
3. 指针指向的空间释放
🌺如何规避野指针
1. 指针需要初始化
2. 小心指针越界
3. 指针指向空间释放,及时置成NULL
4. 避免返回局部变量的地址
5. 指针使用前检查有效性
🌷指针运算
指针+-整数
指针-指针
指针的关系运算
注意:标准规定允许指向数组元素的指针与指向数组最后一个元素后面的那个内存的指针进行比较,但不允许与指向第一个元素之前的那个内存位置的指针进行比较。
🌵指针和数组
我们可以知道,数组名和数组首元素地址是一样的。所以我们得出结论:数组名表示的就是数组首元素的地址。(2个情况除外,在数组那一片文章有具体的说明)
既然,可以把数组名当地址存放到一个指针中,我们使用指针来访问一个就成为可能,通过下面的代码我们知道:P+i其实计算的是数组arr下标为i的地址。
所以我们就可以直接通过指针来访问数组:
🌴二级指针
指针也是变量,是变量就有地址,那指针变量的地址存在哪里呢?那当然是存在二级指针中!!!
对于二级指针的运算:
*ppa通过对ppa中的地址进行解引用,这样找到的是pa,*ppa其实访问的就是pa。
int b = 20;
*ppa = &b; 等价于pa = &b;
**ppa先通过*ppa找到pa,然后对pa进行解引用操作:*pa,然后找到a。
**pa = 30;
等价于*pa = 30
等价于a = 30
🍀指针数组
指针数组是指还是数组呢?当然是数组,是存放指针的数组。
数组我们已经知道整型数组,字符数组。
int arr[3];
char arr[3];
指针数组的样子:
这里用代码举例:
🍁总结
到这里,我们对于指针的内容初步有了个认识和了解,学到这里相比大家在理解相关的内容和写一些指针代码已经不成问题了。不过对于指针这个东西还有很多内容没有细讲,在之后的文章还会给大家介绍的,大家可以期待一下。