11 C語言之優先順序和聯結器

2021-06-18 20:00:59 字數 1457 閱讀 1232

一.優先順序

在c語言中,經常會出現一些複雜的型別宣告。而大多數都是涉及到指標的型別。

那麼就在這一節來集中認識一下。

首先,我們先來了解*,()和的組合。在看實際例子前,先來看乙個重要的規則:

在做選擇時,始終使和()的優先順序大於*。舉個簡單的例子:

int *arr[10]。由於的優先順序大於*。也就代表,首先這是乙個含有10個元素陣列,那麼陣列內的內容是什麼呢?是int *arr。去掉型別名稱,陣列內的型別是int *。所以這是乙個含有10個整數型別指標的陣列。

同樣的規則繼續看:float *fp(float)。由於()的優先順序大於*,所以說明這首先是乙個函式,函式的返回型別是指向float型別的指標。

void (*fp)(float)。由於括號的存在,代表首先這是乙個指標,這個指標指向什麼呢?指向的是乙個引數個數為1,型別是float的函式。

接下來看乙個複雜的:(*(void(*)())0)();讓我們慢慢來拆分,首先(void(*))()是乙個函式指標型別的原型,因此(void(*)())0是將0轉換成乙個函式指標型別,那麼(*(void(*)())0)也就是位址0處所在的函式,那麼上面一條語句的意思也就是執行位址0處的函式。

上面的語句看起來非常複雜繁瑣,因此我們在實際工作中,最好使用typedef來重新制定一下比較複雜的資料型別:

例如上面的例子:我們不妨typedef void (*functionpoint)(); 這樣我們就可以非常簡單的

(*(functionpoint)0)();

二.聯結器

1. 聯結器

c語言有個思想是分別編譯,也就是把乙個c語言的專案分成若干個源程式,讓他們在不同的時候單獨進行編譯,然後在恰當的時候整合到一起。這個整合的過程就是由聯結器完成的。

大多數時候,聯結器和編譯器都是分開的,聯結器本身並不懂得太多c語言的語法規則。因為他一般不與c直接接觸,我們想想之前說過c語言的編譯執行過程,編譯器的責任其實就是將c語言翻譯成聯結器能夠理解的形式。

聯結器把由編譯器生成的若干個目標模組,整合成乙個載入模組,或者是乙個可執行檔案,能夠被作業系統直接執行。

此外,聯結器還要處理命名衝突。聯結器通常把目標模組看成時一組外部物件組成的,每個外部物件都代表著機器記憶體的一部分,並且通過乙個外部名稱來識別。因此,當函式和變數沒有被宣告為static的時候,都被看做是乙個外部物件。也有一些編譯器,對static宣告的變數進行乙個名字的特殊處理,然後也將其當做外部物件。

2. 再說extern

其實extern也是聯結器的功勞。例如extern int i;再聯結器看來,這是乙個宣告,不是乙個定義,這個宣告代表他不需要為其分配空間,而是在其他程式中尋找乙個同名的外部物件的引用。

因此,在這個專案中必須有extern的引用。如果當程式中包含兩個定義,一般的編譯器都會報錯。那麼,我們最好的辦法,是把extern的定義都寫在乙個統一的標頭檔案中,當需要外部變數的時候,就引用這個標頭檔案。

c語言之運算子優先順序

c語言之運算子優先順序 c語言運算子優先順序 優先順序 運算子 名稱或含義 使用形式 結合方向 說明 1 陣列下標 陣列名 常量表示式 左到右 圓括號 表示式 函式名 形參表 成員選擇 物件 物件.成員名 成員選擇 指標 物件指標 成員名 2 負號運算子 表示式 右到左 單目運算子 按位取反運算子 ...

C語言之運算子優先順序

在乙個表示式中可能包含多個有不同運算子連線起來的 具有不同資料型別的資料物件 由於表示式有多種運算,不同的結合順序可能得出不同結果甚至出現錯誤運算錯誤,因為當表示式中含多種運算時,必須按一定順序進行結合,才能保證運算的合理性和結果的正確性 唯一性。優先順序從上到下依次遞減,最上面具有最高的優先順序,...

C語言之優先順序 結合性與自增運算

優先順序 結合性這些概念在初學的時候並沒有放在心上,今天又碰到這個問題,查了不少資料,再次做個總結。在標準c語言的文件裡,對操作符的結合性並沒有做出非常清楚的解釋。乙個滿分的回答是 它是仲裁者,在幾個操作符具有相同的優先順序時決定先執行哪乙個。每個操作符擁有某一級別的優先順序,同時也擁有左結合性或右...