提问人:QC4R 提问时间:11/15/2023 更新时间:11/16/2023 访问量:98
C - 如何创建处理数组中不同数据类型的单个函数
c - how to create a single function that handle different data type in an array
问:
我想创建一个函数,它可以修改静态数组的最后一个元素,但可以处理不同类型的数据(int16_t、uint16_t 和浮点数)
我已经设法使它适用于每种数据,但功能不同。我想设计一个可以处理每个函数的函数。
下面是浮点元素的代码片段。
void fifo_datas_update_float(float data_in, float *datas, uint8_t size)
{
datas[size-1] = data_in; //assign new value to last element
}
const uint8_t dtsize = 3;
static float datas_fake[dtsize] = {10,20,30};
float new_value = 40;
fifo_datas_update_float(new_value, datas_fake, dtsize);
任何帮助将不胜感激......
答:
1赞
ikegami
11/15/2023
#1
您可以使用以下方法:
void set( void *a, size_t i, void *val_ptr, size_t ele_size ) {
char *p = a;
memcpy( p + ( i * ele_size ), val_ptr, ele_size );
}
set( datas_fake, dtsize-1, &new_value, sizeof( *datas_fake ) );
但这并不能比直接打电话节省任何东西。memcpy
memcpy( datas_fake + dtsize-1, &new_value, sizeof( *datas_fake ) );
评论
0赞
booo
11/16/2023
我在 Debian 上使用 gcc12.2.0 时出现以下错误:错误:从“void*”到“char*”的转换无效 [-fpermissive] 17 |字符 *p = a;
0赞
pmg
11/16/2023
@QC4R尝试#ifdef __cplusplus
/ #error bad compiler
/ #endif
0赞
ikegami
11/16/2023
@QC4R 您似乎正在将代码编译为 C++,但问题被标记为 C。
1赞
pmg
11/16/2023
#2
正如some_programmer_dude在评论中所说,您可以使用(自 C 2011 起)如下所示。
请注意,您只能使用 1 个泛型关联,因此我将其中一个参数设为 a (void *)。
_Generic
#include <inttypes.h>
#include <stdio.h>
#define update_last(n, X, p) \
_Generic((X), \
float *: updatef, \
default: updatei16, \
uint16_t *: updateu16 \
)(n, X, p)
// src must have type (int16_t *)
void updatei16(size_t n, int16_t a[static n], void *src) {
a[n-1] = *(int16_t *)src;
}
// src must have type (uint16_t *)
void updateu16(size_t n, uint16_t a[static n], void *src) {
a[n-1] = *(uint16_t *)src;
}
// src must have type (float *)
void updatef(size_t n, float a[static n], void *src) {
a[n-1] = *(float *)src;
}
int main(void) {
float ff[1] = { 2023 }, fff = 3.1416F;
uint16_t uu[1] = { 2023 }, uuu = 42;
int16_t ii[1] = { 2023 }, iii = -1;
printf("%f, %"PRIu16", %"PRId16"\n", ff[0], uu[0], ii[0]);
update_last(1, ff, &fff);
update_last(1, uu, &uuu);
update_last(1, ii, &iii);
printf("%f, %"PRIu16", %"PRId16"\n", ff[0], uu[0], ii[0]);
return 0;
}
上面代码的输出是
2023.000000, 2023, 2023 3.141600, 42, -1
评论
0赞
pmg
11/16/2023
顺便说一句:通过添加适当的功能,您可以使用 、 或 或 、 ...update_last()
char
long double
struct whatever
0赞
booo
11/16/2023
谢谢,这正是我想要的。很抱歉让每个人都混淆了 c 和 c++ 混乱
0赞
Harith
11/16/2023
#3
要建立在@pmg的答案之上,您可以使用:
#define gen_update(_suffix, _type) \
void update_##_suffix(size_t n, _type a[static n], void *src) \
{ a[n-1] = *(_type *)src; }
gen_update(ld, long double)
gen_update(d, double)
gen_update(f, float)
gen_update(ull, unsigned long long)
gen_update(ll, long long)
gen_update(ul, unsigned long)
gen_update(l, long)
gen_update(u, unsigned)
gen_update(i, int)
...
// And so on.
以避免重复。
评论
union
_Generic
_Generic