原来C语言还可以这样实现“泛型编程”!
在回答標題問題之前,先了解下什么是泛型編程。
泛型編程(generic programming)是程序設計語言的一種風格或范式。泛型允許程序員在強類型程序設計語言中編寫代碼時使用一些以后才指定的類型,在實例化時作為參數指明這些類型。C++支持泛型編程,也就是模板,比如:
#include? template?<class?T> T?add(T?a,T?b){T?ret?=?a?+?b;std::cout<<?a?<<?"?+?"?<<?b?<<"?=?"?<<?ret?<<?std::endl;return?ret; } int?main(){add(1,2);??//?整數相加add(1.2,2.3);?//?浮點數相加return?0; }運行結果:
1?+?2?=?3 1.2?+?2.3?=?3.5從上面的結果可以看到,對于調用add函數,如果傳入的是整型,則按照整型加法計算,如果是浮點數,則按照浮點數進行加法計算。也就是說,add函數沒有針對特定類型(泛型)。
你同樣可以使用重載實現上面的功能,但是存在大量重復代碼。
C語言支持泛型編程嗎?
很遺憾,C語言本身不支持真正意義上的泛型編程,但是卻在一定程度上可以“實現泛型編程”。
_Generic關鍵字
_Generic是C11的關鍵字,通過該關鍵字可以有一個泛型表達式:
_Generic((value).?int:"int",?float:"float",char*:"char*",default:"other?type")什么意思呢?如果value是int類型,那么表達式的值就是“int”,其他的以此類推。看起來是不是和switch語句有點類似呢?
根據這個示例,我們來實現一個功能,打印變量或常量到底是什么類型:
這里為了方便使用,我們通過define關鍵字,將泛型表達式簡化。
運行結果:
1?+?2?type:?int 1/3?type:?int 2/3?type:?float???????????????????????????????????????????????????????? xxx?type:?char*可以看到通過TYPE就可以獲得表達式的結果類型,這對初學者來說,可真是福音了。
泛型算法
既然C語言有_Generic關鍵字了,那么我們嘗試實現開頭C++示例代碼中的加法。看過上面的例子后,相信你已經會了:
#include? //?int類型加法 int?addI(int?a,?int?b) {printf("%d?+?%d?=?%d\n",a,b,?a?+?b?);return?(a?+?b); } //?double類型加法 double?addF(double?a,?double?b) {printf("%f?+?%f?=?%f\n",a,b,?a?+?b?);return?(a?+?b); } void?unsupport(int?a,int?b) {printf("unsupport?type\n"); } #define?ADD(a,b)?_Generic((a),?\int:addI(a,b),\double:addF(a,b),?\default:unsupport(a,b)) int?main(void) {ADD(1?,?2);ADD(1.1,2.2);return?0; }觀察上面的代碼,我們注意到:
在這里,我們需要定義兩種類型的加法(實際上,通過C++的模板,由編譯器幫我們完
成了這件事),由于C語言中并不支持重載,因此兩個加法的函數名不一樣。
由于涉及參數有兩個,在做類型判斷時,如果兩個參數不一致,可能仍然存在編譯問題
調用者無需區分被加對象是什么類型,都可以統一使用ADD
C99的tgmath.h
前面說到,_Generic關鍵字在C11中才有,那么C99怎么辦呢?實際上,tgmath.h中提供了一些泛型類型宏,如果math.h的函數中定義了float,double和long double版本,tgmath就會提供一個泛型類型宏。效果和前面的例子一樣,舉個例子:
#include? #include? int?main(void) {float?f?=?4.0f;long?double?d?=?1.44;printf("%f\n",sqrt(f));?//?實際上調用了sqrtfprintf("%Lf\n",sqrt(d));?//?實際上調用了sqrtlreturn?0; }編譯運行結果:
2.000000 1.200000但是不得不說,tgmath中提供的泛型宏也是有限的。
聲明:
本文于網絡整理,版權歸原作者所有,如來源信息有誤或侵犯權益,請聯系我們刪除或授權事宜。
總結
以上是生活随笔為你收集整理的原来C语言还可以这样实现“泛型编程”!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何使用iPhone 14拍摄出真实夜景
- 下一篇: C语言入门基础之输入和输出