日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言实现泛型编程

發(fā)布時(shí)間:2025/6/15 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言实现泛型编程 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

泛型編程讓你編寫完全一般化并可重復(fù)使用的算法,其效率與針對某特定數(shù)據(jù)類型而設(shè)計(jì)的算法相同。在C語言中,可以通過一些手段實(shí)現(xiàn)這樣的泛型編程。這里介紹一種方法——通過無類型指針void*

看下面的一個(gè)實(shí)現(xiàn)交換兩個(gè)元素內(nèi)容的函數(shù)swap,以整型int為例:

void swap(int* i1,int* i2){ int temp; temp = *i1; *i1 = *i2; *i2 = temp; }

當(dāng)你想交換兩個(gè)char類型時(shí),你還得重寫一個(gè)參數(shù)類型為char的函數(shù),是不是能用無類型的指針來作為參數(shù)呢?看如下改動(dòng):

void swap(void *vp1,void *vp2){ void temp = *vp1; *vp1 = *vp2; *vp2 = temp; }

這段代碼是錯(cuò)誤的,是通不過編譯的。首先,變量是不能聲明為void無類型的。而你不知道調(diào)用此函數(shù)傳進(jìn)的參數(shù)是什么類型的,無法確定一種類型的聲明。同時(shí),不能將*用在無類型指針上,因?yàn)橄到y(tǒng)沒有此地址指向?qū)ο蟠笮〉男畔ⅰT诰幾g階段,編譯器無法得知傳入此函數(shù)參數(shù)的類型的。這里要想實(shí)現(xiàn)泛型的函數(shù),需要在調(diào)用的地方傳入相關(guān)要交換的對象的地址空間大小size,同時(shí)利用在頭文件string.h中定義的memcpy()函數(shù)來實(shí)現(xiàn)。改動(dòng)如下:

void swap(void *vp1,void *vp2,int size){ char buffer[size];//注意此處gcc編譯器是允許這樣聲明的 memcpy(buffer,vp1,size); memcpy(vp1,vp2,size); memcpy(vp2,buffer,size); }

在調(diào)用這個(gè)函數(shù)時(shí),可以像如下這樣調(diào)用(同樣適用于其它類型的x、y):

int x = 27,y = 2; swap(&x,&y,sizeof(int));

下面看另一種功能的函數(shù):

int lsearch(int key,int array[],int size){for(int i = 0;i < size; ++i)if(array[i] == key)return i;return -1; }

此函數(shù)在數(shù)組array中查找key元素,找到后返回它的索引,找不到返回-1.如上,也可以實(shí)現(xiàn)泛型的函數(shù):

void* lsearch(void* key, void *base, int n, int elemSize){for(int i = 0;i < n; ++i){void *elemAddr = (char *)base+i*elemSize;if(memcmp(key, elemAddr, elemSize) == 0)return elemAddr;}return NULL; }

代碼第三行:將數(shù)組的首地址強(qiáng)制轉(zhuǎn)換為指向char類型的指針,是利用char類型大小為1字節(jié)的特性,使elemAddr指向此”泛型“數(shù)組的第i-1個(gè)元素的首地址。因?yàn)橹耙呀?jīng)說過,此時(shí)你并不知道你傳入的是什么類型的數(shù)據(jù),系統(tǒng)無法確定此數(shù)組一個(gè)元素有多長,跳向下個(gè)元素需要多少字節(jié),所以強(qiáng)制轉(zhuǎn)換為指向char的指針,再加上參數(shù)傳入的元素大小信息和累加數(shù)i的乘積,即偏移地址,即可得此數(shù)組第i-1個(gè)元素的首地址。這樣使無論傳入的參數(shù)是指向什么類型的指針,都可以得到指向正確元素的指針,實(shí)現(xiàn)泛型編程。

函數(shù)memcmp()原型:int memcmp(void *dest,const void *src,int n),比較兩段長度為n首地址分別為dest、src的地址空間中的內(nèi)容。

此函數(shù)在數(shù)組base中查找key元素,找到則返回它的地址信息,找不到則返回NULL。

如果使用函數(shù)指針,則可以實(shí)現(xiàn)其行為的泛型:

void *lsearch(void *key,void *base,int n,int elemSize,int(*cmpfn)(void*,void*,int)){for(int i = 0;i < n; ++i){void *elemAddr = (char *)base+i*elemSize;if(cmpfn(key,elemAddr,elemSize) == 0)return elemAddr;}return NULL; }

再定義一個(gè)要調(diào)用的函數(shù):

int intCmp(void* elem1,void* elem2){int* ip1 = elem1;int* ip2 = elem2;return *ip1-*ip2; }

看如下調(diào)用:

int array[] = {1,2,3,4,5,6}; int size = 6; int number = 3; int *found = lsearch(&number,array,size,sizeof(int),intCmp); if(found == NULL)printf("NO\n"); elseprintf("YES\n");

C語言也可以實(shí)現(xiàn)一定的泛型編程,但這樣是不安全的,系統(tǒng)對其只有有限的檢查。在編程時(shí)一定要多加細(xì)心。

總結(jié)

以上是生活随笔為你收集整理的C语言实现泛型编程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。