Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c语言中的泛型和函数_C - Fatal编程技术网

c语言中的泛型和函数

c语言中的泛型和函数,c,C,可以用C写一个通用的求和函数吗 我试图编写一个处理任何数字类型的求和函数 double sum(void* myArrayVoidPtr, size_t arrayLength, int arrayType){ int i; double result = 0; //The goal is to make this next line depend on arrayType //e.g. if(arrayType == UINT16) unsigned

可以用C写一个通用的求和函数吗

我试图编写一个处理任何数字类型的求和函数

double sum(void* myArrayVoidPtr, size_t arrayLength, int arrayType){
    int i;
    double result = 0;

    //The goal is to make this next line depend on arrayType
    //e.g. if(arrayType == UINT16)
    unsigned short* myArrayTypePtr = (unsigned short*) myArrayVoidPtr;

    for(i = 0; i < arrayLength; i++){
        result += *myArrayTypePtr;
        myArrayTypePtr++;
    }
    return result;
}
double sum(void*myArrayVoidPtr,size\u t arrayLength,int arrayType){
int i;
双结果=0;
//目标是使下一行依赖于arrayType
//e、 g.如果(arrayType==UINT16)
无符号短*myArrayTypePtr=(无符号短*)myArrayVoidPtr;
对于(i=0;i< C. >不可能在C++中生成一个通用函数,而C++是不可能的。模板允许您创建同一函数的多个版本,这些版本因它们“接受”的
类型(即
int
float
或任何
)而不同。这意味着函数会被编译多次

C没有模板,但您可以为此编写宏。这基本上相当于C++的模板,只是功能不太强大。但它将是“内联”的,而不是真正的函数

#define SUM(arr, len, sum) do { int i; for(i = 0; i < len; ++i) sum += arr[i]; } while(0);

int main(void) {
    int i_arr[] = {1,2,3};
    double d_arr[] = {1.5, 2.5, 3.5};
    int sum = 0;
    double d_sum = 0;
    SUM(i_arr, 3, sum)
    SUM(d_arr, 3, d_sum);
    printf("%d, %f\n", sum, d_sum);
    return 0;

}

@Mark_Segal是正确的,尽管我认为我的宏实现稍好一些,它的返回值与函数类似:

#define summation(arr, len) ({      \
    __typeof(*arr) sum = 0;         \
    for (int i = 0; i < len; ++i)   \
        sum += arr[i];              \
    sum; })

int main(void) {
    int   isum, iarr[] = { 1, 3, 7 };
    float fsum, farr[] = { 1.5, 3.2, 6.9 };
    isum = summation(iarr,3);
    printf("int sum: %d\n",isum);
    fsum = summation(farr,3);
    printf("float sum: %g\n",fsum);
    return(0);
}

这取决于
\uuu typeof
运算符(在GNU编译器中定义)的存在,在其他一些编译器中可以用
typeof
(无前导下划线)替换该运算符。

如果要使用函数执行此操作,并且要传递确定如何访问数组的arrayType变量(与使用typeof相反)那么这可能会起作用:

#include <stdio.h>
#include <stdint.h>

enum type_v {
    UINT8,
    UINT16,
    UINT32,
    UINT64,
    FLOAT,
    DOUBLE
};

union type_t {
    uint8_t*  uint8Array;
    uint16_t* uint16Array;
    uint32_t* uint32Array;
    uint64_t* uint64Array;
    float*    floatArray;
    double*   doubleArray;
};
    
double sum(void* voidArray, size_t arrayLength, int arrayType)
{
    union type_t arrays;

    switch(arrayType) {
        case UINT8:  arrays.uint8Array  = voidArray; break;
        case UINT16: arrays.uint16Array = voidArray; break;
        case UINT32: arrays.uint32Array = voidArray; break;
        case UINT64: arrays.uint64Array = voidArray; break;
        case FLOAT:  arrays.floatArray  = voidArray; break;
        case DOUBLE: arrays.doubleArray = voidArray; break;
    }

    int i;
    double result = 0;
    
    for(i = 0; i < arrayLength; i++){
        switch(arrayType) {
            case UINT8:  result += arrays.uint8Array [i]; break;
            case UINT16: result += arrays.uint16Array[i]; break;
            case UINT32: result += arrays.uint32Array[i]; break;
            case UINT64: result += arrays.uint64Array[i]; break;
            case FLOAT:  result += arrays.floatArray [i]; break;
            case DOUBLE: result += arrays.doubleArray[i]; break;
        }
    }
    return result;
}

int main()
{
    uint16_t array[] = {1,2,3,4};
    double result = sum(array, 4, UINT16);
    printf("Sum = %f\n", result);

    return 0;
}
#包括
#包括
枚举类型{
UINT8,
UINT16,
UINT32,
UINT64,
浮动
双重的
};
联合型{
uint8_t*uint8阵列;
uint16_t*uint16阵列;
uint32_t*uint32阵列;
uint64_t*uint64阵列;
浮点*浮点数组;
双*双阵列;
};
双和(void*voidArray,size\u t arrayLength,int arrayType)
{
联合型数组;
开关(arrayType){
案例UINT8:arrays.uint8Array=voidArray;break;
案例UINT16:arrays.UINT16数组=无效数组;中断;
案例UINT32:arrays.UINT32数组=无效数组;中断;
案例UINT64:arrays.uint64Array=voidArray;break;
case FLOAT:arrays.floatArray=voidArray;break;
双格:arrays.doubleArray=voidArray;break;
}
int i;
双结果=0;
对于(i=0;i
请在此处尝试:

请注意,这并不是真正的泛型,尽管它可以扩展到新类型,因此您可以轻松地将其扩展到对数组中的结构的单个成员求和。例如:

#include <stdio.h>
#include <stdint.h>

struct player {
    char name[32];
    int score;
};

enum type_v {
    UINT8,
    UINT16,
    UINT32,
    UINT64,
    FLOAT,
    DOUBLE,
    PLAYER
};

union type_t {
    uint8_t*        uint8Array;
    uint16_t*       uint16Array;
    uint32_t*       uint32Array;
    uint64_t*       uint64Array;
    float*          floatArray;
    double*         doubleArray;
    struct player*  playerArray;
};
    
double sum(void* voidArray, size_t arrayLength, int arrayType)
{
    union type_t arrays;

    switch(arrayType) {
        case UINT8:  arrays.uint8Array  = voidArray; break;
        case UINT16: arrays.uint16Array = voidArray; break;
        case UINT32: arrays.uint32Array = voidArray; break;
        case UINT64: arrays.uint64Array = voidArray; break;
        case FLOAT:  arrays.floatArray  = voidArray; break;
        case DOUBLE: arrays.doubleArray = voidArray; break;
        case PLAYER: arrays.playerArray = voidArray; break;
    }

    int i;
    double result = 0;
    
    for(i = 0; i < arrayLength; i++){
        switch(arrayType) {
            case UINT8:  result += arrays.uint8Array [i];       break;
            case UINT16: result += arrays.uint16Array[i];       break;
            case UINT32: result += arrays.uint32Array[i];       break;
            case UINT64: result += arrays.uint64Array[i];       break;
            case FLOAT:  result += arrays.floatArray [i];       break;
            case DOUBLE: result += arrays.doubleArray[i];       break;
            case PLAYER: result += arrays.playerArray[i].score; break;
        }
    }
    return result;
}

int main()
{
    struct player array[] = {{"Bob",1},{"MEl",2},{"Jim",3},{"Ann",4}};
    double result = sum(array, 4, PLAYER);
    printf("Sum = %f\n", result);

    return 0;
}
#包括
#包括
结构播放器{
字符名[32];
智力得分;
};
枚举类型{
UINT8,
UINT16,
UINT32,
UINT64,
浮动
双重的
玩家
};
联合型{
uint8_t*uint8阵列;
uint16_t*uint16阵列;
uint32_t*uint32阵列;
uint64_t*uint64阵列;
浮点*浮点数组;
双*双阵列;
结构玩家*玩家阵列;
};
双和(void*voidArray,size\u t arrayLength,int arrayType)
{
联合型数组;
开关(arrayType){
案例UINT8:arrays.uint8Array=voidArray;break;
案例UINT16:arrays.UINT16数组=无效数组;中断;
案例UINT32:arrays.UINT32数组=无效数组;中断;
案例UINT64:arrays.uint64Array=voidArray;break;
case FLOAT:arrays.floatArray=voidArray;break;
双格:arrays.doubleArray=voidArray;break;
案例玩家:arrays.playerray=voidArray;break;
}
int i;
双结果=0;
对于(i=0;i

请在此处尝试:

可以,但不能这样。“任意”数据不能求和为双精度。而且
+
也不能处理“任意”类型。将问题从“任意”更改为“任意数字”。为什么不可能?你可以创建一个泛型函数。@hacck你如何定义泛型函数?你没有C语言的模板。你可以做的最接近的事情是一个宏,或者手动编写相同方法的多个实例。你需要一个包含一个
联合
的结构和该数据类型的一个数据成员。我现在没有时间因此,我会发布代码。@haccks不想匆忙进入,但你现在有时间吗?我对你提到的通用实现感兴趣。我会这样做:你让返回类型
double
tho,这不是很通用。
#include <stdio.h>
#include <stdint.h>

enum type_v {
    UINT8,
    UINT16,
    UINT32,
    UINT64,
    FLOAT,
    DOUBLE
};

union type_t {
    uint8_t*  uint8Array;
    uint16_t* uint16Array;
    uint32_t* uint32Array;
    uint64_t* uint64Array;
    float*    floatArray;
    double*   doubleArray;
};
    
double sum(void* voidArray, size_t arrayLength, int arrayType)
{
    union type_t arrays;

    switch(arrayType) {
        case UINT8:  arrays.uint8Array  = voidArray; break;
        case UINT16: arrays.uint16Array = voidArray; break;
        case UINT32: arrays.uint32Array = voidArray; break;
        case UINT64: arrays.uint64Array = voidArray; break;
        case FLOAT:  arrays.floatArray  = voidArray; break;
        case DOUBLE: arrays.doubleArray = voidArray; break;
    }

    int i;
    double result = 0;
    
    for(i = 0; i < arrayLength; i++){
        switch(arrayType) {
            case UINT8:  result += arrays.uint8Array [i]; break;
            case UINT16: result += arrays.uint16Array[i]; break;
            case UINT32: result += arrays.uint32Array[i]; break;
            case UINT64: result += arrays.uint64Array[i]; break;
            case FLOAT:  result += arrays.floatArray [i]; break;
            case DOUBLE: result += arrays.doubleArray[i]; break;
        }
    }
    return result;
}

int main()
{
    uint16_t array[] = {1,2,3,4};
    double result = sum(array, 4, UINT16);
    printf("Sum = %f\n", result);

    return 0;
}
#include <stdio.h>
#include <stdint.h>

struct player {
    char name[32];
    int score;
};

enum type_v {
    UINT8,
    UINT16,
    UINT32,
    UINT64,
    FLOAT,
    DOUBLE,
    PLAYER
};

union type_t {
    uint8_t*        uint8Array;
    uint16_t*       uint16Array;
    uint32_t*       uint32Array;
    uint64_t*       uint64Array;
    float*          floatArray;
    double*         doubleArray;
    struct player*  playerArray;
};
    
double sum(void* voidArray, size_t arrayLength, int arrayType)
{
    union type_t arrays;

    switch(arrayType) {
        case UINT8:  arrays.uint8Array  = voidArray; break;
        case UINT16: arrays.uint16Array = voidArray; break;
        case UINT32: arrays.uint32Array = voidArray; break;
        case UINT64: arrays.uint64Array = voidArray; break;
        case FLOAT:  arrays.floatArray  = voidArray; break;
        case DOUBLE: arrays.doubleArray = voidArray; break;
        case PLAYER: arrays.playerArray = voidArray; break;
    }

    int i;
    double result = 0;
    
    for(i = 0; i < arrayLength; i++){
        switch(arrayType) {
            case UINT8:  result += arrays.uint8Array [i];       break;
            case UINT16: result += arrays.uint16Array[i];       break;
            case UINT32: result += arrays.uint32Array[i];       break;
            case UINT64: result += arrays.uint64Array[i];       break;
            case FLOAT:  result += arrays.floatArray [i];       break;
            case DOUBLE: result += arrays.doubleArray[i];       break;
            case PLAYER: result += arrays.playerArray[i].score; break;
        }
    }
    return result;
}

int main()
{
    struct player array[] = {{"Bob",1},{"MEl",2},{"Jim",3},{"Ann",4}};
    double result = sum(array, 4, PLAYER);
    printf("Sum = %f\n", result);

    return 0;
}