Путаница в типах данных в двумерном массиве - PullRequest
6 голосов
/ 03 марта 2011

Вот код, который печатает адрес первого элемента двумерного массива с последующим добавлением 1. Хотя все 4 базовых адреса одинаковы, но их добавление с 1, очевидно, не дает тот же результат из-за их различий " типы». Я могу выяснить тип для некоторых (если они правильные), но не для всех.

int main()
{
    int array[4][3];
    printf("array %u\n",array);   //of type int(*)[3]
    printf("array+1 %u\n",array+1);
    printf("&array %u\n",&array);   //....???
    printf("&array+1 %u\n",&array+1);
    printf("array[0] %u\n",array[0]);    //of type int*
    printf("array[0]+1 %u\n",array[0]+1);
    printf("&array[0] %u\n",&array[0]); //....???
    printf("&array[0]+1 %u\n",&array[0]+1);
} 

Можете ли вы объяснить "тип" каждого базового адреса в деталях, чтобы понять арифметику указателей, которая используется после добавления 1. Ниже приведен пример вывода для машины gcc.

array       3214383040 
array+1     3214383052 
&array      3214383040 
&array+1    3214383088 
array[0]    3214383040 
array[0]+1  3214383044 
&array[0]   3214383040 
&array[0]+1 3214383052 

Ответы [ 2 ]

10 голосов
/ 03 марта 2011

Имея int array[4][3]; применяется следующее

array - это массив из 4 элементов. Каждый элемент представляет собой массив с 3 int с. В большинстве случаев использование имени само по себе приводит к уменьшению массива до указателя на его первый элемент; тогда array становится указателем на массивы 3 int s

array + 1 - указатель на массив из 3-х целых. Здесь array распадается на указатель, а 1 относится к массиву 3 int

&array - адрес всего массива. Указывает на объекты типа массив из 4 массивов по 3 дюйма

&array + 1 является вторым (который на самом деле не существует) элементом псевдо- массива массивов из 4 массивов по 3 дюйма

array[0] - массив из 3-х целых. Обычно затухает до указателя на первый элемент

array[0] + 1 указывает на 2-е int в array[0]

&array[0] адрес объекта массива типов из 3-х точек

&array[0]+1 2-й элемент массива массивов из 3-х элементов

PS. Я постараюсь сделать рисунок (ASCII) после обеда.


Хммм ... рисунок сложный:)

Прежде чем попытаться, я подумал, что смогу сделать лучший рисунок. Это лучшее, что я мог придумать ...


    int array[4][3]        ........[aaabbbcccddd]........
                              where aaa, bbb, ccc, ddd are arrays of 3 ints'

    the [] represent the object itself; the {} represent pointers.

    array (object)         ........[AAABBBCCCDDD]........       int[4][3]
    array (decayed)    ==> ........{aaa}bbbcccddd........       int(*)[3]

    array + 1          ==> ........aaa{bbb}cccddd........       int(*)[3]

    &array             ==> ........{aaabbbcccddd}........       int(*)[4][3]
    &array + 1         ==> ........aaabbbcccddd{xxxxxxxxxxxx}........       int(*)[4][3]

    array[0] (object)      ........[AAA]bbbcccddd........       int[3]
    array[0] (decayed) ==> ........{a}aabbbcccddd........       int*

    array[0] + 1       ==> ........a{a}abbbcccddd........       int*

    &array[0]          ==> ........{aaa}bbbcccddd........       int(*)[3]
    &array[0] + 1      ==> ........aaa{bbb}cccddd........       int(*)[3]

3 голосов
/ 03 марта 2011

Если вы скомпилируете это как C ++, вы можете использовать оператор typeid из библиотеки typeinfo STL для получения этой информации.Например, запуск этого

#include <stdio.h>
#include <typeinfo>

void main()
{
     int array[4][3];
     printf("array %s\n",typeid(array).name());   //of type int(*)[3]
     printf("array+1 %s\n",typeid(array+1).name());
     printf("&array %s\n",typeid(&array).name());   //....???
     printf("&array+1 %s\n",typeid(&array+1).name());
     printf("array[0] %s\n",typeid(array[0]).name());    //of type int*
     printf("array[0]+1 %s\n",typeid(array[0]+1).name());
     printf("&array[0] %s\n",typeid(&array[0]).name()); //....???
     printf("&array[0]+1 %s\n",typeid(&array[0]+1).name());
}  

дал мне следующие результаты

array int [4][3]
array+1 int (*)[3]
&array int (*)[4][3]
&array+1 int (*)[4][3]
array[0] int [3]
array[0]+1 int *
&array[0] int (*)[3]
&array[0]+1 int (*)[3]

Это объясняет, почему добавление 1 может увеличить указатель на 4 байта (один int), 12 байтов (int[3]) или 48 байтами (int [4] [3]).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...