Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 从void**数组返回数据_C_Arrays_Pointers - Fatal编程技术网

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

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];
      }
   }
}