欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語(yǔ)言泛型編程實(shí)例教程

 更新時(shí)間:2014年09月10日 14:39:11   投稿:shichen2014  
這篇文章主要介紹了C語(yǔ)言泛型編程,針對(duì)泛型的用法做了深入淺出的實(shí)例介紹,是C程序設(shè)計(jì)中非常實(shí)用的技巧,需要的朋友可以參考下

本文實(shí)例講述了C語(yǔ)言泛型編程的方法,分享給大家供大家參考之用。具體分析如下:

首先,泛型編程讓你編寫(xiě)完全一般化并可重復(fù)使用的算法,其效率與針對(duì)某特定數(shù)據(jù)類(lèi)型而設(shè)計(jì)的算法相同。在C語(yǔ)言中,可以通過(guò)一些手段實(shí)現(xiàn)這樣的泛型編程。這里介紹一種方法——通過(guò)無(wú)類(lèi)型指針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類(lèi)型時(shí),你還得重寫(xiě)一個(gè)參數(shù)類(lèi)型為char的函數(shù),是不是能用無(wú)類(lèi)型的指針來(lái)作為參數(shù)呢?看如下改動(dòng):

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

但是這段代碼是錯(cuò)誤的,是通不過(guò)編譯的。首先,變量是不能聲明為void無(wú)類(lèi)型的。而你不知道調(diào)用此函數(shù)傳進(jìn)的參數(shù)是什么類(lèi)型的,無(wú)法確定一種類(lèi)型的聲明。同時(shí),不能將*用在無(wú)類(lèi)型指針上,因?yàn)橄到y(tǒng)沒(méi)有此地址指向?qū)ο蟠笮〉男畔ⅰT诰幾g階段,編譯器無(wú)法得知傳入此函數(shù)參數(shù)的類(lèi)型的。這里要想實(shí)現(xiàn)泛型的函數(shù),需要在調(diào)用的地方傳入相關(guān)要交換的對(duì)象的地址空間大小size,同時(shí)利用在頭文件string.h中定義的memcpy()函數(shù)來(lái)實(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)用(同樣適用于其它類(lèi)型的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類(lèi)型的指針,是利用char類(lèi)型大小為1字節(jié)的特性,使elemAddr指向此”泛型“數(shù)組的第i-1個(gè)元素的首地址。因?yàn)橹耙呀?jīng)說(shuō)過(guò),此時(shí)你并不知道你傳入的是什么類(lèi)型的數(shù)據(jù),系統(tǒng)無(wú)法確定此數(shù)組一個(gè)元素有多長(zhǎng),跳向下個(gè)元素需要多少字節(jié),所以強(qiáng)制轉(zhuǎn)換為指向char的指針,再加上參數(shù)傳入的元素大小信息和累加數(shù)i的乘積,即偏移地址,即可得此數(shù)組第i-1個(gè)元素的首地址。這樣使無(wú)論傳入的參數(shù)是指向什么類(lèi)型的指針,都可以得到指向正確元素的指針,實(shí)現(xiàn)泛型編程。

函數(shù)memcmp()原型:int memcmp(void *dest,const void *src,int n),比較兩段長(zhǎng)度為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");
else
     printf("YES\n");

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

相信本文所述對(duì)大家C程序設(shè)計(jì)的學(xué)習(xí)有一定的借鑒價(jià)值。

相關(guān)文章

  • C語(yǔ)言之包含min函數(shù)的棧實(shí)例詳解

    C語(yǔ)言之包含min函數(shù)的棧實(shí)例詳解

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言之包含min函數(shù)的棧,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-02-02
  • C語(yǔ)言基礎(chǔ)之格式化輸出控制長(zhǎng)度

    C語(yǔ)言基礎(chǔ)之格式化輸出控制長(zhǎng)度

    這篇文章主要介紹了C語(yǔ)言基礎(chǔ)之格式化輸出控制長(zhǎng)度的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • 詳解C++中的指針、數(shù)組指針與函數(shù)指針

    詳解C++中的指針、數(shù)組指針與函數(shù)指針

    本文從初學(xué)者的角度,深入淺出地講解C++中的指針、數(shù)組指針與函數(shù)指針,對(duì)最?;煜囊脗鬟f、值傳遞和指針傳遞做了區(qū)處,需要的朋友可以參考下
    2015-07-07
  • C++關(guān)于字符的接收與輸出操作示例

    C++關(guān)于字符的接收與輸出操作示例

    這篇文章主要介紹了C++關(guān)于字符的接收與輸出操作,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2023-01-01
  • C++中const應(yīng)放在類(lèi)型前還是后

    C++中const應(yīng)放在類(lèi)型前還是后

    之前遇到小伙伴問(wèn)C++中const加在類(lèi)型名前和變量名前的區(qū)別,今天給大家簡(jiǎn)單分析下。
    2016-05-05
  • 一文徹底搞懂IO底層原理

    一文徹底搞懂IO底層原理

    我們今天要給大家講的底層的IO看上去簡(jiǎn)單,實(shí)則抽象。并且在它之上衍生出了語(yǔ)言層面用于實(shí)戰(zhàn)的技術(shù),比如我們熟悉的java語(yǔ)言中的NIO或者像Netty這樣的框架
    2021-06-06
  • Qt實(shí)現(xiàn)給窗口繪制陰影的示例代碼

    Qt實(shí)現(xiàn)給窗口繪制陰影的示例代碼

    這篇文章主要為大家詳細(xì)介紹了Qt實(shí)現(xiàn)給窗口繪制陰影的方法,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Qt有一定的幫助,感興趣的可以了解一下
    2022-11-11
  • 基于C語(yǔ)言實(shí)現(xiàn)2048游戲

    基于C語(yǔ)言實(shí)現(xiàn)2048游戲

    這篇文章主要為大家詳細(xì)介紹了基于C語(yǔ)言實(shí)現(xiàn)2048游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • C++實(shí)現(xiàn)AVL樹(shù)的示例詳解

    C++實(shí)現(xiàn)AVL樹(shù)的示例詳解

    AVL Tree 是一個(gè)「加上了額外平衡條件」的二叉搜索樹(shù),其平衡條件的建立是為了確保整棵樹(shù)的深度為O(log_2N),本文主要介紹了AVL樹(shù)的實(shí)現(xiàn),需要的可以參考一下
    2023-03-03
  • C++使用string的大數(shù)取模運(yùn)算(5)

    C++使用string的大數(shù)取模運(yùn)算(5)

    這篇文章主要為大家詳細(xì)介紹了C++使用string的大數(shù)取模運(yùn)算,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-09-09

最新評(píng)論