当前位置: 首页 > 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.jsqmd.com/news/887749/

相关文章:

  • 告别Unity默认Text!手把手教你用TextMeshPro打造炫酷UI文字(附中文字体制作避坑指南)
  • ARMv8虚拟化核心:HCRX_EL2寄存器架构与配置详解
  • 用XGBoost和SHAP搞定多分类预测:一份Python 3.7下的实战避坑指南
  • 具身智能的发展面临哪些挑战?
  • Spine动画在Unity里卡顿?性能优化实战:从Draw Call、材质实例化到网格合并
  • ARM调试状态核心机制与PSTATE处理详解
  • 你的模型结果总飘忽不定?可能是异常值在捣鬼:实战对比缩尾、截尾与RobustScaler
  • 给OpenGL学完就忘的你:用Unity Shader重温渲染管线,打通任督二脉
  • OpenGL地球渲染踩坑实录:GLFW、GLUT、FreeGLUT到底怎么选?附性能对比
  • UE5多人联机开发:从游戏大厅到玩家生成的完整蓝图流程(含游戏实例传参)
  • 教育科技产品集成AI批改功能时如何通过Taotoken保障服务稳定性
  • Unity URP程序化材质与立方体纹理实战指南
  • ARM调试与复位机制详解及实践技巧
  • LMD优化器:低精度训练与MXFP6格式的突破
  • 混合求解器:用神经网络增强传统微分方程数值方法
  • 技术美术入门必懂:用OpenGL知识反推Unity Shader与渲染管线(实战解析)
  • CentOS 7下‘Development Tools’和‘开发工具’组有区别吗?实测告诉你答案
  • BetterNCM Installer:Rust构建的网易云音乐插件管理器深度解析
  • 低延迟可解释AI模型在实时决策系统中的应用
  • 现代视角下的《周易》浅谈
  • Win10家庭版别再卡了!保姆级教程:手动修复gpedit.msc路径,彻底关闭Antimalware Service
  • 经颅超声刺激(TUS)技术原理与PlanTUS系统应用指南
  • CVPR 2023反无人机数据集实战:用ModelScope上的开源模型快速上手目标检测
  • 用Python手搓SMO算法:从SVM理论到sklearn源码级复现(附避坑指南)
  • 告别卡顿!用Potree+WebGL在浏览器里流畅查看超大规模点云(附Octree原理详解)
  • DeepSeek RAG系统渗透测试全链路复现(含PoC代码与防御加固清单)
  • 2026年5月更新:昆明广告纸杯订购厂家选择指南与实力解析 - 2026年企业推荐榜
  • 告别警告和强制刷新!用UGUI LayoutGroup + Content Size Fitter实现完美聊天框自适应(Unity 2022 LTS)
  • 从安防监控到在线视频:聊聊Chrome对H265‘又爱又恨’的硬解策略与我们的日常影响
  • 2026年4月优秀的冷库设备企业推荐,冷库/冷库机组/冷库制冷设备/冷库安装/保鲜冷库/速冻冷库,冷库设备品牌推荐 - 品牌推荐师