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

楼主: TobyH4cker (Toby (我要当好人))   2015-05-13 03:15:38
※ 引述《Hazukashiine (耻ずかしい ね...(>///<))》之铭言:
: 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 的,它被编译器巧妙地包装了。
不用争论了,反正下面三件事情结果都是一样的:
#include <stdio.h>
int main()
{
int a[5];
printf("&a[0]\t%p\n", &a[0]);
printf("a\t%p\n", a);
printf("&a\t%p\n", &a);
return 0;
}
执行结果:
&a[0] 0018FF48
a 0018FF48
&a 0018FF48
反组译奉上:
.text:004011E8 push ebp
.text:004011E9 mov ebp, esp
.text:004011EB add esp, 0FFFFFFECh
.text:004011EE lea eax, [ebp-14h] ; 是这样
.text:004011F1 push eax ; &a[0]
.text:004011F2 push offset aA0P ; "&a[0]\t%p\n"
.text:004011F7 call 00403DA8 ; 前往 printf
.text:004011FC add esp, 8
.text:004011FF lea edx, [ebp-14h] ; 一样
.text:00401202 push edx ; a
.text:00401203 push offset aAP ; "a\t%p\n"
.text:00401208 call 00403DA8 ; 前往 printf
.text:0040120D add esp, 8
.text:00401210 lea ecx, [ebp-14h] ; 还是一样
.text:00401213 push ecx ; &a
.text:00401214 push offset aAP_0 ; "&a\t%p\n"
.text:00401219 call 00403DA8 ; 前往 printf
.text:0040121E add esp, 8
.text:00401221 xor eax, eax
.text:00401223 mov esp, ebp
.text:00401225 pop ebp
.text:00401226 retn
由于 a is an array of 5 int,
又 sizeof(int) = 4,
故 sizeof(a) = 5 * 4 = 20 跟ASM中的[ebp-0x14]符合,
add esp, 0FFFFFFECh 又 相当于 sub esp, 0x14
反正这个 array 会放在 stack,
会担心找不到位址吗?
编译器都安排好一切了,
结案。
题外话我后来用MSVC CL没有其他参数下编译后,
&a[0]的部分反组译结果是
.text:00401010 mov eax, 4 ; sizeof(int) = 4
.text:00401015 imul ecx, eax, 0 ; 0 elements
.text:00401018 lea edx, [ebp+ecx-18h]
有趣的是这样比较贴近原始的意义,
是透过阵列元素型态的大小(4)和数量(0)来算所需的偏移量(ecx)。
作者: Feis (永远睡不着 @@)   2015-05-13 07:55:00
array 不一定会放在 stack, 其实用组语解释真的有点风险阿为什么人家 python 都不需要用组语 xD
作者: dritchie (卍~迈斯纳效应~卍)   2015-05-13 08:11:00
楼上????
楼主: TobyH4cker (Toby (我要当好人))   2015-05-13 09:49:00
是的我是以原发问者的例子来解释而已C的好玩之处就是可以直接想像在CPU会怎么运算
作者: Killercat (杀人猫™)   2015-05-13 11:20:00
用组语解释其实是“编译器”怎么算 XD不过这个求证方法至少有90分 赞
作者: wenyonba (射后不理很XX啊!!!!)   2015-05-13 13:33:00
其实每次有这个问题的讨论串,我都很想问,int a[5];到底什么时候会用到 &a?? ?_?
作者: MOONRAKER (㊣牛鹤鳗毛人)   2015-05-13 14:06:00
不小心戳到的时候?
作者: bibo9901 (function(){})()   2015-05-13 14:15:00
通常就是用二维阵列的时候
作者: Killercat (杀人猫™)   2015-05-13 14:18:00
大概只有“特别指出避免被误以为a是int的时候”吧
楼主: TobyH4cker (Toby (我要当好人))   2015-05-13 14:49:00
可是用array本来就要有只有a时是什么意义的观念
作者: Feis (永远睡不着 @@)   2015-05-13 15:03:00
wenyonba: 当你有个指标的阵列, 每个元素想指向阵列时传统的例子就是一堆字串要排序.实际上应该还是有很多特殊的情境需要.阵列原则上也是 object 的一种, 这部分好像也没道理要不一样

Links booklink

Contact Us: admin [ a t ] ucptt.com