Question 1
char arr[][4] = {"abc","def"};
defines arr
to be an array of arrays. With other objects, such as a structure, one structure, say C
, could be assigned to another structure, say B
, of the same type, using B = C;
. However, C has special rules for arrays.
When an array is used in an expression, it is automatically converted to a pointer to its first element, except when it is the operand of sizeof
or unary &
or is a string literal used to initialize an array. So, when we write:
x = arr;
the automatic conversion makes it as if we had written:
x = &arr[0];
Then, since &arr[0]
is a pointer to an array of 4 char
, x
must also be a pointer to an array of 4 char
(or something compatible, perhaps a pointer to an array of an unknown number of char
).
Note that char **x;
declares a pointer to a pointer. That is, it is a pointer, and, at the memory it points to, there must be another pointer. In contrast, &arr[0]
is a pointer to an array. It is a pointer, and, at the memory it points to, there is an array of 4 char
. If you tried to use **x
, the compiler would look at the memory that x
points to and expect to find a pointer there. If, instead, there is not a pointer but rather four arbitrary char
values, the program would be broken. So char **x
is not compatible with a pointer to an array of 4 char
.
A proper declaration for x
would be char (*x)[4];
. After such a declaration, the assignment x = arr;
would be proper.
Question 2
Your code t->text = { "IF WE COULD TAKE THE TIME", "TO LAY IT ON THE LINE", "I COULD REST MY HEAD" };
is not strictly conforming C and does not compile in typical compilers.
Question 3
Consider the code (adjusted to allow compilation):
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]
declares arr
to be an array of 3 pointers to char
. It is then initialized to contain three pointers to (the first characters of) strings.
So each element of arr
, arr[i]
is a pointer to char
. By C’s rule about automatic conversion of arrays, in t.text = arr;
, arr
is converted to a pointer to its first element. So we have t.text = &arr[0];
. Then &arr[0]
is a pointer to a pointer to a char
, and t.text
is a pointer to a pointer to a char
, so the types are compatible.