内存如何实际寻找C数组?

时间:2012-03-09 18:06:41

标签: c arrays memory allocation

假设你有这个C程序

int main() {
     int *ptr;
     int ar[4];
     ptr = ar;
     return 0;
}

与标签ar关联的地址是否会保留数组第一个元素的基本地址,还是会保留第一个元素本身?如果它是第二个,那么当你有 ptr = ar; ar必须评估其代表的地址,而不是该地址中的内容......对吗?

我很感激对此

的任何意见

4 个答案:

答案 0 :(得分:3)

ar是一个数组,与指针不同。

但是,在大多数情况下(例如将其分配给ptr时),衰减成为指针,即数组中第一个元素的地址。

答案 1 :(得分:0)

它将保留地址。要访问第一个元素,请使用arr [0]或ptr [0]。

答案 2 :(得分:0)

数组名称的值是数组的第一个元素的地址。

答案 3 :(得分:0)

表达式 ar始终引用数组对象,类型为int [4]。除非arsizeof或一元&运算符的操作数,否则它将被替换为(“decay to”)类型为int *的表达式,其值为数组中第一个元素的地址。

所以,给出像

这样的代码
printf("address of ar[0] is %p\n", (void *) ar);

首先发生的事情是表达式ar“衰减”到类型为int *的指针表达式,并且值与&a[0]相同,后者被强制转换为{{ 1}},这就是印刷品。指针值不存储在void *;它是从ar计算出来的。

如何将这一切转换为机器代码取决于编译器。以下是linux上gcc的用法(我将代码保存到名为ar的文件中,并将其编译为layout.c以获得以下汇编列表):

gcc -o layout -ansi -pedantic -Wall -Wa,-aldh=layout.lst layout.c

表达式GAS LISTING /tmp/fbgo448-tmp.359a6da/files/ccoNessg.s page 1 1 .file "layout.c" 2 .version "01.01" 3 gcc2_compiled.: 4 .text 5 .align 4 6 .globl main 8 main: 9 0000 55 pushl %ebp 10 0001 89E5 movl %esp, %ebp 11 0003 83EC28 subl $40, %esp 12 0006 8D45D8 leal -40(%ebp), %eax 13 0009 8945F4 movl %eax, -12(%ebp) 14 000c B8000000 movl $0, %eax 14 00 15 0011 C9 leave 16 0012 C3 ret 17 .Lfe1: 19 0013 90 .ident "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.2 2.96-112.7.2)" -40(%ebp)的第一个元素; ar-12(%ebp)。第12行计算ptr处项目的有效地址,并将该值保存到-40(%ebp),然后将其写入%eax

因此,在gcc / linux的上下文中,您的问题的答案是与-12(%ebp)关联的地址包含第一个元素的值。请注意,答案可能在不同的平台上有所不同。