C语言深入了解指针一(14)

devtools/2024/10/11 13:27:40/

文章目录

  • 前言
  • 一、内存和地址
    • 内存
    • 究竟该如何理解编址
  • 二、指针变量和地址
    • 取地址操作符&
    • 解引用操作符*
    • 指针变量的大小
  • 总结


前言

  终于来到指针啦!如前篇末尾总结所说,这是你们马上要下大功夫的地方
  但是,就像我们上初中的时候,有人说函数难;我们上高中的时候,有人说导数、圆锥难;上大学的时候,有人说微积分难,事实上,别被吓到了,先勇敢尝试,迈过去了也就那么回事~


一、内存和地址

脱离内存和地址讲指针就是耍流氓!

内存

在讲解之前,先来个比方:

假设有一栋宿舍楼,把你放在楼里,楼上有100个房间,但是房间没有编号,你的一个朋友来找你玩,如果他想找到你,就得挨个房子去找,这样效率很低,但是我们根据楼层和楼层的房间的情况,给每个房间上号,如:
一楼:100、101、102…
二楼:200、201、202…

有了房间号的话,你的朋友就能很快找到你

如果把这个例子对照到计算中,又是怎么样的呢?
我们知道,CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的数据也会放回内存中,那我们买电脑的时候,电脑上内存是8GB/16GB/32GB等,那么这些内存该如何高效管理?
其实也是把内存分为一个个内存单元,每个内存单元的大小为1个字节,一个比特位可以放一个二进制位的1或者0

在这里,每个内存单元就相当于是一个学生宿舍,一个人字节空间里面能放8个比特位,就好比同学们住的八人间,每个人是一个比特位,每个内存单元也都有一个编号(这个编号就相当于是宿舍房间的门牌号)有了这个内存单元的编号,CPU就可以快速找到一个内存空间

生活中,我们把门牌号叫做地址,在计算机中我们把内存单元的编号也称为地址,C语言给这个地址起了一个新的名字,就叫做指针

一言以蔽之,内存单元的编号 == 地址 == 指针
在这里插入图片描述

究竟该如何理解编址

首先,我们必须要理解,计算机中有很多的硬件单元,而硬件单元是要互相协同工作的,所谓的协同,至少相互之间能够进行数据传递
但是硬件与硬件之间是互相独立的,那么如何通信呢?答案很简单,用“线”连起来
而CPU和内存之间也是有大量的数据交互的,所以,两者必须也用线连起来
CPU访问内存中的某个字节空间,必须知道它在内存中的位置,而因为字节很多,所以需要编址(如同宿舍很多。必须要编号一样自然),并且,计算机中的编址,并不是把每个字节的地址记录下来,而是通过硬件设计完成的
钢琴,吉他上面没有写上“都瑞咪发嗦啦”这样的信息,但演奏者照样能够准确找到每一个琴弦的每一个位置,这是什么原因?因为制造商已经在乐器硬件层面设计好了,并且所有的演奏者都知道。这质是一种约定俗成的共识!
而硬件的编址也是一样,我们可以简单理解为,32位机器有32根地址总线,每根线只有两态,表示0,1(电脉冲的有无),那么一根线,就有了2种含义,2根线就能表示4种含义,依次类推,32根地址线就能表示232种含义,每一种含义都代表一个地址
地址的信息被下达给内存,在内存中,就可以找到该地址对应的数据,将数据在通过数据总线传入CPU内寄存器
在这里插入图片描述

二、指针变量和地址

取地址操作符&

理解了内存和地址的关系,我们再回到C语言,在C语言中创建变量其实就是向内存申请空间

比如:
在这里插入图片描述

上述代码就是创建了整型变量a,内存中申请4个字节,用于存放整数10,其中每个字节都有地址,上图中4个字节的地址分别是:

0x000000109136F544
0x000000109136F545
0x000000109136F546
0x000000109136F547

那我们如何得到a的地址呢?
这里就得学习一个操作符&-取地址操作符
在这里插入图片描述

有意思的是,我们是如果&p打印a的地址,是打印出四个字节的地址中的首地址(低地址),也能理解,比如你家有四套房子,那你收一个快递的时候,也还是填一个地址,只要得到了首地址,其他三个地址也就很好求了

所以说&a是一个地址,那么假设变量pa = &a,那么pa是什么类型呢?
答案是int* ,即int* pa = &a; 其中pa就是指针变量,用来存放地址,即用来存放指针

我们也可以有一种形象的说法,pa指向a的第一个字节,这很形象,很有画面感
在这里插入图片描述

解引用操作符*

我们将地址保存起来,未来是要使用的,那怎么使用呢?
答案是在指针变量前面加个*

int a = 10;
int* pa = &a;
*pa = 20; // *是解引用操作符,*pa等价于a

pa就像一个代理人,联想到电视剧《狂飙》,强哥高启强想噶人,不能直接动手,跟老默说想吃鱼了,就是这个意思
至于你说为什么不直接a = 20; 难道计算机里面也会有类似安欣的存在限制了这一操作吗?哈哈,我们以后就会知道的,在这里先按下不表

指针变量的大小

指针变量是专门用来存放地址的,指针变量的大小是多少呢?取决于一个地址的存放需要多大空间!
在前面,我们了解到,32位机器假设有32根地址总线,每根地址线出来的电信号转换成数字信号后是1或者0,那我们把32根地址线产生的2进制序列当作一个地址,那么一个地址就是32个bit位,需要4个字节才能存储
同理64位机器,假设有64根地址线,一个地址就是64个二进制位组成的二进制序列,存储起来就需要八个字节(8 * 8 = 64),所以指针的大小都是4/8个字节

x86和x64环境下的输出结果:
在这里插入图片描述

32位平台下地址是32个bit位,指针变量大小是4个字节
64位平台下地址是64个bit位,指针变量大小是8个字节
注意指针变量的大小和类型是无关的,只要是指针类型的变量,在相同的平台下,大小都是相同的


总结

  指针我估计会出好几篇,第一篇就先不太难,也不太多,并且尽量以图形语言来展示,也卖了几个关子,回头见!


http://www.ppmy.cn/devtools/110068.html

相关文章

社会适老化建设,从一个 LLM 应用开始

引言 “变老很糟糕(Getting old sucks)”,这是电影《勇敢者的游戏》里的一句台词。变老会让人不再敏捷、健壮,会让人疲于跟上社会发展的脚步。据统计,截止 2023 年底,60 岁以上人口占全国总人口的 21.1%。…

【Redis】redis5种数据类型(string)

目录 redis5种数据类型和内部编码方式 redis单线程模型 string字符串类型相关命令 SET GET MSET MGET SETNX SETEX ​编辑PSETEX value值为整数,进行加减操作 INCR INCRBY DECR DECRBY INCRBYFLOAT APPEND GETRANGE SETRANGE STRLEN string的…

在stable diffussion中完美修复AI图片

无论您的提示和模型有多好,一次性获得完美图像的情况很少见。 修复小缺陷的不可或缺的方法是图像修复(inpainting)。在这篇文章中,我将通过一些基本示例来介绍如何使用图像修复来修复缺陷。 需要的软件 我们将使用 AUTOMATIC11…

【JAVA】第五天

【JAVA】第五天 一、Math类二、System类三、Runtime类四、BigDecimal类五、JDK8之前传统的日期、时间(不推荐)1.Date类2.SimpleDateFormat类3.Calendar类 六、JDK8之后新增的日期、时间1.LocalDateTime类2.ZoneId类3.ZonedDateTime类4.Instant类5.DateTi…

Leetcode面试经典150题-55.跳跃游戏

解法都在代码里,不懂就留言或者私信 class Solution {public boolean canJump(int[] nums) {/**如果就一个位置,你本来就在这,肯定可以跳到*/if(nums.length 1) {return true;}/**这个题的解题思路是遍历数组,如果当前位置不在之…

【SRC】某次众测绕过限制注册用户+敏感信息泄露漏洞

吉祥知识星球http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247485367&idx1&sn837891059c360ad60db7e9ac980a3321&chksmc0e47eebf793f7fdb8fcd7eed8ce29160cf79ba303b59858ba3a6660c6dac536774afb2a6330&scene21#wechat_redirect 《网安面试指南》…

再见Java 8,请掌握最新LTS

简介 在Java开发中,Java 8曾经是无可争议的主流,凭借其稳定性和广泛的社区支持,陪伴了无数开发者走过多年辉煌时刻。然而,随着时间的推移,技术不断革新,企业和开发者们逐渐把目光投向了更新的LTS&#xff0…

磁盘映射(C语言)

目录 一、背景介绍 二、磁盘映射技术概述 1.磁盘映射原理 2.磁盘映射的优势 三、C语言实现磁盘映射 磁盘映射技术在C语言中的应用能够极大地提高文件操作的效率。本文将详细介绍磁盘映射的概念、如何在C语言中实现磁盘映射,并通过实际案例展示其在文件读写、数据…