链表:用函数初始化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 只会让读者感到困惑。

您可以改用 pushpush_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' );