C语言指针讲解

目录

一.前言

二.什么是指针

1.内存与地址

三.指针变量与使用方法

1.指针变量和地址

2.指针变量的大小

3.指针变量类型的意义

4.指针运算

四.总结

二.什么是指针


一.前言

      在学习C语言时候常听到有人说指针很难,不知道是个什么东西,不知道该怎么使用,接下来就由我给正在学习指针的朋友多一些理解,相信看完此篇文章会有不一样的收获。

二.什么是指针

1.内存与地址

指针其实就是内存里的一个单元地址,那么内存单元地址又是什么呢?

在讲解内存地址之前,我们先看看我们现实生活中地址的例子,假如你现在点了一份外卖,你首先需要在外卖软件上填写自己的地址,比如xx小区xx栋xx室,这样外卖员才能把外卖快速准确的把外卖送到你手里,那么CPU想要给内存存储数据,也是通过找到内存里的一个地址找到内存单元进行存储数据,CPU想要读出内存数据也是通过内存地址找到数据,那内存地址又是怎么来的呢?

我们在用一个生活中例子讲清楚,比如学校里有一栋一栋的宿舍楼,每栋宿舍楼里都会给每个宿舍进行编号,比如一楼是101,102二楼是201,202像这样排序编号,别人想去找你,都是知道你在那个房间才能快速找到你,而每个宿舍都有八个人住,那么内存也是这样,一块内存就像是一栋宿舍楼,大的宿舍楼住的人也就多,大的内存也是一样存的多,我们去买手机电脑时选择要8G,16G,32G内存,内存的单位与换算:

1个字节就好比一间学生宿舍,1个字节有8个bit比特位就像一间宿舍有8个人,1个人就是1个bit比特位,内存里给每个字节单元进行编号(这些编号也和我们宿舍的门牌号一样),CPU只有知道了这些地址编号,才能快速高效的找到数据,我们把宿舍门牌号叫做地址,那么内存里的内存编号也叫做地址,在C语言中又给地址起了一个新名字叫“指针”所以     内存单元编号=地址=指针

1.1理解内存编址

首先CPU想要读取一个字节的内存数据,得知道这个字节空间在哪,但地址编号不是事先就保存好的,而是通过硬件设计完成的,我们要知道在计算机硬件中CPU和其他外设硬件之间都是通过线进行通讯,其中一根叫地址总线。

地址总线其中的一根线有0和1两种含义,那么两根线就有4种,依此类推32根线就有2^32种含义,CPU通过地址总线发送给内存2^32种含义,一种含义就是内存单元的一个地址,内存生产的时候就已经对地址总线2^32种含义进行了对应的编号,就像钢琴演奏者,不用给钢琴的每一个按键贴上编号,人家就知道了这个钢琴键是什么音,为什么呢?是因为钢琴生产时就已经规定每个按键都是固定的一个音,只要会钢琴的人都知道,本质是一种约定出来的共识!CPU和内存之间也是如此。

三.指针变量与使用方法

1.指针的变量和地址

1.1指针变量创建

 

第一个为普通变量,我们知道创建变量后系统会给变量申请内存空间,那么内存空间肯定会有地址 ,那么有没有东西可以帮我们把地址存放起来,供我们以后使用呢?那就需要用到指针变量了

第二个就是指针变量的创建了,让我们来解读一下  pw 是变量名,*表示pw是个指针变量,int表示指针变量指向的是一个整型类型的对象,根据以上图所示  &为取地址操作符把变量a的地址取出来赋给指针变量所以指针变量是用来存放地址的!根据我们上面分析把变量a的地址给了指针变量pw后,那么pw里面存放的就是a的地址了,把地址打印出来看看到底是不是呢?

用%p打印我们看到pw存放的的确是a的地址。

1.2  * 解引用操作符 

 上面我们知道了指针变量存放的是地址,那么把地址存放起来后有什么用呢,这就得介绍一下*解引用操作符了,把指针变量进行解引用找到他存放的那个地址的数据,以上面为例:pw进行解引用后找到了a地址的数据,就可以修改a的数值

 2.指针变量大小

我们知道了指针变量创建左边写类型加一个*比如int*,但是这里的类型不代表指针变量也是int类型的指针,而是指针指向的对象是int类型,那么指针变量也是变量,是变量系统就会为变量开辟内存空间那么系统不知道指针变量是什么类型怎么开辟空间呢?

在前面时我们了解到地址总线在32位机器中是32根地址线,那么每根地址出来的电信号转换成数字信号后是1或者0的 那么我们把32线产生的这样的二进制序列当做一个地址,那么一个地址就是32个比特位,所以32位机器中的地址就是4个字节,所以指针变量就是存放地址的在32位机器就是4个字节的空间,同理在64位机器中计算64个比特位就是8个字节

X86环境下:

X64环境下: 

3.指针变量类型和意义

前面指针变量左边加上个类型比如:int  我们知道它是指针指向的int类型的对像,那它有什么用呢?

int是的4个内存空间是4个字节大家都知道,但是在指针变量这里表示指针解引用后能对指向的对象内存有4个字节的访问权限同理char是一个字节的空间,那么创建char*类型的指针后,解引用只能对指向的对象有一个字节的访问权限。接下来用代码调试看看:

修改变量a前 a在内存的数据:

 

经过*pw=0修改后

 

 变量a的空间是4个字节,所以int*指针变量就有了4个字节访问权限,也就有了四个字节的修改权限,那么在把指针pw改成char*试试:

 

修改变量a前 a在内存的数据: 

 

 经过*pw=0修改后

 变量a的空间是4个字节,但是pw改成char*只有了1个字节访问修改权限。

4.指针运算

指针的基本运算有三种,分别是:

指针+-整数

指针-指针

指针的关系运算

4.1指针+-整数

 

我们先知道arr是数组名,其实数组的数组名就是数组首元素的地址,代码演示:

 此时pw同等于arr首元素地址,也就是arr[0]下标的元素1,那么我们加1后指针就跳过首元素地址,指向第二个下标arr[1]元素2地址并打印。所以这里的指针加1就是跳过一个元素地址

当然这里指针是int*对应上了int类型的数组,数组的元素也是int跳过4个字节:

如果char*指针就不是一个元素了而是跳过1个字节:

4.2指针-指针

 这里的指针-指针是不是也可以计算字符串长度呀,这也是库函数strlen的功能,所以用指针-指针可以实现库函数strlen的功能,指针-指针减的是两个指针中间元素个数,上面的代码pw的地址先赋给ps,然后pw++加到\0的地址停下,再用pw-ps不就是\0减a得出的计算中间相差几个元素了嘛。

4.3指针的关系运算

 以上关系运算和指针-指针差不多,指针首先拿到arr第一个素数的地址,arr+sz(sz在上面代码中计算出来是10)此时arr+sz等于元素10后面的空间地址,pw的地址比arr+sz的地址小就进入循环,依次打印,然后++,pw+到和arr+sz的地址就停下,就成功打印了所有元素。

四.总结

其实指针并不难,难的是应该如何理解指针,希望大家看完本篇文章,能够对学习指针有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值