--- tags: os, c --- 2018q1 Homework2 (assesment) === contributed by <`team6612`> (Daniel Chen) :::info ### Table of Content [TOC] ::: 第一週測驗 Q3 --- 在 C 程式中,表達式 `1 << 2 + 3 << 4` 求值後為何? `(a)` 512 `(b)` 16 `(c)` 26 `(d)` 52 `(e)` 25 延伸問題: - 在 C 語言規格書中,找出對應運算子優先權的描述並嘗試解讀 ### 思考 在 C11 (ISO/IEC 9899:2011) 規格書中,有關運算子的優先順序定義在 `6.5 Expressions` 一章中,一連串的運算元和運算子組合起來稱爲 Expression,可用來表達:求值、指派、產生 `side effect`、或以上的組合。 在規格書中定義優先順序的方式不是列出個列表標示每個運算子的順序,而是一連串的語法定義,來告訴編譯器實作應該要先處理哪種運算子,一共分成 17 種 Expressions,分別是: 1. Primary expressions 2. Postfix operators 3. Unary operators 4. Cast operators 5. Multiplicative operators 6. Additive operators 7. Bitwise shift operators 8. Relational operators 9. Equality operators 10. Bitwise AND operator 11. Bitwise exclusive OR operator 12. Bitwise inclusive OR operator 13. Logical AND operator 14. Logical OR operator 15. Conditional operator 16. Assignment operators 17. Comma operator 各 Expression 的定義可能由別種 Expression 所表達,表示別種 Expression 必須先組合起來再解讀該 Expression,例如 `unary-expression` 的定義 ``` unary-expression: postfix-expression ++ unary-expression -- unary-expression unary-operator cast-expression sizeof unary-expression sizeof ( type-name ) _Alignof ( type-name ) unary-operator: one of & * + - ~ ! ``` 中包含 `postfix-expression` 及 `cast-expression`,意味着當 Expression 中包含這兩種 Expression 時必須先解讀`postfix-expression` & `cast-expression` 再解讀 `unary-expression`。 [C Operator Precedence - cppreference.com](http://en.cppreference.com/w/c/language/operator_precedence) 將這樣的關係整理成 precedence table,但也有提到不是所有的語法定義都可以很好的用次序表定義,例如三元運算子。 ### 相關議題 #### 有關 `side-effect` 的順序 在 `6.5` 中第二點提到 > If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings. 並舉了兩個例子 ``` a[i++] = i; //! undefined a[i] = i; // allowed ``` ``` i = ++i + 1; //! undefined i = i + 1; // allowed ``` 第一次看的時候不太懂,於是去找了一些資料來看,其中在 StackOverflow 上找到的[這篇](https://stackoverflow.com/questions/22616044/assignment-operator-sequencing-in-c11-expressions)和[這篇](https://stackoverflow.com/questions/21066593/sequence-points-and-side-effects-quiet-change-in-c11)有討論到這個規範的解讀,目前還在研究當中。 #### string-literal `string-literal` 是 `primary-expression` 的一種,用來表示字串,規格書在敘述中有提到 `string-literal` 是 `lvalue`,宣告時就佔有記憶體空間,可以對其做相關操作,之前並無注意到此特性,因此做了一點小實驗,對 `string-literal` 進行 `address-of (&)` 操作: ```c printf("&\"string-literal\" = %p\n", &"string-literal"); ``` 執行結果 ``` &"string-literal" = 0x561204b247de ``` ### Reference [ISO/IEC 9899:2011 - WG14 draft version N1570](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up