复杂C语法的含义

use*_*201 30 c c++ pointers

可能重复:
这个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**作为参数.

注意:如果您编写这样的代码,您应该被打耳光.

  • 注意+1.Typedefs plz k thx. (13认同)
  • @markwatson最好使用`typedef`s. (2认同)

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)

  • Gibberish是更好的ROTFL (9认同)
  • 我觉得它一点也不好,非常错误并经常无法理解完全有效的C. (2认同)

Mor*_*pfh 45

一些示例,以及最后使用decl 的片段.

1.指向函数的指针:

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)

2.指针指针

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

3.返回指针的函数

防爆.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

4.函数指针指向返回指针的函数

创建一个函数指针 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

5.函数指针数组,用于返回char指针,取一个char指针

防爆.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

6."将c声明为指向函数的指针的数组10(指向int的指针)返回指向char的指针"

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

  • 这是我见过的最全面,最易理解的解释之一. (3认同)

Jes*_*ood 12

c10指向函数的指针数组,指针指向指针int作为参数并返回指针char.


wks*_*wks 8

类型声明涉及三个运算符:数组[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

但我宁愿添加更多括号而不是使用螺旋.


Ale*_*lex 5

好吧,现在你得到的答案,它是一个函数指针数组,但是有干净(呃)方式来编写这样的代码吗?是的,我相信乍看之下可能会理解这些代码:

typedef char *(*weirdFuncPtr)(int **p);
weirdFuncPtr funcPtrArray[10];
Run Code Online (Sandbox Code Playgroud)

顺便说一句.通常我会避免使用typdefs - 我在声明函数指针时使用它们.这使得更容易理解这种C代码(C是Cryptic的缩写,是吗?)

  • 好建议._Always_在使用函数指针时使用typedef. (2认同)