[英]Can we use void pointer of arrays
I am just working on a liberty functions in which we define our own datatypes for student and book I have to write a code which finds student by id and book by id these are the two functions. 我只是在研究一个自由函数,在其中我们为学生和书定义了自己的数据类型。我必须编写一个代码,通过id和id来查找学生,这是两个函数。 In this functions the pointers which I pass are different but the logic is the same so I got a though that why can't we write one function and pass which thing we want.
在这个函数中,我传递的指针是不同的,但是逻辑是相同的,所以我明白了为什么我们不能编写一个函数并传递想要的东西。 I mean when we pass the student list it will return the index of student when we pass the book list it will return the book index of the book.
我的意思是,当我们通过学生名单时,它将返回学生的索引;当我们通过书目列表时,它将返回该书的书籍索引。 Can we use void pointers for that???
我们可以为此使用空指针吗??? Thank you everyone!!!
谢谢大家!!!
int findBookId(Book* booklist,int* bcount,unsigned int* tbid)
{
int i;
for (i=0; i<*bcount; i++)
{
if (booklist[i].id==*tbid)
{
return i;
}
}
return NOT_FOUND;
}
int findStuId(Student* stulist,int* scount,unsigned int* tsid)
{
int i;
for (i=0; i<*scount; i++)
{
if (stulist[i].id==*tsid)
{
return i;
}
}
return NOT_FOUND;
}
Assuming you have a student
structure: 假设您有一个
student
结构:
struct student {
int id;
char name[20];
};
You can imitate qsort()
function, to design a parameter to receive a callback function and to receive the size and size of each element if you'd like use void *
. 您可以模仿
qsort()
函数,设计一个参数以接收回调函数,并在需要使用void *
接收每个元素的大小和大小。
int find_ele(void *base, size_t num, size_t width,
int (*equal)(const void *, const void *),
void *param)
{
int i;
for (i = 0; i < num; ++i) {
if (equal((char *) base + i * width, param)) {
return i;
}
}
return -1;
}
Then, define a "tester": 然后,定义一个“测试器”:
int student_tester(const void *p1, const void *p2)
{
struct student *sp = (struct student *) p1;
int id = *(int *) p2;
return sp->id == id;
}
In main()
function: 在
main()
函数中:
int main(void)
{
struct student student_list[] = {
0, "A",
1, "B",
2, "C"
};
int id = 2;
int index = find_ele(student_list, sizeof student_list,
sizeof(struct student), student_tester, &id);
if (index != -1) {
printf("find_ele(id=2) = student_list[%d]; name = %s. \n",
index, student_list[index].name);
} else {
printf("Not found. \n");
}
return 0;
}
This is a bit complicated. 这有点复杂。 You can create macros to simplify it if you don't care.
如果您不在意,可以创建宏来简化它。
Rename find_ele
to _find_ele
, and create a macro: 将
find_ele
重命名为_find_ele
,然后创建一个宏:
#define find_ele(base, num, compare, param) _find_ele(base, \
num / sizeof base[0], \
sizeof base[0], \
compare, param)
And create another macro to define a "tester": 并创建另一个宏来定义“测试器”:
#define define_tester(name, type, type_to_find, code) \
int name(const void *_p, const void *param) { \
type *p = (type *) _p; \
type_to_find value = *(type_to_find *) param; \
return (code); \
}
Now you can define a "tester" like this: 现在您可以定义一个“测试器”,如下所示:
define_tester(student_tester, struct student, int,
p->id == value);
Complete code: 完整的代码:
#include <stdio.h>
int _find_ele(void *base, size_t num, size_t width,
int (*equal)(const void *, const void *),
void *param)
{
int i;
for (i = 0; i < num; ++i) {
if (equal((char *) base + i * width, param)) {
return i;
}
}
return -1;
}
#define find_ele(base, num, compare, param) _find_ele(base, \
num / sizeof base[0], \
sizeof base[0], \
compare, param)
#define define_tester(name, type, type_to_find, code) \
int name(const void *_p, const void *param) { \
type *p = (type *) _p; \
type_to_find value = *(type_to_find *) param; \
return (code); \
}
struct student {
int id;
char name[20];
};
define_tester(student_tester, struct student, int,
p->id == value);
int main(void)
{
struct student student_list[] = {
0, "A",
1, "B",
2, "C"
};
int id = 2;
int index = find_ele(student_list, sizeof student_list, student_tester, &id);
if (index != -1) {
printf("find_ele(id=2) = student_list[%d]; name = %s. \n",
index, student_list[index].name);
} else {
printf("Not found. \n");
}
return 0;
}
是的,如果您试图存储数组的地址,则可以使用void指针。您的数组可能包含整数类型或其他存储的数据类型,这并不重要,但是在取消引用void指针时进行正确的类型转换很重要。
Yes you can use void*
, but while dereferencing you should know the exact type
of the pointer. 是的,您可以使用
void*
,但是在取消引用时,您应该知道指针的确切type
。
So, when you can your function, add another parameter: 因此,当您可以使用函数时,请添加另一个参数:
type = 0 for Books
= 1 for students
And then your function becomes: 然后您的函数变为:
int findId(void* list,int* count,unsigned int* tbid, int type)
{
Book* booklist=NULL;
Student* stulist=NULL;
int i;
if(type===0)
booklist = (Book*) list;
else if(type==1)
stulist = (Student*) list;
else
// Handle this undefined case
// And now use the same type variable to decide which pointer to use to match the values
. . . .
}
I don't think you can use void*
in these functions. 我认为您不能在这些函数中使用
void*
。
If you changed your functions to one and created something like: 如果将功能更改为一个,并创建如下内容:
int findObjId(void* objlist,int* count, unsigned int* objid)
{
int i;
for (i=0; i<*scount; i++)
{
if (objlist[i].id==*objid)
{
return i;
}
}
return NOT_FOUND;
}
you won't be able to extract the data from objlist
. 您将无法从
objlist
提取数据。 Neither *objlist
, nor objlist[i]
can be dereferenced to evaluate to an object. *objlist
和objlist[i]
都objlist[i]
引用来评估对象。 The compiler will definitely stop you from using any such statement. 编译器肯定会阻止您使用任何此类语句。
If you have the option, switch to C++. 如果可以选择,请切换到C ++。 Using templates, you can accomplish your goal without breaking a sweat.
使用模板,您可以不费吹灰之力即可实现目标。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.