【问题标题】:Linked list: Initialize Head with function?链表:用函数初始化 Head?
【发布时间】:2018-03-23 16:48:23
【问题描述】:

我是一名专业的 C# 程序员,但正在尝试重新学习 C。我一直在用 C 编写一个简单的链表。当在 main() 中定义头节点时,我已经让它工作正常。但现在我想尝试在函数“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。

如何做到这一点?

【问题讨论】:

  • 你必须传递head的地址,(例如struct node **head)和initializeHead(&head, 'a');
  • 为什么要 initializeHead 是一个 void 函数?将其结果作为返回值返回似乎更合乎逻辑。
  • @Nick Lordi “我是一名专业的 C# 程序员” - 我无法用言语表达我的惊讶。:)
  • 有没有人注意到 C 中没有方法?
  • void f(int i) {i = 6;} - 当我运行int i = 5; f(i); 时我还是 5?

标签: c linked-list singly-linked-list


【解决方案1】:

术语方法不是 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';
    //...

也就是说,函数参数是它的局部变量,由用作参数的表达式初始化。因此,参数的任何更改都不会影响原始参数。正如上面提到的,如果你想改变一个原始对象,你必须通过引用间接地通过指针传递它。

此外,当程序不再使用列表时,您应该释放列表分配的所有内存以避免内存泄漏。

函数不应发出消息。最好是返回成功或失败的代码。

例如,在单链表中推送值的函数可以如下所示

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' );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-19
    • 1970-01-01
    相关资源
    最近更新 更多