如何解决C向量处理基于参数的不同数组类型
我正在研究C语言中的向量,即可动态调整大小的数组。我已经实现了一个处理char数组的对象。
但是,如果我想为不同类型的数组使用相同的功能(整数,长整型等),则我必须做完整个事情,并且要给它们使用不同的名称,以免发生串扰在同一个命名空间中。
我的问题是:根据传递给初始化器函数的某个参数,有没有办法处理int数组或char数组?
所以说我有一个结构向量,其成员是char指针。就目前而言,当我运行init函数时,它将为该char指针分配内存,以用作char数组。
我能否做到这一点,例如,根据传递给init的某个参数,它将为int数组而不是char数组分配内存?
我一直在考虑这个问题,这将涉及使用void指针并在很多地方进行转换。还有其他方法/最好的方法是什么?
解决方法
这不可能以非常整洁的方式完成,但是有可能。这是一个示例:
enum vec_type { CHAR,INT,DOUBLE };
struct vector {
enum vec_type vec_type;
void *data;
};
struct vector *vec_realloc(struct vector *vec,enum vec_type vec_type,size_t n)
{
size_t elsize;
switch(vec_type) {
case CHAR: elsize = sizeof(char); break;
case INT: elsize = sizeof(int); break;
case DOUBLE: elsize = sizeof(double); break;
}
struct vector *ret = realloc(vec,elsize * n);
return ret;
}
是的,我知道sizeof(char)
总是取值为1,但在这种情况下,我认为它看起来要好得多。
您可以使用类型通用宏来实现它:
简单的例子:
int* vec_alloc_int (size_t n)
{
return malloc(sizeof(int[n]));
}
char* vec_alloc_char (size_t n)
{
return malloc(sizeof(char[n]));
}
#define vec_alloc(type,n) _Generic( (type[]){0}[0],\
int: vec_alloc_int,\
char: vec_alloc_char)(n)
用法:
int* i = vec_alloc(int,5);
char* c = vec_alloc(char,5);
说明:
(type[]){0}[0]
技巧是创建一个包含1个项目的复合文字数组,然后取消引用该数组的第1个项目。这会将宏参数从类型转换为对象,然后可以传递给_Generic
。 _Generic
然后选择要使用的合适功能。
优点:
- 输入比void指针更安全的数字。
- 类型是在编译时而不是运行时解析的。
缺点:
- 必须列出所有受支持的类型,每种类型具有单独的功能。
- 不能使用恐龙编译器(C90 / C99)。
上面的邪恶的“ X宏”版本(我不会真正推荐)看起来像这样:
#include <stdio.h>
#include <stdlib.h>
#define SUPPORTED_TYPES(X) \
X(int) \
X(char) \
#define define_vec_alloc(type) \
type* vec_alloc_##type (size_t n) \
{ return malloc(sizeof(type[n])); }
SUPPORTED_TYPES(define_vec_alloc)
void* vec_alloc_dummy (size_t param){}
#define GENERIC_LIST(type) type: vec_alloc_##type,#define vec_alloc(type,n) _Generic((type[]){0}[0],SUPPORTED_TYPES(GENERIC_LIST) default: vec_alloc_dummy)(n)
int main(void)
{
int* i = vec_alloc(int,5);
char* c = vec_alloc(char,5);
}
此处的解释:https://stackoverflow.com/a/60454338/584518
此版本非常难以理解,但是避免了所有形式的代码重复,这是它唯一的好处。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。