2011-07-27 45 views
3

我对单向链表,这是我不能在其他问题找到答案一个非常简单的问题。单链表 - Visual C

这是我的代码:

#include <stdio.h> 
#include <stdlib.h> 

void add(int data); 
void printList(); 

struct node 
{ 
    int data; 
    struct node * link; 
}; 

struct node * head = NULL; 

main() 
{ 
    char c; 

    while ((c = getchar()) != 'q') 
    { 
     if (c == 'a') 
     { 
      int temp; 

      printf("data: "); 
      scanf("%d", &temp); 

      add(temp); 
     } 

     if (c == 'p') 
      printList(); 
    } 
} 

void add(int data) 
{ 
    struct node * temp = (struct node *) malloc(sizeof(struct node)); 

    if (temp == NULL) 
     fprintf(stderr, "error"); 

    temp->link = head; 
    temp->data = data; 
    head = temp; 
} 

void printList() 
{ 
    struct node * temp = (struct node *) malloc(sizeof(struct node)); 

    if (temp == NULL) 
     fprintf(stderr, "error"); 

    temp = head; 

    while (temp != NULL) 
    { 
     printf("%d", temp->data); 
     temp = temp->link; 
    } 
} 

现在,我一直在告诉我,我需要创建一个功能或我的外接功能内的情况下,如果正在创建一个新的列表以不同方式做一些事情。换句话说,当列表是空的,并且第一个元素被添加到它时,它需要与填充列表正在接收前面的另一个节点时不同。我发现这样的代码在网上的一个例子:

# // Adding a Node at the Beginning of the List 
# 
# void addBeg(int num) 
# { 
# struct Node *temp; 
# 
# temp=(struct Node *)malloc(sizeof(struct Node)); 
# temp->Data = num; 
# 
# if (Head == NULL) 
# { 
#  //List is Empty 
#  Head=temp; 
#  Head->Next=NULL; 
# } 
# else 
# { 
#  temp->Next=Head; 
#  Head=temp; 
# } 
# } 

正如你会发现,如果列表为空,则头节点填充。

我的代码工作正常,但我想知道如果我俯瞰关于处理空头部形势东西。

非常感谢!

+4

您的add()函数可以正常工作,但如果malloc失败,它会发生故障。如果temp = NULL,你应该'返回'。你不需要打印新的节点,只需使用指向头部的指针就足够了。内存泄漏 –

+2

您的printList函数有一个错误:它malloc一个新的临时节点,然后立即用头指针覆盖malloc'd指针,从而泄漏分配的节点。在这种情况下分配是不必要的。 –

+0

啊!你是对的!谢谢! – seyelent

回答

6

没有什么根本性的错误你add()功能。 head == NULL不需要特殊处理的情况。

正如其他人所注意到的,因为你需要从功能的情况下malloc失败回到你的错误检查是不正确的。因为它代表你add()功能进行了尝试分配给*temptempNULL

你这样的特殊待遇表现出的代码是伪造的。当head == NULL时,该代码中的else子句可以很好地工作。

+1

有趣。谢谢!我觉得很奇怪,我是如何在学校单独教他们做的。好吧! – seyelent

+0

+1当malloc返回null它会转储核心 – Konstantin

+0

好吧,所以我理解它的方式,我的代码是好的。最好检查null的实例,否则,我的程序不应该产生任何意外的故障?再次感谢所有! – seyelent

1

如果您对头节点进行了不同的处理,您可以在每次使用头时检查头上的指针是否为空,也可以假定它不为空。

良好的举止假定你应该总是检查它,但如果你不检查并且不解引用空指针,那么你的代码无论如何都会工作。

0

如果考虑addBeg如果分支:

if (Head == NULL) 
{ 
    Head=temp; 
    Head->Next=NULL; 
} 
else 
{ 
    Head=temp; 
    temp->Next=Head; 
} 

你看,你要分配给temphead,然后设置next指针。 你的实现是,在另一方面:

temp->link = head; 
temp->data = data; 
head = temp; 

,如果你跳过data一部分(head = temp这是目前在这两种情况下),你会很容易地看到,这是等同于第一位的,因为

temp->link = head; 

是一样的:

if (Head == NULL) 
{ 
    Head->Next=NULL; 
} 
else 
{ 
    temp->Next=Head; 
} 
+3

当Head == NULL时,Head-> Next = NULL'肯定会使程序崩溃。 –

+0

@larsmans:我不好!你是对的,我编辑了我的答案,推理仍然存在...... – sergio

1

既然你将永远运行线(增加一个节点时)

head = temp; 

添加节点后,您的头节点中永远不会有NULL引用。这是因为您验证上面(temp!= null)temp不是空指针。

现在,当您搜索节点时,在您访问任何(不)指向的字段之前检查头节点是否为空是一个非常好的主意。也许这就是“特殊条件”中的含义,笔记与这种情况混在一起,通常不是必需的。

+0

那么......除非temp是'NULL'。 –

+1

在这种情况下,代码将退出上面的四行。编码(像国际象棋)要求你们都关注本地发生的事情以及可能影响本地事件的远距离事件。 –