C语言【指针】你还模糊?看这篇!

发布于:2022-11-01 ⋅ 阅读:(401) ⋅ 点赞:(0)


前言

在C语言的学习中,指针几乎是让所有学者又爱又恨的东西,没学好指针的人觉得指针真复杂,学好指针的人觉得指针真NB。

并且圈内流传一句话“指针没学好,相当于C语言白学”,也看得出指针在C语言的重要性,几乎占据核心地位,那么本篇将分享本人学习指针时记录的笔记,从0带你认识指针,理解指针!


提示1:本篇仅定位在指针的初阶部分,并不是全部!!下篇会介绍指针的进阶知识及用法

提示2:是正在努力进步的小菜鸟一只,如有大佬发现文章欠佳之处请多多指点~ 废话不多说,直接上干货!那么一下就是本篇的正文啦

一、指针是什么?

指针理解的2个要点:

  1. 指针是内存中一个最小单元的编号,也就是地址
  2. 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量

总而言之:
指针就是地址,口语中说的指针通常指的是指针变量

1.理解指针

如果我们定义一个整形变量a:

int a = 10

那么这个int类型的变量所占内存空间为4个字节(32位平台),而计算机中存储数据的最小单位就是字节
局部变量存放在栈区,所以为a分配内存需要压栈(a在栈底),可以理解为:在这里插入图片描述

00 00 00 0a 是十六进制序列,转化成十进制就是数字10,为什么大家看到的从低地址到高地址显示的是0a 00 00 00 是因为这个编译器是采用小端存储的方式,感兴趣的可以去了解一下大小端的问题

a的这每一个字节都有一个地址(编号),注意,我是通过取地址符&找到a的地址的

那我们是否可以把a的地址当作一个值存放到一个可以接收地址的变量里呢?
这就是指针变量。

int* pa = &a;

我们把a的地址存放在pa这个变量里,*表示这是一个指针,int表示指针指向的数据是int类型。
这样我们就可以通过pa这个指针,找到a的地址,继而找到a。

2.两个问题

至此,有两个问题需要注意:
1、
pa存放着a的地址,但是我们刚刚看到a有四个字节的地址,这里实际上只把a的首地址(低地址处)存放在pa中!!!!
我们只找到了a的四个地址中的首地址啊,那如何找到完整的地址,访问a呢?刚刚我们创建指针变量的时候,定义了这个指针指向的数据的类型是int,int占4个字节,所以我们只需要存放a的首地址,从这为起点向下找够四个就可以找到a的全部地址,从而访问到a。

2、
刚刚提到了“指针变量”这个词
a 是一个整形变量,a有自己的内存空间,占4个字节
pa是一个指针类型的变量,pa必然也有自己的内存空间,那pa占几个字节呢?

pa里面存放着的是一个地址对吗,我们看到的地址一般都是十六进制序列,转化为二进制就是32位bit位,所以地址本质就是一个32位的二进制序列,占4个字节,
把4个字节的地址存放在变量中,那这个变量的大小是多少呢?不就是四个字节嘛~所以无论什么类型的指针,它的大小都是四个字节

3.总结

在这里插入图片描述
指针pa用来存放a的地址,&a,把a的地址赋给pa这个指针变量
那么pa的值就是a的地址,我们在调试–窗口–监视可以看到&a和pa的值是一模一样的
并且pa本身也有一个地址,&pa可以得到pa的地址

二、指针和指针类型

1.指针的解引用

刚刚用了那么多文字讲清楚指针是个啥,那么现在来说说指针有什么用呢?

还拿刚刚的栗子来说,pa中存放着a的地址。
我们知道,如果我有你家的地址,就可以找得到你,那么我有了a的地址,是否可以通过这个地址找到a呢?
找到了a就可以改变a。

来看代码是如何操作的:
在这里插入图片描述
我们取出a的地址,把a的地址存放在pa这个指针变量中,那么解引用这个指针就可以直接更改a的值,这里用到了一个操作符:解引用操作符
第七行和第八行的两个星号的意义是不同的
第七行的星号是标注出pa是一个指针类型的变量,而第八号的星号是一个操作符,它可以对指针变量使用,直接修改存放在指针变量中的地址的值

通俗理解为,解引用操作符就像酒店房间的房卡
找到对应的房间(pa),对房门刷房卡(解引用)就可以进入房间内,吃饭睡觉看电视(更改a)

理解了指针的解引用操作以后,请思考:
例如a=10;b=20; 自定义一个函数,如何在函数中把10和20交换呢?
在此之前需要一个基本的知识:调用函数的时候,会有 “实参” 和 “形参” 两个概念,而形参只是实参的临时拷贝,如果在函数内部交换a和b,交换的只是形参,实际上实参并没有改变,那怎么办呢?

这就需要用到指针,解引用指针就可直接访问到数据。
具体代码小伙伴们可以自己写一下,欢迎评论区讨论~

关于函数的栈帧创建和销毁,作者第一篇文章就分享啦,超详细解析了函数调用的过程,包括压栈出栈,实参形参等等,十分建议大家去考古,对大家的 “内功” 修炼很有帮助~

2.指针类型的意义

以上,我们定义pa这个指针的类型都是int*,那它是否有其他类型呢?
当然有,我们可以 int* pa,也可以char* pa,也可以double* pa

那定义不同类型的指针有什么意义呢?
在这里插入图片描述
这里注意区分 36 行和 40 行处,指针+1解引用指针再+1是不一样的噢
指针+1是修改地址,解引用之后再+1是直接修改这个值
小伙伴们自己敲代码的时候不要敲错噢

再强调一遍,指针就是地址,地址就是指针
指针的值发生变化,地址也就变化了,那么这个地址对应的值自然也就不是原来的值了

三、野指针

概念: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

1.野指针成因

在这里插入图片描述
第三点是什么呢?如果你是初学者可能不是很了解动态开辟内存,所以这里不过多描述,等后面小伙伴们学到 malloc 这个函数的时候就知道啦

2.如何规避野指针

在这里插入图片描述

四、指针运算、二级指针、指针数组

在这里插入图片描述
68 行处的 *pa和 69 行的pa++,这两句小伙伴们一定要好好理解!!自己敲的时候很容易写混
包括下面 106 行和 108 行、124 行和 126 行
在这里插入图片描述
在这里插入图片描述
如果是刚刚接触指针的朋友不需要着急弄懂二级指针,基础阶段一般用到的不多,等熟练掌握一级指针后,再理解二级指针及使用就很轻松了


总结

以上就是今天要讲的关于【指针】的初阶!!!注意是初阶内容,本文仅仅简单介绍了指针是啥东西,指针类型及意义,以及基本的使用方式。
而【指针】远不止这些,你还需要更加深入的了解指针,使用指针,本篇埋了个铺垫,卖了个关子,刚刚提到指针数组就戛然而止了。
下篇文章将给大家带来【指针】的进阶知识,带大家更加深入的掌握指针,下篇文章你会收获更多,更加感叹指针的强大!指针YYDS!!

如果本篇对你有帮助,请点赞收藏支持一下,小手一抖就是对作者莫大的鼓励啦~

上山总比下山辛苦
下篇文章见

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到