程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C說話泛型編程實例教程

C說話泛型編程實例教程

編輯:關於C++

C說話泛型編程實例教程。本站提示廣大學習愛好者:(C說話泛型編程實例教程)文章只能為提供參考,不一定能成為您想要的結果。以下是C說話泛型編程實例教程正文


本文實例講述了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法式設計的進修有必定的自創價值。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved