在 C 中接受任何数字类型的函数

Function that accepts any numeric type in C

我正在尝试用 C 构建一个程序,它可能会接收任何类型的数值数组和一个要在数组中搜索的数字,并将 return 它的位置。 目前,我在 func 函数的第 3 行收到“错误:void 表达式的无效使用”错误。 我试图解决问题的方式是否相关?如果不是,我想尽可能通用的解决方案应该是什么?

代码如下:

void func(int,void*,double,int);
int main(){
        /* arrays and numbers to search in each array*/
        int arrInt[]={3,4,5,15,6,24,7,13,12};
        double arrD[]={1.1,1.4,1.5,2.2,7.6,10.2};
        long arrL[]={10,20,30,40,50,60};
        int i2s=7;
        double d2s=7.6;
        long l2s=40;

        func(sizeof(int*),arrInt,i2s,9);
        func(sizeof(double*),arrD,d2s,6);
        func(sizeof(long*),arrL,l2s,6);

}

void func(int size,void *arr,double num,int arrSize){
        int i;
        for(i=0;i<arrSize;i++){
                if((double*)*arr==num)
                        return i+1;
                arr=arr+size;
        }
        return -1;
}

在以下条件下取消引用 void* 会触发错误:

 if((double*)*arr==num)

此外,在 void* 上进行指针运算是不标准的。

即使您修复语法以在 指针转换后取消引用,除非您实际传递一个double 数组,否则比较将失败,因此您需要更改方法。

您可以通过将指针传递给搜索项并使用 memcmp:

进行比较来解决此问题
int func(size_t size, void *arr, void* pnum, size_t arrSize) {
    for (int i=0 ; i != arrSize ; i++, arr = ((char*)arr)+size ) {
        if(memcmp(arr, pnum, size)==0)
                return i+1;
    }
    return -1;
}

请注意,现在您需要在调用中使用地址运算符 &,即

int x = func(sizeof(int), arrInt, &i2s, 9);

Demo.

您遇到的错误在这里:

(double*)*arr

您正在尝试解除对 void * 的引用,这是不允许的。您想将该指针转换为特定类型,然后 然后 取消引用:

*(double *)arr

但是,这仍然不能如您所愿。对于 double 以外的类型,您将尝试读取多个字节,就好像它们是 double。不同的类型有不同的表示,因此您不能获取包含 int 的地址,告诉编译器将其读取为 double,并期望得到任何有意义的内容。

为此,您需要将实际类型传递给函数(或指定类型的值)。类型不能在 C 中传递,所以你需要一个标志:

enum searchTypes {
    INT,
    LONG,
    DOUBLE
};

void func(int type, void *arr, double num, int arrSize){
        int i;
        for(i=0; i<arrSize; i++){
                double val = 0;
                switch (type) {
                case INT: 
                    val = ((int *)arr)[i];
                    break;
                case LONG: 
                    val = ((long *)arr)[i];
                    break;
                case DOUBLE: 
                    val = ((double *)arr)[i];
                    break;
                }
                if (val==num) {
                        return i+1;
                }
        }
        return -1;
}

然后这样称呼它:

func(INT,arrInt,i2s,9);
func(DOUBLE,arrD,d2s,6);
func(LONG,arrL,l2s,6);