指针(1)

指针是什么?

1.内存和地址

1.1内存

计算机上CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的数据也会放回内存中
在这里插入图片描述

把内存划分为⼀个个的内存单元,每个内存单元的大小取1个字节。 
计算机中常见的单位:⼀个比特位可以存储⼀个2进制的位1或者0其中,
每个内存单元,相当于⼀个学生宿舍,⼀个字节空间里面能放8个比特位,
就好比宿舍住的八人间,每个人是⼀个比特位。
每个内存单元也都有⼀个编号(这个编号就相当于宿舍房间的门牌号),
有了这个内存单元的编号,CPU就可以快速找到⼀个内存空间。

在这里插入图片描述

在这里插入图片描述

1.2究竟该如何理解编址

在这里插入图片描述

2.指针变量和地址

2.1取地址操作符(&)

在这里插入图片描述
在这里插入图片描述
&a取出的是a所占4个字节中地址较⼩的字节的地址,第一个字节的地址。
这里的19其实是十六进制的25。

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

2.2.1指针变量
我们通过取地址操作符(&)拿到的地址是⼀个数值,比如0X003B52EFFC24,
如果我们需要用到这个地址的话我们就需要将这个数值存储起来,⽅便后期
再使用的,那我们把这样的地址值存放在哪里呢?
答案是:指针变量中
#include<stdio.h>
int main()
{
	int a = 25;
	int* p = &a;//将a的地址放在指针变量p中,这个p的类型是int*

	return 0;
}
指针变量也是⼀种变量,这种变量就是用来存放地址的,存放
在指针变量中的值都会理解为地址。
2.2.2如何拆解指针类型

在这里插入图片描述
这里p左边写的是 int* , * 是在说明p是指针变量,而前面的 int 是
在说明p指向的是整型(int)类型的对象
在这里插入图片描述

2.2.3解引用操作符

当我们知道一个房间的号码时,我们可以找到这个房间,那么如何打开门进去拿东西,便需要一把钥匙,那么解引用操作符(*)就是这把钥匙

#include<stdio.h>
int main()
{
	int a = 25;
	int* p = &a;
	*p = 0;
	return 0;
}
  *p 的意思就是通过p中存放的地址,找到指向的空间,*p其实就是a变量了;
所以*p = 0,这个操作符是把a改成了0。

  这个步骤是不是多此一举,明明可以直接a = 0,为什么要加个指针呢?
这是因为,有时候我们需要通过地址来寻找到a,比如在一个个的程序段中,
变量是局部的,出了这段代码,局部变量就消失了,我们不能在其他程序段中
访问这个变量,这个时候地址就表现的特别重要,我们可以直接在外部访问
这个地址从而取出或改变里面的值。比如酒店有一个房间,酒店的主人可以
随时改变这个房间的内容(局部变量),但在外面的我如何知道房间,以及
打开房间呢,就需要一个编码(比如3002等)和一把钥匙(*)。
(这只是一个例子,便于理解)

2.3指针变量的大小

前面的内容我们了解到,32位机器假设有32根地址总线,每根地址线出来的电信号转换成数字信号后是1或者0,那我们把32根地址线产生的2进制序列当做⼀个地址,那么⼀个地址就是32个bit位,需要4个字节才能存储。
如果指针变量是⽤来存放地址的,那么指针变的⼤⼩就得是4个字节的空间才可以。
同理64位机器,假设有64根地址线,⼀个地址就是64个⼆进制位组成的⼆进制序列,存储起来就需要8个字节的空间,指针变的⼤⼩就是8个字节。

X64环境下
X86环境下
结论:(很重要)
• 32位平台下地址是32个bit位,指针变量大小是4个字节。
• 64位平台下地址是64个bit位,指针变量大小是8个字节。
• 注意指针变量的大小和类型是无关的,只要指针类型的变量,在相同的平台下,大小都是相同的。

3.指针变量类型的意义

3.1指针的解引用

在这里插入图片描述
由图可知,指针类型决定了指针进行解引用操作的时候访问多大空间,比如 :
int* 的指针解引用访问4个字节
char* 的指针解引用访问1个字节
所以上面的图中,int* 定义的pa,可以改变4个字节的内容,
char* 定义的pa,只能改变1个字节的内容。
注意:上述的做法是不对的,之所以用char*类型的指针来存放int 类型的变量,是为了来方便理解访问内容的权限。
在这里插入图片描述
如果非要放置可以强制类型转化一下
在这里插入图片描述

3.2 指针±整数

在这里插入图片描述
char* 类型的指针变量**+1跳过1个字节**,
int* 类型的指针变量**+1跳过了4个字节**,
这就是指针变量的类型差异带来的变化。
结论:指针的类型决定了指针向前或者向后⾛⼀步有多⼤(距离)。

//如:
int main()
{
    type* p;//(type代表一个指针类型,用于解释)
    p + i;//相当于跳过了i个type类型的数据
           //相当于跳过了i*sizeof(type)个字节
}

3.3 void* 指针

在指针类型中有⼀种特殊的类型是 void* 类型的,可以理解为无具体类型的指针
(或者叫泛型指针),这种类型的指针可以用来接受任意类型地址。但是也有局限性,
 void* 类型的指针不能直接进行指针的+-整数和解引用的运算

上面指针的解引用中最后有讲到类型不兼容,而void*这个类型的指针可以接收任何类型的地址(指针)。
在这里插入图片描述

但是 void* 类型的指针不能直接进行指针的±整数和解引用的运算(如下图)因为它没有具体的类型,无法进行解引用(可以理解为我不知道我的权限有多少,我怎么解) , "±"运算同样如此
在这里插入图片描述

总结

本篇博客,简单介绍了指针的部分内容,包括什么是内存和地址,什么是指针变量,如何取地址,如何解引用,以及指针变量类型的意义等,希望能给大家一点点帮助,有什么不对的地方还请在评论区指正。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值