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

【时时三省】(C语言基础)通过指针引用数组

山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省

数组元素的指针

一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。指针变量既然可以指向变量,当然也可以指向数组元素(把某一元素的地址放到一个指针变量中)。所谓数组元素的指针就是数组元素的地址。可以用一个指针变量指向一个数组元素。

例如:

int a [ 10 ] = ( 1,3,5,7,9,11,13,15,17,19 );

int * p ;

p = & a [ 0 ];

以上是使指针变量p指向a数组的第0号元素。

引用数组元素可以用下标法(如a [ 3 ]),也可以用指针法,即通过指向数组元素的指针找到所需的元素。使用指针法能使目标程序质量高(占内存少,运行速度快)。

C语言中,数组名(不包括形参数组名)代表数组中首元素(即序号为0的元素)的地址。因此,下面两个语句等价:

p=&a[0];

p=a;

注意:程序中的数组名不代表整个数组,只代表数组首元素的地址。上述“p = a;"的作用是“把a数组的首元素的地址赋给指针变量p”,而不是“把数组a各元素的值赋给p”

在定义指针变量时可以对它初始化,如:

int p &a [ 0 ];

它等效于下面两行:

int *p;

p=&a[0];

当然定义时也可以写成

int * p = a ;

它的作用是将a数组首元素(即a [ 0 ])的地址赋给指针变量p(而不是赋值给*p)。

在引用数组元素时指针的运算

在引用数组元素时常常会遇到指针的算术运算。有人会提出问题:对数值型数据进行算术运算(加、减、乘、除等)的目的和含义是清楚的,而在什么情况下需要用到对指针型数据的算术运算呢?其含义是什么?

前已反复说明指针就是地址。对地址进行赋值运算是没有问题的,但是对地址进行算术运算是什么意思呢?显然对地址进行乘和除的运算是没有意义的,实际上也无此必要。那么,能否进行加和减的运算?答案是:在一定条件下允许对指针进行加和减的运算。

那么,在什么情况下需要而且可以对指针进行加和减的运算呢?回答是:当指针指向数组元素的时候。譬如,指针变量p指向数组元素a [ 0 ],我们希望用p +1表示指向下一个元素a1。如果能实现这样的运算,就会对引用数组元素提供很大的方便。

在指针已指向一个数组元素时,可以对指针进行以下运算:

加一个整数(用+或+ =),如p +1;

减一个整数(用-或- =),如p -1;

自加运算,如p++,++p;

自减运算,如p--,--p。

两个指针相减,如pl -p2(只有pl和p2都指向同一数组中的元素时才有意义)。

分别说明如下:

( 1 )如果指针变量p已指向数组中的一个元素,则p +1指向同一数组中的下一个元素,p-1指向同一数组中的上一个元素。注意:执行p +1时并不是将p的值(地址)简单地加1,而是加上一个数组元素所占用的字节数。例如,数组元素是float型,每个元素占4个字节,则p +1意味着使p的值(是地址)加4个字节,以使它指向下一元素。

p +1所代表的地址实际上是p +1×d,d是一个数组元素所占的字节数(在Visual C++中,对int型,d = 4,对float和long型,d = 4;对char型,d = 1 )。若p的值是2000,则p +1的值不是2001,而是2004。

系统怎么知道要把这个1转换为4,然后与p的值相加呢?不要忘记,在定义指针变量时必须要指定基类型,如:

float * p;

现在p指向float型的数组元素,在执行++p时,系统会根据p的基类型为float型而将其值加4,这样,p就指向float型数组的下一个元素。如果p原来指向a [ 0 ],执行++p后p的值改变了,在p的原值基础上加d,这样p就指向数组的下一个元素a [ 1 ]。

( 2 )如果p的初值为& a [ 0 ],则p + i和a + i就是数组元素a数组a [i]的地址,或者说,它们指向a数组序号为i的元素,这里需要注意的是a代表数组首元素的地址,a +1也是地址,它的计算方法同p +1,即它的实际地址为a +1×d。

( 3 ) * ( p + i )或* ( a + i )是p + i或a + i所指向的数组元素,即a [ i ]。例如,* ( p + 5 )或* ( a + 5 )就是a[ 5 ],即:*(p+5),*(a+5)和a[5]三者等价。实际上,在编译时,对数组元素a[i]就是按* ( a + i )处理的,即按数组首元素的地址加上相对位移量得到要找的元素的地址,然后找出该单元中的内容。若数组a的首元素的地址为1000,设数组为float型,则a [ 3 ]的地址是这样计算的:1000 + 3×4 = 1012,然后从1012地址所指向的float型单元取出元素的值,即a [ 3 ]的值。

说明:[ ]实际上是变址运算符,即将a [ i ]按a + i计算地址,然后找出此地址单元中的值。

( 4 )如果指针变量pl和p2都指向同一数组中的元素,如执行p2 -p1,结果是p2 - p1的值(两个地址之差)除以数组元素的长度。假设,p2指向实型数组元素a [ 5 ],p2的值为2020;pl指向a [ 3 ],其值为2012,则p2 - pl的结果是( 2020-2012 )/ 4 = 2。这个结果是有意义的,表示p2所指的元素与pl所指的元素之间差2个元素。这样,人们就不需要具体地知道pl和p2的值,然后去计算它们的相对位置,而是直接用p2 - p1就可知道它们所指元素的相对距离。

注意:两个地址不能相加,如pl + p2是无实际意义的。

http://www.dtcms.com/a/271060.html

相关文章:

  • 阿里开源WebSailor:超越闭源模型的网络智能体新星
  • 疏锦行Python打卡 DAY 54 Inception网络及其思考
  • HTML + CSS + JavaScript
  • 字体 Unicode 区块字符展示 PDF 生成器
  • Ubuntu重装系统后ssh连接不上(遇到 ​​“Unit ssh.service not found“​​ 错误)
  • kubernetes存储入门
  • Spring Boot + Vue.js 全栈开发:从前后端分离到高效部署,打造你的MVP利器!
  • 【05】MFC入门到精通——MFC 为对话框中的控件添加变量 和 数据交换和检验
  • 【01】MFC入门到精通—— MFC新建基于对话框的项目 介绍(工作界面、资源视图 、类视图)
  • Flink-1.19.0源码详解6-JobGraph生成-后篇
  • AJAX总结
  • Flink1.20.1集成Paimon遇到的问题
  • Electron 应用打包全指南
  • 机器学习模型在C++平台的部署
  • 基于 Redis 实现高并发滑动窗口限流:Java实战与深度解析
  • 开始读 PostgreSQL 16 Administration Cookbook
  • 深度学习 最简单的神经网络 线性回归网络
  • ArtifactsBench: 弥合LLM 代码生成评估中的视觉交互差距
  • 论文解析篇 | YOLOv12:以注意力机制为核心的实时目标检测算法
  • 腾讯云COS,阿里云OSS对象存储服务-删除操作的响应码204
  • 汽车智能化2.0引爆「万亿蛋糕」,谁在改写游戏规则?
  • 通用游戏前端架构设计思考
  • VSCode配置Cline插件调用MCP服务实现任务自动化
  • 旅游管理实训室建设的关键要点探讨
  • 向量空间 线性代数
  • 软件测试偏技术方向学习路线是怎样的?
  • 安装nvm管理node.js,详细安装使用教程和详细命令
  • Spring Boot微服务中集成gRPC实践经验分享
  • 【每日算法】专题六_模拟
  • 全球发展币GDEV:从中国出发,走向全球的数字发展合作蓝图