---
# System prepended metadata

title: 逗號運算子

---

# 逗號運算子
## 共同討論
田雅今, 叢壯滋, 高唯恩, 王頌晴, 謝曜宇, 古詠熙, 吳珩睿, 邵中叡, 郭明勳(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)並沒有儲存到ｉ。

現在我們可以看看之前的程式
```
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同時也是第一次發文，別鞭太大力，有錯歡迎指正
