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

    运行截图:

  • 相关阅读:
    python学习笔记:遍历目录
    c++笔记:友元函数
    VMware Workstation 9: This virtual machine's policies are too old to be run by this version of VMware
    inet_ntoa内存问题
    python学习笔记:sqlite3查询
    python学习笔记:利用asyncore的端口映射(端口转发)
    编写谷歌浏览器的油猴脚本
    window编译7z
    通过配置nginx的header路由到不同环境的服务器
    用U盘给物理机安装ubuntu20.04
  • 原文地址:https://www.cnblogs.com/bukekangli/p/4319486.html
Copyright © 2011-2022 走看看