Как на самом деле выглядит память для массива C? - PullRequest
0 голосов
/ 09 марта 2012

Скажем, у вас есть эта программа на C

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

будет ли адрес, связанный с меткой, содержать базовый адрес первого элемента массива или сам первый элемент? Если это второй, то когда у вас есть ptr = ar; ar должен оценивать адрес, который он представляет, в отличие от того, что находится в этом адресе ... правильно?

Буду признателен за любую информацию по этому вопросу

Ответы [ 4 ]

3 голосов
/ 09 марта 2012

ar - это массив, отличный от указателя.

Однако в большинстве ситуаций (например, когда вы присваиваете его ptr), он распадается , чтобы стать указателем, то есть адресом первого элемента в массиве.

0 голосов
/ 10 марта 2012

Выражение ar всегда ссылается на объект массива и имеет тип int [4].За исключением случаев, когда ar является операндом операторов sizeof или унарных &, он будет заменен ("decay to") выражением типа int *, значением которого является адрес первого элемента в массиве.

Итак, для данного кода, подобного

printf("address of ar[0] is %p\n", (void *) ar);

, первое, что происходит, это то, что выражение ar «распадается» на выражение указателя, тип которого равен int *, а значение -такой же как &a[0], который приводится к void *, и это то, что печатается.Значение указателя не сохраняется в ar;это вычислено из ar.

Как все это переводится в машинный код, зависит от компилятора.Вот что делает с ним gcc в linux (я сохранил ваш код в файл с именем 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) - это ptr.В строке 12 вычисляется эффективный адрес элемента в -40(%ebp) и сохраняется это значение в %eax, которое затем записывается в -12(%ebp).

Итак, в контексте gcc / linux ответ на ваш вопрос заключается в том, что адрес, связанный с ar, содержит значение первого элемента.Обратите внимание, что ответ может быть другим на другой платформе.

0 голосов
/ 09 марта 2012

Значением имени массива является адрес первого элемента массива.

0 голосов
/ 09 марта 2012

Он будет содержать адрес. Чтобы получить доступ к первому элементу, используйте arr [0] или ptr [0].

...