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
как его массив?
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
.
Многомерные массивы 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
- это массив указателей)
Как 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]
Похожие вопросы
Новые вопросы
c
C - это язык программирования общего назначения, используемый для системного программирования (ОС и встраиваемых), библиотек, игр и кроссплатформенности. Этот тег следует использовать с общими вопросами, касающимися языка C, как это определено в стандарте ISO 9899 (последняя версия 9899: 2018, если не указано иное, а также для запросов, специфичных для версии, с c89, c99, c11 и т. Д.). C отличается от C ++ и не должен сочетаться с тэгом C ++ без разумной причины.