我打算理解CI中function pointers
的工作是为一个函数编写了这个程序,该函数有一个函数指针disp_function
,希望使用指针打印任何类型数组的内容。 ptr
到预定目的地,但不起作用:
void show_array(void* ptr, void (*disp_function)(void*), int nr_elem) {
int i=0;
while(i<nr_elem) {
(*disp_function) (ptr);
ptr++;
i++;
}
}
以下是该程序的使用实例:
void show_movements(Movement* movs, int nr) {
void (*display_function) (void* ptr) = show_movement;
show_array(movs, display_function, nr);
}
void show_movement(void* ptr) {
Movement* ptr2 = NULL;
ptr2 = (Movement*) ptr;
printf("%d -> '%s'\n", ptr2->id, ptr2->title);
}
程序在最后一个函数中崩溃。具体如下:
我认为ptr++
导致崩溃,因为我正在递增void*
。我也尝试使用数组语法(*display_function) (ptr[i]);
但我总是收到错误invalid use of void expression
任何人都可以告诉我这个问题的确切原因是什么?
答案 0 :(得分:3)
当递增void*
指针时,C必须猜测您的数据大小是多少。它始终假设数据与char
的大小相同,也称为最小可分配单元(MAU)。您应该做的是传递数据大小并执行以下操作:
void show_array(void* ptr, void (*disp_function)(void*), int nr_elem, size_t data_size) {
int i=0;
while(i<nr_elem) {
(*disp_function) (ptr);
ptr += data_size;
i++;
}
}
您的数据大小应按如下方式传递:
void show_movements(Movement* movs, int nr) {
void (*display_function) (void* ptr) = show_movement;
show_array(movs, display_function, nr, sizeof(Movement) );
}
答案 1 :(得分:1)
使用typedef
声明函数指针类型
typedef void (*disp_function)(void*);
现在它是一个类型,它可以是函数参数的一部分。也无效*不能递增
void show_array(void* ptr, disp_function f, int nr_elem) {
int i=0;
while(i<nr_elem) {
f(ptr);
//ptr++; // void * cannot be incremented without casting to a concrete type
i++;
}
}
void show_movement(void* ptr) {
Movement* ptr2 = NULL;
ptr2 = (Movement*) ptr;
printf("%d -> '%s'\n", ptr2->id, ptr2->title);
}
只需将show_movement
传递给show_array
void show_movements(Movement* movs, int nr) {
show_array(movs, show_movement, nr);
}
答案 2 :(得分:1)
当您对它们执行指针算法和数组语法时,Void指针可能会非常棘手。您的问题的一个很好的答案在答案:Pointer arithmetic for void pointer in C
由于void指针被认为等同于字节指针以用于指针算术,因此您将增加1而不是类型的大小。