Summary
1)在C語言中,三目運算子返回的結果是一個右值
,並不是一個變數(不能放在賦值符號左側)
2)三目運算子的返回型別
:
- 通過
隱式型別轉換
規則返回b和c中的較高型別(注意:char和short
在運算時會隱式轉換成int) - 當b和c
不能隱式轉換
到同一型別時編譯出錯
3)逗號表示式(exp1, exp2, ... expN)
- 逗號表示式用於將
多個子表示式連線為一個表示式
- 逗號表示式的
值為最後一個子表示式的值
(前N-1個子表示式可以沒有返回值) - 計算順序為
從左到右
4)一般一行程式碼實現某種功能
時,往往需要用到遞迴 + 逗號表示式 + 三目運算子
三目運算子和逗號表示式
1、三目運算子
三目運算子(expression ? a : b):當expression的值為真時,返回a的值
;否則返回b的值
。
程式碼閱讀
int a = 1; int b = 2; int c = 0; c = a < b ? a : b; // c = 1 (a < b ? a : b) = 3; // error, lvalue required as left operand of assignment
三目運算子(expression ? a : b)的返回型別:
- 通過
隱式型別轉換
規則返回b和c中的較高型別 當b和c
不能隱式轉換
到同一型別時編譯出錯
char c = 0; short s = 0; int i = 0; double d = 0; char* p = "str"; printf("%d\n", sizeof(c ? c : s)); // 4, 返回型別隱式轉換為int printf("%d\n", sizeof(i ? i : d)); // 8,返回型別隱式轉換為double printf("%d\n", sizeof(d ? d : p)); // error,double和char*不能隱式型別轉換為同一型別
2、逗號表示式
逗號表示式(exp1, exp2, ... expN)
- 逗號表示式用於將
多個子表示式連線為一個表示式
- 逗號表示式的
值為最後一個子表示式的值
(前N-1個子表示式可以沒有返回值) 計算順序為
從左到右
// 以下程式碼會輸出什麼? int i = 0; while (i < 5) printf("i = %d\n", i), i++; // 分析,這段程式碼並不會編譯失敗,也不會死迴圈,因為這是一個逗號表示式 int i = 0; while(i < 5) printf("i = %d\n", i), i++;
// 以下程式碼會輸出什麼? int a[3][3] = { (0, 1, 2), (3, 4, 5), (6, 7, 8) }; int i=0, j=0; for(i = 0; i<3; i++) { for(j = 0; j<3; j++) { printf("a[%d][%d] = %d\n", i, j, a[i][j]); } } // 分析 這段程式碼並不會像乍看一樣輸出 0 ~ 8,而輸出的是2, 5, 8, 0, 0, ... 原因在於逗號表示式。初始化時使用的是逗號表示式,而不是花括號{} 相當於: int a[3][3] = {2, 5, 8};
3、一行程式碼實現strlen
遞迴 + 三目運算子 + 逗號表示式
版本一,未考慮空指標,入參為NULL時會崩潰
int myStrlen(const char* s) { return (*s ? myStrlen(s+1)+1 : 0); }
版本二,考慮空指標,使用巢狀的三目運算子
int myStrlen(const char* s) { return (s == NULL ? -1 : *s ? myStrlen(s+1)+1 : 0); }
版本三,使用assert斷言,逗號表示式 + 三目運算子
int myStrlen(const char* s) { return (assert(s), *s ? myStrlen(s+1)+1 : 0); }
本文總結自“狄泰軟體學院”唐佐林老師《C語言進階課程》。
如有錯漏之處,懇請指正。