1. 程式人生 > >【C語言】右左法則——準確理解所有宣告

【C語言】右左法則——準確理解所有宣告

  現在很多IT公司都會有一些關於複雜宣告的面試題,那麼我們應該怎麼解決這個問題呢?可以利用右左法則。這是一個簡單的法則,但可以讓我們準確理解所有的宣告。The right-left rule:Start reading the declaration from the innermost parentheses, go right, and then go left. When you encounter parentheses, the direction should be reversed. Once everything in the parentheses has been parsed, jump out of it. Continue till the whole declaration has been parsed.

這個法則運用如下:

  右左法則:首先從最裡面的圓括號(應該是未定義的識別符號)看起,然後往右看,再往左看。每當遇到圓括號時,就應該掉轉閱讀方向。一旦解析完圓括號裡面所有的東西,就跳出圓括號。重複這個過程直到整個宣告解析完畢。

  右左法則不是C標準裡面的內容,它是從C標準的宣告規定中歸納出來的方法。C標準的宣告規則,是用來解決如何建立宣告的,而右左法則是用來解決如何辯識一個宣告的。

下面是一道面試題,我們可以通過分析這道題來學會使用右左法則。

用變數a給出下面的定義:

1、一個整數(An integer

2、一個指向整型數的指標(A pointer to an integer)

3、一個指向指標的指標,它指向的指標是指向一個整型數(

A pointer to a pointer to an integer

4、一個有10個整型數的陣列(An array of 10 integers

5、一個有10個指標的陣列,該指標是指向一個整型數的(An array of 10 pointers to integers

6、一個指向有10個整型陣列的指標(A pointer to an array of 10 integers

7、一個指向函式的指標,該函式有一個整型引數並返回一個整型數(A pointer to a function that takes an integer as an argument and returns an integer

8、一個有10個指標的陣列,該指標指向一個函式,該函式有一個整型引數並返回一個整型(An array of ten pointers to functions that take an integer argument and return an integer

答案如下:

(1) int a;  //整型變數

(2) int *a;  //整型指標變數

(3) int **a;  //整型指標的指標變數

(4) int a[10];  //整形陣列

(5) int *a[10];  //整型指標陣列

(6) int (*a)[10];  //整型陣列指標變數

(7) int (*a)(int);  //函式指標變數

(8) int (*a[10])(int);  //函式指標陣列

  我們來利用右左法則一個一個分析。

(1)int a;

  首先我們先找到變數名a,然後我們看向變數名的右邊,這時我們看到一個“;”,說明a是一個變數,那麼這個變數儲存的是什麼值呢?接下來向左看,這時我們看到“int”,這時我們便確定在變數a裡存放的是整型值,即整型變數。

  小結:如果a是一個變數,那麼接下來要確定這個變數裡存放的是什麼值。

(2)int *a;

  首先我們找到變數名a,然後向右看,看到了“;”,說明a是一個變數;再向左看,看到了“*”,說明這個變數裡存放的都是地址,即指標變數,那麼該指標變數所指向空間裡存放的值是什麼型別的呢?而此時右邊已經沒有了,所以我們繼續向左看,看到“int”,說明指標變數所指向空間裡儲存的值是整型的,即整型指標變數。

  小結:如果確定變數a裡儲存的是地址,那麼a就是一個指標變數,然後便要確定指標變數所指向空間裡儲存的值是什麼型別。

(3)int **a;

  首先我們可以很快判斷出a是一個指標變數,那麼接下來便要確定這個指標變數所指向的空間裡儲存的值是什麼型別的,而此時右邊已經沒有了,那麼我們向左看,看到一個“*”,說明這個指標變數所指向空間裡儲存的還是地址型別的,即指標的指標;再向左看,看到“int”,說明地址所指向空間裡的值是整型。即這個地址是指標變數的地址,並且裡面儲存的型別是整型,即整型指標的指標變數。

  小結:如果確定a是一個指標變數,又確定了這個指標變數裡儲存的還是指標,那麼這便是指向指標的指標,繼而確定指標指向空間裡儲存的是什麼型別的地址。

(4)int a[10];

  首先我們往變數名a的右邊看,看到一個“【”,說明a是陣列,那麼接下來就要確認這個數組裡的每一個元素裡存放的是什麼值;向左看,看到“int”,即整型陣列。

  小結:如果變數名a向右看是“【”,那麼a便是陣列。接下來就要確定這個陣列的每一個元素存放的是什麼型別的值,存放的是什麼型別便是什麼型別的陣列。

(5)int *a[10];

  首先我們確定a是一個數組,向右看,看到“*”,證明這個數組裡的每一個元素存放的都是地址,即指標陣列,那麼接下來便要確認指標指向的空間裡的值的型別。再向右看,看到“;”,這時返回,再向左看,看到“int”,證明地址是整型的。即整型指標陣列。

(6)int (*a)[10];

  首先我們找到變數a,向右看,看到“)”,返回向左看,看到“*”,便確定a是一個指標變數,再向右看,看到“【”,說明指標變數裡儲存的地址是陣列的地址,即陣列指標變數,再向右看,看到“int”,說明這個陣列指標變數裡的每一個元素都是整型的,即整型陣列指標變數。

  小結:指標變數指向什麼型別的,就是什麼型別的指標變數。

(7)int (*a)(int);

  首先我們確定a是一個指標變數,向右看,看到“(”,說明這個指標變數裡儲存的是函式,即函式指標變數;而這個函式的形參是整型的,返回值也是整型。

  小結:如果確定a是一個指標變數,並且向右看看到“(”,即指標變數指向函式,即函式指標變數。

(8)int (*a[10])(int);

  首先我們確定a是一個指標陣列,而這個指標指向函式,即為函式指標陣列,並且函式的形參為整型,返回值也是整型。

下面結合一些比較複雜的例子來演示一下“右左法則”的使用。(這裡參考並使用了“樑庚 陳明 馬小陸 編著的《高質量嵌入式Linux C程式設計》”的部分內容)。 
int * (* (*fp1) (int) ) [10];
閱讀步驟: 
1. 從變數名開始 -------------------------------------------- fp1 
2. 往右看,什麼也沒有,碰到了),因此往左看,碰到一個* ------ 一個指標 
3. 跳出括號,碰到了(int) ----------------------------------- 一個帶一個int引數的函式 
4. 向左看,發現一個* --------------------------------------- (函式)返回一個指標 
5. 跳出括號,向右看,碰到[10] ------------------------------ 一個10元素的陣列 
6. 向左看,發現一個* --------------------------------------- 指標 
7. 向左看,發現int ----------------------------------------- int型別 
總結:fp1被宣告成為一個函式的指標,該函式返回指向指標陣列的指標. 
再來看一個例子: 
int *( *( *arr[5])())(); 
閱讀步驟: 
1. 從變數名開始 -------------------------------------------- arr 
2. 往右看,發現是一個數組 ---------------------------------- 一個5元素的陣列 
3. 向左看,發現一個* --------------------------------------- 指標 
4. 跳出括號,向右看,發現() -------------------------------- 不帶引數的函式 
5. 向左看,碰到* ------------------------------------------- (函式)返回一個指標 
6. 跳出括號,向右發現() ------------------------------------ 不帶引數的函式 
7. 向左,發現* --------------------------------------------- (函式)返回一個指標 
8. 繼續向左,發現int --------------------------------------- int型別 
總結:arr被宣告成為一個函式的陣列指標,該函式返回指向函式指標的指標。

相關推薦

C語言法則——準確理解所有宣告

  現在很多IT公司都會有一些關於複雜宣告的面試題,那麼我們應該怎麼解決這個問題呢?可以利用右左法則。這是一個簡單的法則,但可以讓我們準確理解所有的宣告。The right-left rule:Star

C語言輸出100~999之間的所有“水仙花數”

  “水仙花數”:   “水仙花數”又稱為“阿姆斯特朗數”。如果一個n(n≥3)位數的各位數字的n次冪之和等於該數本身,則該數稱為“水仙花數”。如:153=1³+5³+3³。   問題:輸出100~999之間的所有“水仙花數”。   實現思路:   根據

C語言求一個數的二進位制位模式從翻轉後對應的十進位制值。

用函式unsigned int reverse_bit(unsigned int value)實現想要的功能 value是我們想要求的值。 #include <stdio.h> #include <math.h> unsigned

C語言實現一個函式,可以旋字串中的k個字元。

.實現一個函式,可以左旋字串中的k個字元。 AABCD左旋一個字元得到ABCDA AABCD左旋兩個字元得到BCDAA 思路: 1.如果直接進行左移,肯定會存在陣列前面的元素丟失。 解決辦法:

C語言統計數字在排序數組中出現的次數

語言 個數 統計 ret r+ () class tdi times //數字在排序數組中出現的次數。 //統計一個數字在排序數組中出現的次數。比如:排序數組{1,2,3,3,3,3,4,5}和數字3,因為3出現了4次,因此輸出4. #include <stdio

C語言推斷一個數是否為2的n次方

post data- popu scanf scan ng- 輸入 ont print //推斷一個數是否為2的n次方 #include <stdio.h> int is_two_n(int num) { if ((num&(num - 1))

C語言 二叉樹的基本運算

IT btree AS CA style pri != -- str • 二叉樹節點類型BTNode: 1 typedef struct node 2 { 3 char data; 4 struct node *lchild, *rch

C語言類型限定詞

變量 可變 oct 包含 一個數 sta ans eof 方式 ANSI C 的類型限定詞有const、volatile以及restrict三個,以下分別介紹三個限定詞: 1、類型限定詞const (1)、如果變量中帶有const關鍵字,則該變量無法進行賦值、增量及減量運算

C語言平衡二叉樹

avl 簡介 二叉搜索樹 沒有 TP 假設 它的 left 操作 AVL樹簡介 AVL樹的名字來源於它的發明作者G.M. Adelson-Velsky 和 E.M. Landis。AVL樹是最先發明的自平衡二叉查找樹(Self-Balancing Binary Searc

C語言輸入一個整數,求它的原碼,反碼,補碼值

補碼 while src info idt IV com scan -- 1 #include<stdio.h> 2 #include<math.h> 3 int main() 4 { 5 int m,n,a[10],i=0,y[

C語言數據對其(內存對齊)

brush size return () def ont http 之間 sign 數據對齊 結構體之間的對齊是有很多種方法的,也是根據你所用的系統位數有關。下面都是以32位系統來講的,32位系統一般以字對齊,字就是系統位數,32位系統則是32位對齊,也就是4字節(in

C語言Coursera課程《計算機程式設計》臺灣大學劉邦鋒——Week4課堂筆記

三次 編譯 scan parameter pass 命令 是把 dex float Coursera課程 《計算機程式設計》臺灣大學 劉邦鋒 Week4 Functions 4-1 System Function 函數主要分為兩大類系統定義函數與使用者定義函數,例如prin

C語言學習筆記3——字符串

store 寫代碼 inf 變量類型 density scanf() 想要 限定符 tor 1. 字符串(charcacter string)是一個或多個字符的序列 2. C語言沒有專門用於存儲字符串的變量類型。字符串都被存儲在char類型的數組種。 3. 數組由連續的

C語言學習筆記7——指針與多維數組

一個 聲明 %d mage 分享圖片 技術分享 pan 最好 include 1. 聲明一個指向多維數組的指針 int (* pz) [2]; //pz指向一個內涵兩個int類型元素的數組 int * pax[2]; //pax 是一個內含兩個指針元素的

C語言二維陣列解魔方陣

解題思路: 魔方陣的排列規律如下(思路來自網際網路): 注意:剛開始我也沒看懂,但是相信我多看幾遍理解已經能看懂的。 如3×3的魔方陣:      8   1   6  &nbs

C語言利用選擇法進行從小到大排序

選擇法思路: 取其中的最大值與最後一個數進行交換 假設一共有6個數組,我們用選擇法進行從小到大的排序; 6,5,4,2,3,1 第一次: 【6,5,4,2,3,1】->> 【1,5,4,2,3,6】 第二次:【1,5,4,2,3】,6 ->>【1

C語言楊輝三角(陣列)

什麼是楊輝三角(圖片來自網際網路): 楊輝三角陣列做法就是將楊輝三角的結構虛擬成一個二維陣列,通過二維陣列對楊輝三角的規律得出一個演算法來 演算法即為:a[i][j] = a[i-1][j-1]+a[i-1][j]; 一定要注意 arr(0,0) 一定為1 這是整個楊輝三角的計算核

C語言 利用篩選法求100以內的素數

演算法思路: 原理很簡單,就是當i是質(素)數的時候,i的所有的倍數必然是合數。如果i已經被判斷不是質數了,那麼再找到i後面的質數來把這個質數的倍數篩掉。 程式碼如下: //C語言 篩選法求100以內的素數 //原理很簡單,就是當i是質(素)數的時候,i的所有的倍數必然是合數。如果i已經

C語言利用迴圈輸出菱形

輸出菱形的思想主要是用了等差數列 an = a1 + (n - 1) * d  來求每個迴圈的約束條件; 一個完整的菱形必須是由空格 、星形 來組成,切分為兩部分。   題目效果如下: //要求輸出如下圖形 *   ***  *

C語言製作九九乘法表

程式碼: #include "stdio.h" int main(){ int x,y;//申請行和列變數 for(x = 1;x <= 9; x++){//迴圈行 for(y = 1; y <= x; y++){ // 迴圈列 列數等於當前行數 pri