c语言关键字c11,_Generic关键字及其语法和应用(C11标准),C语言_Generic详解
對接觸過面向對象程序設計的程序員來講,相信各位對泛型編程并不陌生。在 C11 標準中,_Generic 關鍵字可以讓 C 語言也如同 等面向對象程序設計語言一樣,使其支持輕量級的泛型編程設計。
利用 _Generic 關鍵字,可以簡單地將一組具有不同類型卻有相同功能的函數抽象為一個統一的接口,語法形式如下:
generic-selection:
_Generic (assignment-expression, generic-assoc-list)
generic-assoc-list:
generic-association
generic-assoc-list , generic-association
generic-association:
type-name : assignment-expression
default : assignment-expression
與 sizeof 與 typeof 類似,_Generic 中的 assignment-expression 只用于在編譯時獲得該表達式的類型,而不會對該表達式做運行時計算,如以下代碼所示。
#include #include #include #include #define getTypeName(x) _Generic((x), _Bool:"_Bool", char: "char", signed char: "signed char", unsigned char: "unsigned char", short int: "short int", unsigned short int: "unsigned short int", int: "int", unsigned int: "unsigned int", long int: "long int", unsigned long int: "unsigned long int", long long int: "long long int", unsigned long long int: "unsigned long long int", float: "float", double: "double", long double: "long double", char *: "pointer to char", void *: "pointer to void", int *: "pointer to int") int main(void) { char c = 'a'; size_t s; ptrdiff_t p; intmax_t i; int arr[3] = { 0 }; printf("s is '%s'n", getTypeName(s)); printf("p is '%s'n", getTypeName(p)); printf("i is '%s'n", getTypeName(i)); printf("c is '%s'n", getTypeName(c)); printf("arr is '%s'n", getTypeName(arr)); printf("0x7FFFFFFF is '%s'n", getTypeName(0x7FFFFFFF)); printf("0xFFFFFFFF is '%s'n", getTypeName(0xFFFFFFFF)); printf("0x7FFFFFFFU is '%s'n", getTypeName(0x7FFFFFFFU)); }
運行結果為:
s is 'unsigned int'
p is 'int'
i is 'long long int'
c is 'char'
arr is 'pointer to int'
0x7FFFFFFF is 'int'
0xFFFFFFFF is 'unsigned int'
0x7FFFFFFFU is 'unsigned int'
除此之外,還必須保證 generic-association-list 中有與 assignment-expression 類型相同的 generic-association 與之對應,否則編譯就會報錯。例如,在上面代碼的main函數中添加如下兩行代碼:
float *fp=NULL; printf("fp is '%s'n", getTypeName(fp));
很顯然,generic-assoc-list 中沒有 generic-association 與 fp 相匹配的類型,從而導致編譯出錯,如圖 1 所示。
圖 1 類型不匹配
要解決圖 1 這種類型不匹配時導致的編譯錯誤,你可以在 generic-association-list 中添加 default 處理,那么編譯就能夠順利進行,如下面的代碼所示:
#define getTypeName(x) _Generic((x), _Bool:"_Bool", char: "char", signed char: "signed char", unsigned char: "unsigned char", short int: "short int", unsigned short int: "unsigned short int", int: "int", unsigned int: "unsigned int", long int: "long int", unsigned long int: "unsigned long int", long long int: "long long int", unsigned long long int: "unsigned long long int", float: "float", double: "double", long double: "long double", char *: "pointer to char", void *: "pointer to void", int *: "pointer to int", default: "other")
現在,如果編譯器發現 generic-assoc-list 中沒有 generic-association 與 fp 相匹配的類型時,將默認執行 default 處理,運行結果為:
s is 'unsigned int'
p is 'int'
i is 'long long int'
c is 'char'
arr is 'pointer to int'
fp is 'other'
0x7FFFFFFF is 'int'
0xFFFFFFFF is 'unsigned int'
0x7FFFFFFFU is 'unsigned int'
總結
以上是生活随笔為你收集整理的c语言关键字c11,_Generic关键字及其语法和应用(C11标准),C语言_Generic详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android找工作系列之自定义View
- 下一篇: 合并所有文档