链表:用函数初始化Head?
Linked list: Initialize Head with function?
我是一名专业的 C# 程序员,但正在尝试重新学习 C。我一直在用 C 编写一个简单的链表。当在 main() 中定义头节点时,我已经让它工作正常。但现在我想尝试在函数 "initializeHead()".
中初始化头节点
这是节点定义和 Main() 函数:
struct node
{
char value;
struct node * next;
};
int main()
{
struct node * head = NULL;
initializeHead(head, 'a');
return 0;
}
初始化头节点的函数:
void initializeHead(struct node * head, char vertexCategory)
{
if (head == NULL)
{
head = malloc(sizeof(struct node));
head->value = vertexCategory;
head->next = NULL;
}
else
{
printf("\nError: Head already initialized!");
}
}
...调用initializeHead()后,好像什么都没发生,因为head还是NULL
如何实现?
术语方法不是 C 和 C++ 中的规范术语。请改用术语函数(或 C++ 中的成员函数)。
根据 C 标准,不带参数的函数 main 应声明为
int main( void )
事实上head已经在声明中初始化了
struct node * head = NULL;
例如,您可以使用比较来检查列表是否为空
if ( head == NULL ) { /* ...*/ }
您尝试使用该函数执行的操作是将一个值附加到列表。所以函数名称 initializeHead
只会让读者感到困惑。
您可以改用 push
、push_front
或其他合适的名称。
函数应在使用前声明。
参数在 C 中通过值传递给函数。术语通过引用传递在 C 中意味着传递指向原始对象的指针。否则函数将处理原始对象的副本。
您可以想象您的函数定义及其调用方式如下(为清楚起见,我重命名了参数名称)
initializeHead(head, 'a');
//...
void initializeHead( /*struct node * list, char vertexCategory */ )
{
struct node *list = head;
char vertexCategory = 'a';
//...
即函数参数是它的局部变量,由用作参数的表达式初始化。因此参数的任何更改都不会影响原始参数。正如上面提到的,如果你想改变一个原始对象,你必须通过间接通过指针的引用传递它。
此外,当程序中不再使用列表时,您应该释放列表分配的所有内存以避免内存泄漏。
函数不应发出消息。如果是returns成功或失败的代码就更好了。
例如,在单链表中压入一个值的函数可以如下所示
int push_front( struct node **head, char value )
{
struct node *new_node = malloc( sizeof( struct node ) );
int success = new_node != NULL;
if ( success )
{
new_node->value = value;
new_node->next = *head;
*head = new_node;
}
return success;
}
注意第一个参数声明struct node **head
。由于列表的原始头部必须在函数中更改,因此它通过引用传递给函数,即使用指向它的指针。
函数可以这样调用
push_front( &head, 'a' );
我是一名专业的 C# 程序员,但正在尝试重新学习 C。我一直在用 C 编写一个简单的链表。当在 main() 中定义头节点时,我已经让它工作正常。但现在我想尝试在函数 "initializeHead()".
中初始化头节点这是节点定义和 Main() 函数:
struct node
{
char value;
struct node * next;
};
int main()
{
struct node * head = NULL;
initializeHead(head, 'a');
return 0;
}
初始化头节点的函数:
void initializeHead(struct node * head, char vertexCategory)
{
if (head == NULL)
{
head = malloc(sizeof(struct node));
head->value = vertexCategory;
head->next = NULL;
}
else
{
printf("\nError: Head already initialized!");
}
}
...调用initializeHead()后,好像什么都没发生,因为head还是NULL
如何实现?
术语方法不是 C 和 C++ 中的规范术语。请改用术语函数(或 C++ 中的成员函数)。
根据 C 标准,不带参数的函数 main 应声明为
int main( void )
事实上head已经在声明中初始化了
struct node * head = NULL;
例如,您可以使用比较来检查列表是否为空
if ( head == NULL ) { /* ...*/ }
您尝试使用该函数执行的操作是将一个值附加到列表。所以函数名称 initializeHead
只会让读者感到困惑。
您可以改用 push
、push_front
或其他合适的名称。
函数应在使用前声明。
参数在 C 中通过值传递给函数。术语通过引用传递在 C 中意味着传递指向原始对象的指针。否则函数将处理原始对象的副本。
您可以想象您的函数定义及其调用方式如下(为清楚起见,我重命名了参数名称)
initializeHead(head, 'a');
//...
void initializeHead( /*struct node * list, char vertexCategory */ )
{
struct node *list = head;
char vertexCategory = 'a';
//...
即函数参数是它的局部变量,由用作参数的表达式初始化。因此参数的任何更改都不会影响原始参数。正如上面提到的,如果你想改变一个原始对象,你必须通过间接通过指针的引用传递它。
此外,当程序中不再使用列表时,您应该释放列表分配的所有内存以避免内存泄漏。
函数不应发出消息。如果是returns成功或失败的代码就更好了。
例如,在单链表中压入一个值的函数可以如下所示
int push_front( struct node **head, char value )
{
struct node *new_node = malloc( sizeof( struct node ) );
int success = new_node != NULL;
if ( success )
{
new_node->value = value;
new_node->next = *head;
*head = new_node;
}
return success;
}
注意第一个参数声明struct node **head
。由于列表的原始头部必须在函数中更改,因此它通过引用传递给函数,即使用指向它的指针。
函数可以这样调用
push_front( &head, 'a' );