ОП задал два вопроса.
Вопрос 1
В чем разница между *pt
в int (*pt)[2]
и pt
в int *pt
?
В этом
int (*pt)[4];
pt
- указатель, который может указывать на массив из 4
целых чисел.
Предположим, массив 4
целое число - int arr[4] = {1,3,4,6};
Вы можете сделать
pt = &arr; //pt is now pointing to array arr.
В контексте вашей программы
pt = target;
это эквивалентнов
pt = &target[0];
, потому что target
- это адрес первого элемента массива, который является массивом 1D
:
target -> target + 0 -> &(*(target + 0) -> &target[0]
, а target[0]
- это массив 4
целых чисел.
Обратите внимание, что тип из *pt
равен int [4]
, и когда вы используете *pt
в своей программе, вы получите адрес первого элемента массива, на который он указывает и который такжебазовый адрес массива:
*pt -> *pt + 0 -> &(*(*pt + 0)) -> &(*pt)[0]
Учтите это
#include <stdio.h>
int main (void)
{
int (*pt)[4];
int target[3][4] = {{1,3,4,6},{2,4,5,8},{3,4,6,7}};
pt = target; // pointer pt pointing to target[0] array
printf ("%p\n", (void *)*pt);
printf ("%p\n", (void *)&target[0][0]);
return 0;
}
Вывод:
# ./a.out
0x7ffee35389e0
0x7ffee35389e0
Приходит к 2 и часть вопросав этом утверждении
int *pt;
Здесь pt
- указатель нацелое число.
Предположим, у вас есть массив 4
целое число - int arr[4] = {1,3,4,6};
Когда вы делаете
pt = arr;
эквивалентно
pt = *arr[0];
потому что
arr -> arr + 0 -> &(*(arr + 0)) -> &arr[0]
Итак, *pt
даст значение по адресу, на который он указывает.
Рассмотрим этот пример:
#include <stdio.h>
int main (void)
{
int *pt;
int arr[4] = {1,3,4,6};
pt = arr;
printf ("%p\n", (void *)pt);
printf ("%p\n", (void *)arr);
printf ("%p\n", (void *)&arr[0]);
printf ("%d\n", *pt);
return 0;
}
Вывод:
# ./a.out
0x7ffee86f0a00
0x7ffee86f0a00
0x7ffee86f0a00
1
Вопрос 2
почему это «[Ошибка] неверное присвоение массива»
*pt = target[0];
Обратите внимание, что pt
является указателем на массив целых чисел 4
.Тип *pt
- int [4]
.Имя массива не является изменяемым lvalue, и вы не можете присвоить ему.Следовательно, компилятор выдает ошибку в этом утверждении.