ชนิดของกฎ "หมุนวน" ที่ตกลงมาจากกฎที่มีลำดับความสำคัญต่อไปนี้:
T *a[] -- a is an array of pointer to T
T (*a)[] -- a is a pointer to an 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
ห้อย[]
และสายงาน()
ผู้ประกอบการมีความสำคัญสูงกว่าเอก*
เพื่อให้*f()
มีการแยกวิเคราะห์เป็น*(f())
และจะแยกเป็น *a[]
*(a[])
ดังนั้นหากคุณต้องการชี้ไปยังอาร์เรย์หรือชี้ไปยังฟังก์ชั่นได้แล้วคุณจะต้องไปยังกลุ่มอย่างชัดเจน*
กับตัวระบุเป็นในหรือ(*a)[]
(*f)()
จากนั้นคุณก็รู้a
และf
สามารถแสดงออกได้ซับซ้อนกว่าตัวบ่งชี้ ในT (*a)[N]
, a
อาจจะเป็นตัวระบุง่ายหรือมันอาจจะเป็นฟังก์ชั่นเช่น(*f())[N]
( a
-> f()
) หรือมันอาจจะเป็นอาร์เรย์เช่น(*p[M])[N]
( a
-> p[M]
) หรือมันอาจจะเป็นอาร์เรย์ของตัวชี้ไปที่ฟังก์ชั่นเช่น(*(*p[M])())[N]
( a
-> (*p[M])()
) เป็นต้น
มันจะดีถ้าโอเปอเรเตอร์ทางอ้อม*
เป็น postfix แทนที่จะเป็น unary ซึ่งจะทำให้การประกาศค่อนข้างง่ายต่อการอ่านจากซ้ายไปขวา ( void f[]*()*();
ไหลแน่นอนดีกว่าvoid (*(*f[])())()
) แต่ไม่ใช่
เมื่อคุณเจอการประกาศที่มีขนดกแบบนี้ให้เริ่มต้นด้วยการค้นหาตัวระบุซ้ายสุดและใช้กฎที่มีลำดับความสำคัญเหนือกว่า
f -- f
f[] -- is an array
*f[] -- of pointers ([] has higher precedence than *)
(*f[])() -- to functions
*(*f[])() -- returning pointers
(*(*f[])())() -- to functions
void (*(*f[])())(); -- returning void
signal
ฟังก์ชั่นในห้องสมุดมาตรฐานน่าจะเป็นประเภทตัวอย่างสำหรับชนิดของความบ้านี้:
signal -- signal
signal( ) -- is a function with parameters
signal( sig, ) -- sig
signal(int sig, ) -- which is an int and
signal(int sig, func ) -- func
signal(int sig, *func ) -- which is a pointer
signal(int sig, (*func)(int)) -- to a function taking an int
signal(int sig, void (*func)(int)) -- returning void
*signal(int sig, void (*func)(int)) -- returning a pointer
(*signal(int sig, void (*func)(int)))(int) -- to a function taking an int
void (*signal(int sig, void (*func)(int)))(int); -- and returning void
ณ จุดนี้คนส่วนใหญ่พูดว่า "use typedefs" ซึ่งแน่นอนว่าเป็นตัวเลือก:
typedef void outerfunc(void);
typedef outerfunc *innerfunc(void);
innerfunc *f[N];
แต่...
คุณจะใช้ f
ในการแสดงออกอย่างไร คุณรู้ว่ามันเป็นชุดพอยน์เตอร์ แต่คุณจะใช้มันอย่างไรเพื่อรันฟังก์ชั่นที่ถูกต้อง? คุณต้องไปที่ typedefs และไขปริศนาไวยากรณ์ที่ถูกต้อง ในทางตรงข้ามรุ่น "เปลือยกาย" นั้นดูเหมือนจะสวยมาก แต่มันบอกคุณได้อย่างชัดเจนว่าจะใช้งานอย่างไร f
ในนิพจน์ (กล่าวคือ(*(*f[i])())();
สมมติว่าไม่มีฟังก์ชันใดใช้อาร์กิวเมนต์)