当前位置: 首页 > news >正文

C语言指针01

1.如何理解指针

首先我们需要有这样的认识,在计算机中当CPU处理数据时,是从内存中读取数据的,而内存由一个个内存单元组成的,因此我们需要读取的数据就被存放在一个个内存单元中。但是,你想操作一个数据的话,你首先需要找到这个数据的位置。那么怎么才能找我们需要的数据所在的内存单元呢,这时,我们会给每个内存单元编号,这些编号就是地址,而指针其实就是地址。

我们可以简单理解为内存单元的编号 == 地址 == 指针。

2.指针变量和地址

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

如上所示就是当我们创建变量a时,在内存中申请的连续的4个字节的空间,每个字节8个比特位,这里用的是十六进制来表示的,这四个字节地址由低到高分别是

00F6FAD4//0A 00F6FAD5//00 00F6FAD6//00 00F6FAD7//00

2.1取地址操作符

那么我们应该如何获取a的地址呢,这时候我们就需要用到取地址操作符&,用法如下:

当我们需要打印地址的时候,用到的占位符是%p,如果想要获取a的地址的话,就使用&a。

但是这里可以看到,这里生成的a的地址,和我们上面所获得的a的地址并不一样,内存是随机分配的,每次执行程序的时候,a的地址都会不一样。并且,在取地址时(&a),取出是a所占4个字节中地址较⼩的字节的地址。

虽然整型变量占⽤4个字节,我们只要知道了第⼀个字节地址,顺藤摸⽠访问到4个字节的数据也是可⾏的。

2.2解引用操作符

2.2.1指针变量

当我们得到了一个地址的时候,我们通常还需要将该地址保存起来,比如说0x006FFF30,这是一个地址型的数据,我们该如何保存呢?我们在最开始的时候说过,地址就是指针,指针就是地址,所以我们把一个地址存放在指针变量中。

此时,&a得到的是p的地址,p这个指针变量中存放的也是a的地址

我们不只有int* 这个类型的指针变量,同时也有存放各种数据类型的地址的指针变量

char*//用于存放char类型数据的地址 short*//用于存放short类型数据的地址 int*//用于存放int类型数据的地址 long*//用于存放long类型数据的地址 long long*//用于存放long long类型数据的地址 float*//用于存放float类型数据的地址 double*//用于存放double类型数据的地址 long double*//用于存放long double类型数据的地址

比如说现在有个char类型的变量a,我想把他的地址存放进指针中,那该怎么做呢,即

char ch = 'a'; char* p = &ch;

2.2.2解引用操作符(*)

我们将地址保存起来,未来是要使⽤的,那怎么使⽤呢?在现实⽣活中,我们使⽤地址要找到⼀个房间,在房间⾥可以拿去或者存放物品。C语⾔中其实也是⼀样的,我们只要拿到了地址(指针),就可以通过地址(指针)找到地址(指针) 指向的对象,这⾥必须学习⼀个操作符叫解引⽤操作符(*)。
用法如下:
这里说明,解引用操作符*一般是和指针搭配在一起使用的,而且这里的*p意思是指向p中存储的地址的内存单元中的数据。

同时,通过解引用操作符,我们现在可以不直接通过变量a而改变a的值了。

*p = 5;

注意:这里的解引用操作符*,和创建指针变量时用的int* 中的*两个虽然是同一个操作符,但是概念上是不一样的,这里就用*pa举例。这里的解引用操作符就是通过指针变量pa中存放的地址,找到该地址指向的空间。而int* 这里的*相当于声明我现在定义的变量是一个指针变量,并且该变量用于存放int类型数据的地址。二者虽然是同一个符号,我们自己要清楚二者的含义是不一样的。

2.3指针变量的大小

既然指针变量中存放的是地址,那么该地址是否有大小限制呢,答案是一定的。、

但是我们先来了解一下计算机内部的知识,计算机中CPU用于对数据进行计算,但是数据都存放在内存中的内存单元中,因此CPU就需要通过地址找到目标数据的内存单元。那么该如何寻找呢,这时候就需要用到地址总线。

在32位的机器中,就有32跟地址总线,每一根线有两种状态,表示0和1(电脉冲有无),所以32根线就有2^32种状态,每一种状态都代表一个地址。那么64位机器就是64根地址总线,能表示2^64种状态。

地址信息被下达给内存,在内存上,就可以找到该地址对应的数据,将数据在通过数据总线传入CPU内寄存器。

了解了这些知识之后,我们再来了解指针变量的大小。32位机器有32根地址总线,那么每个地址就由32个bit位构成,8个bit位就是一个字节,那么在32位机器中就需要4个字节来存储地址。又因为指针就是地址,因此,指针变量的大小就是4个字节。

那么64位机器有64跟地址总线,每个地址就由64个bit构成,即8个字节,因此在64位机器当中,一个指针变量需要占8个字节的大小。

x86表示32个bit位

x64表示64个bit位

总结:在32位下,指针变量大小是4个字节,在64位下,指针变量大小是8个字节。注意,指针变量的大小与指针类型类型是无关的,在同一个机器下,大小都是相同的。

3指针类型变量的意义

指针变量的⼤⼩和类型⽆关,只要是指针变量,在同⼀个平台下,⼤⼩都是⼀样的,为什么还要有各种各样的指针类型呢?

3.1指针的解引用

对比下面两段代码,观察内存变化。

第一段代码

可以看到a的地址占了004FF968,004FF969,004FF96A,004FF96B四个地址,当我们执行*p = 0这个语句时,这四个地址对应的内存单元中的数据都变成了0。

第二段代码

我们可看到当指针p的类型时char*,执行*p = 0时,只有1个字节的数据改成了0,

结论:指针的类型决定了,对指针解引⽤的时候有多⼤的权限(⼀次能操作⼏个字节)。

⽐如: char*的指针解引⽤就只能访问⼀个字节,⽽int*的指针的解引⽤就能访问四个字节。

3.2 指针+-整数

这里看到,char*类型的指针变量+1一次跳过一个字节,int* 类型的指针变量+1一次跳过4个字节。

这就是指针变量类型差异带来的变化。指针+1,其实就是跳过1个指针指向的元素。当然指针既可以+1,也可以-1。

总结:指针的类型决定了指针向前一步或者向后走一步有多大(字节)

http://www.zskr.cn/news/1386995.html

相关文章:

  • ELKStack高效部署与架构解析
  • 为什么苏州工厂老板都会选择响课教育做GEO优化?一文深度解读!
  • Claude Code 全栈提示词:前端/Java/UI/测试一册通
  • ARM调试状态核心机制与PSTATE处理详解
  • 告别手动选点:cam_lidar_calibration如何用VOQ自动筛选最优标定位姿?
  • 你的图片安全吗?聊聊LSB隐写的‘易碎性’和那些年我们踩过的坑
  • FlashAttention V3 前瞻:下一代Attention优化方向
  • 考研复习 Day 40 | 密码学--第四章 分组密码(中)
  • Linux运维之磁盘分区与挂载详解
  • TVA在电子元器件领域的创新应用(9)
  • 终极指南:如何在Mac上使用Topit实现300%效率提升的窗口置顶
  • 利用Taotoken模型广场为智能CRM选择合适的大模型
  • 技术美术入门必懂:用OpenGL知识反推Unity Shader与渲染管线(实战解析)
  • 低延迟可解释AI模型在实时决策系统中的应用
  • 现代视角下的《周易》浅谈
  • 别再只用ARIMA了!当数据少得可怜时,试试灰色预测GM(1,1)模型(附Python/R代码对比)
  • 避坑指南:Unity 2018/2019 WebGL透明背景设置全流程,解决PostProcess颜色异常
  • Oracle EBS中库存事务是如何影响成本计算的?
  • 2026年4月优秀的冷库设备企业推荐,冷库/冷库机组/冷库制冷设备/冷库安装/保鲜冷库/速冻冷库,冷库设备品牌推荐 - 品牌推荐师
  • YOLOv8传送带缺陷识别检测系统(项目源码+YOLO数据集+模型权重+UI界面+python+深度学习+环境配置)
  • JavaSSM框架从入门到精通!第六天(Spring篇 一)
  • DeepSeek技术方案生成:从“能跑通”到“可交付”的5级成熟度跃迁路径(含Gartner对标矩阵)
  • Cortex-M3/M4调试架构与多节点SWD技术解析
  • ROS1 Action通信避坑指南:手把手教你配置CMakeLists.txt和解决常见编译错误
  • 合肥工商注册代理技术解析及合规服务机构盘点:合肥小规模纳税人代账/合肥注册公司名称核准/合肥注册公司地址挂靠/合肥注册公司材料/选择指南 - 优质品牌商家
  • 别再浪费磁盘空间了!手把手教你用LVM精简卷(Thin Provisioning)给服务器‘瘦身’
  • 合肥代理记账权威机构判定维度与合规服务解析:合肥工商注册代理/合肥注册公司名称核准/合肥注册公司地址挂靠/合肥注册公司材料/选择指南 - 优质品牌商家
  • 怎么知道机械臂该怎么动
  • 低延迟可解释AI模型架构设计与边缘计算优化
  • 保姆级避坑指南:在Ubuntu 20.04上搞定VINS-Fusion环境与手机数据采集(含源码修改细节)