Possible Duplicate:
What does this C statement mean?
What does this expression mean?
char *(*c[10])(int **p);
Possible Duplicate:
What does this C statement mean?
What does this expression mean?
char *(*c[10])(int **p);
c
is an array of 10 function pointers that return a char*
and take a int**
as an argument.
(*c[10])
^^^^ = array of 10
(*c[10])
^ = function pointer
So right now we have an array of 10 function pointers.
char *(*c[10])
^^^^^^ = returns a char*
char *(*c[10])(int** p)
^^^^^ = takes a int** as an argument
Array of 10 function pointers that return a char*
and take a int**
as an argument.
NOTE: If you write code like this you deserve to be slapped in the face.
cdecl is a nice tool to translate C
gibberish into English
$ cdecl explain 'char * (*c[10]) (int **)'
declare c as array 10 of pointer to function (pointer to pointer to int) returning pointer to char
Some examples, and a snippet at the end that uses the decl.
void (*foo)(void);
Would give you a function pointer foo
which takes no parameters and returns nothing.
Ex. A:
void fun_1(void)
{
...
}
foo = fun_1;
foo(); /* this would call fun_1() */
Ex. B:
char (*bar)(int);
Would give you a function pointer bar
which takes 1 parameter as integer and return a char
.
char fun_2(int x)
{
if (x == 50)
return 'a';
return 'Z';
}
char v;
bar = fun_2;
v = bar(50); /* this would call fun_2() with 50 as parameter and return 'a' */
int **p;
is a pointer that points to a pointer of type int.
Ex. C:
int y[3] = {4, 3, 6};
int *w = &y[0];
int **z = &w;
printf("print: %d ", **z);
printf("%d ", *++(*z));
printf("%d\n", *(*z+1));
print: 4 3 6
Ex. D:
char *zez(char *s)
{
s = "def";
return s;
}
char *str = "abc";
printf("%s - ", str);
printf("%s\n", zez(str));
abc - def
Creating a function pointer to zez()
Ex. E:
char *(*ptr_zez)(char *);
ptr_zez = zez;
printf("ptr: %s - ", str);
printf("%s\n", ptr_zez(str));
ptr: abc - def
Ex. F:
char *(*c[10])(char *);
c[0] = zez;
printf("c[0]: %s - ", str);
printf("%s\n", c[0](str));
c[0]: abc - def
char *cumlade(int **p)
{
char *c;
int i;
if ((c = malloc(sizeof(char) * 7)) == NULL) {
fprintf(stderr, "Unable to reserve 7 bytes\n");
exit(0);
}
for (i = 0; i < 6; ++i) {
c[i] = (unsigned char)*(*p+i);
}
c[6] = '\0';
return c;
}
int main(void)
{
int t[3][3] = {{97 ,98, 99}, {100, 101, 102}};
int *u = &t[0][0];
int **v = &u;
char *ex;
char *(*c[10])(int **p); /* <-- the fun */
c[0] = cumlade;
c[1] = cumlade;
ex = c[0](v);
printf("EX: %s\n", ex);
free(ex);
ex = c[1](v);
printf("AX: %s\n", ex);
free(ex);
return 0;
}
EX: abcdef
AX: abcdef
c
is an array of 10
pointers to functions taking a pointer to pointer to int
as its parameter and returning a pointer to char
.
Type declaration involves three operators: array [SIZE]
, pointer *
and function (type1 param1, type2 param2, ...)
. Remember that all the three operators are right-associative.
char *(*c[10])(int **p);
Let's add more parenthesis to make the associativity more clear.
char *((*(c[10]))(int *(*p)))
Start from c
, the variable.
c[10]
means "c is an array of 10 elements, but each element is a ..."
Then see the *
beside it. *(c[10])
means "c is an array of 10 elements, each element is a pointer pointing to ..."
Then (*(c[10]))(int *(*p))
means "c is an array of 10 elements, each element is a pointer to a function, which returns ..." Using similar methods we see the function takes one parameter which is "a pointer to a pointer to an int".
Then *((*(c[10]))(int *(*p)))
means "c is an array of 10 elements, each element is a pointer to a function, which returns a pointer to a ..."
Finally char *((*(c[10]))(int *(*p)))
means "c is an array of 10 elements, each element is a pointer to a function, which returns a pointer to a char". That's it.
I find the Clockwise/Spiral Rule very useful. See http://c-faq.com/decl/spiral.anderson.html
But I'd rather add more brackets than using spirals.
ok now the answer you have, it is an array of function pointer, but is there clean(er) way to write code like this? Yes there is, and I am sure this code might be understood at the first glance:
typedef char *(*weirdFuncPtr)(int **p);
weirdFuncPtr funcPtrArray[10];
Btw. usually I avoid typdefs - I use them when declaring function pointers though. This makes it easier to understand this sort of C code (C is an abbreviation for Cryptic, is it?)
It declares an array of function pointers. There are 10 elements in the array (from c[10] part of the declaration). the function to which these pointers can point will return char* and takes only one parameter i.e pointer to pointer to integer (int **p)
Take a look at the first answer to this question How can I use an array of function pointers? there you will find another example of declaring function-pointer array and it may end your confusion.
If you are looking for intuitive explanation for this, http://www.geeksforgeeks.org/archives/16841
They explained this using postfix order evaluation, just like expression evaluation.