手把手教你深入理解指针,超级超级详细(1)

2025博客之星年度评选已开启 10w+人浏览 738人参与

前言

这一章将初步介绍指针变量和地址以及运算
看完秒懂指针
制作不易,求个关注,是博主写下去的动力


一、内存和地址

一个比特位为一个0或1。
电脑上的内存空间有8G/16G/32G,那这些内存空间如何进行管理?
内存其实划分为一个一个的内存单元,一个内存单位为一个字节(一个字节=8比特位)每个内存单元都有自己的编号(这个编号就相当于学生宿舍的门牌号)。
在这里插入图片描述

内存单元的编号就是它的地址,在C语言中又叫做指针。

下面我在讲一下地址和变量的关系

int a =4;
一步一步拆解:
当你写int a=4;其实是你跟计算机说:
1.帮我在内存中找一个能存一个int类型(4个字节)的数据的空间
2.然后把4放进去
3.给这块内存空间起名叫做a,
计算机会做两件事:
1.分配内存空间:给这块地方分配一个门牌号(地址)0x1234
2.存储数据:把4放进这个地址对应的内存单元里。
后续写a = a + 2时;
计算机的逻辑是:
1.计算机看到这个a时会先去查“变量信息表”,根据这个找到a的地址(第一步是找到地址)
2.从0x1234开始读取4个字节把里面的4取出来
3.加2得到6
4.再把6放回这个地址内
全程没有变量a,变量a只是让我们方便记忆,让我们不用去写那个晦涩的地址,就是为了找到地址;而计算机中只认地址。
这时可能对地址有疑问,不是申请4个字节,应该是4个地址啊
下面进行讲解?
连续的内存空间只认“起始地址”,计算机会把起始地址当做整个变量的地址
运行时计算机会根据类型(也就是那个int类型)查长度(4个字节)

如何理解编址

CPU想要访问内存中的某个字节空间时,必须知道这个字节在哪个位置,又因为内存中的字节很多,必须进行编址(就相当于宿舍楼的宿舍很多,必须给每个宿舍一个门牌号)。
钢琴、吉他 上⾯没有写上“剁、来、咪、发、唆、拉、西,但是演奏者仍然能够根据琴弦找到每个位置。这是因为制造厂商已经在硬件层面设计好了。

硬件编制同理
如果是32位机器,一共有32位地址总线,每根线表示一个0或1,那么如果有两根线,那就是22 (4种),所以32根地址总线,一共有232 种含义,每种含义表示一个地址。32个0或1就是32个比特位就是4个字节,所以每个地址都是4个字节。
如果64位机器则是8个字节。
所以地址的字节数只跟编译器有关

图片描述

大家不要认为地址的字节数和数据类型有关系

其实这两个一点关系也没,地址的字节数,其实就是地址的宽度(就是门牌号的长度)跟编译器有关。数据类型的字节数决定的是里面能存储的长度(也就是变量内存能占多大地方)。
当然大家也别误解地址4个字节和8个字节存储长度不一样,其实门牌号多宽跟里面能存多少东西无关

看到这如果还不理解就多看几遍,实在不行就私信问我

二、指针变量和地址

1.取地址操作符(&)

代码如下(示例):

#include <stdio.h>
int main()
{
	int a = 10;
	&a;//取出a的地址
	printf("%p\n", &a);
	return 0;
}

&a实际是取出的a的起始地址,但是我们知道了起始地址就能找到后面的地址.

2.指针变量

有时候我们也需要对地址进行使用,地址是存储到指针变量中的。

#include <stdio.h>
int main()
{
	int a = 10;
	int* pa = &a;//取出a的地址并存储到指针变量pa中
	return 0;
}

pa左边的*说明pa是一个指针变量(只能存储地址)int说明pa指向的是int类型的对象。

解引用操作符

pa指向的是a的地址,而*pa就是通过pa中存放的地址,找到指向的空间;
*pa实际上就是a了;*pa = 0;就是把a改为了0。

#include <stdio.h>
int main()
{
	int a = 10;
	int* pa = &a;//取出a的地址并存储到指针变量pa中
	*pa = 0;
	return 0;
}

指针变量的大小

指针变量的大小在上面第一节已经讲的很详细了
指针变量的大小由编译器决定的

指针变量类型的意义

指针变量类型决定了一次能够访问几个字节
指针的类型还决定了指针向前或向后走一步的距离
例:pc+1走一个字节
pa+1走四个字节

#include <stdio.h>
int main()
{
	int n = 0x11223344;//每4个二进制改成一个16进制数字,所以11223344把
	//4个字节全占满了
	char* pc = (char*)&n;//&n本质上是int*类型的
	int* pa = &n;
	*pc = 0;
	return 0;
}//只能把第一个字节改成0,所以是0x00223344

void*指针

void类型的指针可以接受任意类型的地址,但是不能直接进行指针±整数和解引用的运算,因为不知道自身什么类型的,所以不知道加/减多少。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值