C語(yǔ)言逗號(hào)運(yùn)算符的具體使用
逗號(hào) , 在 C 語(yǔ)言里,既可以作為逗號(hào)運(yùn)算符,也可以作為分隔符(比如函數(shù)參數(shù)分隔、變量聲明分隔)。本文重點(diǎn)講的是逗號(hào)運(yùn)算符。
一、逗號(hào)運(yùn)算符是什么?
逗號(hào)運(yùn)算符(Comma Operator)是 C 語(yǔ)言中的一個(gè)二元運(yùn)算符,其作用是:
- 依次計(jì)算逗號(hào)左邊的表達(dá)式,然后計(jì)算右邊的表達(dá)式,
- 整個(gè)逗號(hào)表達(dá)式的值和類型為右邊表達(dá)式的值和類型。
即:
(e1, e2)
先計(jì)算 e1,丟棄其結(jié)果,再計(jì)算 e2,整個(gè)表達(dá)式的值為 e2 的值。
二、逗號(hào)運(yùn)算符的語(yǔ)法和優(yōu)先級(jí)
語(yǔ)法
expression1 , expression2
優(yōu)先級(jí)
逗號(hào)運(yùn)算符的優(yōu)先級(jí)是 所有運(yùn)算符中最低的,僅比賦值表達(dá)式 (=) 和條件表達(dá)式 (?:) 優(yōu)先級(jí)低。
優(yōu)先級(jí)表里逗號(hào)運(yùn)算符是最末的,且結(jié)合性是左結(jié)合。
所以小括號(hào)很重要,通常需要用括號(hào)明確表達(dá)式邊界。
三、逗號(hào)運(yùn)算符的應(yīng)用場(chǎng)景
- 在循環(huán)中執(zhí)行多條表達(dá)式
for (int i = 0, j = 0; i < 10; i++, j += 2) {
printf("i=%d, j=%d\n", i, j);
}
這里 i++, j += 2 中的逗號(hào)是逗號(hào)運(yùn)算符,使得兩條表達(dá)式得以連續(xù)執(zhí)行。
- 在 return 語(yǔ)句或賦值中執(zhí)行多步命令
int x;
x = (printf("Hello "), 42);
打印“Hello ”,再賦值 42 給 x。
- 宏定義中的多步操作
#define SWAP(a, b) do { int tmp = a; a = b; b = tmp; } while(0)
雖然用多條語(yǔ)句,但如果一定要用逗號(hào)運(yùn)算符,可以寫成:
#define SWAP(a, b) ((a) != (b) && ((a) ^= (b), (b) ^= (a), (a) ^= (b)))
利用逗號(hào)運(yùn)算符依次執(zhí)行三條異或交換表達(dá)式。
四、逗號(hào)運(yùn)算符與逗號(hào)分隔符的區(qū)別
- 逗號(hào)運(yùn)算符是運(yùn)算符:
(expr1, expr2),返回expr2的值。 - 逗號(hào)分隔符是語(yǔ)法結(jié)構(gòu),分隔參數(shù)、聲明等元素,無(wú)返回值。
示例:
int a = 1, b = 2, c = 3; // 逗號(hào)作為聲明語(yǔ)法分隔符 int x = (a = 1, b = 2, a + b); // 逗號(hào)運(yùn)算符,x最終是3
五、逗號(hào)運(yùn)算符的求值順序
逗號(hào)運(yùn)算符保證:
- 左邊表達(dá)式先完整求值并完成所有副作用,再求右邊表達(dá)式。
這比用 ; 語(yǔ)句分割更嚴(yán)格。
比如這段(假設(shè)無(wú)優(yōu)化):
int i = 1; int c = (i++, i + 10); // i++先執(zhí)行, i變?yōu)?,c = 2 + 10 = 12
六、逗號(hào)運(yùn)算符的類型和值
逗號(hào)運(yùn)算符的類型和數(shù)值均由右側(cè)表達(dá)式?jīng)Q定。
示例:
int x = (1, 2); // x = 2,類型是 int
float y = (printf("Hi\n"), 3.14f); // y = 3.14f,類型是 float
七、逗號(hào)運(yùn)算符的典型用例
1. 將多條表達(dá)式寫成一個(gè)表達(dá)式
int a = 5, b = 10; int c = (a *= 2, b += 3, a + b); // 先 a = 10,b = 13, 然后 c = 23
2. for 循環(huán)多個(gè)變量迭代
for (int i = 0, j = 10; i < 5; i++, j--) {
printf("i=%d, j=%d\n", i, j);
}
八、使用逗號(hào)運(yùn)算符的注意事項(xiàng)
- 優(yōu)先級(jí)低,要用括號(hào)明確范圍,避免歧義。
- 不要濫用逗號(hào)運(yùn)算符,代碼可讀性容易下降。
- 效果等同于用多條語(yǔ)句,但逗號(hào)運(yùn)算符保留在單個(gè)表達(dá)式中——這時(shí)非常有用,比如在宏里。
- 在逗號(hào)表達(dá)式中應(yīng)避免修改同一對(duì)象的不同副作用造成未定義行為。
九、經(jīng)典逗號(hào)運(yùn)算符誤區(qū)示例
int x = 1; int y = 2; int z = x, y; // 不是逗號(hào)運(yùn)算符!是聲明兩個(gè)變量:z 和 y,y未初始化 int w = (x, y); // 逗號(hào)運(yùn)算符,這里 w = y = 2
十、你不知道的細(xì)節(jié):逗號(hào)運(yùn)算符可鏈?zhǔn)绞褂?/h2>
int val = (printf("Step 1\n"), printf("Step 2\n"), 100);
// 先打印兩條消息,最后 val = 100
int val = (printf("Step 1\n"), printf("Step 2\n"), 100);
// 先打印兩條消息,最后 val = 100
逗號(hào)運(yùn)算符結(jié)合性是左結(jié)合,所以上面等價(jià)于:
int val = ((printf("Step 1\n"), printf("Step 2\n")), 100);
總結(jié)
| 方面 | 說(shuō)明 |
|---|---|
| 定義 | 順序求值多個(gè)表達(dá)式,返回最后一項(xiàng)的值和類型 |
| 語(yǔ)法 | expr1 , expr2 |
| 優(yōu)先級(jí) | 優(yōu)先級(jí)最低,左結(jié)合 |
| 關(guān)鍵特性 | 確保按順序求值副作用 |
| 與逗號(hào)分隔符區(qū)別 | 逗號(hào)運(yùn)算符是表達(dá)式,逗號(hào)分隔符是語(yǔ)法(聲明、函數(shù)參數(shù)等) |
| 應(yīng)用場(chǎng)景 | for循環(huán)多變量,宏定義中的多步表達(dá)式,緊湊表達(dá)式等 |
| 使用注意 | 易降低代碼可讀性,需加括號(hào),避免產(chǎn)生未定義行為 |
額外趣味:逗號(hào)運(yùn)算符的“隱藏套路”
一些大師級(jí)宏會(huì)用逗號(hào)運(yùn)算符巧妙生成表達(dá)式鏈,巧妙且凌厲:
#define LOG_AND_RETURN(x) (printf("Return value: %d\n", (x)), (x))
// 調(diào)用可以一邊打印,一邊返回值
int foo() {
return LOG_AND_RETURN(42);
}
到此這篇關(guān)于C語(yǔ)言逗號(hào)運(yùn)算符的具體使用的文章就介紹到這了,更多相關(guān)C語(yǔ)言逗號(hào)運(yùn)算符內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Matlab實(shí)現(xiàn)別踩白塊小游戲的示例代碼
別踩白塊是一款音樂(lè)類休閑游戲,游戲的玩法不難,只需跟著音樂(lè)的節(jié)奏點(diǎn)中對(duì)的方塊即可。本文將用Matlab實(shí)現(xiàn)這一經(jīng)典游戲,感興趣的可以了解一下2022-03-03
Qt編寫提示進(jìn)度條的實(shí)現(xiàn)示例
進(jìn)度條在很地方都可以使用到,Qt自帶的進(jìn)度條或者操作系統(tǒng)的進(jìn)度條樣式,不夠炫,本文就介紹一下Qt編寫自定義控件的提示進(jìn)度條的實(shí)現(xiàn)示例,感興趣的可以了解一下2021-12-12
Linux下Select多路復(fù)用實(shí)現(xiàn)簡(jiǎn)易聊天室示例
大家好,本篇文章主要講的是Linux下Select多路復(fù)用實(shí)現(xiàn)簡(jiǎn)易聊天室示例,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12
c++使用regex報(bào)錯(cuò)regex_error兩種解決方案
C++正則表達(dá)式是一個(gè)非常強(qiáng)大和實(shí)用的工具,但是使用它們時(shí)需要注意仔細(xì)檢查代碼是否符合語(yǔ)法規(guī)則,這篇文章主要給大家介紹了關(guān)于c++使用regex報(bào)錯(cuò)regex_error的兩種解決方案,需要的朋友可以參考下2024-03-03
C++中vector模擬實(shí)現(xiàn)中的迭代器失效問(wèn)題
本文主要介紹了C++中vector插入操作導(dǎo)致迭代器失效的問(wèn)題,插入后返回的迭代器位置變化,需及時(shí)更新以避免錯(cuò)誤,具有一定的參考價(jià)值,感興趣的可以了解一下2025-06-06
C++各種數(shù)據(jù)類型所占內(nèi)存大小詳解
這篇文章主要介紹了C++各種數(shù)據(jù)類型所占內(nèi)存大小,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08
C語(yǔ)言定義字符串?dāng)?shù)組簡(jiǎn)單代碼示例
在C語(yǔ)言中字符串?dāng)?shù)組是用來(lái)存儲(chǔ)多個(gè)字符串的,可以通過(guò)字符數(shù)組或指針數(shù)組的方式定義,這篇文章主要介紹了C語(yǔ)言定義字符串?dāng)?shù)組的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-11-11

