网易首页 > 网易号 > 正文 申请入驻

C语言指针底层原理

0
分享至

如果要选出C语言中最重要、难度大的概念是什么,那就是指针!难度大,意味着使用方便、实用高效,同时也意味这个知识点复杂、实用的时候容易出错。指针用的好,可以提高代码执行效率、节约系统资源;如果用的不好,程序中就会出现一定的问题。

今天我们就来聊一下指针。从最底层的内存存储空间开始,一直到应用层的各种指针使用技巧,循序渐进,以最简洁的语言进行讲解,希望能对你有一点点帮助就够了。

说明:素材难找,为了偷懒和方便讲解和理解,文中配图的内存空间的地址是随便写的,在实际计算机中是要遵循地址对齐方式的。

变量与指针的本质

内存地址

我们编写一个程序源文件之后,编译得到的二进制可执行文件存放在电脑的硬盘上,此时它是一个静态的文件,一般称之为程序。

当这个程序被启动的时候,操作系统将会做下面几件事情:

·把程序的内容(代码段、数据段)从硬盘复制到内存中;

·创建一个数据结构 PCB(进程控制块),来描述这个程序的各种信息

·在代码段中定位到入口函数的地址,让 CPU从这个地址开始执行。

当程序开始被执行时,就变成一个动态的状态,一般称之为进程。

内存分为:物理内存和虚拟内存。操作系统对物理内存进行管理、包装,我们开发者面对的是操作系统提供的虚拟内存。

这 2个概念不妨碍文章的理解,因此就统一称之为内存。

在我们的程序中,通过一个变量名来定义变量、使用变量。

变量本身是一个确确实实存在的东西,变量名是一个抽象的概念,用来代表这个变量。

那么,我们定义一个变量之后,这个变量放在哪里呢?那就是内存的数据区。

内存是一个很大的存储区域,被操作系统划分为一个一个的小空间,操作系统通过地址来管理内存。

内存中的最小存储单位是字节(8个 bit),一个内存的完整空间就是由这一个一个的字节连续组成的。

32位与 64位系统

我们平时所说的计算机是 32位、64位,指的是计算机的 CPU中寄存器的最大存储长度,如果寄存器中最大存储 32bit的数据,我们就叫作32位系统。

在计算机中,数据一般都是在硬盘、内存和寄存器之间进行来回存取。CPU通过 3种总线把各组成部分联系在一起:地址总线、数据总线和控制总线。地址总线的宽度决定了 CPU的寻址能力,也就是 CPU能达到的最大地址范围。

刚才说了,内存是通过地址来管理的,那么 CPU想从内存中的某个地址空间上存取一个数据,那么 CPU就需要在地址总线上输出这个存储单元的地址。

假如地址总线的宽度是 8位,能表示的最大地址空间就是 256个字节,能找到内存中最大的存储单元是 255这个格子。即使内存条的实际空间是 2G字节,CPU也没法使用后面的内存地址空间。如果地址总线的宽度是 32位,那么能表示的最大地址就是 2的 32次方,也就是 4G字节的空间。

【注意】这里只是描述地址总线的概念,实际的计算机中地址计算方式要复杂的多,比如:虚拟内存中采用分段、分页、偏移量来定位实际的物理内存,在分页中还有大页、小页之分。

变量

我们在 C程序中使用变量来“代替”一个数据,使用函数名来“代替”一个函数,变量名和函数名是程序员使用的助记符。变量和函数最终是要放到内存中才能被 CPU使用的,而内存中所有的信息(代码和数据)都是以二进制的形式来存储的,计算机根据就不会从格式上来区分哪些是代码、哪些是数据。CPU在访问内存实际上是访问地址,而不是访问变量名、函数名。

在程序代码中使用变量名来指代变量,而变量在内存中是根据地址来存放的,这二者之间是通过编译器映射(关联)起来的。

变量有 2个重要属性:变量的类型和变量的值。

示例:代码中定义了一个变量

int a = 20;

类型是 int型,值是 20。这个变量在内存中的存储模型为:

我们在代码中使用变量名a,在程序执行的时候就表示使用 0x11223344地址所对应的那个存储单元中的数据。

因此,可以理解为变量名 a就等价于这个地址 0x11223344。换句话说,如果我们可以提前知道编译器把变量 a安排在地址 0x11223344这个单元格中,我们就可以在程序中直接用这个地址值来操作这个变量。

在上图中,变量 a的值为 20,在内存中占据了 4个格子的空间,也就是 4个字节。为什么是 4个字节呢?在 C标准中并没有规定每种数据类型的变量一定要占用几个字节,这是与具体的机器、编译器有关。

比如:32位的编译器中:

char: 1个字节;

short int: 2个字节;

int: 4个字节;

long: 4个字节。

比如:64位的编译器中:

char: 1个字节;

short int: 2个字节;

int: 4个字节;

long: 8个字节。

为了方便描述,下面都以 32位为例,也就是 int型变量在内存中占据 4个字节。

另外,0x11223344,0x11223345,0x11223346,0x11223347这连续的、从低地址到高地址的 4个字节用来存储变量 a的数值 20。

在图示中,使用十六进制来表示,十进制数值 20转成 16进制就是:0x00000014,所以从开始地址依次存放 0x00、0x00、0x00、0x14这 4个字节(存储顺序涉及到大小端的问题,不影响文本理解)。

根据这个图示,如果在程序中想知道变量 a存储在内存中的什么位置,可以使用取地址操作符&,如下:

printf("&a = 0x%x \n", &a);

这句话将会打印出:&a = 0x11223344。

考虑一下,在 32位系统中:指针变量占用几个字节?

指针变量

指针变量可以分 2个层次来理解:

·指针变量首先是一个变量,所以它拥有变量的所有属性:类型和值。它的类型就是指针,它的值是其他变量的地址。既然是一个变量,那么在内存中就需要为这个变量分配一个存储空间。在这个存储空间中,存放着其他变量的地址。

·指针变量所指向的数据类型,这是在定义指针变量的时候就确定的。例如:int *p;意味着指针指向的是一个 int型的数据。

在 32位系统中,一个指针变量在内存中占据 4个字节的空间。因为 CPU对内存空间寻址时,使用的是 32位地址空间( 4个字节),也就是用 4个字节就能存储一个内存单元的地址。而指针变量中的值存储的就是地址,所以需要 4个字节的空间来存储一个指针变量的值。

示例:

int a = 20;

int *pa;

pa = &a;

printf("value = %d \n", *pa);

在内存中的存储模型如下:

4.在返回到STM32CubeMX后,在Pinout&Configuration里面的pinout view,点击选择PA8 PIN脚,在弹出的小框里面选择RCC_MCO,使得PA8作为MCO输出PIN脚。同样地方式,设置PA1为GPIO Output。

5.本期先分享到这里,想要进群学习单片机编程的同学可以私信我,回复“我要入门”,与我们一起成长,喜欢的可以点个赞关注我们!

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
CCTV5直播国足vs泰国:张玉宁&阿兰火速复出+参与合练 只求一胜

CCTV5直播国足vs泰国:张玉宁&阿兰火速复出+参与合练 只求一胜

智道足球
2024-06-03 11:22:22
胡塞打了美国航母,然后70%的国家都有想法了!

胡塞打了美国航母,然后70%的国家都有想法了!

武当云中客
2024-06-01 21:33:39
变天!东欧战双探花球市火爆G6最便宜超1万3一张 无詹杜库仍大赚

变天!东欧战双探花球市火爆G6最便宜超1万3一张 无詹杜库仍大赚

厝边人侃体育
2024-06-03 17:11:55
出轨大瓜,曝光网红果果老公大尺度聊天记录,好恶心

出轨大瓜,曝光网红果果老公大尺度聊天记录,好恶心

户外阿崭
2024-06-02 19:25:03
网约车提现收入迟迟不到账,官方回应:不要接这个平台的单!

网约车提现收入迟迟不到账,官方回应:不要接这个平台的单!

用车指南
2024-06-03 09:59:42
张海迪曾患十几种癌病,被判定只能活27年,为何活到现在快70岁?

张海迪曾患十几种癌病,被判定只能活27年,为何活到现在快70岁?

胥言
2024-03-11 23:22:23
由财政部监管的央企数量超过了国资委,达到了143家,可分为三类

由财政部监管的央企数量超过了国资委,达到了143家,可分为三类

小圣杂谈原创
2024-06-02 19:48:38
把跌停进行到底!10只连续跌停一个月的股票,又开启6月连续跌停

把跌停进行到底!10只连续跌停一个月的股票,又开启6月连续跌停

惜别的海岸
2024-06-03 11:11:16
无偿献血可降低血脂

无偿献血可降低血脂

华易商丘
2024-04-15 08:55:51
炸了!伊万火速敲定锋线“恐怖组合”,中泰之战赢球稳了

炸了!伊万火速敲定锋线“恐怖组合”,中泰之战赢球稳了

徽派体育
2024-06-02 22:17:04
106个国家确认出席瑞士和平峰会,泽连斯基称俄罗斯试图破坏峰会

106个国家确认出席瑞士和平峰会,泽连斯基称俄罗斯试图破坏峰会

山河路口
2024-06-02 16:35:18
血栓“大户”被揪出,是肥肉的10倍!医生:经常吃,血管或扛不住

血栓“大户”被揪出,是肥肉的10倍!医生:经常吃,血管或扛不住

今日养生之道
2024-06-03 02:03:46
蔡斌为何雪藏朱婷?央视解说给出的分析你赞同吗,惠若琪一针见血

蔡斌为何雪藏朱婷?央视解说给出的分析你赞同吗,惠若琪一针见血

何老师呀
2024-06-02 22:16:34
86年刘伯承离世,为啥邓小平在看到治丧委员会名单后,勃然大怒?

86年刘伯承离世,为啥邓小平在看到治丧委员会名单后,勃然大怒?

丹宝说文史
2023-10-19 15:38:12
120年的日内瓦车展停办,欧美车企无法接受!美媒:都怪中国汽车

120年的日内瓦车展停办,欧美车企无法接受!美媒:都怪中国汽车

户外小阿隋
2024-06-03 01:44:08
“偷卖学校”之后,又有研究生把导师挂上二手平台,同学纷纷效仿

“偷卖学校”之后,又有研究生把导师挂上二手平台,同学纷纷效仿

熙熙说教
2024-06-01 12:50:17
记者:若无法达成续约协议,尤文至少3500万到4000万欧出售基耶萨

记者:若无法达成续约协议,尤文至少3500万到4000万欧出售基耶萨

直播吧
2024-06-03 17:23:08
外国网友热议嫦娥六号成功登陆,法国网友:没有看到美国国旗!

外国网友热议嫦娥六号成功登陆,法国网友:没有看到美国国旗!

田间农人阿馋
2024-06-03 12:49:02
俄乌战争即将发生根本性改变

俄乌战争即将发生根本性改变

诉说人世间
2024-06-02 14:33:39
克罗斯退役后做什么?

克罗斯退役后做什么?

星耀国际足坛
2024-05-26 22:59:13
2024-06-03 17:44:49
小伙单片机编程
小伙单片机编程
想学单片机的看过来,带你入门
75文章数 262关注度
往期回顾 全部

科技要闻

2万字演讲|黄仁勋剧透 未来3年新品有这些

头条要闻

武汉一警察与歹徒搏斗身中15刀牺牲细节:现场异常逼仄

头条要闻

武汉一警察与歹徒搏斗身中15刀牺牲细节:现场异常逼仄

体育要闻

万人空巷!皇马举行欧冠夺冠庆典

娱乐要闻

混战升级!编剧赵冬苓力挺王阳遭围攻

财经要闻

接班100天,宗馥莉急了

汽车要闻

搭载华为HiCAR 传祺M6 MAX售14.58万元

态度原创

旅游
艺术
健康
手机
房产

旅游要闻

哈尔滨至香港航线正式开通

艺术要闻

穿越时空的艺术:《马可·波罗》AI沉浸影片探索人类文明

晚餐不吃or吃七分饱,哪种更减肥?

手机要闻

一加12 Glacial White海外发布 赠送行李袋约售5670元

房产要闻

12000+起!海口40+楼盘,最新价格曝光!

无障碍浏览 进入关怀版