2016-09-22 5 views
5

В KR С книжной странице 112 он говорит, что следующее:указатель на массив целых чисел и обычный массив целых чисел

int (*arr1)[10]; 

является указателем на массив из 10 целых чисел. Я не понимаю, что это разница между выше и:

int arr2[10]; 

1- Не arr2 сам указатель на массив из 10 целых чисел? (Поскольку имя массива является самим указателем.)

2- Если имя массива является адрес массива и указатель на этот массив, то оба arr1 и arr2 является указателем на массив целых чисел, не является ли это правда?

+1

Как большой указатель 'Е ("% цу \ п", SizeOf arr1); '? -> может быть 4 или 8 и т. д. Насколько велика массив 'printf ("% zu \ n ", sizeof arr2);'? -> может быть 40 или 80 и т. д. – chux

ответ

5

Isn't arr2 itself a pointer to array of 10 integers?

Нет, это массив.

Isn't the name of an array the array address and pointer to that array?

Имена массивов могут быть/преобразуются в указатели их 0-й элемент (а не весь массив).

So both arr1 and arr2 are pointer to array of integers?

Номер

  1. arr1 представляет собой указатель на массив из 10 целых чисел.
  2. arr2 представляет собой массив из 10 целых чисел. В большинстве контекстов он преобразуется в указатель на целое число (а не на указатель на массив).

Проверить это неправильно пример, например:

#include <stdio.h> 

int main(void) 
{ 
    int arr2[10] = {0}; 
    arr2[5] = 747; 

    int (*arr1)[10] = {0}; 
    arr1[5] = 747; 

    return 0; 
} 

Здесь я подхожу как arr1 и arr2 как "то же самое", и я получил эту ошибку:

C02QT2UBFVH6-lm:~ gsamaras$ gcc -Wall main.c 
main.c:9:13: error: array type 'int [10]' is not assignable 
    arr1[5] = 747; 
    ~~~~~~~^
1 error generated. 

Но если да, то:

arr1[0][5] = 747; 

будет проходить сбор! То же самое и с (*arr1)[5] = 747;.

1

Взаимосвязь между массивами и указателями является одним из наиболее запутанных аспектов C. Позвольте мне объяснить в качестве примера. Следующий код заполняет и отображает простой одномерный массив:

void showArray(int *ptr, int length) 
{ 
    for (int i = 0; i < length; i++) 
     printf("%d ", ptr[i]); 
    printf("\n"); 
} 

int main(void) 
{ 
    int array[10]; 
    for (int i = 0; i < 10; i++) 
     array[i] = i; 
    showArray(array, 10); 
} 

Вы можете видеть, что, когда массив передается в функцию, имя массива воспринимается как указатель на первый элемент массива. В этом примере первым элементом является int, поэтому указатель int *.

Теперь рассмотрим этот код, который заполняет и выводит двумерный массив:

void showArray(int (*ptr)[10], int rows, int cols) 
{ 
    for (int r = 0; r < rows; r++) 
    { 
     for (int c = 0; c < cols; c++) 
      printf("%2d ", ptr[r][c]); 
     printf("\n"); 
    } 
} 

int main(void) 
{ 
    int array[5][10]; 
    for (int row = 0; row < 5; row++) 
     for (int col = 0; col < 10; col++) 
      array[row][col] = row * 10 + col; 
    showArray(array, 5, 10); 
} 

Имя массива по-прежнему является указателем на первый элемент массива.Но в этом примере первый элемент массива сам по себе является массивом, а именно массивом из 10 int. Таким образом, указателем в функции является указатель на массив из 10 int.

Что я надеюсь произвести на вас впечатление, так это то, что указатель формы (int *ptr)[10] имеет некоторое соответствие двумерному массиву, тогда как указатель формы int *ptr имеет некоторое соответствие одномерному массиву.

0

cdecl.org покажет вам, что C интерпретирует объявление переменной как. Довольно удобно, когда вы начинаете получать более сложные объявления переменных.

int arr2[10]; объявить arr2 как массив 10 ИНТ

int (*arr1)[10]; объявить arr1 как указатель на массив 10 ИНТ

Смежные вопросы