zoukankan      html  css  js  c++  java
  • 用 void* 编写泛型函数

    1.泛型交换

    //1.编写int类型的swap
    void swap(int *vp1, int *vp2) {
        int a = *vp1;
        *vp1 = *vp2;
        *vp2 = a;
    }
    //2.引申至泛型swap
    void swap(void *vp1, void *vp2, int size){
        char buffer[size];
        memcpy(buffer, vp1, size);
        memcpy(vp1, vp2, size);
        memcpy(vp2, buffer, size);
    }

    使用泛型swap交换C-string:

    char* husband = "Fred";
    char* wife = "Wilma";
    swap(&husband,&wife,sizeof(char));

    2.泛型线性搜索

    //1.编写int类型的lsearch
    int * lsearch(int key ,int* array, int size){
        for (int i = 0; i < size; i++)  
        {
            if(array[i] == key)
                return i;
        }
        return NULL;
    }
    //2.编写泛型lsearch
    int *lsearch(void *key, void *base, int size, int elementSize){
        for (int i = 0; i < size; i++) {
          void * elemAddr = (char *)base + i * elemSize; 
          if (memcmp(key, elemAddr, elemSize) == 0)
            return elemAddr;
        }       
        return NULL;
    }

    如果用泛型lsearch来搜索C-string,因为C-string的长度不是固定的,故无法利用memcmp进行比较。可以利用函数指针实现:

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

    实现cmpFunc:

    //比较int
    int intCmp(void *elem1,void *elem2){
        int *ip1 = elem1;
        int *ip2 = elelm2;
        return *ip1-*ip2;
    }
    //比较C-string
    int strCmp(void *elem1,void *elem2){
        char *s1 = *(char**)elem1;
        char *s2 = *(char**)elem2;
        return strcmp(s1,s2);
    }

    3.泛型二分搜索

    void *binary_search(void *key,void *base,int n,int elemSize,int (*cmpFunc)(void *,void *)){
        int low = 0;
        int high = n-1;
        while(low <= high){    
            int mid = low+(high-low)/2;
            void *midAddr = (char*)base+mid*elemSize;
            if(cmpFunc(key,midAddr) == 0){
                return midAddr;
            }
            else if(cmpFunc(key,midAddr) < 0){
                high = mid-1;
            }
            else{
                low = mid+1;
            }
        }
        return NULL;
    }

    编码验证:

    #include<iostream>
    using namespace std;
    
    int intCmp(void *elem1,void *elem2){
        int *ip1 = (int*)elem1;
        int *ip2 = (int*)elem2;
        return *ip1-*ip2;
    }
    
    void *binary_search(void *key,void *base,int n,int elemSize,int (*cmpFunc)(void *,void *)){
        int low = 0;
        int high = n-1;
        while(low <= high){
            int mid = low+(high-low)/2;
            void *midAddr = (char*)base+mid*elemSize;
            if(cmpFunc(key,midAddr) == 0){
                return midAddr;
            }
            else if(cmpFunc(key,midAddr) < 0){
                high = mid-1;
            }
            else{
                low = mid+1;
            }
        }
        return NULL;
    }
    
    int main(){
        int a[]={1,2,3,4,5,6,7,8,9};
        int i;
        for(i=1;i<10;i++){
        
            cout<<((int*)binary_search(&i,a,9,sizeof(int),intCmp))<<endl;        
        }    
        return 0; 
    } 
    View Code

    运行截图:

  • 相关阅读:
    linux的vim按了ctrl+s之后假死的解决办法
    linux下的终端模拟器urxvt的配置
    vim下正则表达式的非贪婪匹配
    linux中的一个看图的软件
    解决windows的控制台显示utf8乱码的问题
    [PHP][位转换积累]之异或运算的简单加密应用
    [PHP][REDIS]phpredis 'RedisException' with message 'read error on connection'
    [PHP][位转换积累]之与运算截取二进制流的值
    [PHP][位转换积累]之pack和unpack
    [正则表达式]PCRE反向分组引用
  • 原文地址:https://www.cnblogs.com/bukekangli/p/4319486.html
Copyright © 2011-2022 走看看