2010-02-12 184 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函數。

相關問題