Re: [问题] 对阵列名称取址

楼主: Hazukashiine (私は幸せです)   2015-05-12 21:42:16
※ 引述《lalaboom (lalaboom)》之铭言:
: 标题: [问题] 对阵列名称取址
: 时间: Tue May 12 19:54:31 2015
: 
: 之前我的认知阵列名称是一个常数指标,非指标常数喔,
:  
: 1. 请问这个叙述对吗?
:  
: 现在有阵列 int b[2]; int a[2][3];
:  
: 2. 请问为什么 b 跟 &b 两个address会一样呢?
: 我可以理解 a, a[0], &a[0][0] 这3个一样,
: 但是type不同,还是说这个认知也是错的XD
:  
: 3. 阵列在内存里面除了宣告出来的连续空间,
: 阵列名称是否会有另外像宣告指标一样有一个变量空间吗?
:  
: 关于2之前好像有看到说&b = b 是定义好的 (compiler ? )
这些问题好像有许多的初学者都很困惑,
虽然明天我要考可怕的偏微分段考已经自顾不暇了,不过还是想回答一下。(笑
站在C语言本身的角度,阵列本身不是一个指标,它就是一个单单纯纯的阵列。
站在机器的角度,阵列占据了内存一段连续的空闲,并且有个变量记录了它的位置。
但是这个变量不是程式设计师可以直接获得的,它需要进行转换才能获得。
先说说第二个好了:
b 跟 &b 的地址不一样,简单地说, &b 的地址并不存在,而且对编译器来说是非法的。
因为当你在写单独一个 b 的时候, b 已经被隐式转换成指标型态,而且这是被强制的。
在且 b 是一个右值(r-value),意思是你不能对此作取址的动作。
根据 ISO 文件 §4.2.1 Standard Conversions: Array-to-pointer conversion
An lvalue or rvalue of type "array of N T" or "array of unknown bound of T"
can be converted to an rvalue of type "pointer to T." The result is a pointer
to the first element of the array.
接下来的第三个也是一样,
阵列名称有占空间吗?结果呼之欲出,当然不占。因为阵列名称(b)是右值,并不占空间。
可是你一定会很好奇不占空间的话你的程式要如何知道阵列在哪?
这件事很妙,站在C语言的角度并不占空间,但是实作上办不到,所以当然要占空间。
只是这个变量不是你的程式可以 access 的,它被编译器巧妙地包装了。
这样很矛盾吗?
其实,不。
因为程式语言本身定义的是语法结构,并不是实作的内容。
因此一个程式语言可以有很多种编译器,像是 GCC C Compiler, MSVC etc.
如有错误欢迎指正。
( ̄▽ ̄#)=﹏﹏ 飘走=
作者: Feis (永远睡不着 @@)   2015-05-12 21:54:00
&b 存在且合法. b 不占空间的话, 试解释 sizeof(b)b 是个阵列. 但是不占空间吗? 蛮有趣的
作者: CaptainH (Cannon)   2015-05-12 22:53:00
b 是 lvalue
作者: AstralBrain   2015-05-12 22:57:00
b[2]不是阵列, b[2]是阵列的第3个elementb 是 lvalue (这很重要) http://ideone.com/mKCvI2
作者: CaptainH (Cannon)   2015-05-12 22:58:00
那你怎么解释An lvalue or rvalue of type "array of NT"这个东西?
作者: Feis (永远睡不着 @@)   2015-05-12 23:15:00
放在 stack 中? 这也蛮有趣的
作者: CaptainH (Cannon)   2015-05-12 23:15:00
修正后仍是错,b[]不是正确的语法,更别说他代表什么了
作者: Feis (永远睡不着 @@)   2015-05-12 23:17:00
推一下右值的定义. 蛮有趣的对了. 忘了问 4.2.1 的那节是 ISO C 哪个版本?我建议你可以去 C 标准找一下 rvalue (如果你在说 C 的话)所以你的 compiler 印不出 &b ?此外你可以想想 struct 变量~ 比对一下跟 array 的差别还有你的 sizeof 的说明不是已经说了 b 是 array type ?如果 b 不是 array type, 那 sizeof(b) 到底是什么.. 头痛b 会被转成 &b[0] 喔~ 所以是 int * 而不是 int(*)[2]恩.. 我们看的是同一篇吗 XDDDDD我需要一点时间理解. 晚安 : )是阿. 那不就是 &b 吗 xD但是你说的不是 b 在程式码中会被转 int (*)[2] 吗?我说的是 b 会转为 int * 不是 &b 阿 QQ用编辑文章好难回阿 xD 原文 &b 的 address 应该不是 &&b 的意思. 或者我以为他不是 xD
作者: bibo9901 (function(){})()   2015-05-13 00:00:00
你是跟叶孤红一样有人专门写一本错误的书给你看吗 XD既然 b 是一个 rvalue 那你怎么能用 address-of 呢?
作者: Feis (永远睡不着 @@)   2015-05-13 00:06:00
提醒一下... standard conversion 是 C++ 的...
作者: bibo9901 (function(){})()   2015-05-13 00:10:00
我说的是 address-of "&" 不是 sizeof如果 b 不占空间的 rvalue, 那你写下 &b 就是非法的
作者: Feis (永远睡不着 @@)   2015-05-13 00:12:00
其实我不知道 rvalue 不占空间这样的说法到底该怎么解释 xD我是觉得 rvalue 很玄阿~ 大家晚安~
作者: bibo9901 (function(){})()   2015-05-13 00:14:00
的确很怪, 但暂且假设如他所说的那样, 对 b 取址更怪
作者: Feis (永远睡不着 @@)   2015-05-13 00:25:00
对转换有兴趣请参阅 C89 标准 3.2.2.1
作者: yvb   2015-05-13 14:57:00
94行说 "使用C++来检视C?"但 35行 "ISO 文件 §4.2.1" 似乎引自 C++ ??另外, 原原PO问 "为什么 b 跟 &b 两个address会一样"然后 30行那边回 "b 跟 &b 的地址不一样" ...感觉答非所问? 还是 "地址不一样" 似乎不是唯一解??上面 F大的 3.2.2.1 其实是指 6.3.2.1 ?
作者: Feis (永远睡不着 @@)   2015-05-13 17:20:00
yvb: 好像是版本差异 XD 那是 C89 Draft
作者: yvb   2015-05-13 17:57:00
soga... C89 3.2.2.1 => C90 6.2.2.1 => C99~C11 6.3.2.1c89 要 google ansi.c.txt 才找得到 :P (好像没 pdf 的?)

Links booklink

Contact Us: admin [ a t ] ucptt.com