編譯器思維之結合律

2021-09-07 17:21:15 字數 1196 閱讀 1656

結合律指的就是操作符優先順序的結合方向的規律,共兩種「左到右」,「右到左」,好像很簡單的樣子,但是,你真的全部了解了嗎?你了解的是編譯器真正的工作方法嗎?

1、左到右的含義:就是左結合,右到左就是:右結合。

2、所謂結合:就是多個東西結合成乙個整體,變為乙個新的東西。

3、當乙個操作符是左結合且為雙目運算子時,它會把它左邊的東西整個當作乙個整體並與之結合,右邊的只認離它最近的乙個,右結合與之相反。

4、舉乙個算式:a+b+c,這個算式都是加號,大家優先順序相同,所以轉而考慮結合律,+號是左結合,所以第乙個+號,先結合a,並且只認識右邊和它最近的b,而對於第二個+號,會把a+b當作乙個整體,並與之結合,然後只認識右邊和它最近的c。結果就是 ((a)+b)+c 。

5、來乙個複雜的例子:

(*((void (*)())0))()

我第一次看到它時,第一反應是,這是乙個正確的表示式嗎?呵呵。

1)確定主語,在這裡是0,其他的都是修飾它的。

2)離0最近的是一對括號,裡面的內容是:void (*)(),其實是乙個型別,是我們自定義的乙個函式指標型別,用小括號括起來,這個小括號是強制轉換符。

3) (void (*)())0

的含義是:把0強制轉換為乙個函式指標型別。

4) ((void (*)())0) 表示這是乙個整體,如果我們把 (void (*)())0

看作乙個整體,用乙個記號p替換它。

5)這樣整個表示式變為: (*p)() ,這句話其實就是利用乙個函式指標來呼叫這個函式,而指標的值p其實是0。

7)不過我們知道,記憶體中0位址是被作業系統保護的,所以,這個表示式編譯沒有任何問題,但執行時候會報「段錯誤」,因為非法引用被保護的位址。

6、回過頭來,繼續說優先順序:上述表示式簡化一下: *(型別)0

,我們知道強轉()和*號均為2級優先符,那麼還是結合律在起作用了,它們的結合律是右結合,也就是說(型別)會先和右側所有內容也就是0結合,然後結合左邊的*,而*號會把右側的所有內容(型別)0看作乙個整體,然後進行取值運算,這樣好像計算沒有啥變化,所以這樣是不必要的: *((型別)0) 。

7、再來乙個簡單的: **p ,作為乙個2級指標,因為都是*號,所以優先順序相同,結合律為右結合,那麼靠近p的那個*號,首先結合p,在結合最左邊的*,這時它會將*p看作乙個整體進行取值運算,所以不必這樣寫了: *(*p) 。

8、細節的東西一定要牢牢的掌握好,這樣再複雜的東西都很簡單。

編譯器之語義分析

semantic 語言的意義 編譯器的語義分析階段將變數與其用法關聯起來,檢查每個表示式是否有正確的型別,還有,將抽象的語法翻譯成更簡單的形式以 方便生成機器語言 碼 符號表將識別符號和其型別 位置關聯起來,當我們去處理變數,函式的宣告時,就是將這些資訊組織 繫結 起來,放在表裡,當需 要知道這些函...

編譯器之語義分析

semantic 語言的意義 編譯器的語義分析階段將變數與其用法關聯起來,檢查每個表示式是否有正確的型別,還有,將抽象的語法翻譯成更簡單的形式以 方便生成機器語言 碼 符號表將識別符號和其型別 位置關聯起來,當我們去處理變數,函式的宣告時,就是將這些資訊組織 繫結 起來,放在表裡,當需 要知道這些函...

Linux 編譯器之 GCC

編輯器是指我用它來寫程式的 編輯 而我們寫的 語句,電腦是不懂的,我們需要把它轉成電腦能懂的語句,編譯器就是這樣的轉化工具。就是說,我們用編輯器編寫程式,由編譯器編譯後才可以執行!gcc gnu compiler collection,gnu 編譯器套件 是由gnu開發的程式語言編譯器。gcc 原本...