详解指针(超详细)(第一卷)

说好的今天讲指针,说到做到啦

文章目录

  • 指针概念
  • 指针变量
  • 指针运算
  • 野指针


一.指针概念

1.要学好指针首先要了解什么是指针,首先给个定义它是一种用来存储变量地址的变量类型,通常我们也会说指针其实就是一个地址,下面先看一段代码叭

详解指针(超详细)(第一卷)_第1张图片

这段代码的大意就是我定义了一个整型变量,并赋给它一个值,之后我将这个整型变量a的地址给指针p,最后我就可以通过p去找到a的值,就相当于你把你家的地址给我,我就可以通过这个地址找到你家(当然啦有点废话文学),不过非常形象。

2.解引用(用于访问指针所指向的内存单元的值)

详解指针(超详细)(第一卷)_第2张图片

当我们用指针访问到a的地址后,就可以不用直接操作a进而改变a的值,可以直接在a的地址中改变a的值(当然a的地址不变,只是地址中存储的值发生了改变),通过这个方法我们可以进行一些“非法”操作啦

详解指针(超详细)(第一卷)_第3张图片

比如我们将a定义成一个具有常属性的变量,就无法直接对a的值进行改变,这时我们就可以用解引用,例如这样

详解指针(超详细)(第一卷)_第4张图片(c++中不支持该操作,编译器会报错)

二.指针变量

1.注意我上文对指针p的定义是int*,那么会有人问如果写成int * p或者int *p可以吗,答案是肯定的啦,它们本质是一样的,那么又有人要问了为什么非要用int嘞,char/short/long这些不行吗?

对于这个问题就涉及到我们接下来要讲的指针变量啦。提到变量我们首先就要考虑这个变量占多少字节

详解指针(超详细)(第一卷)_第5张图片详解指针(超详细)(第一卷)_第6张图片

详解指针(超详细)(第一卷)_第7张图片详解指针(超详细)(第一卷)_第8张图片

当然这里我就用了int char两个类型,我们不难发现在debug状态下x64中任意指针变量的字节都是8,x86中任意指针类型的字节都为4。那么有人就要问了,release状态下呢,这里我没贴图,但结论就是release下任意指针类型(不论x64x84)的字节都为4。

这时又有人要问了,那既然它们在同一环境下字节相同,为什么还要定义不同的变量名呢,这就涉及到我们接下来所讲的以及指针运算。

贴上一个错误代码示例

详解指针(超详细)(第一卷)_第9张图片

编译器会给出类型不兼容的警告,所以指针变量类型和你要访问的变量类型要保持一致。

当然所有的指针变量中有一个极为特殊,void*可以接受所有变量类型的地址并不会触发类型不兼容的警告,但它的缺陷就是不能进行解引用操作和接下来要讲的指针运算。

再看两组代码

详解指针(超详细)(第一卷)_第10张图片详解指针(超详细)(第一卷)_第11张图片

通过这两种代码我们不难发现当指针前移或后移时,移动字节并不相同,int移动4个,short移动2个,char移动1个,这也是不同指针变量设置不同变量名的意义之一。

2.const修饰指针变量

众所周知,const可以用来定义常量也可以用来修饰变量,当然它也可以用来修饰指针变量(有两种情况)第一种例如详解指针(超详细)(第一卷)_第12张图片详解指针(超详细)(第一卷)_第13张图片

对*p进行const修饰,造成的结果是无法用解引用操作,因为此时的*p被定义成一个常变量后不能修改其中的值。

详解指针(超详细)(第一卷)_第14张图片

第二种例如详解指针(超详细)(第一卷)_第15张图片

此时用const对p进行修饰,所以*p不受影响,依旧可以被重新赋值。

三.指针运算

上面讲啦许多与指针有关的知识,但好像没有太大的实际价值,接下来讲一下指针的实际应用——指针运算。

1.指针+整数

详解指针(超详细)(第一卷)_第16张图片

详解指针(超详细)(第一卷)_第17张图片

这两个算法都是用指针遍历数组然后打印,把数组中第一个元素的地址存进指针,然后顺藤摸瓜找出数组中剩余元素的地址。

2.指针-指针(地址-地址)

详解指针(超详细)(第一卷)_第18张图片

大家觉得最后打印出来的值是多少,相信大部分人会说36(因为int类型指针移动4个字节),但结果却并不是36,而是9。

所以记住这么一句话指针-指针的绝对值是元素的个数,那为什么是绝对值嘞,再看一组代码

详解指针(超详细)(第一卷)_第19张图片

所以懂了叭!

我们都知道C语言中有个函数叫做strlen,统计一个字符串中出\0外的字符个数

详解指针(超详细)(第一卷)_第20张图片

就像这样,那么接下来我们可以用指针-指针自己设计一个类似于strlen函数的函数,来更直观的体验一下指针-指针:

具体代码如下

详解指针(超详细)(第一卷)_第21张图片

见证奇迹的时刻,你会发现它和C语言标准函数strlen的功能一样。

三.野指针

野指针是指指向一个已释放或者未分配的内存地址的指针。这种情况通常会导致程序崩溃、数据损坏或者安全漏洞等问题。野指针的成因有以下几种情况:

1. 未初始化的指针:在使用指针之前没有对其进行初始化,导致指针指向一个随机的内存地址。

2. 释放后使用指针:在释放动态分配的内存之后仍然使用指向该内存的指针。

3. 越界访问指针:指针指向超出分配内存范围的地址。

4. 空指针解引用:对一个空指针进行解引用操作。

5. 指针运算错误:在指针运算过程中出现错误,导致指针指向错误的地址。

为了避免野指针的出现,可以采取以下措施:

1. 初始化指针:在使用指针之前,务必将其初始化为一个有效的地址,例如 NULL。

2. 使用智能指针:智能指针可以自动管理动态分配的内存,避免手动释放内存时出现错误。

3. 检查指针有效性:在使用指针之前,通过检查指针是否为 NULL 或者是否指向有效的内存地址来确保指针的有效性。

4. 使用范围检查:对于数组或动态分配的内存,使用范围检查来避免越界访问。

5. 避免指针运算错误:确保指针运算的正确性,避免指针指向错误的地址。

6. 使用错误处理机制:在程序中添加错误处理机制,捕获和处理可能出现的野指针错误。

你可能感兴趣的:(#指针详解(共四卷),c语言,学习)