成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

原來C語言還可以這樣實現“泛型編程”!

開發 后端
泛型編程(generic programming)是程序設計語言的一種風格或范式。泛型允許程序員在強類型程序設計語言中編寫代碼時使用一些以后才指定的類型,在實例化時作為參數指明這些類型。C++支持泛型編程。

[[360397]]

本文轉載自微信公眾號「編程珠璣」,作者守望先生。轉載本文請聯系編程珠璣公眾號。   

在回答標題問題之前,先了解下什么是泛型編程。

泛型編程(generic programming)是程序設計語言的一種風格或范式。泛型允許程序員在強類型程序設計語言中編寫代碼時使用一些以后才指定的類型,在實例化時作為參數指明這些類型。C++支持泛型編程,也就是模板,比如:

  1. // 來源:公眾號【 編程珠璣】 
  2. // 作者:守望先生 
  3. #include <iostream> 
  4. template <class T> 
  5. add(T a,T b){ 
  6.   T ret = a + b; 
  7.   std::cout<< a << " + " << b <<" = " << ret << std::endl; 
  8.   return ret; 
  9. int main(){ 
  10.   add(1,2);  // 整數相加 
  11.   add(1.2,2.3); // 浮點數相加 
  12.   return 0; 

運行結果:

  1. 1 + 2 = 3 
  2. 1.2 + 2.3 = 3.5 

從上面的結果可以看到,對于調用add函數,如果傳入的是整型,則按照整型加法計算,如果是浮點數,則按照浮點數進行加法計算。也就是說,add函數沒有針對特定類型(泛型)。

你同樣可以使用重載實現上面的功能,但是存在大量重復代碼。

C語言支持泛型編程嗎?

很遺憾,C語言本身不支持真正意義上的泛型編程,但是卻在一定程度上可以“實現泛型編程”。

_Generic關鍵字

_Generic是C11的關鍵字,通過該關鍵字可以有一個泛型表達式:

  1. _Generic((value). int:"int"float:"float",char*:"char*",default:"other type"

什么意思呢?如果value是int類型,那么表達式的值就是“int”,其他的以此類推。看起來是不是和switch語句有點類似呢?

根據這個示例,我們來實現一個功能,打印變量或常量到底是什么類型:

  1. // 來源:公眾號【編程珠璣】 
  2. // 作者:守望先生 
  3. #include <stdio.h> 
  4. #define TYPE(v) _Generic((v), \ 
  5.     int:"int", \ 
  6.     char:"char", \ 
  7.     float:"float", \ 
  8.     double:"double", \ 
  9.     char*:"char*", \ 
  10.     default:"other type"
  11. int main(void) 
  12.     printf("1 + 2 type: %s\n",TYPE(1 + 2)); 
  13.     printf("1/3 type: %s\n",TYPE(1/3)); 
  14.     printf("2/3 type: %s\n",TYPE((float)2/3)); 
  15.     printf("xxx type: %s\n",TYPE("xxx")); 
  16.     return 0; 

這里為了方便使用,我們通過define關鍵字,將泛型表達式簡化。

運行結果:

  1. 1 + 2 type: int 
  2. 1/3 type: int 
  3. 2/3 type: float                                                         
  4. xxx type: char

可以看到通過TYPE就可以獲得表達式的結果類型,這對初學者來說,可真是福音了。

泛型算法

既然C語言有_Generic關鍵字了,那么我們嘗試實現開頭C++示例代碼中的加法。看過上面的例子后,相信你已經會了:

  1. // 來源:公眾號【編程珠璣】 
  2. // 作者:守望先生 
  3. #include <stdio.h> 
  4. // int類型加法 
  5. int addI(int a, int b) 
  6.     printf("%d + %d = %d\n",a,b, a + b ); 
  7.     return (a + b); 
  8. // double類型加法 
  9. double addF(double a, double b) 
  10.     printf("%f + %f = %f\n",a,b, a + b ); 
  11.     return (a + b); 
  12. void unsupport(int a,int b) 
  13.     printf("unsupport type\n"); 
  14. #define ADD(a,b) _Generic((a), \ 
  15.     int:addI(a,b),\ 
  16.     double:addF(a,b), \ 
  17.     default:unsupport(a,b)) 
  18. int main(void) 
  19.     ADD(1 , 2); 
  20.     ADD(1.1,2.2); 
  21.     return 0; 

觀察上面的代碼,我們注意到:

  • 在這里,我們需要定義兩種類型的加法(實際上,通過C++的模板,由編譯器幫我們完成了這件事),由于C語言中并不支持重載,因此兩個加法的函數名不一樣。
  • 由于涉及參數有兩個,在做類型判斷時,如果兩個參數不一致,可能仍然存在編譯問題
  • 調用者無需區分被加對象是什么類型,都可以統一使用ADD

C99的tgmath.h

前面說到,_Generic關鍵字在C11中才有,那么C99怎么辦呢?實際上,tgmath.h中提供了一些泛型類型宏,如果math.h的函數中定義了float,double和long double版本,tgmath就會提供一個泛型類型宏。效果和前面的例子一樣,舉個例子:

  1. // 來源:公眾號【編程珠璣】 
  2. // 作者:守望先生 
  3. #include <stdio.h> 
  4. #include <tgmath.h> 
  5. int main(void) 
  6.     float f = 4.0f; 
  7.     long double d = 1.44; 
  8.     printf("%f\n",sqrt(f)); // 實際上調用了sqrtf 
  9.     printf("%Lf\n",sqrt(d)); // 實際上調用了sqrtl 
  10.     return 0; 

編譯運行結果:

  1. 2.000000 
  2. 1.200000 

但是不得不說,tgmath中提供的泛型宏也是有限的。

void *指針

眾所周知,C語言中void *指針是一種無類型指針,從這點看,也可以算是泛型指針了。而它的使用在C語言中是非常常見的,舉例來說,在《高級指針話題-函數指針》中,我們介紹了快速排序接口的使用,它的函數聲明是這樣的:

  1. #include <stdlib.h> 
  2. void qsort(void *base, size_t nmemb, size_t size
  3.                   int (*compar)(const void *, const void *)); 

庫函數qsort實際上就是泛型排序算法了,它可以針對任何類型的數據進行排序。當然有一個前提,就是你需要按照它的協議,實現一個compar函數,用于比較大小。

像這樣類似的例子,C語言中還有很多,不過相比于其他語言,如C++中的模板,這種所謂的泛型,確實有些小巫見大巫了。

總結

C語言語法上本身基本不支持泛型編程,但是借助_Generic關鍵字和一些手段,可以實現泛型編程。

作者:守望,linux應用開發者,目前在公眾號【編程珠璣】?分享Linux/C/C++/數據結構與算法/工具等原創技術文章和學習資源。

 

責任編輯:武曉燕 來源: 編程珠璣
相關推薦

2013-09-18 10:44:01

搜狗輸入法詞語

2023-12-11 13:57:00

RFM模型激勵機制

2021-03-03 08:05:53

C++項目函數

2022-12-06 17:30:04

2022-07-30 23:45:09

內存泄漏檢測工具工具

2016-09-29 17:48:32

騰訊云語音質檢珍愛網

2021-02-01 13:35:28

微信Python技巧

2022-05-17 07:26:33

動畫CSS前端

2023-07-03 16:49:47

5G

2024-12-17 12:00:00

C++對象模型

2009-08-24 18:22:05

C# 泛型編程

2012-10-12 10:13:26

eclips代碼編寫Editplus

2017-11-27 12:24:02

命令行代碼指令

2024-03-12 08:44:56

WebWorkerTypeScript語法

2009-09-02 18:03:19

C#實現泛型類

2020-08-24 07:19:13

主鍵自增數據庫

2019-01-29 10:00:59

GitHub開源搜索

2024-06-13 08:19:08

Controller接口參數

2024-05-17 09:37:26

format屬性Spring

2024-11-19 09:15:40

搜索類型MySQL
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 一级毛片在线播放 | 精品九九 | 伊人免费在线观看高清 | 久久久久国产视频 | 欧美日韩亚洲三区 | 国产一卡二卡三卡 | 亚洲日本成人 | 特级特黄特色的免费大片 | 免费一区 | 在线视频一区二区 | 日日骚av | 成人精品一区二区三区中文字幕 | 第四色播日韩第一页 | 成人免费网视频 | 成人在线免费 | 午夜精品一区二区三区三上悠亚 | 久草色视频| 国产日韩精品一区 | 久久久久91 | 亚洲精品视频在线播放 | 国产福利在线 | 一级免费毛片 | 亚洲高清在线 | 日日日操 | 精品久久影院 | 国产精品片 | 狠狠ri| 国产成人在线播放 | 成人一区二区在线 | 理论片午午伦夜理片影院 | 欧美精品一区二区三区在线播放 | 国产成在线观看免费视频 | 欧美一二三 | 久久免费国产 | 久久久久久毛片免费观看 | 在线毛片网 | 狠狠色综合久久婷婷 | 久久综合久| 精品国产乱码久久久久久果冻传媒 | 国产免费又黄又爽又刺激蜜月al | 国产人成在线观看 |