[英]Returning data from void** array
Suppose we have the following: 假设我们有以下内容:
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];
}
}
}
Further suppose that fp_t
returns 0 if the two things compared are equal to each other (other return values for the function pointer are unimportant now). 进一步假设如果比较的两个事物彼此相等,则
fp_t
返回0(函数指针的其他返回值现在不重要)。 I'm also assuming, to make things easier, that the item in the second argument of find_item
will always be in the array. 我还假设,为了使事情更容易,
find_item
的第二个参数中的find_item
将始终在数组中。
I guess I'm having trouble understanding how void**
works. 我想我无法理解
void**
工作原理。 In the get_data
function, we're supplied as an argument a void*
pointer to an array cell, which is a void*
pointer to some data object. 在
get_data
函数中,我们作为参数提供了一个指向数组单元格的void*
指针,该数组单元格是指向某个数据对象的void*
指针。 So how do we get that data object? 那么我们如何获得该数据对象呢? I understand the user has to cast it for it to be useful, but I still don't know what I'm supposed to be returning.
我知道用户必须将其强制转换为有用,但我仍然不知道我应该返回什么。 I also know you can't dereference a
void*
, so doing something like return *item;
我也知道你不能取消引用空格
void*
,所以做一些像return *item;
(which in my mind seems like what we're trying to do- just get the void*
pointer at the array cell), compiles with warnings/errors. (在我看来,这似乎是我们想要做的 - 只是在数组单元格中获取
void*
指针),编译警告/错误。
I guess delete_element
carries the same type of confusion for me. 我想
delete_element
我带来同样的困惑。 We're supplied a void*
pointer item
, which points to a void*
pointer array cell that points to the actual data. 我们提供了一个
void*
指针item
,它指向一个指向实际数据的void*
指针数组单元格。 So we need to dereference the item somehow so that we can delete the array cell. 所以我们需要以某种方式取消引用该项目,以便我们可以删除该数组单元格。
Any ideas? 有任何想法吗?
It's easy to get confused by void *
and void **
. 很容易被
void *
和void **
弄糊涂了。 A void *
is a generic container for any pointer-to-object. void *
是任何指向对象的指针的通用容器。 Any object pointer can be converted to void *
and back again to the original value. 任何对象指针都可以转换为
void *
并再次返回原始值。 (Note that a void *
is not guaranteed to be able to hold a function pointer). (注意,
void *
不保证能够保存函数指针)。 It doesn't really matter what type of objects these functions are handling. 这些函数处理的对象类型并不重要。 They are storing and retrieving objects (that just happen to have the type
void *
). 它们存储和检索对象 (恰好有类型为
void *
)。
struct container { void** array; function_pointer_typedef fp_t; int length; };
Your array
member is simply a pointer to an array of objects. 您的
array
成员只是指向对象数组的指针。
void* get_data(const void* item){ return item; //unsure. also produced warning. }
I have no idea what this function is supposed to return, but the reason you're getting a warning from this is that you are removing a const
qualifier. 我不知道这个函数应该返回什么,但是你收到警告的原因是你要删除一个
const
限定符。 You are turning a (pointer to) read-only object into a writable object. 您正在将(指向)只读对象转换为可写对象。 This is not allowed in C. To get away with this, you have to cast away the
const
qualifier. 在C中不允许这样做。为了避免这种情况,你必须抛弃
const
限定符。 ( return (void *)item;
). (
return (void *)item;
)。
If item
really is a pointer to an array cell (converted to void *
), then you have to cast it to the original type before you dereference it to retrieve the object. 如果
item
确实是指向数组单元格的指针(转换为void *
),那么在取消引用它以检索对象之前,必须将其强制转换为原始类型。 ( return *(void **)item;
). (
return *(void **)item;
)。 But I really have no idea what this function is supposed to do. 但我真的不知道这个功能应该做什么。 Ask your teacher.
问你的老师。
void delete_element(container* c, void* item) { /* 1. delete the array element pointed at by "item" 2. reposition remaining array elements */ }
You're supposed to go through the array
of objects until you find one that compares equal to item
, remove it from the array by moving the following objects to fill that slot, and then adjust the length
. 你应该去通过
array
的对象,直到找到一个比较等于item
,通过移动下列对象,以填补该插槽从数组中删除它,然后调整length
。 The only thing you have to dereference is the array
pointer, not the stored objects. 您必须取消引用的唯一内容是
array
指针,而不是存储的对象。
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]; } } }
This function should probably return NULL
if item
is not found. 如果找不到
item
此函数应该返回NULL
。 Just return NULL;
只
return NULL;
right before the functions closing brace. 就在关闭括号的功能之前。
int*
is a pointer to int. int*
是指向int的指针。 Given int* x
pointing to valid memory for each of the following, *x
and x[0]
references the memory x points to; 给定
int* x
指向以下每个有效内存, *x
和x[0]
引用内存x指向; x+1
points to the location sizeof(int)
bytes after x, *(x+1)
or x[1]
references that location; x+1
指向x, *(x+1)
或x[1]
之后的位置sizeof(int)
字节引用该位置; x+2
points to the location sizeof(int)*2
bytes after x, and so on. x+2
指向位置sizeof(int)*2
x之后的sizeof(int)*2
个字节,依此类推。
void
is not type of object; void
不是对象的类型; so void*
is a pointer to memory but not a pointer to something. 所以
void*
是指向内存的指针,但不是指向某个东西的指针。 Given void* y
, *y
, y[0]
, y+1
, *(y+1)
, etc simply don't make sense. 给定
void* y
, *y
, y[0]
, y+1
, *(y+1)
等等根本没有意义。
void*
is a type of an object--it is a pointer to memory. void*
是一种对象 - 它是一个指向内存的指针。 Given void** z
pointing to valid memory for each of the following, *z
and z[0]
references the memory z points to; 给定
void** z
指向以下每一个的有效存储器, *z
和z[0]
引用存储器z指向; z+1
points to the location sizeof(void*)
bytes after z, and so on. z+1
指向z+1
的位置sizeof(void*)
字节,依此类推。
If it helps, pretend "void*" is spelled "pointer" (as if you are using typedef void* pointer
), and is on par with "int". 如果它有帮助,假装“void *”拼写为“指针”(就好像你使用的是
typedef void* pointer
),并且与“int”相同。 So, if I have int q and pointer p, I can't do *q
because q isn't a pointer to something, nor can I do *p
because p isn't a pointer to something (strictly this is true). 所以,如果我有int q和指针p,我不能做
*q
因为q不是指向某个东西的指针,也不能做*p
因为p不是指针的东西(严格来说这是真的)。 But you can assign int's to other int's, and assign pointer's to other pointers; 但是你可以将int分配给其他int,并将指针指定给其他指针; and you can allocate memory for
int*
just as you can allocate it for pointer*
, and dereference objects of type pointer* just as you can with int*. 您可以为
int*
分配内存,就像为pointer*
分配内存一样,并且可以像使用int *一样取消引用类型为pointer*
对象。
That's enough to answer your question, but to do what you want to do generally depends on a few implementation details. 这足以回答你的问题,但做你想做的事情一般取决于一些实现细节。 If you're going to store memory as arrays of
void*
's (aka, void**
's or "pointer*'s"), you will need to either require your user pass you a create function, or just allocate each element's memory themselves (or just handle it themselves, if you want to allow them to point to non-heap objects; it really depends on what you want to do; if you let them have items pointing to non-heap objects, though, you probably don't want to delete it). 如果你要将内存存储为
void*
的数组(aka, void**
或“pointer * s”),你需要要求你的用户传递一个create函数,或者只是分配每个元素的内存本身(或者只是自己处理它,如果你想让它们指向非堆对象;它实际上取决于你想要做什么;如果你让它们有指向非堆对象的项目,那么,你可能不想删除它)。 Your code could delete the items easily enough. 您的代码可以轻松删除项目。 How to remove items from this set is another implementation detail--depends on what you want to do.
如何从该集中删除项目是另一个实现细节 - 取决于您想要做什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.