C 从void**数组返回数据
假设我们有以下情况:C 从void**数组返回数据,c,arrays,pointers,C,Arrays,Pointers,假设我们有以下情况: struct container { void** array; function_pointer_typedef fp_t; int length; }; void* get_data(const void* item){ return item; //unsure. also produced warning. } void delete_element(container* c, void* item) { /* 1. delete
struct container
{
void** array;
function_pointer_typedef fp_t;
int length;
};
void* get_data(const void* item){
return item; //unsure. also produced warning.
}
void delete_element(container* c, void* item)
{
/* 1. delete the array element pointed at by "item"
2. reposition remaining array elements
*/
}
void* find_item(container* c, void* item)
{
int i;
for(i = 0; i < c->length; i++){
if(c->fp_t(item, c->array[i]) == 0){
return c->array[i];
}
}
}
struct容器
{
空**数组;
函数\u指针\u类型定义fp\t;
整数长度;
};
void*获取数据(const void*项){
返回项;//不确定。还生成了警告。
}
void delete_元素(容器*c,void*item)
{
/*1.删除“item”指向的数组元素
2.重新定位剩余的数组元素
*/
}
作废*查找物品(容器*c,作废*物品)
{
int i;
对于(i=0;ilength;i++){
如果(c->fp_t(项,c->数组[i])==0){
返回c->array[i];
}
}
}
进一步假设fp_t
如果所比较的两个对象彼此相等,则返回0(函数指针的其他返回值现在不重要)。为了使事情更简单,我还假设find\u item
的第二个参数中的项始终在数组中
我想我很难理解void**
是如何工作的。在get_data
函数中,我们作为参数提供了指向数组单元格的void*
指针,它是指向某个数据对象的void*
指针。那么我们如何获得数据对象呢?我知道用户必须使用它才能使其有用,但我仍然不知道应该返回什么。我也知道你不能取消引用一个void*
,所以做一些类似return*的事情
(在我看来,这就像我们正在尝试做的——只需将void*
指针指向数组单元格),编译时会出现警告/错误
我猜delete_元素
对我来说也有同样的困惑。我们提供了一个void*
指针项
,它指向指向实际数据的void*
指针数组单元格。因此,我们需要以某种方式取消对该项的引用,以便删除该数组单元格
有什么想法吗?很容易被
void*
和void**
弄糊涂。void*
是任何指向对象的指针的通用容器。任何对象指针都可以转换为void*
,然后再转换回原始值。(请注意,void*
不能保证能够保存函数指针)。这些函数处理的对象类型并不重要。它们正在存储和检索对象(恰好具有类型void*
)
您的数组
成员只是指向对象数组的指针
我不知道这个函数应该返回什么,但是您从中得到警告的原因是您正在删除一个
const
限定符。您正在将(指向的)只读对象变为可写对象。这在C语言中是不允许的。为了避免这种情况,您必须抛弃const
限定符。(返回(void*)项;
)
如果item
实际上是指向数组单元格的指针(转换为void*
),则必须将其转换为原始类型,然后才能取消引用以检索对象。(返回*(void**)项;
)。但是我真的不知道这个函数应该做什么。问问你的老师
您应该遍历对象的
数组
,直到找到一个与项
比较相等的对象,通过移动以下对象以填充该插槽将其从数组中移除,然后调整长度
。唯一需要取消引用的是数组
指针,而不是存储的对象
void*find_项目(容器*c,void*item)
{
int i;
对于(i=0;ilength;i++){
如果(c->fp_t(项,c->数组[i])==0){
返回c->array[i];
}
}
}
如果未找到
项
,此函数可能会返回NULL
。只需返回NULL函数右括号前面的code>。int*
是指向int的指针。给定int*x
指向以下各项的有效内存,*x
和x[0]
引用x指向的内存x+1
指向x之后的位置sizeof(int)
字节,*(x+1)
或x[1]
引用该位置x+2
指向x后面的位置sizeof(int)*2
字节,依此类推
void
不是对象的类型;所以void*
是指向内存的指针,但不是指向某个东西的指针。给定的void*y
,*y
,y[0]
,y+1
,*(y+1)
,等等根本没有意义
void*
是一种对象类型——它是指向内存的指针。给定指向以下各项的有效内存的void**z
,*z
和z[0]
引用z指向的内存z+1
指向z后的位置sizeof(void*)
字节,依此类推
如果它有帮助,假装“空洞*”拼写为“指针”(就像你使用的是<代码> TyBuff.Vule*指针< /C> >),并且与“int”相同。所以,如果我有int q和指针p,我不能做
*q
,因为q不是指向某个对象的指针,我也不能做*p
,因为p不是指向某个对象的指针(严格来说,这是真的)。但您可以将int分配给其他int,并将指针分配给其他指针;您可以为int*
分配内存,就像为pointer*
分配内存一样,也可以像使用int*一样取消对pointer*类型对象的引用
这就足够回答您的问题了,但要做您想做的事情通常取决于一些实现细节。如果要将内存存储为void*
数组(也称为void**
或“指针*”),则需要用户向您传递一个create函数,或者只分配每个元素的内存本身(如果您想让它们指向非堆对象,也可以自己处理;这实际上取决于您想要什么
struct container
{
void** array;
function_pointer_typedef fp_t;
int length;
};
void* get_data(const void* item){
return item; //unsure. also produced warning.
}
void delete_element(container* c, void* item)
{
/* 1. delete the array element pointed at by "item"
2. reposition remaining array elements
*/
}
void* find_item(container* c, void* item)
{
int i;
for(i = 0; i < c->length; i++){
if(c->fp_t(item, c->array[i]) == 0){
return c->array[i];
}
}
}