2010-02-12 138 views
5

INT *(*)的为(int *,诠释*(*)())类型为int *(*)(INT *,诠释*(*)())

我想知道是什么类型是什么? ,有人可以给出一个使用这种类型的声明的例子。

任何帮助将是伟大的。

谢谢。

+1

甚至哪种语言? C++? – 2010-02-12 16:56:43

+1

我猜测它是C并将其标记为这样。 – 2010-02-12 16:57:49

+0

哇,这是相当虐待... – 2010-02-12 17:02:00

回答

19

它是一个指向函数,返回int*并接受int*和指针的函数,返回int*(和接受的参数未定义数量;见注释)。

一些示例(不看起来非常漂亮,它仅仅是其构建为含有所提到的声明):

#include <stdio.h> 

static int a = 10; 
int* f1() { 
    return &a; 
} 

static int b; 
int* f2(int *j, int*(*f)()) { 
    b = *j + *f(); 
    // this is just for demonstrational purpose, such usage 
    // of global variable makes this function not thread-safe 
    return &b; 
} 


int main(int argc, char *argv[]) { 
    int * (*ptr1)(); 
    int * (*ptr2) (int * , int * (*)()); 
    ptr1 = f1; 
    ptr2 = f2; 

    int i = 42; 
    int *pi = ptr2(&i, ptr1); 
    printf("%d\n", *pi); 

    return 0; 
} 

// prints 52 
+6

严格地说,因为它被标记为C,它接受未定义数量的参数。在C++和空参数列表意味着没有参数,在C中它将需要(无效)来指定。奥术,但真的;-) – Clifford 2010-02-12 17:01:37

+0

实际上我认为参数是未指定的,假设这是C.“(void)”将不接受任何参数,就像在C++中的“()”一样。 – aib 2010-02-12 17:02:27

0
typedef int* (*fptr)();  
int* foo(int* p1, fptr p2); 

你可以把foo在这个类型。

7

cdecl是你的朋友:

$ cdecl explain 'int * (*x) (int * , int * (*)())' 
declare x as pointer to function (pointer to int, pointer to function returning pointer to int) returning pointer to int 
+11

是的,除非它没有添加'x',否则不起作用,除非你首先理解声明,否则不会添加'x'; – ezpz 2010-02-12 17:07:37

+1

如果没有标识符(应该很容易发现),那么你可以通过在''前加'('后缀')x'来获得'cdecl'来解释它。然后它会说“'把x转换成...'”,然后是类型的解释。 – caf 2010-02-13 06:51:59

2

嗯...根据cdecl.org这是一个语法错误 - 让我来试试

 
int * (*) (int *,int *(*)()) 
  • (INT *,诠释) ()) - 最内层 (*)() - 指向函数的指针 int )() - poi返回指向int的指针
  • (int *,...) - 两个参数,其中一个是指向int的指针,另一个是指向函数的指针,不带参数 - 返回指针到INT
  • (*)(...) - 与参数的函数指针
  • INT *(*)(...) - 函数指针,返回指针,TO-诠释

所以: 这是一个函数指针,它有两个参数,第一个参数是int的指针,另一个是指针到功能与 - 无参数,返回指针到-int和它的返回指针指向int。

编辑:,我在该网站所使用的C声明 - 我没有把变量名作为

 
int *(*x)(int *,int *(*)()) 

其返回:x声明为函数指针(指针为int ,指针函数返回指针INT)返回指针为int

希望这有助于 最好的问候, 汤姆。

1

有一种叫做“左 - 右规则”的技巧,可以帮助你解密这些复杂的声明。该规则通过将英语关键字替换为声明中出现的属性起作用。然后,当你把关键字放在一起时,构造的句子将描述该声明。

这里的属性和关键字,你应该使用:

  • 当你看到属性“()”使用关键字“功能,返回”当你看到属性
  • “[N]”使用关键字
  • “N数组”当你看到属性“*”使用关键字“指针”

现在,这里的“右左法则”:

  1. 以标识符开头。
  2. 向右看属性。
  3. 如果找不到,请向左看。
  4. 一旦找到属性,用其英文关键字替代。
  5. 继续左右替换,当你工作的出路。
  6. 当您到达声明中的数据类型时停止。

下面是一些例子:

int n[10]; 

标识符为n。右边的属性是[10],所以使用关键字“10的数组”。接下来你到达数据类型int。所以,

n是一个“10个整数数组”。

int *n[10]; 

该标识符是n。右边的属性是[10],所以使用关键字“10的数组”。向左看,属性是*,所以使用关键字“指向”。没有更多的属性。剩下的就是数据类型,即int。将关键字放在一起得到:

n是一个“10个指向整数的指针数组”。

int (*pf)(); 

该标识符是pf。 pf右边没有任何属性。在pf的左边是*。所以第一个关键字是“指向”。接下来,回到右侧,属性是()。这意味着下一个关键字是“返回的函数”。现在回到数据类型int的左侧。把关键字合力得到:

PF是一个“指针返回一个int的函数”

int *(*pf)(); 

PF是标识符。 pf右侧没有属性。左边是*,所以第一个关键字是“指向”。回到右边是(),所以下一个关键字是“返回的函数”。回到左边是*,所以下一个关键字是“指向”。接下来,到达int数据类型:

pf是“指向返回指向int的指针的函数的指针”。

下一个例子就像上一个例子,但是这次有一些参数是pf函数的。参数是int *xint *(*y)()。你应该能够基于所有事情来描述这些论点,直到现在。一旦你这样做,你就可以描述整个事情:

int *(*pf)(int *x, int *(*y)()); 

PF是一个指针,返回一个指针为int的函数。 pf需要两个参数。第一个参数x是一个指向int的指针。第二个参数y是一个指向返回指向int的指针的函数的指针。

0

这样的声明真的被使用!考虑标准C库的信号功能:

void (* 
    signal(int sig, void (*func)(int)))(int); 

信号手册页解释了它等同于以下typedef定义版本:

typedef void (*sig_t) (int); 
sig_t signal(int sig, sig_t func); 

是有两个参数的函数,int和一个sig_t函数,并返回旧的sig函数。

相关问题