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

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

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

要注意指针变量的当前值。

例题:

通过指针变量输出整型数组a的10个元素。

解题思路:

用指针变量p指向数组元素,通过改变指针变量的值,使p先后指向a [ 0 ] ~ a [ 9 ]各元素。

编写程序:

运行结果: 

是一串乱码的 不是想要的结果

(在不同的环境中运行时显示的数据可能与上面的有所不同)。

程序分析:

显然输出的数值并不是a数组中各元素的值。需要检查和分析程序。有的人觉得上面的程序没有什么问题,即使已被告知此程序有问题,还是找不出问题出在哪里。问题出在指针变量p的指向。请仔细分析p的值的变化过程。指针变量p的初始值为a数组首元素(即a [ 0 ])的地址,经过第1个for循环读入数据后,p已指向a数组的末尾。因此,在执行第2个for循环时,p的起始值不是& a[0]了,而是a + 10。由于执行第2个for循环时,每次要执行p + +,因此p指向的是a数组P下面的10个存储单元,而这些存储单元中的值是不可预料的。

解决这个问题的办法是,只要在第2个for循环之前加一个赋值语句:p = a;使p的初始值重新等于& a [ 0 ]这样结果就对了。

程序为

 ( 1 )虽然定义数组时指定它包含10个元素,并用指针变量p指向某一数组元素,但是实际上指针变量p可以指向数组以后的存储单元。如果在程序中引用数组元素a [ 10 ],虽然并不存在这个元素(最后一个元素是a [ 9 ]),但C编译程序并不认为它非法。系统把它按* ( a + 10 )处理,即先找出( a + 10 )的值(是一个地址),然后找出它指向的单元( * ( a + 10 ) )的内容。这样做虽然在编译时不出错,但运行结果不是预期的,应避免出现这样的情况。这是程序逻辑上的错误,这种错误比较隐蔽,初学者往往难以发现。在使用指针变量指向数组元素时,应切实保证指向数组中有效的元素。

( 2 )指向数组元素的指针变量也可以带下标,如p [ i ]。有些读者可能想不通,因为只有数组才能带下标,表示数组某一元素。带下标的指针变量是什么含义呢?当指针变量指向数组元素时,指针变量可以带下标。因为在程序编译时,对下标的处理方法是转换为地址的,对p [ i ]处理成* ( p + i ),如果p是指向一个整型数组元素a [ 0 ],则p [ i ]代表a [ i ]。但是必须弄清楚p的当前值是什么?如果当前p指向a [ 3 ],则p [ 2 ]并不代表a [ 2 ],而是a [ 3 + 2 ],即a [ 5 ]。建议少用这种容易出错的用法。

( 3 )利用指针引用数组元素,比较方便灵活,有不少技巧。在专业人员中常喜欢用一些技巧,以使程序简洁。在看别人写的程序时可能会遇到一些容易使人混淆的情况,要仔细分析。

请分析下面几种情况(设p开始时指向数组a的首元素(即p = a)):

①分析:

p + +;

*p;

p++使p指向下一元素a [ 1 ]。然后若再执行*p,则得到下一个元素a[1]的值。

②* p + +;

由于+ +和*同优先级,结合方向为自右而左,因此它等价于* ( p++ )。先引用p的值,实现* p的运算,然后再使p自增1。

③* ( p++ )与* ( + + p )作用是否相同?不相同。前者是先取*p值,然后使p加1。后者是先使p加1,再取* p。若p初值为a(即& a[0] ),若输出*(p++),得到a [ 0 ]的值,而输出( + + p ),得到a [ 1 ]的值。

④+ + ( *p )。表示p所指向的元素值加1,如果p = a,则++( *p )相当于+ + a [ 0 ],若a[0]的值为3,则在执行+ + ( *p ) (即+ + a [ 0 ] )后a [ 0 ]的值为4。注意:是元素a [ 0 ]的值加1,而不是指针p的值加1。

⑤如果p当前指向a数组中第i个元素a [ i ],则:

* ( p--)相当于a [ i-- ],先对p进行“*”运算(求p所指向的元素的值),再使P自减。

* ( + + p )相当于a [ + + ],先使p自加,再进行“*”运算。

*(--p)相当于a[--i],先使p自减,再进行"*"运算

将++和--运算符用于指针变量十分有效,可以使指针变量自动向前或向后移动,指向下一个或上一个数组元素。

http://www.xdnf.cn/news/15501.html

相关文章:

  • 20250711_Sudo 靶机复盘
  • 【读书笔记】《Effective Modern C++》第4章 Smart Pointers
  • 串口学习和蓝牙通信HC05(第八天)
  • es里的node和shard是一一对应的关系吗,可以多个shard分配到一个node上吗
  • Pandas-数据清洗与处理
  • 构建可落地的企业AI Agent,背后隐藏着怎样的技术密码?
  • redis汇总笔记
  • 什么时候需要用到 multiprocessing?
  • 基于 CentOS 7 的 LVS+DR+Web+NFS 旅游攻略分享平台部署
  • 【RA-Eco-RA6E2-64PIN-V1.0 开发板】ADC 电压的 LabVIEW 数据采集
  • 【读书笔记】《Effective Modern C++》第六章 Lambda Expressions
  • Windows 常用命令
  • vue防内存泄漏和性能优化浅解
  • 如何自动化处理TXT日志,提升工作效率新方式
  • RabbitMQ队列的选择
  • 03.Python 字符串中的空白字符处理
  • Springboot实现一个接口加密
  • 华为交换机 undo negotiation auto功能(华为交换机端口接光纤两端起不来)
  • 【Complete Search】-基础完全搜索-Basic Complete Search
  • JAVA 项目工程化实践
  • fatal: active `post-checkout` hook found during `git clone`
  • v-for中key值的作用:为什么我总被要求加这个‘没用的‘属性?
  • 大小为 K 且平均值大于等于阈值的子数组数目
  • “找到一个或多个多重定义的符号“(LNK2005 或 LNK1169)
  • 006_测试评估与安全实践
  • 深入理解 LangChain:AI 应用开发的全新范式
  • 面试150 填充每个节点的下一个右侧节点指针Ⅱ
  • 第一个Flink 程序 WordCount,词频统计(批处理)
  • ReAct论文解读(1)—什么是ReAct?
  • AI大模型计数能力的深度剖析:从理论缺陷到技术改进