我是一名专业的C#程序员,但是正在尝试重新学习C.我一直在用C编写一个简单的链表。当在main()中定义head-node时,我已经使它工作正常。但现在我想尝试在函数中初始化头节点" initializeHead()"。
这是Node定义和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。
如何实现这一目标?
答案 0 :(得分:2)
术语方法不是C和C ++中的标准术语。请改用术语“函数”(或C ++中的成员函数)。
根据C标准,没有参数的函数main应声明为
int main( void )
事实上,头部已在声明中初始化
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';
//...
那就是函数参数是它的局部变量,它们由用作参数的表达式初始化。因此,参数的任何更改都不会影响原始参数。如上所述,如果你想要改变原始对象,你必须通过引用间接通过指针传递它。
此外,当程序中不再使用列表以逃避内存泄漏时,您应该通过列表释放所有已分配的内存。
该功能不应发出消息。如果它返回成功或失败的代码会更好。
例如,在单链表中推送值的函数可以采用以下方式
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' );