天天看點

複雜指針解析-右左法則

  右左法則:首先從最裡面的圓括号看起,然後往右看,再往左看。每當遇到圓括号時,就應該掉轉閱讀方向。一旦解析完圓括号裡面所有的東西,就跳出圓括号。重複這個過程直到整個聲明解析完畢。

  現在要對這個法則進行一個小小的修正,應該是從未定義的辨別符開始閱讀,而不是從括号讀起,之是以是未定義的辨別符,是因為一個聲明裡面可能有多個辨別符,但未定義的辨別符隻會有一個。

  現在通過一些例子來讨論右左法則的應用,先從最簡單的開始,逐漸加深:

  int (*func)(int *p);

  首先找到那個未定義的辨別符,就是func,它的外面有一對圓括号,而且左邊是一個*号,這說明func是一個指針,然後跳出這個圓括号,先看右邊,也是一個圓括号,這說明(*func)是一個函數,而func是一個指向這類函數的指針,就是一個函數指針,這類函數具有int*類型的形參,傳回值類型是int。

  int (*func)(int *p, int (*f)(int*));

  func被一對括号包含,且左邊有一個*号,說明func是一個指針,跳出括号,右邊也有個括号,那麼func是一個指向函數的指針,這類函數具有int *和int (*)(int*)這樣的形參,傳回值為int類型。再來看一看func的形參int (*f)(int*),類似前面的解釋,f也是一個函數指針,指向的函數具有int*類型的形參,傳回值為int。

  int (*func[5])(int *p);

  func右邊是一個[]運算符,說明func是一個具有5個元素的數組,func的左邊有一個*,說明func的元素是指針,要注意這裡的*不是修飾func的,而是修飾func[5]的,原因是[]運算符優先級比*高,func先跟[]結合,是以*修飾的是func[5]。跳出這個括号,看右邊,也是一對圓括号,說明func數組的元素是函數類型的指針,它所指向的函數具有int*類型的形參,傳回值類型為int。

  int (*(*func)[5])(int *p);

  func被一個圓括号包含,左邊又有一個*,那麼func是一個指針,跳出括号,右邊是一個[]運算符号,說明func是一個指向數組的指針,現在往左看,左邊有一個*号,說明這個數組的元素是指針,再跳出括号,右邊又有一個括号,說明這個數組的元素是指向函數的指針。總結一下,就是:func是一個指向數組的指針,這個數組的元素是函數指針,這些指針指向具有int*形參,傳回值為int類型的函數。

  int (*(*func)(int *p))[5];

  func是一個函數指針,這類函數具有int*類型的形參,傳回值是指向數組的指針,所指向的數組的元素是具有5個int元素的數組。

要注意有些複雜指針聲明是非法的,例如:

  int func(void) [5];

  func是一個傳回值為具有5個int元素的數組的函數。但C語言的函數傳回值不能為數組,這是因為如果允許函數傳回值為數組,那麼接收這個數組的内容的東西,也必須是一個數組,但C語言的數組名是一個右值,它不能作為左值來接收另一個數組,是以函數傳回值不能為數組。

  int func[5](void);

  func是一個具有5個元素的數組,這個數組的元素都是函數。這也是非法的,因為數組的元素除了類型必須一樣外,每個元素所占用的記憶體空間也必須相同,顯然函數是無法達到這個要求的,即使函數的類型一樣,但函數所占用的空間通常是不相同的。

      實際當中,需要聲明一個複雜指針時,如果把整個聲明寫成上面所示的形式,對程式可讀性是一大損害。應該用typedef來對聲明逐層分解,增強可讀性,例如對于聲明:

  int (*(*func)(int *p))[5];

可以這樣分解:

  typedef  int (*PARA)[5];

  typedef PARA (*func)(int *);

  這樣就容易看得多了。

  int (*(*func)[5][6])[7][8];

  func是一個指向數組的指針,這類數組的元素是一個具有5X6個int元素的二維數組,而這個二維數組的元素又是一個二維數組。

  typedef int (*PARA)[7][8];

  typedef PARA (*func)[5][6];

  int (*(*(*func)(int *))[5])(int *);

  func是一個函數指針,這類函數的傳回值是一個指向數組的指針,所指向數組的元素也是函數指針,指向的函數具有int*形參,傳回值為int。

  typedef int (*PARA1)(int*);

  typedef PARA1 (*PARA2)[5];

  typedef PARA2 (*func)(int*);

  int (*(*func[7][8][9])(int*))[5];

  func是一個數組,這個數組的元素是函數指針,這類函數具有int*的形參,傳回值是指向數組的指針,所指向的數組的元素是具有5個int元素的數組。

  typedef int (*PARA1)[5];

  typedef PARA1 (*PARA2)(int*);

  typedef PARA2 func[7][8][9];

本文來自CSDN部落格,轉載請标明出處:http://blog.csdn.net/megaboy/archive/2005/09/17/482771.aspx

轉載于:https://www.cnblogs.com/zqrferrari/archive/2010/07/05/1771741.html