C 使用带有空指针参数的函数
我是一个C初学者,正在试验链表,我发现了一个Github repo。create函数的编写方式如下:C 使用带有空指针参数的函数,c,void-pointers,C,Void Pointers,我是一个C初学者,正在试验链表,我发现了一个Github repo。create函数的编写方式如下: Node* ListCreate(void* data) { Node *head = malloc(sizeof(Node)); if ( head != NULL) { head->next = NULL; head->data = data; } return head; } 我可以通过将void*更改为int然
Node* ListCreate(void* data) {
Node *head = malloc(sizeof(Node));
if ( head != NULL) {
head->next = NULL;
head->data = data;
}
return head;
}
我可以通过将void*
更改为int
然后在main
中执行以下操作来使用它:
Node *root = ListCreate(5);
但是我读了一些关于空指针的文章,它们看起来可以像C++模板一样使用泛型类型,如果我能弄清楚它们是如何工作的话,这将是很有用的。我尝试了几种方法,最接近于让它工作的方法是没有错误,但有一个警告:
将'int'传递给'void*'类型的参数的整数到指针转换不兼容。
我在这里漏了一步吗?我首先觉得应该在函数定义中添加一些内容,但我假设编写它的人知道他们在做什么,而我只是没有在
main
中正确使用它。那么,有没有一种不同的方法可以将参数传递给这个函数呢?我认为需要对数字文本进行包装(或强制转换)。像这样:
void *BOX_VAR;//Not require if use GCC extension
#define BOX(type, value) ((*(type *)(BOX_VAR=malloc(sizeof(type))) = value), BOX_VAR)
#define UNBOX(type, value) (*(type *)(value))
Node *list = ListCreate(BOX(int, 5));
int v = UNBOX(int, list->data);
printf("%d\n", v);
正如其他人在评论中提到的,更适合为不同类型创建不同的列表 但是,如果要使用相同的函数定义,那么use可以将指针传递给数据(
int
或char
),并将它们转换为void*
/* main: start */
int main(void)
{
Node *list_head; /* Points to first element in list */
Node *node_tmp; /* Just a temporary pointer */
int *pint;
char *pchar;
/* create an empty list */
list_head = NULL;
/* Note that there is no error checking done for
* malloc, which is not good
*/
/* Create a node which points to int */
pint = malloc(sizeof(int));
*pint = 10;
node_tmp = ListCreate((void *) pint);
/* Add this node to list */
list_head = add(node_tmp, list_head);
/* Create a node which points to char */
pchar = malloc(sizeof(char));
*pchar = 'c';
node_tmp = ListCreate((void *) pchar);
/* Add this node to list */
list_head = add(node_tmp, list_head);
/* print total number of nodes in list */
print_tot_nodes(list_head);
return 0;
}
添加和打印节点的代码是为了简洁
请注意,如果数据
指向不同的数据类型,则像打印到节点
或添加
这样的函数不会有太多问题。但是如果您需要实现像Node*minimest(Node*head)
这样的函数,该函数返回指向具有最小元素的节点的指针,那么它可能会变得复杂
因此,对于不同的类型使用不同的列表更容易。但是,如果需要使用与原始帖子中相同的函数定义,您可以将指向某个数据类型的实际指针转换为
void*
当单个函数要处理不同类型的数据时(特别是当向这些不同类型的数据传递指针是有意义的时候),您可能会使用void指针,但当它要处理单个类型时,您通常会尝试避免这种情况。请注意,像qsort()
或bsearch()
这样的函数传递空指针-因此,如果您使用这些函数,您将拥有接受空指针但将传递的指针转换为正确(预期)类型的函数。如果没有显式强制转换,则无法从整数类型转换为指针;您根本无法从浮点类型转换。我尝试将其转换为使链接列表的数据可以设置为int、float或chars。在C中这比C++更难吗?列表中的数据类型是什么?您是在存储int
值还是int*
值?处理int*
在列表代码中很容易,但在使用列表代码的代码中就更难了-您必须为指向的每个指针都有一个单独的int
变量,这样您就可以将这些变量存储在列表中(因为您既有指针又有它指向的值,所以浪费了空间)。与float
相同。当你说char
,你是指单个字符(硬)还是字符串(akachar*
,相对容易)?有多种方法来实现同质性,但一种是针对不同的成员类型使用不同的列表类型。您只需根据下面的void*
实现它们。您需要考虑的一个问题是“哪些操作适用于您的列表”。创建列表、向列表中添加项目、从列表中删除项目、销毁列表——这些都很简单,而且大多没有争议(不过您需要考虑谁管理数据内存以避免泄漏)。如果您想在列表中查找值,或打印列表,或对列表中的每个项目应用函数,您必须更仔细地思考。通常,跑步前步行更容易:D