Here is a straight-forward adaptation of your code, combining the two variants of main()
into one by using variables p
and q
:
#include <stdio.h>
static int counter = 0;
static int arreglo(int locArr[])
{
locArr[0] = ++counter;
printf("el arreglo es: %i\n", locArr[0]);
return 0;
}
int main(void)
{
int manArr[10];
int (*p)[] = &manArr;
/* Here passing pointer p is not allowed as expected, since
** the function has int* as argument so I need to cast it...
*/
arreglo((int*)p);
printf("manArr[0] = %d\n", manArr[0]);
/* Or, since p is a pointer to an array, *p is the array,
** which can be passed directly without a cast.
*/
arreglo(*p);
printf("manArr[0] = %d\n", manArr[0]);
void *q = NULL;
/* This is a no-op */
q = (int (*)[])q; /* Cast from q to void to q to array */
q = &manArr; /* assign the address of the array manArr as above */
/* Now given the pointer to array as parameter to function WORKS¡¡
** Why?. As before the function expects int* as argument not
** a pointer to an array
*/
arreglo(q);
printf("manArr[0] = %d\n", manArr[0]);
/* Convert the void * back to a pointer to array, then dereference it */
arreglo(*(int (*)[])q);
printf("manArr[0] = %d\n", manArr[0]);
return 0;
}
The reason you could not pass p
to arreglo()
without a cast was that the type 'pointer to array of int
' is not the same as 'pointer to int
', and the parameter to the function is equivalent to a 'pointer to int
'. Your cast bludgeoned the compiler into agreeing with you, and you get away with it because even though the type of p
is incorrect, its value (byte address) is the same as the address of the start element of the array which the function expects. As noted in the comments, since you have a pointer to an array and the function expects an array, you can pass *p
without any cast being necessary.
The void *
version (ab)uses the fact that a void *
can be converted to any other pointer to object type without a cast in C (C++ would require a cast). The compiler is not able to warn you because you're using void *
. Again, you get away with it because the byte address of &manArr
is the same as the byte address of &manArr[0]
, even though the type is different. Note that the explicit cast (back to pointer to array) and then dereferencing works.
Be cautious with void *
; it loses type information. It can be a boon; it can also hide major problems.
Normally, you don't use pointers to arrays at all — they exist in the 'esoterica' section of the C pantheon of types. You'd normally write code such as:
#include <stdio.h>
static int counter = 0;
static int arreglo(int locArr[])
{
locArr[0] = ++counter;
printf("el arreglo es: %i\n", locArr[0]);
return 0;
}
int main(void)
{
int manArr[10];
int *p = manArr;
arreglo(p);
printf("manArr[0] = %d\n", manArr[0]);
return 0;
}
Which is much simpler to understand.