LINUX.ORG.RU

[c] многомерный массив

 


0

1

Из Output 1/2 видно, что одномерный (вектор) и многомерный массивы хранятся в памяти одинаково - в виде вектора [x1, x2, x3, x4] (запись идет по-строкам). При этом a и b - указатели на векторы, т. е. хранят адреса, по которым размещены векторы.

Вопрос вызывает Output 3. Если разобрать выражение *((*(a+i))+j)), получится:

1. К адресу первого элемента прибавляем число равное произведению индекса i и размера элемента.

2. Полученное в п1 значение трактуется как адрес переменной (указатель). Из этого адреса извлекается значение (происходит разыменование указателя) и складывается со вторым индексом j умноженным на размер элемента.

3. Полученное в п2 значение трактуется как адрес переменной (указатель). Из этого адреса извлекается значение (выполняется второе разыменование указателя) которое и является результатом выражения.

Как, при всем этом, Output 3 может работать правильно? Ведь у нас переменная "a" указатель на «одномерный» массив, а не указатель на массив указателей. Откуда _два_ разыменования?

       
 указатель на одномерный массив                  

  &---&       &-------------------&                      
  | a |------>| x1 | x2 | x3 | x4 |               
  &---&       &-------------------&                    
                                                  
 указатель на массив указателей                   

  &---&       &---------& 
  | a |------>| x1 | x2 | 
  &---&       &---------& 
                |     |  
                |     |  
                V     V  
               &--&  &--&
               |y1|  |y1|
               |y2|  |y2|
               &--&  &--&
Код:
#include <stdio.h>

int main() {
    int i, j;
    int a[2][2]={{1, 2},
                 {3, 4}};

    int b[4]={1, 2, 3, 4};

    printf("Output 1: ");

    for (i=0; i < 2; i++)
        for (j=0; j < 2; j++)
            printf("%d ",((int*)a)[i*2+j]);

    printf("\nOutput 2: ");

    for (i=0; i < 2; i++)
        for (j=0; j < 2; j++)
            printf("%d ",b[i*2+j]);

    printf("\nOutput 3: ");

    for (i=0; i < 2; i++)
        for (j=0; j < 2; j++)
            printf("%d ",*((*(a+i))+j));
    printf("\n");
    
    return 0;
}
Вывод:
$ ./test
Output 1: 1 2 3 4 
Output 2: 1 2 3 4 
Output 3: 1 2 3 4 


Ответ на: комментарий от anonymous

int a[2][10]; a == int (*[10]) *a == int* **a == int если словами то int a[2][10]; это указатель на массив из 10 элементов типа int int (*[10]) если разыменовать *a получим int* если два раза разыменовать **a то получим int

anonymous
()
Ответ на: комментарий от anonymous
int a[2][10];
a == int (*[10]) 
*a == int*  
**a == int
если словами то 
int a[2][10];
это указатель на массив из 10 элементов типа int
int (*[10]) 
если разыменовать *a получим int*
если два раза разыменовать **a то получим int
anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.