`
michael-java
  • 浏览: 18876 次
  • 性别: Icon_minigender_1
  • 来自: 合肥
最近访客 更多访客>>
社区版块
存档分类
最新评论

第四章 [ ]运算符的本质

J# 
阅读更多

 

数组是存在于人们头脑中的一个逻辑概念,而编译器其实并不知道有数组这个东西,它所知道的,只是[]运算符,当遇到[]运算符的时候,编译器只是简单地把它转换为类似*(*(a+i)+j)这样的等价表达式,之所以是这种表达式,如前几章所述,是因为C语言的数组实现本质上是数组的嵌套。

        由于这种等价关系的存在,会产生一些古零精怪的表达式,例如:

10[a]

这个表达式初看上去让人摸不着头脑,它是什么呢?如上所述,编译器会把它转换为*(10+a),把a和10调换一下,就是*(a+10)了,这个就是a[10]。

[]运算符之前还可以是一个表达式,例如:(10+20)[a]。

严格来讲,以上两个表达式是非法的,因为C89对于数组的引用(注意不是数组定义)规定:带下标的数组引用后缀表达式由一个后缀表达式后跟一个括在方括号中的表达式组成。方括号前的后缀表达式的类型必须为“指向T类型的指针”,其中T为某种类型;方括号中表达式的类型必须为整型。这个规定说明,进行数组引用的时候,[]运算符的左边并非必须为数组名,而可以是一个表达式,但这个表达式的类型必须为“指向某类型的指针”。显然10跟(10+20)连地址都不是,因此实际上他们是非法的,编译器在这里并没有严格遵守标准的规定。但如果是:

int a[10], *p = a;

(p+1)[2]这样就是合法的,因为p+1的结果仍然是一个指针。

要注意的是,虽然后缀表达式是一个“指向某类型的指针”,但不要被这里所说的指针一词搞混了,上面的规定不能反过来使用。还是以上面的例子为例,我们可以p[i]这样使用p,这是符合上述规定的,但并不能因为指针p能够以p[i]这种形式使用就认为p是一个数组,这就错误了,不能反过来应用上述规则。

        最后说一下编译器对&*的优化,对于数组int a[10],如果对其中一个元素取地址,例如&a[1],这条表达式等价于&*(a+1),编译器并不会先计算*再运算&,而是对&*两个运算符进行优化,把它们同时去掉,因为两者的作用是相反的,最后得到计算的是a+1表达式。

分享到:
评论

相关推荐

    Java语言程序设计第10版基础篇 第四章答案

    《Java语言程序设计第10版基础篇》是学习Java编程的重要教材,第四章通常涵盖了Java的基本语法和核心概念。本资源提供了该章节的课后习题答案,旨在帮助学习者检验自己的理解并深化对Java知识的掌握。下面将详细阐述...

    第 运算符重载PPT学习教案.pptx

    运算符重载本质上是函数重载的特殊形式。在C++中,每个运算符都有对应的运算符函数。当一个运算表达式如`a+b`被编译时,会被解析为对`operator+(a, b)`的调用。这里的`operator`是一个关键字,它与后面跟着的运算符...

    简明 Python 教程 中文版

    第4章 基本概念 第5章 运算符与表达式 第6章 控制流 第7章 函数 第8章 模块 第9章 数据结构 第10章 解决问题——编写一个Python脚本 第11章 面向对象的编程 第12章 输入/输出 第13章 异常 第14章 Python标准库 第15...

    Python程序设计-第二章-Python语言数据类型、运算符和表达式.ppt

    首先,Python提供了四种类型的数。整数(如2)是最常见的,它们不带小数部分。长整数用于表示非常大的整数,如1234567890123456789。浮点数(如3.23和52.3E-4)包含小数部分,E标记用于表示10的幂。复数由实部和虚部...

    javascript运算符——位运算符全面介绍.docx

    ### JavaScript运算符——位运算符全面介绍 #### 一、引言 JavaScript作为一种广泛使用的编程语言,在前端开发、后端开发乃至数据科学等领域都有着举足轻重的地位。位运算符作为JavaScript运算符的一种,虽然不如...

    c语言程序设计现代方法第4章习题

    King的经典教材,第二版中第4章的习题涵盖了C语言的核心概念和编程技巧。本章重点讨论了指针、数组以及它们在程序设计中的应用,这些都是C语言的核心内容。下面将详细阐述这些知识点。 一、指针 1. 指针的定义:...

    c#本质论 提供前6章试读

    4. **第四章:函数与方法** - 函数定义:如何定义和调用函数,参数传递(按值或按引用)。 - 方法重载:同名方法通过不同的参数列表实现多态性。 - 局部变量和成员变量:理解函数内部和类级别的变量差异。 - ...

    java数据类型和运算符共3页.pdf.zip

    了解这些基本数据类型和运算符是学习Java编程的第一步。在实际编程中,它们是构建复杂逻辑和算法的基础。通过熟练运用,可以创建出功能强大的应用程序。在“java数据类型和运算符共3页.pdf”中,你将找到更深入的...

    试析C语言中的自增自减运算符.pdf

    通常情况下,两个连续的符号会被当作一个自增或自减运算符处理,但如果连续出现三个或四个相同符号时,通常情况下第一个或前两个符号构成自增或自减运算符,最后一个符号则会按照加法或减法运算符处理。例如: ```c...

    东北大学c++课程PPT 第4章

    C++编程语言中的第四章主要讨论了友元和运算符重载两个重要概念。这两个特性扩展了C++的灵活性和可读性,特别是在处理类和对象时。 首先,我们来看友元(Friends)。友元函数是能够直接访问类中私有(private)和...

    JavaScript第3章答案

    总之,这份"JavaScript第3章答案"是一个全面且深度讲解的资料,它将帮助你在学习JavaScript的过程中,无论是在理论还是实践层面,都能得到实质性的提升。充分利用这份资源,你将在JavaScript的世界里游刃有余。

    程序员编程艺术第一~二十七章集锦与总结(教你如何编程)by_July-带书签目录超清文字版

    第二十一章至第二十四章可能会讨论错误处理和调试技巧,这是每个程序员都需要掌握的重要技能。理解如何通过异常处理来捕获和处理程序运行时的问题,以及如何使用调试工具来定位和修复错误,能显著提高开发效率。 ...

    C#本质论(第3版)

    第4章聚焦于方法和参数,涵盖了方法的调用和声明、命名空间、类型名称、作用域、方法返回值,以及using指令的使用。此外,本章还介绍了main()方法的返回值和参数、参数的分类(值参数、引用参数、输出参数、参数数组...

    Linux C程序设计大全

    第4章 C语言中的指针与字符串 4.1 sizeof运算符 4.1.1 sizeof运算符的应用——得到内置类型的大小 4.1.2 sizeof运算符的应用——得到复合类型的大小 4.2 指针的应用 4.2.1 指针与别名陷阱 4.2.2 数组的指针 4.2.3 ...

    第四章讲稿.pdf

    抽象帮助我们关注问题的本质,而不是具体实现的细节。数据抽象关注对象的状态,而代码抽象则关注对象的行为。在实现抽象时,我们通常会创建一个类来封装这些属性和行为。 封装是另一种关键特性,它将数据和处理这些...

    C语言课件:3_第四章 最简单的C程序设计.ppt

    第四章的C程序设计主要介绍了C语言的基本构造和语句类型,这些都是编写C程序的基础。在C语言中,一个程序通常由多个源程序文件组成,每个文件可能包含预处理指令、全局变量声明、函数定义等元素。预处理指令用于处理...

    大学老师多年阅书整理版C++初学教程

    4. **指针与函数、指针与堆内存**:第四章的第三个部分深入讨论了指针,这是C++的一个强大特性,它允许我们间接访问和修改内存中的数据。这部分内容包括指针与函数的关系,如传址调用,以及如何使用指针在堆内存中...

    C++Primer课后习题解答(第1~18章完整答案)完整版

    4. **第四章 数组和指针** - **数组**:一维和多维数组的声明、初始化和操作。 - **指针**:理解指针的本质,学习如何声明、初始化和使用指针,以及指针与数组的关系。 5. **第五章 表达式** - **运算符优先级**...

Global site tag (gtag.js) - Google Analytics