可能重复:
这个C语句是什么意思?
这个表达是什么意思?
char *(*c[10])(int **p);
Run Code Online (Sandbox Code Playgroud)
Mar*_*lon 77
c
是一个由10个函数指针组成的数组,它们返回a char*
并将a int**
作为参数.
(*c[10])
^^^^ = array of 10
(*c[10])
^ = function pointer
Run Code Online (Sandbox Code Playgroud)
所以现在我们有一个包含10个函数指针的数组.
char *(*c[10])
^^^^^^ = returns a char*
char *(*c[10])(int** p)
^^^^^ = takes a int** as an argument
Run Code Online (Sandbox Code Playgroud)
一组10个函数指针,它们返回a char*
并将a int**
作为参数.
注意:如果您编写这样的代码,您应该被打耳光.
Bar*_*ski 52
cdecl是一个很好的工具,可以将C
乱码翻译成英文
$ cdecl explain 'char * (*c[10]) (int **)'
declare c as array 10 of pointer to function (pointer to pointer to int) returning pointer to char
Run Code Online (Sandbox Code Playgroud)
Mor*_*pfh 45
一些示例,以及最后使用decl 的片段.
void (*foo)(void);
会给你一个函数指针foo
,它不带任何参数,也不返回任何内容.
防爆.A:
void fun_1(void)
{
...
}
foo = fun_1;
foo(); /* this would call fun_1() */
Run Code Online (Sandbox Code Playgroud)
防爆.B:
char (*bar)(int);
会给你一个函数指针bar
,它将1个参数作为整数并返回一个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' */
Run Code Online (Sandbox Code Playgroud)
int **p;
是一个指向int类型指针的指针.
防爆.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));
Run Code Online (Sandbox Code Playgroud)
print: 4 3 6
防爆.d:
char *zez(char *s)
{
s = "def";
return s;
}
char *str = "abc";
printf("%s - ", str);
printf("%s\n", zez(str));
Run Code Online (Sandbox Code Playgroud)
abc - def
创建一个函数指针 zez()
防爆.E:
char *(*ptr_zez)(char *);
ptr_zez = zez;
printf("ptr: %s - ", str);
printf("%s\n", ptr_zez(str));
Run Code Online (Sandbox Code Playgroud)
ptr: abc - def
防爆.F:
char *(*c[10])(char *);
c[0] = zez;
printf("c[0]: %s - ", str);
printf("%s\n", c[0](str));
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
EX: abcdef
AX: abcdef
类型声明涉及三个运算符:数组[SIZE]
,指针*
和函数(type1 param1, type2 param2, ...)
.请记住,所有三个运算符都是右关联的.
char *(*c[10])(int **p);
Run Code Online (Sandbox Code Playgroud)
让我们添加更多括号,使关联性更加清晰.
char *((*(c[10]))(int *(*p)))
Run Code Online (Sandbox Code Playgroud)
从c
变量开始.
c[10]
表示"c是一个包含10个元素的数组,但每个元素都是......"
然后看看它*
旁边.*(c[10])
表示"c是一个包含10个元素的数组,每个元素都是一个指向......的指针"
然后(*(c[10]))(int *(*p))
意味着"c是一个包含10个元素的数组,每个元素都是一个指向函数的指针,它返回..."使用类似的方法,我们看到该函数接受一个参数,即"指向int的指针".
然后*((*(c[10]))(int *(*p)))
意味着"c是一个包含10个元素的数组,每个元素都是一个指向函数的指针,它返回一个指向...的指针".
最后char *((*(c[10]))(int *(*p)))
意味着"c是一个包含10个元素的数组,每个元素都是一个指向函数的指针,它返回一个指向char的指针".而已.
我发现顺时针/螺旋规则非常有用.见http://c-faq.com/decl/spiral.anderson.html
但我宁愿添加更多括号而不是使用螺旋.
好吧,现在你得到的答案,它是一个函数指针数组,但是有干净(呃)方式来编写这样的代码吗?是的,我相信乍看之下可能会理解这些代码:
typedef char *(*weirdFuncPtr)(int **p);
weirdFuncPtr funcPtrArray[10];
Run Code Online (Sandbox Code Playgroud)
顺便说一句.通常我会避免使用typdefs - 我在声明函数指针时使用它们.这使得更容易理解这种C代码(C是Cryptic的缩写,是吗?)