int f(int b[][3]);

int main()
{
    int a[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
    f(a);
    printf("%d\n", a[2][1]);
}

int f(int b[][3])
{
    ++b;
    b[1][1] = 1;
}

3x3 => 9 элементов, содержащихся в двумерном массиве a. Когда он будет передан, b будет содержать базовый адрес a. Если предположить, что базовый адрес - 1000, то ++b, как он связан с 3 местоположениями, а не 9 местоположениями впереди? Выполняем ли мы приведение типов, когда переменная a передается в b[][3] только как три элемента?

Как b[1][1] соответствует адресу 8, а не 5?

Мы не можем увеличивать или уменьшать массив в массиве, поскольку массив является указателем const, но как они увеличивают ++b как его массив?

c
2
Angus 29 Авг 2011 в 21:58

3 ответа

Лучший ответ

Заголовок функции

 int f(int b[][3])

Это не более чем запутанный способ записи (и в точности эквивалент )

 int f(int (*b)[3])

Тип b - "указатель на трехэлементный массив int". Когда вы увеличиваете параметр b, вы настраиваете его так, чтобы он указывал на следующий трехэлементный массив int - теперь он указывает на {4,5,6}. Затем b[1] индексирует еще раз и дает вам массив {7,8,9} и, наконец, b[1][1] дает вам единственный элемент этого массива, а именно 8.

5
hmakholm left over Monica 29 Авг 2011 в 20:37

Многомерные массивы C действительно линейны, за исключением того, что есть синтаксический сахар для правильной арифметики.

Поэтому с b[][3] он исключает одномерный массив и неявно переводит b[i][j] --> b[3*i+j]

++b работает следующим образом: (++b)[i][j] = ORIGINAL_b[i+1][j]. Итак, в вашем случае вы получаете доступ к ORIGINAL_b[1+1][1] = ORIGINAL_b[2*3+1] = ORIGINAL_b[7] (8-й элемент)

Примечание: это резко контрастирует с динамической версией malloc (в **b b - это массив указателей)

0
Foo Bah 29 Авг 2011 в 18:39

Как b [1] [1] соответствует адресу 8, а не адресу 5?

Это ожидаемое поведение:

int f(int b[][3])
{
    //at this point b[0][0] is 1, b[1][1] is 5

    ++b;
    //now b[0][0] is 4, b[1][1] is 8

    b[1][1]=1;
}

Указатель увеличился, чтобы указать на следующий слот памяти, который является вторым слотом массива a. По сути:

b -> a[0]
++b -> a[1]
-1
Chad 29 Авг 2011 в 18:02