gpt4 book ai didi

c - 如何编写一个从未知类型返回数值数组总和的函数?

转载 作者:太空宇宙 更新时间:2023-11-04 08:02:00 25 4
gpt4 key购买 nike

我需要编写一个函数来汇总一个我不知道其类型的数值数组。该函数可以接收数组的大小和每个变量的大小。有人告诉我应该使用 void 指针,但我不知道该怎么做。顺便说一句,我不能使用宏。谢谢!

最佳答案

老实说,整个练习听起来很愚蠢。

您需要使用一个接口(interface)与 qsort() 大致相似的函数:

void calculate_sum(const void  *ptr,
const size_t size,
const size_t num,
void *sum,
void (*sum_func)(void *, const void *))
{
size_t i;
for (i = 0; i < num; i++)
sum_func(sum, (void *)((char *)ptr + size * i));
}

调用者仍然需要每个类型的求和函数,比方说

void sum_int(void *acc, const void *val)
{
*(int *)acc += *(const int *)val;
}

void sum_float(void *acc, const void *val)
{
*(float *)acc += *(const float *)val;
}

假设调用者有几个数组,比如说

float  fdata[50];
double ddata[40];

要计算它们的总和,需要

float  fsum;
double dsum;

fsum = 0.0f;
calculate_sum(fdata, sizeof fdata[0], 50, &fsum, sum_float);

dsum = 0.0;
calculate_sum(ddata, sizeof ddata[0], 40, &dsum, sum_double);

该接口(interface)适用于像 qsort() 这样的事情——尽管即使是 qsort() 也会受益于调用者能够传递第三个参数,一个 void *,传递给比较函数。在我看来,排序练习对于这种接口(interface)非常有效,尤其是在与某种小型 struct 一起使用时。

在这里,我认为练习将学习者引向了错误的方向:这不是算术运算的正确接口(interface)。它生成企业代码,过于复杂和缓慢,专为工作安全而设计;不可读、不可维护、好的代码。

在我看来,算术运算,例如求和,需要专用函数。但这并不意味着您必须复制粘贴大量代码;我们可以在这里使用预处理器来发挥我们的优势。

让我们看看如何使用 C11 _Generic 语义实现求和:

#include <stdlib.h>  /* For  size_t  type */

#define DEFINE_SUM_FUNC(type, funcname) \
type funcname (const type *data, size_t count) \
{ \
const type *ends = data + count; \
type sum = 0; \
while (data < ends) \
sum += *(data++); \
return sum; \
}

DEFINE_SUM_FUNC(float, float_sum);
DEFINE_SUM_FUNC(double, double_sum);
DEFINE_SUM_FUNC(short, short_sum);
DEFINE_SUM_FUNC(int, int_sum);
DEFINE_SUM_FUNC(long, long_sum);

#define array_sum(array, count) _Generic((array)[0], \
float: float_sum((const float *)(array), (size_t)(count)), \
double: double_sum((const double *)(array), (size_t)(count)), \
short: short_sum((const short *)(array), (size_t)(count)), \
int: int_sum((const int *)(array), (size_t)(count)), \
long: long_sum((const long *)(array), (size_t)(count)) )

DEFINE_SUM_FUNC(type, funcname) 宏的计算结果为函数定义。该函数计算数组元素的总和。 (此实现使用指针方法。)

现在,如果你有两个和以前一样的数组,float fdata[50];double ddata[40];,你可以调用

fsum = array_sum(fdata, 50);
dsum = array_sum(ddata, 40);

请注意,array_sum() 适用于数组和指针。也就是说,如果您有 float *fdata;const double *ddata;,以上两行就可以正常工作。

在 C11 之前的代码中,您可以删除 array_sum() 宏,然后自己调用特定于类型的函数:

fsum = float_sum(fdata, 50);
dsum = double_sum(ddata, 40);

(GCC 确实提供了一个扩展,__builtin_types_compatible_p(),即使没有 _Generic(),也可以使用它来构造 array_sum() 宏.)

关于c - 如何编写一个从未知类型返回数值数组总和的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45772357/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com