一.優先順序
在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語言的文件裡,對操作符的結合性並沒有做出非常清楚的解釋。乙個滿分的回答是 它是仲裁者,在幾個操作符具有相同的優先順序時決定先執行哪乙個。每個操作符擁有某一級別的優先順序,同時也擁有左結合性或右...