`
java-mans
  • 浏览: 11414659 次
文章分类
社区版块
存档分类
最新评论

深入探索 C/C++ 数组与指针的奥秘之二:数组名是一个指针常量吗?

 
阅读更多

深入探索 C/C++ 数组与指针的奥秘之二:数组名是一个指针常量吗?

数组名是一个指针常量这种观点来源于数组名在表达式计算中与指针的结果等效性。例如下面的代码:


在效果上看,a + 1 与 p + 1 是相同的,这很容易给人一种 a 就是 p 的假象,但,这仅仅是假象。鉴于指针常量包含了指针和常量两类概念,我们可以把这个问题分开两部分进行讨论。
一、数组名是指针吗?
在《C 与指针》一书中,作者用一个著名的例子阐述了数组名与指针的不同。在一个文件中定义:int a[10];然后在另一个文件中声明:extern int *a; 笔者不在这里重复其中的原理,书中的作者试图从底层操作上阐述数组名与指针的不同点,但笔者认为这个例子存在一些不足,a 在表达式中会转换为一个非对象的符号地址,而指针 a 却是一个对象,用一个非对象去跟一个对象比较,有“偷跑”的嫌疑,这个例子只是说明了数组名的非对象性质,只能证明对象与非对象实体在底层操作上的不同,事实上,如上一章所述,指针也有非对象形态。笔者认为,无须从底层的角度上花费那么多唇舌,仅仅从字面上的语义就可以推翻数组名是一个指针的观点。
首先,在 C/C++ 中,数组类型跟指针类型是两种不同的派生类型,数组名跟指针是两种不同类型的实体,把数组类型的实体说成“是”另一个类型的实体,本身就是荒谬的;
其次,a + 1 在效果上之所以等同于 p + 1,是因为 a 进行了数组到指针的隐式转换,这是一个转换的过程,是 converted to 而不是 is a 的过程。如果是两个相同的事物,又怎会有转换的过程呢?当把 a 放在 a + 1 表达式中时,a 已经从一个数组名转换为一个指针,a 是作为指针而不是数组名参与运算的;
第三,a + 1 与 p + 1 是等效关系,不是等价关系。等价是相同事物的不同表现形式,而等效是不同事物的相同效果。把数组名说成是指针实际上把等效关系误解为等价关系。
因此,数组名不是指针,永远也不是,但在一定条件下,数组名可以转换为指针。
二、数组名是一个常量吗?
看见这句话有人会觉得奇怪,数组定义之后就不能改变了,数组名不就是个常量吗?在表达式中,数组名的确可以转换为一个不变的符号地址,但在C 中,不变的实体不一定是常量!而且,C/C++ 有常量与常量表达式之分,常量与常量表达式是两种不同的实体,但常量表达式可以作为常量使用。C/C++ 中的常量虽然有所不同,但都不包括数组或数组名,而且数组名也不一定是常量表达式。
请在 C90 的编译器中编译如下代码,注意不能是 C99 和 C++ 的,因为 C99 和 C++ 不再规定数组的初始化器必须是常量表达式,会看不到效果:


B 为什么不能通过编译?是由于自动数组名并不是常量表达式。在 C 中,常量表达式必须是编译期的,只在运行期不变的实体不是常量表达式,请看标准的摘录:
6.6 Constant expressions
A constant expression can be evaluated during translation rather than runtime, and accordingly may be used in any place that a constant may be.
c 和 d 是自动数组,首地址在编译期是不可知的,因为这样的对象在编译期还不存在;a 和 b 是静态数组,静态对象从程序开始时就已存在,因此 a 和 b 的首地址在编译期是已知的,它们都属于常量表达式中的地址常量表达式。
所以,C/C++ 中的数组名,都不是常量。C 中的数组名,是否常量表达式要视其存储连续性而定,全局数组、静态数组名都是常量表达式,而自动数组名不是。在 C++ 中,由于不再规定常量表达式必须是编译期的,因此 C++ 的数组名都是常量表达式。
原文链接:http://blog.csdn.net/supermegaboy/archive/2009/11/23/4855018.aspx

分享到:
评论

相关推荐

    数组与指针的艺术.doc

    数组与指针的艺术 数组与指针的艺术

    C/C++数组名与指针区别深层探索

    指针是C/C++语言的特色,而数组名与指针有太多的相似,甚至很多时候,数组名可以作为指针使用。于是乎,很多 程序设计者就被搞糊涂了。而许多的大学老师,他们在C 语言的教学过程中也错误得给学生讲解:“数组名就是...

    C++数组与指针深入剖析

    C++数组与指针深入剖析C++数组与指针深入剖析C++数组与指针深入剖析C++数组与指针深入剖析

    C++数组与指针对象数组对象指针

    C++数组与指针对象数组对象指针C++数组与指针对象数组对象指针

    C/C++之数组与指针的艺术

    C/C++之数组与指针的艺术 指针是C/C++的灵魂!它是C/C++众多引人入胜的特性中的一朵奇葩。与底层操作的亲密接触是指针与生俱来的优点,利用指针可以写出许多短小精悍、效率极高的代码。它是C/C++一把无可替代的利器...

    数组与指针区别(很全面)

    指针是C/C++语言的特色,而数组名与指针有太多的相似,甚至很多时候,数组名可以作为指针使用。于是乎,很多程序设计者就被搞糊涂了。而许多的大 学老师,他们在C语言的教学过程中也错误得给学生讲解:"数组名就是...

    C/C++ 避免数组越界的方法

    主要介绍了C/C++ 避免数组越界的方法,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下

    C++数组与指针

    C++数组与指针全面介绍,指针的重要性不言而喻,很多程序员怕指针,越是怕用,越要去用!

    C\C++ 数组与指针彻底总结

    详细讲解了指针,指针数组,数组指针,指针的指针等的应用。

    C++之数组与指针的异同 pdf

    C++之 数组 与 指针 的 异同 pdf

    C/C++ 数组和指针及引用的区别

    C/C++ 数组和指针及引用的区别 1.数组和指针的区别 (1)定义 数组是一个符号,不是变量,因而没有自己对应的存储空间。但是,指针是一个变量,里面存储的内容是另外一个变量的地址,因为是变量所以指针有自己的...

    C++指针 数组 内存释放.docx

    C++指针 数组 内存释放 相关说明

    C++第4章_数组与指针(C++课件,中南大学)

    1 数组及其简单应用 2 指针及其简单应用 3 指针与数组 4 字符串 5 指针数组与命令行参数 6 引用

    C++指针数组、数组指针、数组名及二维数组技巧汇总

    本文较为详细的分析了关于理解C++指针数组,数组指针,数组名,二维数组的一些技巧。是比较重要的概念,相信对于大家的C++程序设计有一定的帮助作用。 一、关于数组名 假设有数组: int a[3] = {1, 2, 3} 1.数组...

    C++习题 6数组与指针

    C++习题 6数组与指针.doc (填空 选择 解答)

    C++动态数组类模板

    动态数组类模板Array C++ //数组类模板声明 template class Array { public: Array(int sz = 50); Array(const Array<T> &A); ~Array(void); Array<T>& operator = (const Array<T> &rhs;); //重载=,使数组...

    指针数组与数组指针与二级指针

    指针与二维数组 数组指针 指针数组 多级指针

    指针数组和数组指针的区别.doc

    这样两者的区别就豁然开朗了,数组指针只是一个指针变量,似乎是C语言里专门用来指向二维数组的,它占有内存中一个指针的存储空间。指针数组是多个指针变量,以数组形式存在内存当中,占有多个指针的存储空间。 还...

    c++ 第四讲数组与指针

    数组与指针 利用数组表示一组相关 数据项  声明数组、初始化数组、 应用数组中的单个元素  将数组传递给函数  声明和使用多维数组

Global site tag (gtag.js) - Google Analytics