Вопрос 1
char arr[][4] = {"abc","def"};
определяет arr
как массив массивов.С другими объектами, такими как структура, одна структура, скажем, C
, может быть назначена другой структуре, скажем, B
, того же типа, используя B = C;
.Однако в C есть специальные правила для массивов.
Когда в выражении используется массив, он автоматически преобразуется в указатель на свой первый элемент, за исключением случаев, когда он является операндом sizeof
или унарным &
или строковый литерал, используемый для инициализации массива.Итак, когда мы пишем:
x = arr;
, автоматическое преобразование делает это так, как если бы мы написали:
x = &arr[0];
Тогда, поскольку &arr[0]
является указателем на массив из 4 char
, x
также должен быть указателем на массив 4 char
(или чем-то совместимым, возможно, указателем на массив с неизвестным числом char
).
Обратите внимание, что char **x;
объявляет указатель на указатель.То есть это указатель, и в памяти, на которую он указывает, должен быть другой указатель.Напротив, &arr[0]
является указателем на массив.Это указатель, и в памяти, на которую он указывает, имеется массив 4 char
.Если вы попытаетесь использовать **x
, компилятор будет искать память, на которую указывает x
, и ожидать, что там найдется указатель.Если вместо этого есть не указатель, а четыре произвольных значения char
, программа будет прервана.Так что char **x
несовместимо с указателем на массив 4 char
.
. Правильное объявление для x
будет char (*x)[4];
.После такого объявления присваивание x = arr;
будет правильным.
Вопрос 2
Ваш код t->text = { "IF WE COULD TAKE THE TIME", "TO LAY IT ON THE LINE", "I COULD REST MY HEAD" };
не строго соответствует C и не компилируется в типичных компиляторах.
Вопрос 3
Рассмотрим код (отрегулированный для разрешения компиляции):
struct document
{
char **text;
int numOfLines;
} t;
char *arr[3] = {
"IF WE COULD TAKE THE TIME",
"TO LAY IT ON THE LINE",
"I COULD REST MY HEAD" };
t.text = arr;
char *arr[3]
объявляет arr
массивом из 3 указателей на char
.Затем он инициализируется, чтобы содержать три указателя на (первые символы) строк.
Таким образом, каждый элемент arr
, arr[i]
является указателем на char
.По правилу C об автоматическом преобразовании массивов, в t.text = arr;
, arr
преобразуется в указатель на свой первый элемент.Итак, у нас есть t.text = &arr[0];
.Тогда &arr[0]
- указатель на указатель на char
, а t.text
- указатель на указатель на char
, поэтому типы совместимы.