C語言三目運算子和逗號表示式
阿新 • • 發佈:2019-02-05
一、三目運算子定義:(a ?b : c) 當a的值為真時,返回b的值;否則返回c的值
二、三目運算子(a ?b : c) 返回型別:
1、通過隱試型別轉換規則返回b和c中的較高型別2、當b和c不能隱試轉換到同一型別時將編譯出錯
下面通過寫一段程式碼測試下:
#include <stdio.h> int main() { int a = 1; int b = 2; int c = 0; char c1 = 0; short s = 0; int i = 0; double d = 0; char* p = "str"; c = a < b ? a : b; (a < b ? a : b) = 3;//編譯錯誤,因為三目運算子返回的是變數值,而不是變數,所以不能作為左值 printf("%d\n", a); //1 printf("%d\n", b); //2 printf("%d\n", c); //因為a < b所以為真,返回a的值,賦給c = a,所以c = 1 printf( "%d\n", sizeof(c1 ? c1 : s) );//根據隱式型別轉換,char和short會轉換成int型別,所以是4 printf( "%d\n", sizeof(i ? i : d) ); //根據隱式型別轉換,int和double會轉換成double型別,所以是8 printf( "%d\n", sizeof(d ? d : p) ); //double和指標型別不能轉換同一個型別,所以編譯error return 0; }
註釋說的很明白,所以不講了
三、逗號表示式
定義:逗號表示式是按照從左向右的順序計算每個子表示式,逗號表示式的值是最後一個子表示式的值
通過定義我們可以知道逗號表示式實際是將多個子表示式組合到一起,形成一個表示式,同時子表示式可以沒有返回值
下面通過寫一段程式碼測試下:
#include <stdio.h> void hello() { printf("Hello!\n"); } int main() { int a[3][3] = { (0, 1, 2), (3, 4, 5), (6, 7, 8) }; //初始化一個二維陣列 int i = 0; int j = 0; while( i < 5 ) //因為 i< 0 所以執行printf()函式,列印i的值,也就是0 printf("i = %d\n", i),//注意這裡是一個逗號,不是分號 hello(), //輸出”Hello!“ 注意這裡也是一個逗號,不是分號 i++; //i遞增 注意這裡才是逗號,所以while裡面包含三條語句 for(i=0; i<3; i++) { for(j=0; j<3; j++) { printf("a[%d][%d] = %d\n", i, j, a[i][j]);//輸出二維陣列 } } return 0; }
再看下輸出:
while迴圈裡面執行了五次,這個好理解,因為while下面語句都是逗號,一直執行到分號,也就是i++後面,但是二維陣列輸出怎麼只有[0]陣列有資料,而且資料還不對,這是因為二維陣列初始化不對造成的,正確初始化應該是這樣的int a[3][3] = {{0,1,2},{3,4,5},{6,7,8}};中間不應該是(),中間是()時,編譯器認為是逗號運算子,所以只有[0]陣列有資料,而且是逗號最後的值,也就是2、5、8,其他陣列都沒有初始化,都是0
四、再寫一個面試可能考的題目,要求用一條語句實現int strlen(const char *p)函式
好吧直接寫答案
#include <stdio.h> #include <assert.h> int strlen(const char* s) { return assert(s), (*s ? strlen(s + 1) + 1 : 0);//遞迴用法 } int main() { printf("len = %d\n", strlen("Delphi")); printf("len = %d\n", strlen(NULL)); return 0; }
這裡注意:
為什麼要加assert();不加可以麼?請自己仔細分析吧
參考資料:狄泰軟體C語言進階教程