我试图更多地了解C及其神秘的隐藏能力,我试图制作一个包含指向void的指针的示例结构,用作数组 . 编辑:重要说明:这是原始C代码 .
假设我有这个结构 .
typedef struct mystruct {
unsigned char foo;
unsigned int max;
enum data_t type;
void* data;
} mystruct;
我希望数据保持无符号字符,无符号短整数和无符号长整数的最大值,data_t枚举包含这3种情况的值 .
enum Grid_t {gi8, gi16, gi32}; //For 8, 16 and 32 bit uints.
然后我有这个函数初始化并分配这个结构之一,并且应该返回一个指向新结构的指针 .
mystruct* new(unsigned char foo, unsigned int bar, long value) {
mystruct* new;
new = malloc(sizeof(mystruct)); //Allocate space for the struct.
assert(new != NULL);
new->foo = foo;
new->max = bar;
int i;
switch(type){
case gi8: default:
new->data = (unsigned char *)calloc(new->max, sizeof(unsigned char));
assert(new->data != NULL);
for(i = 0; i < new->max; i++){
*((unsigned char*)new->data + i) = (unsigned char)value;
//Can I do anything with the format new->data[n]? I can't seem
//to use the [] shortcut to point to members in this case!
}
break;
}
return new;
}
编译器不返回任何警告,但我对此方法不太确定 . 这是使用指针的合法方式吗?
是否有更好的方式©?
我错过了调用它 . 喜欢mystruct * P; P = new(0,50,1024);
工会很有意思但不是我想要的 . 因为无论如何我都必须单独处理每一个具体案件,铸造似乎和工会一样好 . 我特别希望拥有比32位数组大得多的8位数组,因此联合似乎没有帮助 . 为此,我会把它变成一长串:P
4 回答
type
应该是函数的参数吗? (不要命名此函数或任何变量new
或任何试图使用它的C程序员将追捕你)如果要使用数组索引,可以使用如下临时指针:
我真的没有看到你的方法有问题 . 如果你期望一个特定的大小(我认为你给你的名字
gi8
等),我建议包括stdint.h
并使用typedefuint8_t
,uint16_t
和uint32_t
.不,你不能取消引用
void*
指针,它被C语言标准禁止 . 在执行此操作之前,必须将其强制转换为具体的指针类型 .作为替代方案,根据您的需要,您还可以在结构中使用
union
而不是void*
:在任何给定时间,
data.uc
,data.us
或data.ui
中只有一个有效,因为它们都占用内存中的相同空间 . 然后,您可以使用适当的成员来获取数据数组,而无需从void*
强制转换 .关于什么
这样,根本不需要施放 . 只需使用
data_t
来确定您要访问的指针 .指针仅仅是存储空间中的地址 . 您可以根据需要选择解释它 . 有关如何以多种方式解释相同内存位置的详细信息,请查看
union
.指针类型之间的转换在C和C中很常见,并且使用void *意味着您不希望用户意外取消引用(取消引用void *将导致错误,但在转换为int *时取消引用相同的指针)