Почему первый элемент массива равен массиву? C - PullRequest
0 голосов
/ 02 июня 2018

Например, допустим, у вас есть массив a и указатель p. Вот как это происходит.

void main() {
    int a[10];
    int *p;
    for(i = 0;i <=10;i++)
        a[i] = (i + 1) * 2;
    p = &a[0];
    printf("%d",a[4]);
    printf("%d",p[4]);
}

Как они равны?

Ответы [ 6 ]

0 голосов
/ 02 июня 2018

Когда вы пишете p = & a [0];такой же, как р = а;теперь p и a - указатели на начало одного и того же массива

0 голосов
/ 02 июня 2018

Массивы хранятся в заразной памяти, и & a [0] является ссылкой на первый элемент.Теперь, если вы хотите получить указатель на секунду, это будет (адрес первого элемента + sizeof (int)).Теперь вы можете получить доступ к его значению с помощью * (адрес первого элемента + sizeof (int). Это называется арифметикой указателей. Вы должны обратиться к хорошей книге, чтобы узнать больше об этом.

0 голосов
/ 02 июня 2018

В [10] a - указатель, который указывает на адрес первого элемента массива.Поэтому, когда вы присваиваете:

p = &a[0];

P также хранит тот же адрес, что и у, и указывает на тот же элемент.Таким образом, любые манипуляции с p будут отражены в.

0 голосов
/ 02 июня 2018

Определение массива : Массив - это серия элементов одного типа, помещенных в смежные области памяти, на которые можно индивидуально ссылаться, добавляя индекс к уникальному идентификатору.

Когда вывозьмите адрес первого элемента массива (&a[0]), вы получите то же значение, что и a.(однако вы потеряете информацию о размере, так как &a[0] является указателем на память, где a на самом деле является массивом)

Это потому, что a[0] фактически переводится в *(a + 0), где a - указатель на адрес памяти, в котором находится ваш массив.Таким образом, &a[0] становится &(*(a + 0)) или «адресом содержимого адреса a + 0», что совпадает с «адресом a»

Аналогично, a[4] переводится в *(a + 4).

Надеюсь, это прояснит ситуацию:)

РЕДАКТИРОВАТЬ:

Я только что нашел эту страницу, где вы можете прочитать больше об этом: https://www.le.ac.uk/users/rjm1/cotter/page_59.htm

РЕДАКТИРОВАТЬ 2: Уточнил разницу между &a[0] и a

0 голосов
/ 02 июня 2018

Почему первый элемент массива равен массиву? .Допустим, у вас есть целочисленный массив типа int arr[5];, тогда в соответствии с вашим вопросом заголовок

  • первый элемент массива будет arr[0], что является значением arr[0], и
  • массив означает arr и arr имена представляют базовый адрес массива.Так что arr и arr[0] не одно и то же.arr является базовым адресом, а arr[0] является значением.

В вашем конкретном случае массив целых чисел a выглядит следующим образом, и все элементы массива хранятся в последовательной ячейке памяти.Предположим, что базовый адрес массива равен 0x100 (некоторая ячейка памяти)

 a[0]   a[1]  a[2]  a[3]  ........................................ a[9]
  ------------------------------------------------------------------------
 |  2  |  4  |  6  |  8  |  10  |  12  |  14  |  16  |  18  |  20  | 22  |
  ------------------------------------------------------------------------
0x100   0x104  0x108 ..                                         ..    
 a
LSB                                                                   MSB

Так что здесь a означает 0x100, предполагая, что базовый адрес a равен 0x100.Теперь, когда вы делаете

p = &a[0]; /* here you are setting p to point to one of the places in the array a and that is a[0] */ 

, здесь p указывает на first элемент a, то есть 0x100, как показано ниже

       a[0]   a[1]  a[2]  a[3]  ........................................ a[9]
      ------------------------------------------------------------------------
     |  2  |  4  |  6  |  8  |  10  |  12  |  14  |  16  |  18  |  20  | 22  |
      ------------------------------------------------------------------------
    0x100   0x104  0x108  0x112 0x116..                                         ..    
     a
     |
     p   

Теперь, когда вы печатаете a[4]он печатает 10, что довольно просто, как и ожидалось, и расширяется, как показано ниже

a[4] = *(a + 4) /* here you can say that array name a is converted to a pointer to its first element */
     = *(0x100 + 4*4 ) /* multiplied by 4 ? bcz a is int array & each element size is 4 byte */
     = *(0x116) /* value at 0x116 memory location */
     = 10

А когда вы печатаете p[4], он расширяется, как показано ниже

p[4] = *(p + 4)
     = *(0x100 + 4*4) /*multiplied by 4 because int pointer increments by 4 bytes*/
     = *(0x116) ? /* it prints value at 0x116 location which 10 */
     = 10

Также при назначении значений дляэлементы массива в for loop, вы пытаетесь получить доступ к a[10], который выходит за границы и вызывает неопределенное поведение .В приведенном ниже кодовом блоке условие должно быть i<10 вместо i<=10, как вы объявили a[10], а индекс массива начинается с zero.

for(i = 0;i <=10;i++) {  /* make it i<10 */
        a[i] = (i + 1) * 2;
}

Наконец, void main() { /* code */ } - это плохая практика, и этоне соответствует спецификации стандартов C.Вместо этого используйте int main(void) { }, как указано в стандарте C n1256 draft.

5.1.2.2.1 Запуск программы

1 Функция, вызываемая при запуске программы, называется main.Реализация не объявляет прототип для этой функции.Он должен быть определен с типом возврата int и без параметров:

int main(void) { /* ... */ }

или с двумя параметрами (именуемыми здесь как argc и argv, хотя могут использоваться любые имена,поскольку они локальны для функции, в которой они объявлены):

int main(int argc, char *argv[]) { /* ... */ }

или эквивалентной; 9) или каким-либо другим способом, определяемым реализацией.

0 голосов
/ 02 июня 2018

Вы назначили указатель 'p' для указания локального массива 'a', так что теперь 'p' и 'a' - это один и тот же массив, каждое изменение, которое вы вносите в 'p', будет влиять непосредственно на 'a' инаоборот.

p = &a[0];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...