指针与数组

点击打开链接-37楼

1。数组名是一个常量吗?

是。
-----------------------------
不能说是。提示:数组名是一个不变的符号地址,但在C中,不变的量就是常量吗??

愿闻其详。
---------------------------------------------------
在C中,常量表达式必须是编译期的,运行期的不是常量表达式。因此一个自动数组的数组名不是常量表达式,静态数组的数组名才是一个常量表达式。所以说,数组名只是一个符号地址,是否常量不一定,要视其如何定义的。

但在C++中,由于不再规定常量表达式必须是编译期,因此在C++中,数组名才是一个符号地址常量。




2。我们常这样使用:
    int a[10];
    int *p = a + 1;
  这是否意味着数组名是一个指针?

当一个数组标识符出现在表达式中,这个标识符的类型就从“某种类型T的数组”转换成“指向类型T的指针”,而且它的值就等于数组第一个元素的地址。
---------------------------------------------
你没有回答是不是

当数组标识符出现在表达式中,编译器把它当做指针。这样回答可以么?
--------------------------------------------------------
数组名无论何时何地都不是指针,但一定条件下数组名可以隐式转换为指针,把a放在表达式a + 1中的时候,
a已经不是数组名了,而是隐式转换为一个右值指针了。




3。为什么a与&a的地址值相同?

上面说了,a出现在表达式中时,它作为指针,其值是数组第一个元素的地址;而当a作为取址(&)操作的操作数时,取址操作返回的是指向数组的指针。由于数组的地址和数组第一个元素的地址相同,所以a与&a的地址值相同。
--------------------------------------------
这只是表面现象,有没有思考过&a是否合法?一般来说,&运算符要求操作数是对象,但,数组名是对象吗?
先给你解释什么是对象,对象是执行环境中其内容表示为某个值的存储数据的区域。

当数组名出现在&之后时,编译器把它理解为a[0],而a[0]是合法的可用于&运算符的对象。
----------------------------------------------------------------------
如果定义int i; i是一个对象,&i成立是很自然的,但数组名不是对象(数组是对象),因为内存中并不存在一个地方存储数组名的值,数组名本身就代表一个值,没有指针对象那样的取值操作,因此按照&的本意,&a是非法的,但是由于早期有些编译器已经允许了&a这样的东西的存在,因此C标准委员会鉴于这种结构并没有害处而且对象的概念已经有了扩展,因此也规定了&a的合法性,但&a并不表示对数组名取地址,而是对数组对象取地址,也正因为这个原因,&a的值跟a是一样的



4。在C中,有人说以下代码定义了一个常量:const int i = 10;但为什么如下代码不能通过编译?
    int main( void )
  {
        const int i = 10;
        int a[i];
        ..........
  }

我在VC里可以通过编译,并正常使用啊?
-----------------------------------------
不要使用VC6,VC6对标准的支持很差,用对标准支持很好的gcc再试试看。

这是不是又和编译器对常量的理解有关?愿闻其详。
-----------------------------------------------------
是的,在C中,作为自动变量的i运行期内才建立,因此不是常量表达式,虽然被const修饰,但这里的const的确切意义,只不过表示不能直接通过i这个标识符去修改i的值而已。数组声明器内部的操作数被规定为必须是常量表达式。

在C++中,同样由于不再规定必须是编译期,因此在C++中上述代码成立。





7。我们常常使用这样的指针:const char *p1;但对于下面的声明:
    typedef char * T;
    const T p2; 
    p1与p2也一样吗??为什么?重点在于为什么??

p1是指向const char的指针;p2是常量,其类型是字符指针。原因是指针修饰符是从右向左结合的,typedef的定义打乱了结合的次序。如果如下定义,则p2与p1相同。
C/C++ codetypedefconstchar T;
T*p2;
------------------------------------------------------------------
解释基本上可以。从标准的角度来讲,指针说明符跟标识符原本是组合在一起的,标准是这样说明的:

6.7.5.1 Pointer declarators

Semantics

If, in the declaration ‘‘T D1’’, D1 has the form

* type-qualifier-listopt D

D就是指标识符

typedef char * T把指针说明符从declarator中硬生生分开了,打乱了次序,才造成这么奇怪的现象。本来是一个不良的声明,但由于typedef对于ADT是一个不可缺少的东西,ADT一条重要原则是数据隐藏,要用户直接使用*来使用ADT是违背ADT的原则的,同时所造成的问题看起来也并不大,只部分影响了阅读习惯而已,因此就无所谓了。

弱弱地问,ADT是啥?另外,你引的这段英文没理解的说。
--------------------------------------------------------
ADT叫抽象数据类型,是C++中的类的前身,C++的类使用了OOP的思想,同时由C的ADT发展而来的

T表示类型,D1表示declarator,type-qualifier-listopt 表示可选类型修饰符列表,opt表示可选,例如:

int * const p;

T就是那个int,* const p就是D1,const就是type-qualifier-listopt 。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值