指针与数组

来源:互联网 发布:加入软件免费下载 编辑:程序博客网 时间:2024/06/05 15:58

点击打开链接-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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小学三年级数学才考86怎么办 小孩子一发脾气就打妈妈怎么办 孩子做错事不肯道歉怎么办 小孩写作业注意力不集中怎么办 六年级的数学下册差怎么办 一年级小孩做作业慢怎么办 静不下心写作业怎么办 二年级应用题太差怎么办 小学二年级数学差怎么办 小学二年级成绩差怎么办 6个月小孩爱动怎么办 儿子叛逆期我该怎么办 宝宝两岁好动不听话怎么办 生宝宝后奶水少怎么办 生了孩子没出来怎么办 孩子在学校表现不好怎么办 3岁半宝宝话太多怎么办 孩子不喜欢和小朋友玩怎么办 孩子不喜欢和小朋友说话怎么办 4岁半宝宝不听话怎么办 小孩在学校打老师怎么办 老师老找孩子时怎么办 幼儿园老师批评孩子后家长怎么办 老师跟家长吵架了怎么办 孩子在幼儿园被老师孤立怎么办 学生在幼儿园被老师欺负怎么办 小孩脚痒怎么办小窍门 小孩肚子病怎么办天天说 幼儿园幼儿信息表填错了怎么办 水浒传书孩子说看不懂怎么办 孩子丢了书老师怎么办 小朋友做错事不承认老师怎么办 教师被学生骂后怎么办 嘴吧里面长泡怎么办 有个小孩怕下雨怎么办? 幼儿的家长打我怎么办 老师打学生被家长起诉怎么办 家长在学校打了老师怎么办 老师打小孩我们家长怎么办呢? 孩子长手、腿毛怎么办 腿毛又黑又多怎么办