現在,我正在讀APUE.and我發現中定義的功能如下:如何理解這個定義
void (*signal(int signo, void (*func)(int)))(int);
我很困惑,我知道信號是指向函數的指針和最後一個(INT)是他的參數。 我不知道什麼是(int signo,void(* func)(int))。
現在,我正在讀APUE.and我發現中定義的功能如下:如何理解這個定義
void (*signal(int signo, void (*func)(int)))(int);
我很困惑,我知道信號是指向函數的指針和最後一個(INT)是他的參數。 我不知道什麼是(int signo,void(* func)(int))。
的一般程序:找到最左邊的標識符並按照你的方式工作。如果沒有使用圓括號的明確分組,後綴運算符(如()
和[]
)在諸如*
之類的一元運算符之前綁定;因此,下面都是真:
T *x[N] -- x is an N-element array of pointer to T
T (*x)[N] -- x is a pointer to an N-element array of T
T *f() -- f is a function returning a pointer to T
T (*f)() -- f is a pointer to a function returning T
應用這些規則的聲明後,它打破了作爲
signal -- signal
signal( ) -- is a function
signal( signo, ) -- with a parameter named signo
signal(int signo, ) -- of type int
signal(int signo, func ) -- and a parameter named func
signal(int signo, *func ) -- of type pointer
signal(int signo, (*func)( )) -- to a function
signal(int signo, (*func)(int)) -- taking an int parameter
signal(int signo, void (*func)(int)) -- and returning void
*signal(int signo, void (*func)(int)) -- returning a pointer
(*signal(int signo, void (*func)(int)))( ) -- to a function
(*signal(int signo, void (*func)(int)))(int) -- taking an int parameter
void (*signal(int signo, void (*func)(int)))(int); -- and returning void
總之,signal
返回一個指向返回void
功能。 signal
需要兩個參數:一個整數和指向另一個函數的指針,返回void
。
你可以使用typedefs使它更易於閱讀(而Ubuntu的linux上的signal
的手冊頁就是這麼做的);不過,我認爲展示非typedef'd版本來演示語法的工作方式是很有價值的。 typedef工具非常棒,但您真的需要了解底層類型如何工作纔能有效地使用它。
signal
函數設置了一個信號處理程序;第二個參數是在接收到信號時要執行的功能。返回指向當前信號處理程序(如果有的話)的指針。
例如,如果你希望你的程序來處理中斷信號(如按Ctrl-C):
static int g_interruptFlag = 0;
void interruptHandler(int sig)
{
g_interruptFlag = 1;
}
int main(void)
{
...
/**
* Install the interrupt handler, saving the previous interrupt handler
*/
void (*oldInterruptHandler)(int) = signal(SIGINT, interruptHandler);
while (!g_interruptFlag)
{
// do something interesting until someone hits Ctrl-C
}
/**
* Restore the previous interrupt handler (not necessary for this particular
* example, but there may be cases where you want to swap out signal handlers
* after handling a specific condition)
*/
signal(SIGINT, oldInterruptHandler);
return 0;
}
編輯我延長了示例代碼signal
的東西,就是希望更多的說明。
+1獲得精彩的答案! – Shrayas 2012-10-12 06:51:20
void (*signal(int signo, void (*func)(int)))(int);
signal是一個函數,它接受int和一個指向函數的指針,取int和返回void並返回一個帶int和返回void的函數指針。也就是說,
typedef void(*funcPtr)(int)
那麼我們有
funcPtr signal(int signo, funcPtr func); //equivalent to the above
語法的確是怪了,這樣的事情最好是用一個typedef來完成。舉個例子,如果你要聲明一個函數,它接受一個int並返回一個指向函數取char和雙回將
double (*f(int))(char);
編輯:評論,上面寫着「Wooooooow」後,我我提供了另一個更「例外」的例子:)
讓我們聲明一個函數,其中需要
1.一個指向數組指針的數組,指向每個函數,每個函數使用float和返回double。
2.一個指向數組3個指數到4個數組的指針
並返回一個指向函數的指針,該指針接受一個指向函數的指針,返回一個指向函數的指針,並返回void並返回unsigned int。
的類型定義的解決辦法是這樣的:
typedef double (*f1ptr) (float);
typedef f1ptr (*arr1ptr)[5];
typedef int (*arr2ptr)[4];
typedef arr2ptr (*arr3ptr)[3];
typedef void(*f2Ptr)(float);
typedef f2ptr (*f3ptr)(int);
typedef unsigned int (*f4ptr) (f3ptr);
f4ptr TheFunction(arr1ptr arg1, arr3ptr arg2);
現在,有趣的部分:) 沒有類型定義,這將是:
unsigned int (*TheFunction(double (*(*)[5])(float), int(*(*)[3])[4]))(void(*(*)(int))(float))
我的天啊,我剛寫的是什麼? :)
Wooooooooooooow – valdo 2010-11-08 12:59:30
@valdo:看到我的編輯更壞wooooow :) – 2010-11-08 13:19:31
有趣嗎?非typedef'd版本*完全*透明。 – 2010-11-08 13:38:54
順時針螺旋規則將幫助: http://c-faq.com/decl/spiral.anderson.html
有三個簡單的步驟如下:
與未知元素開始,以螺旋/順時針方向移動; ecountering以下元素時與相應的英文語句代替它:
的...或數組的大小未定義[X]或[] =>數組X大小...
(TYPE1,TYPE2)= >功能通過Type1和Type2返回...
- =>指針(多個)爲...
保存,直到所有令牌已被被覆蓋在螺線/順時針方向這樣做。 總是先解決括號中的任何內容吧!
參見「示例#3:‘終極’」,這是相當多的,你問什麼了:
「信號傳遞一個int和指針的函數傳遞一個int功能返回無(無效)返回一個指針的函數傳遞一個int返回什麼(無效)」
這是一個非常漂亮的資源。謝謝 ! – Shrayas 2012-10-12 07:01:23
本網站爲declerations到C亂碼:
如果您沒有訪問cdecl
現在,這裏是CDECL輸出:
$ cdecl
cdecl> explain void (*signal(int , void (*)(int)))(int);
declare signal as function (int, pointer to function (int) returning void) returning pointer to function (int) returning void
獲取'cdecl'。它會告訴你所有這些事情。我會問:'void void(* signal(int,void(*)(int)))(int);'它會回答:'將信號聲明爲函數(int,指向函數的指針(int)返回void)函數(int)返回void' – 2010-11-08 10:57:15
嘗試http://cdecl.org/ – 2010-11-08 13:09:28