数组名隐式转换为指针时是右值还是不可修改的左值

slowgrace 2009-10-09 09:19:16
数组名隐式转换为指针时是右值还是不可修改的左值?

这两天和supermegaboy就这个问题讨论了好久(在这里),索性重新开个帖来讨论。

据supermegaboy说,标准中规定是右值。

可是来看看著名的Girlrong的说法:下面总结一下数组的数组名的问题。声明了一个数组TYPE array[n],则数组名称array就有了两重含义:第一,它代表整个数组,它的类型是TYPE [n];第二,它是一个指针,该指针的类型是TYPE*,该指针指向的类型是TYPE,也就是数组单元的类型,该指针指向的内存区就是数组第0号单元,该指针自己占有单独的内存区,注意它和数组第0号单元占据的内存区是不同的该指针的值是不能修改的,即类似array++的表达式是错误的。

楼下的觉得哪一种对?
...全文
2767 355 打赏 收藏 转发到动态 举报
写回复
用AI写文章
355 条回复
切换为时间正序
请发表友善的回复…
发表回复
知之洲 2011-09-11
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 slowgrace 的回复:]
引用 9 楼 pcboyxhy 的回复:
因为变量名不占据存储空间
所以无法获得变量名的地址

int abc;
&abc 是变量名abc引用的内容的地址,不是abc的地址


这个说法第一次听说
[/Quote]
pcboyxhy说的是对的
wuyuwww 2011-06-04
  • 打赏
  • 举报
回复
我考,顶,我正在啊看左值右值
slowgrace 2009-10-22
  • 打赏
  • 举报
回复
谢谢各位朋友,尤其是飞雪、pcboyxhy, pmerOFc, supermegaboy, hpsmouse等。

准备结帖了,帖子很长,分数有限,聊表谢意。其实各位朋友也不会很在意这些分,重在讨论和分享。

认真分配分数是为了后来者看到这个帖子的时候,通过查看“得分的回复”,就可以看到最有价值的回复(当然我的判断可能失之偏颇)。

我把对我有启发的回复都或多或少给了分,有些回复的观点我不一定赞同,但是我觉得也有启发,所以也给了分。我自己的回复有些也很好,但不能给自己分,呵呵。

这个帖子的部分内容小结在这个帖子里:http://topic.csdn.net/u/20091020/15/425ceedc-afff-4af1-a298-6466914c1d2d.html

过几天我还会贴其他的小结,现在尚在整理中,谢谢关注。
ahao 2009-10-22
  • 打赏
  • 举报
回复
[Quote=引用 351 楼 slowgrace 的回复:]
引用 350 楼 ahao 的回复:
说实在的,我觉得弄明白这个用处不大,我写c/c++N年,从没遇到一次需要考虑这个问题的


恩 所以我其实也要求很低 没有去搬大部头去钻研 只是和朋友们讨教一下就罢……
[/Quote]

你的总结还是很有用的,这个东西在一些模板库的编写里还是需要考虑的。没想到想在还有人提到girlrong:)
slowgrace 2009-10-22
  • 打赏
  • 举报
回复
[Quote=引用 350 楼 ahao 的回复:]
说实在的,我觉得弄明白这个用处不大,我写c/c++N年,从没遇到一次需要考虑这个问题的
[/Quote]

恩 所以我其实也要求很低 没有去搬大部头去钻研 只是和朋友们讨教一下就罢……
ahao 2009-10-22
  • 打赏
  • 举报
回复
说实在的,我觉得弄明白这个用处不大,我写c/c++N年,从没遇到一次需要考虑这个问题的
slowgrace 2009-10-22
  • 打赏
  • 举报
回复
16楼,28楼,77楼都是很有启发的回复,谢谢两位。

再看这个帖子中:
[Quote=引用 122 楼 supermegaboy 的回复:]
没错。普通对象与数组体现的是两种不同的抽象方法,但目的都是一样的,都为了更容易地操作内存。
[/Quote]

这些回复并在一起看,可以互相印证和纠正。

谢谢pcboyxhy,飞雪和supermegaboy。
slowgrace 2009-10-22
  • 打赏
  • 举报
回复
自己回答一下347楼的疑惑。在28楼飞雪提出pcboy的说法中不大经得起推敲的地方,小结一下我的理解:
(1)16楼的说法是用汇编实现来解释语法现象,因和果弄反了;
(2)16楼的说法里把变量名等同于地址(在汇编实现里是这样的),这种说法并不是和标准一致的说法,还是按28楼那样去理解变量及变量名比较好。依循标准可以避免一些麻烦。
(3)16楼的说法很好地说明了数组这种对象和普通对象在操作上的不同,所以其实也回答了飞雪在77楼提出要思考的问题,虽然用词不够考究(有点混淆了汇编实现和语法概念)。
slowgrace 2009-10-22
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 pcboyxhy 的回复:]
比较一下,两种设计
一,a表示地址常量引用的内容,&a表示地址常量本身
二,a表示地址常量本身,value(a)表示这个地址常量引用的内容

方案二更加符合习惯,因为人们习惯用简单的东西表示本质,然后加一些提取方式,通过它获得更多,
就像句柄一样,通过它去访问它所能引用到的信息。

但是方案二在普通变量上使用起来不方便,因为大部分时候,我们并不关心本质,甚至基本用不到本质,
99%的时候只关心它引用的东西,所以干脆简化一下,默认就表示它引用的东西,当需要取得本质,
就需要通过手段了,也就是&。

在对待数组上,恰好相反,如果把数组名默认解释成它引用的内容,那么取哪一个元素好呢?
其它的元素怎么办? 所以数组上采用了第二种方案,即默认不去引用数组名的地址常量标识的内容,
而是直接表示地址常量。当需要引用这个地址常量标识的内存中的数组元素时,再采取间接方式。

包括label在内,一切名字皆地址常量,类型的意义在于选择解析这个常量的方式。
[/Quote]

[Quote=引用 77 楼 baihacker 的回复:]
整数可以加减乘除.(虽然可能会出现意外)
浮点数也可以加减乘除.
布尔变量可以有真假值.

这一切摆出来,人们当然认为是天然的.

当有人并不认为这是天然的,这就是天才了.

伽罗华,群论,把这些集合,及其上面的关系抽象出来...于是在很多教材上提到伽罗华的时候都加了天才(我看的那本是)

这个集合内部的元素上可以有什么操作?
元素间有什么操作?
操作是封闭的吗?
和其它集合的元素有什么关系?

把这些问题重新问一次就明白了.

数组作为一个元素,我们能有什么操作?
整数作为一个元素,我们能有什么操作?

思考这两个问题...
[/Quote]

这两个发言都在试图解释为何数组标识符的相关语法是那样设计的,我觉得都有道理
lanseshenhua 2009-10-20
  • 打赏
  • 举报
回复
简单的看了下,我个人比较同意pcboyxhy的说法。楼主要是有时间就看看《Compilers: Principles, Techniques, and Tools 》这本书,好像有中文版的(第二版)。前面的词法语法分析就不用看,可以看从符号表那开始看。看完后你就能明白这些问题了。汇编是探究语言底层秘密的有效武器。
taozi1234567 2009-10-20
  • 打赏
  • 举报
回复
数组名只是数组的标识符,不是左值,不能给他赋值,他只是进入方括号语法的手段。可以把他看作数组起始处 的只读指针。(C++编程思想!)
2009-10-20
  • 打赏
  • 举报
回复
[Quote=引用 340 楼 slowgrace 的回复:]
引用 314 楼 baihacker 的回复:
7 Whenever an lvalue appears in a context where an rvalue is expected, the lvalue is converted to an rvalue;
see 4.1, 4.2, and 4.3.
飞雪,这是C++标准吧?
[/Quote]
飞雪一向都是 C++ ~~
slowgrace 2009-10-20
  • 打赏
  • 举报
回复
[Quote=引用 314 楼 baihacker 的回复:]
7 Whenever an lvalue appears in a context where an rvalue is expected, the lvalue is converted to an rvalue;
see 4.1, 4.2, and 4.3.
[/Quote]

飞雪,这是C++标准吧?
Arkwyd 2009-10-20
  • 打赏
  • 举报
回复
对标题问题,记下我的理解。

一般而言,一个 lvalue ,指一个符号所代表的地址;一个 rvalue ,指一个符号所代表的地址的内容。

char a[10];
char *p;
p = a;

以上,a 赋给 p ,p 拿到的是 a 所代表的地址,而不是 a 所代表的地址的内容。此时的 a 表达的是一个 lvalue 所代表的意义。需注意,这里的 a 的 lvalue 是一个不可改变的 lvalue ,所以说“数组名‘是’一个地址常量”。

参考:《expert c programming: deep secrets》Chapter 4. The Shocking Truth: C Arrays and Pointers
Are NOT the Same!

“我参与,我自豪。”
slowgrace 2009-10-20
  • 打赏
  • 举报
回复
[Quote=引用 341 楼 hpsmouse 的回复:]
引用 340 楼 slowgrace 的回复:
引用 314 楼 baihacker 的回复:
7 Whenever an lvalue appears in a context where an rvalue is expected, the lvalue is converted to an rvalue;
see 4.1, 4.2, and 4.3.
飞雪,这是C++标准吧?

飞雪一向都是 C++  ~~
[/Quote]

谢谢鼠。
gbyjrp 2009-10-20
  • 打赏
  • 举报
回复
建议参考一下《c专家编程》一书对数组和指针之间区别的论述!!!!!
jinwei1984 2009-10-16
  • 打赏
  • 举报
回复
这贴真火
slowgrace 2009-10-16
  • 打赏
  • 举报
回复
由衷地谢谢各位 洗洗睡了 希望今晚睡梦中能把这些纠结的理清楚
pmerOFc 2009-10-16
  • 打赏
  • 举报
回复
1.没有任何证据说那个“男人”存在
2.没有任何证据显示“变性”的痕迹

但凭借最后结果给出了一个符合逻辑的幻想过程
这恰恰给奥卡姆剃刀以必然的意义

说多了
无他
当有人讲我概念错误或逻辑错误时
只要有机会
我总要出来说点什么
pmerOFc 2009-10-16
  • 打赏
  • 举报
回复
[Quote=引用 335 楼 supermegaboy 的回复:]
我再打个比喻,一个男人通过变性变成了女人,这是一个男人converted to女人的过程,但如果把它理解成了男人is女人,不是荒谬么?他就是犯了这样一个逻辑错误。
[/Quote]
作为CODER
你只是看到了一个女人而已
你根本没有看到converted to的过程
也永远没有这样的机会
你只是听标准这样说过而已
而且很可能是误听
这个男人对你来说是不存在的
认为你所看见的一个女人是由一个虚无的男人通过你所没看见的变性变成
在我看来不但虚幻也多此一举
如果这种虚幻被容许
那么同样可以说这个男人变过2n+1次性
逻辑上没有丝毫漏洞

加载更多回复(335)

69,381

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧