编程仙尊——深入理解指针(1)

目录

1.认识指针

2.指针变量和地址

2.1取地址操作符(&)

2.2 指针变量和解引用操作符

2.3 指针变量的大小

3.指针类型的意义

3.1指针的解引用

3.2 指针+-整数

3.3 void*指针



1、认识指针

在生活中,一栋楼的每个房间都会有房间号

有了房间号,就能提高效率,很容易的找到房间

而在C语言中,也会有这样一个个的 “房间” ,我们将它称为地址,有了这些地址,我们就很容易找到我们所创建的变量

同时,在C语言中,我们给地址起了一个新的名字,也叫做--指针

指针==地址==内存编号

我们知道,CPU和内存之间是有大量的数据交互的

而内存也被划分为一个个的单元,1个内存单元大小是1个字节(1个字节拥有1个地址)

每个内存单元都会拥有一个编号,这个编号就是地址,C语言中也把地址称作为指针



回到C语言

我们在编程中,每一次创建新的变量,其实就是在向内存中申请新的空间

如下图:在我们 int a 时,因为 int 是4个字节,所以我们会向内存中申请四个字节的地址

而这四个字节中每一个字节都会有属于自己的地址

下图中 int 申请的四个字节中,地址分别是

0*000000765F4FFC34        0*000000765F4FFC35

0*000000765F4FFC36        0*000000765F4FFC37

4394c41dca864de196e2935c72a2a394.png

2、指针变量和地址

2.1取地址操作符(&)

那么,如何在编程中取出我们的地址呢?

这时就要用到取地址操作符(&)

有了取地址操作符,我们就可以将变量的地址取出来,那么,&该如何使用呢,只需要在 & 后加入你想取出地址的变量,就可以取出变量的地址

022dd08dec4d498881be43e50c4cc778.png

如上图,&a就可以将变量a的地址取出来,取出来的地址会是4个字节中地址较小的字节的地址

虽然整型变量占用了4个字节,但是只要我们知道了第一个字节的地址,顺藤摸瓜访问到4个字节的数据也是可以的



2.2 指针变量和解引用操作符

2.2.1指针变量

既然我们可以将地址取出来,那么有没有一种方式,可以将我们的地址存放起来,方便我们以后利用这个地址呢?

其实是有的,那就是我们的指针变量

指针变量是一种专门用来存放地址的变量

比如:

adc6d2dda78948b0858da31835c219a7.png

在这里,我们利用指针变量pb,将a的地址存放在pb中,这样以后我们想利用 a 的地址时,我们只需要利用 pb 就可以访问到a的地址


2.2.2 如何理解指针变量

5746588069e44c3d86ec14736175c62c.png

在指针变量 int * pb 中,*是在说明 pb 是一个指针,int 是在说明 pb 所指向的指针是整型类型的内容

*的位置并不重要,无论是int* pb,还是int *pb,在这里的意义都是等价的

指针变量pb,它的类型是 int* 类型,这就像 int  a 中 a 的类型是int,去掉变量名就是变量的类型


2.2.3 解引用操作符

在指针变量中,我们可以利用地址来进行变量内容的更改,这种更改就需要运用解引用操作符(*)

通过解引用操作符(*),我们就可以实现变量内容的更改

比如:

fd5662171eb14a8f87590c387b70728d.png

这里就通过解引用操作符,实现了 a 内容的更改

通过解引用操作符,*pb 就等于从 a 的较小字节的地址开始,进行4个字节的解析,进而得到 a 的全部内容

通过指针对a的修改,就多了一种修改内容的途径,写代码就会更加灵活


2.3 指针变量的大小

32位平台下地址是32个bit位,指针变量大小是4个字节

64位平台下地址是64个bit位,指针变量大小是8个字节

8c7774cc0fe948fdaae4247ad77a05c1.png7d511544a0f74b05b0aa4f5560823a3e.png

无论是哪种类型的指针类型,它们的字节在平台下都是一致的

结论:

指针变量的大小和类型是无关的,只要指针类型的变量在相同的平台下,大小都是相同的


3. 指针类型的意义

3.1指针的解引用

ef505acc848443c4886416d324ba4140.png170e532f4c0f46b091774a4c18023e6c.png

a4b08345b9784411b5c42be809225cf4.png1e6ec26b05674e0d880138ba2d56854d.png

调试后可以发现,上面的代码会将4个字节全部更改为0,而下面的代码只会将第一个字节更改为0

结论:指针的类型决定了,对指针解引用的时候有多大的权利(一次能操作几个字节)

比如对(char*)类型的解引用就操作了1个字节,对(int*)类型的解引用就操作了4个字节

4cebaa327a304558a67c7e30a20f5244.png

这里 a 的数值是287454020,pa存放的是a的地址,pb存放的也是a的地址

但是对 pa 解引用就会访问4个字节的内容,但对 pb 解引用就只会访问1个字节的内容

这是因为 pa 与 pb 的指针类型不同


3.2 指针+-整数

指针+-整数运行代码如下

2433c1a04d3e472fb6748c45faaa0f0d.pngb0928004ee8443ccb7a83ed0be1a6799.png

可以发现指针+-整数,得到的地址发生了改变

而不同类型的指针,+-整数所得到的地址,跳过的字节是不一样的

int*类型的指针变量+1或者-1都是跳过了4个字节,只不过+1是向前4个字节,-1是向后4个字节

char*类型的指针变量+1或者-1都是跳过了1个字节,只不过+1是向前1个字节,-1是向后1个字节

因此我们可以得出结论:

指针的类型决定了指针向前或者向后走一步有多大(距离 / 字节)

这里跳过的其实是n*sizeof(int)/ n*sizeof(char) ,这里n代表指针 +- 的整数(n)

通用公式为  n*sizeof(类型)


3.3 void*指针

当我们使用void指针时,通常是在实现函数功能时,所接受的地址不确定是什么类型的,有可能是int*类型,也有可能是char*类型,或者其他类型时,我们就会使用void*指针

比如:

54bfdaeb49c04ed5b09b6c3cd81c49a6.png

这时函数不确定接受的指针类型,就可以使用 void* 指针

void*指针是无法实现指针+-整数的,因为void是没有字节大小的,所以无法确定跳过几个字节

当我们想要void*指针+-整数时,系统就会报错,比如 :

2419f044d0eb4779b57dea94a03559f6.png

不过我们可以通过强制转化,间接实现指针+-整数,比如:

6e08750723244f2d9292bd56e6aea53b.png

可以看到即是是 void* 类型的指针,它也确实存进去了a的地址

将void*强制转化为int*,是可以实现指针+-整数的

  • 26
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值