C

时间:2018-07-07 17:14:24

标签: c linked-list nodes

如果我在while条件下进行了修改并将temp != NULL更改为temp->next = NULL,则此功能不起作用。为什么会这样?

void Print() {
     printf("\n");
     printf("The Library data is as follows: \n");
     struct Node *temp = head; // where head is a global variable
     printf("\n");
     while (temp != NULL) {
         printf("%25s", temp->name);
         printf("%25s", temp->author);
         temp = temp->next;
         printf("\n");
     }
}

另外,如果我在while块下将else循环条件从temp1->next = NULL修改为temp1 != NULL,则此方法无效。为什么会这样?

void Insert(char q[50], char r[50]) {
    struct Node *temp = (struct Node*)malloc(sizeof(struct Node));
    temp->next = NULL; // Since we are adding a node to the end, we are linking it to NULL.
    strcpy(temp->name, q); // copying the contents of "q" to "temp->name"
    strcpy(temp->author, r); // same
    if (head == NULL) {
        head = temp;
    } else {
        struct Node *temp1 = head;
        while (temp1->next != NULL)
            temp1 = temp1->next;
        temp1->next = temp;
    }
}

4 个答案:

答案 0 :(得分:2)

Print函数中,您希望枚举列表中的所有节点,并且希望优雅地处理一个空列表(head = NULL)。因此,循环迭代while (temp == NULL),而temp跳到带有temp = temp->next;的下一个节点。

Insert函数中,分配并初始化了一个新节点。空列表(head == NULL)有一种特殊情况,其中head仅接收指向新节点的指针。相反,如果列表不为空,则要通过设置其next指针指向新节点来找到列表的 last 节点以追加新节点。循环从第一个节点循环到最后一个节点,如果该节点不是最后一个节点,则测试temp1->next != NULL成功。因此,temp指向while循环之后的最后一个节点,新节点可以简单地附加temp1->next = temp;

请注意以下几点:

  • 原型void Insert(char q[50], char r[50])应该改进为int Insert(const char *name, const char *author),因为:
    • 作为参数传递的字符串不会被函数修改
    • 参数名称会更清楚
    • 指定的数组大小将被编译器忽略,并且看起来与实际的结构成员不一致。
    • 该功能可能会失败。它至少应该返回一个成功指标。
  • 应该测试内存分配的成功和失败的情况
  • 如果参数字符串太长,
  • strcpy将导致未定义的行为。
  • 无需在C中强制转换malloc的返回值。

这是改进版:

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

struct Node {
    char name[50];
    char author[50];
    struct Node *next;
};

struct Node *head = NULL;

void Print(void) {
     printf("\nThe Library data is as follows:\n\n");
     struct Node *temp = head; // where head is a global variable
     while (temp != NULL) {
         printf("%25s  %-25s\n", temp->name, temp->author);
         temp = temp->next;
     }
}

int Insert(const char *name, const char *author) {
    struct Node *temp = malloc(sizeof(struct Node));
    if (temp == NULL)
        return -1;
    temp->next = NULL;
    snprintf(temp->name, sizeof(temp->name), "%s", name);
    snprintf(temp->author, sizeof(temp->author), "%s", author);

    if (head == NULL) {
        head = temp;
    } else {
        struct Node *temp1 = head;
        while (temp1->next != NULL)
            temp1 = temp1->next;
        temp1->next = temp;
    }
    return 0;
}

int main() {
    if (Insert("Flowers for Algernon", "Daniel Keyes")
    ||  Insert("Blade Runner", "Philip K. Dick")
    ||  Insert("2001, a Space Odyssey", "Arthur C. Clarke")) {
        printf("out of memory\n");
        return 1;
    }
    Print();
    return 0;
}

答案 1 :(得分:0)

在while循环中将其更改为node-> next时,其意思是该循环在node-> next为null时循环,因此您错过了链接数组的最后一个节点,因为此节点的-next为null,因此这次循环中断。并且只在您不需要temp的时候才写temp!= NULL当temp为null时,此循环会中断,因此只能放置

jQuery.ajax({
url: 'https://api.ipgeolocation.io/ipgeo?apiKey=XXXXXXXXXXX',
type: 'GET',
dataType: 'json',
success: function(location) {
    if (location.country_code2 == 'DO') {
        $('#formsearchp').attr('action', '/dominicans.asp');
    }
}
});

我希望这会对您有所帮助。 :-)

答案 2 :(得分:0)

在第一种情况下,您正在遍历整个链表。链表的末尾根据您的代码由NULL指针表示,因此使用while(temp!=NULL)。这将与{{1}一起使用},如果跳过最后一个节点,则有 2 个节点。

在第二种情况下,您将新节点添加到最后一个节点的末尾。因此,您必须使用temp1->next!=NULL。因此最后一个节点的temp1->next!=NULL指针可以指向新添加的节点。如果在这种情况下使用next,则temp变为temp!=NULL。因此下一条语句NULL无法正常工作。

  • 如果在第一种情况下进行更改,只会导致程序跳过 打印链接列表中的最后一个节点。

  • 如果在第二种情况下进行更改,这将导致您的代码被获取 已终止temp1->next=temp;

答案 3 :(得分:0)

非常简单

  1. 在功能print()中,当您使用while(temp->next!=null)时,它将不会最后打印 节点,因为当指针温度位于最后一个节点temp->next为null时,而条件为 变成错误,它会从while循环中出来。
  2. 在功能insert()中,如果将while(temp1->next!=NULL)更改为while(temp1!=NULL),则 当它来自while循环temp1指向null时,意味着没有分配内存。 因此,在while循环之后写入temp1-> next会显示错误为you cannot excess next part of temp because memory is not allocated

希望这对您有帮助!