Working with pointers and arrays in C I've found a curious case which I don't understand why it occurs.
First, I want to describe correct case:
I've defined a function void modifyArray(int *list)
where the array must be modified by reference to multiply items by 2 times (x2). Function implementation is:
void modifyArray(int *list, int arrLength){
for(int i=0; i<arrLength; i++){
*(list + i) = *(list + i) * 2; // x = x * 2
}
}
int main(int nargs, char **args) {
int list[] = {1,2,3,4,5};
modifyArray(&list, 5);
for(int i=0; i<5; i++){
printf("%d\n", *(list + i));
}
}
Output is:
2
4
6
8
10
Now I'm going to explain the incorrect case: I've defined a new data type List
and modified the function to accept List
instead of int *
or int[]
as first parameter:
typedef int List[5];
void modifyArray(List *list, int arrLength){
for(int i=0; i<arrLength; i++){
*(list + i) = *(list + i) * 2; // x = x * 2
}
}
After modification my compiler build fails because the sentence *(list + i) = *(list + i) * 2; // x = x * 2
can't multiply bacause of the following error message:
Invalid operands to binary expression ('List' (aka 'int [5]') and 'int')
I know my compiler is trying to multiply the complete array by 2, but don't know the reason.
The solution I've found is replacing *(list + 1)
by *(*list + 1)
. I'm confused because of in second case, when I print list
and *list
output is a memory address (same memory address for both) instead of a memory address for list
and its content for *list
.
Can you explain why this is happening and what is the difference by using int *
and List
defined type?
When list
is defined with int list[] = {1,2,3,4,5};
, &list
is a pointer to an array of five int
. It is not appropriate to pass this for a parameter of type int *
, and the compiler should have issued a warning or error for that in the first code. The proper argument would be list
. Although that is an array, it will be automatically converted to a pointer to its first element, and that pointer is an int *
, which is the correct type for the parameter.
When the parameter is declared as List *list
, it is a pointer to an array. Then, in *(list + i)
, the addition is done in units of those arrays, not units of int
. The result of the addition is a pointer to an array, so the result of the *
in *(list + i)
is an array. Then the multiplication is trying to multiply an array by two, so the compiler complains.
Instead, declare the parameter as List list
. This declares it to be an array, but it will be automatically adjusted to be a pointer to an int
. Because C does not support passing arrays as parameters, it automatically adjusts a declaration of a parameter as an array to be a declaration of a pointer to an array element instead, which is supported.
Also, do not write *(list + i)
. Use list[i]
. It means the same thing but is easier to read.