p = array[3]; // int * = int
is an error; the types don't match, and the compiler will yell at you for it. The type of p
is int *
, and the type of array[3]
is int
.
There are two ways to fix this, depending on what you want to do. If you want to set p
to point to array[3]
(which is what you want to do in this case), you would write
p = &array[3]; // int * = int *
If you want to write the value of array[3]
to the object that p
points to (which is not what you want to do in this case, since p
isn't pointing anywhere valid yet), you would write
*p = array[3]; // int = int
In this case, we want to set p
to point to array[3]
, so we use the first statement. After doing that, the following are true:
p == &array[3] // int *
*p == array[3] == 2 // int
Now we have the statement
*p = (int) *c;
is saying "take the value of the char
object that c
points to, convert it to an int
value1, and assign the result to the object that p
points to."
Except when it is the operand of the sizeof
or unary &
operators, or is a string literal being used to initialize an array of char
in a declaration, an expression of type "N-element array of T
" will be converted ("decay") to an expression of type "pointer to T
", and the value of the expression will be the address of the first element of the array.
The expression c
has type "5-element array of char
". Since it is not the operand of the sizeof
or unary &
operators, it is converted to an expression of type char *
, and the value of the expression is the address of the first element in the array, c[0]
. Thus:
c == &c[0] // char *
*c == c[0] == 'A' == 65 (ASCII) // char
Taking all that together, that means
*p = (int) *c;
is another way of writing
*p = (int) c[0];
which is another way of writing
array[3] = (int) c[0];
which is another way of writing
array[3] = (int) 'A';
which is another way of writing
array[3] = 65;
(int)
is a cast expression; it means that the value following it should be treated as type int
.