# 逗號運算子 ## 共同討論 田雅今, 叢壯滋, 高唯恩, 王頌晴, 謝曜宇, 古詠熙, 吳珩睿, 邵中叡, 郭明勳(Sort by student ID) 筆者: 新世紀芙茵戰士 ## 前言 上一堂課老師提到逗號運算式(comma operation),由於我們都不太理解其中奧妙,於是就在實習課上討論起來,也就有了這篇文。 ## 問題 我們拿了其中一張PPT的程式跑跑看。 ![tyr](https://i.imgur.com/LREqe6m.png) ```c= #include <stdio.h> int main(){ int k1, k2; int i = 1,j = 10; k1 = ++i, j + 1; k2 = i + 1, j + 1; printf("%d %d \n", k1, k2); } ``` 結果出乎意料, ``` 2 3 ``` 是2跟3而不是PPT上說的11,於是我們就更confused了。 ## 嘗試 於是我們嘗試了下面的寫法,也就是在多寫了括號: ```c= #include <stdio.h> int main(){ int k1, k2, k3, k4,; int i = 1, j = 10; k1 = ++i, j + 1;//i = 2, j = 10 k2 = i + 1, j + 1;//i = 2,j = 10 k3 =( ++i, j + 1);//i = 3, j = 10 k4 = (i + 1, j + 1);//i = 3, j = 10 printf("%d %d %d %d %d %d\n", k1, k2, k3, k4, i ,j); } ``` 結果為: ``` 2 3 11 11 3 10 ``` 因此我們可以知道,要達到PPT上的11,需要額外加括號,另外可以特別注意i與j值的變化。 ## 解決 要解決問題我們可以從逗號運算子的運算跟特性講起,逗號運算子的特性如下: **1.左相依性(left associative)** ``` ex: a , b , c; 等於 (a , b) , c; ``` 也就是由左至右計算。 **2.優先序低於其他運算子** ``` ex: i++ , i + 1; 電腦會優先計算逗號運算子以外的其他運算子, 也就是說電腦會自動讀成 (i++) ,(i + 1) ``` 至於**運算**則就更簡單了,如下: ``` expr1 , expr2 ``` 先計算expr1並把expr1的值拋棄(拋棄容易讓人誤解,可以當作不鳥它),然後計算expr2,接著回傳expr2的值。 舉例: ``` int i = 1 ; i++ , i + 1; ``` 電腦會先計算(i++),i的值會被更新為2,接著拋棄(或不鳥)(i++)的值,然後計算i+1並回傳(i+1)的值,也就是3,所以(i++,i+1)這個式子的值就是3。那麼請問現在i等於多少? 答案是2,因為(i+1)並沒有儲存到i。 現在我們可以看看之前的程式 ``` int i = 1, j = 10; k1 = ++i, j + 1; printf("%d",k1) ``` 我們或許認為k1的值為(j+1),然而根據前述的特性二,電腦實際上讀到的是: ``` (k1 = ++i), (j + 1); ``` 這時印出k1,當然就會是i++的值也就是2,而不是11,相對來說((k1 = ++i), (j + 1))的值才是11。 因此,下面的式子也同理。 ```c= #include <stdio.h> int main(){ int k1, k2, k3, k4,; int i = 1, j = 10; k1 = ++i, j + 1;//電腦讀成(k1 = ++i),(j + 1) k2 = i + 1, j + 1;//電腦讀成(k2 = i + 1), (j + 1) k3 =( ++i, j + 1);//電腦讀成k3 =( ++i, j + 1) ,回傳(j+1) k4 = (i + 1, j + 1);//電腦讀成k4 = (i + 1, j + 1), 回傳(j+1) printf("%d %d %d %d %d %d\n", k1, k2, k3, k4, i ,j); } ``` 所以真相大白,若沒加括號電腦可能會根據逗號運算子低於其他運算子的特性,誤解你原本要表達的意思。 ## 結論 為了避免編譯器誤解你的意思,再使用逗號運算子時,括號我建議一律淦你@加爆! 不過教授的PPT不小心寫錯,反而促成我們在實習課上不斷實驗並嘗試去了解逗號運算子,想起來真是奇妙又有趣。 ## 參考資料 #### 逗號運算子的特性與運算: C Programming: A Modern Approach (page 109) ![link text](https://i.imgur.com/MOIVMX9.jpg) (照片由古詠C提供) #### 相依性跟運算子優先序: https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/Operator_Precedence #### 逗號運算子: https://docs.microsoft.com/zh-tw/cpp/cpp/comma-operator?view=msvc-160 #### 田雅今助教的IG: https://www.youtube.com/watch?v=dQw4w9WgXcQ #### PS 第一次用hackmd同時也是第一次發文,別鞭太大力,有錯歡迎指正