C語言泛型程式設計執行個體教程_C 語言

來源:互聯網
上載者:User

本文執行個體講述了C語言泛型程式設計的方法,分享給大家供大家參考之用。具體分析如下:

首先,泛型程式設計讓你編寫完全一般化並可重複使用的演算法,其效率與針對某特定資料類型而設計的演算法相同。在C語言中,可以通過一些手段實現這樣的泛型程式設計。這裡介紹一種方法——通過無類型指標void*

看下面的一個實現交換兩個元素內容的函數swap,以整型int為例:

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

當你想交換兩個char類型時,你還得重寫一個參數類型為char的函數,是不是能用無類型的指標來作為參數呢?看如下改動:

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

但是這段代碼是錯誤的,是通不過編譯的。首先,變數是不能聲明為void無類型的。而你不知道調用此函數傳進的參數是什麼類型的,無法確定一種類型的聲明。同時,不能將*用在無類型指標上,因為系統沒有此地址指向對象大小的資訊。在編譯階段,編譯器無法得知傳入此函數參數的類型的。這裡要想實現泛型的函數,需要在調用的地方傳入相關要交換的對象的地址空間大小size,同時利用在標頭檔string.h中定義的memcpy()函數來實現。改動如下:

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

在調用這個函數時,可以像如下這樣調用(同樣適用於其它類型的x、y):

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

下面看另一種功能的函數:

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

此函數在數組array中尋找key元素,找到後返回它的索引,找不到返回-1.如上,也可以實現泛型的函數:

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;}

代碼第三行:將數組的首地址強制轉換為指向char類型的指標,是利用char類型大小為1位元組的特性,使elemAddr指向此”泛型“數組的第i-1個元素的首地址。因為之前已經說過,此時你並不知道你傳入的是什麼類型的資料,系統無法確定此數組一個元素有多長,跳向下個元素需要多少位元組,所以強制轉換為指向char的指標,再加上參數傳入的元素大小資訊和累加數i的乘積,即位移地址,即可得此數組第i-1個元素的首地址。這樣使無論傳入的參數是指向什麼類型的指標,都可以得到指向正確元素的指標,實現泛型程式設計。

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

此函數在數組base中尋找key元素,找到則返回它的地址資訊,找不到則返回NULL。

如果使用函數指標,則可以實現其行為的泛型:

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;}

再定義一個要調用的函數:

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

看如下調用:

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");else     printf("YES\n");

C語言也可以實現一定的泛型程式設計,但這樣是不安全的,系統對其只有有限的檢查。在編程時一定要多加細心。

相信本文所述對大家C程式設計的學習有一定的借鑒價值。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.