【问题标题】:C: Loop pops out even when condition is still satisfiedC:即使条件仍然满足,也会弹出循环
【发布时间】:2017-12-07 21:24:44
【问题描述】:

这是一个用 C 编写的链接列表的演示。

描述:该代码是关于操作链接器的,如插入、删除、显示链表。

问题:

  1. 我选择 1 将值插入节点(例如:1)然后值; 2,3,4...
  2. 然后我删除代码退出的头部元素。它应该继续运行,因为循环的条件仍然满足。

如果你打算显示链表,同样的问题。

// ==============================
// Linked List Demo
// ==============================
// 1. Insert to head
// 2. Delete elements by value
// 3. Display all elements
// 4. Search an element
// 5. Delete an element by position
// 6. Exit
// ==============================
// Your choice:

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

struct Node{
    int value;
    struct Node *next;
};
typedef struct Node intLinkedList;

int insertToHead();
void display(intLinkedList *head);
void displayForLoop(intLinkedList *head);
int deleteFromHead(intLinkedList **head);
int delete(int value, intLinkedList **head);
int indexOf(int value, intLinkedList *head);

void menu();
void menu(){
    char* mainMenu[] = {"Insert to head", "Delete", "Display", \
                         "Search Element", "Delete by position", "Exit"};
    printf("=====================================\n");
    for(int i = 0; i < 6; i++)
    {
        printf("%d. %s \n", i + 1,  mainMenu[i]);
    }
    printf("=====================================\n");
}
int main(){
    int choice;
    int value;
    intLinkedList *head;

    do{
        menu();
        printf("#Choice: ");
        scanf("%d", &choice);
        printf("--> %d", choice);
        switch(choice){
            case 1:
                printf("Input new Value to Linked List: ");
                scanf("%d", &value);
                insertToHead(value, &head);
                break;
            case 2:
                printf("Input new Value to delete : ");
                scanf("%d", &value);
                if(delete(value, &head)){
                    printf("%d removed from linked list \n", value);
                }else{
                    printf(" %d not in linked  list \n", value);
                }
                break;
            case 3:
                printf("Display all elements \n");
                display(head);
                break;
            case 4: 
                printf("Input value to search: ");
                scanf("%d", &value);
                int found = indexOf(value, head);
                if( found < 0){
                    printf("%d is isn't in linked list ", value);
                }else{
                    printf("%d is in linked list at %d positino \n", value, found);
                }
                break;
            case 5:
                printf("Delete by position : ");
                break;
            case 6:
                printf("EXIT..");
                return 0;

            default:
                printf(": \n");
                break;
        } 
    }while(choice != 6);  
}

int insertToHead(int value, intLinkedList **head){
    intLinkedList *newElement;
    newElement = (intLinkedList*)malloc(sizeof(intLinkedList));
    newElement -> value = value;
    newElement -> next = *head;
    *head = newElement;
    return 1;
}


void displayForLoop(intLinkedList *head){
    intLinkedList *iterator;
    for(iterator=head; iterator!=NULL; iterator=iterator->next){
        printf("|value: %d| ->", iterator->value);
    }
    printf(" NULL\n");
}

void display(intLinkedList *head){
    intLinkedList *iterator;
    iterator = head;
    while( iterator != NULL){
        printf("|value : %d| -> ", iterator -> value);
        iterator = iterator -> next;
    }
    printf("NULL \n");
}
int deleteFromHead(intLinkedList **head){
    if( *head == NULL){
        return 0;
    }
    intLinkedList *del;
    del = *head;
    *head = del -> next;
    free(del);
    return 1;
}
int delete(int value, intLinkedList **head){
    intLinkedList *current;
    intLinkedList *pre;
    current = *head;
    pre = *head;
    int deleted = 0;

    if(current->value == value){
        printf("get here\n");
        deleteFromHead(head);
        return 1;
    }

    while(current != NULL){
        if(current->value == value){
            deleted = 1;
            if(current==*head){
                deleteFromHead(head);
                current = *head;
                pre = *head;
            }else{
                pre->next = current->next;
                free(current);
                current = pre->next;
            }
            continue;
        }
        pre = current;
        current = current->next;
    }
    return deleted;
}

int indexOf(int value, intLinkedList *head){
    intLinkedList *iterator;
    int i;
    for( iterator = head, i = 0; iterator != NULL; iterator = iterator -> next, i++){
        if(iterator -> value = value){
            return i;
        }
    }
    return -1;
}

【问题讨论】:

  • 首先使用调试器单步调试您的代码。
  • 这是一个“完整的”、“可验证的例子”,什么意思?
  • @VeronykaMunteanu 它绝对是完整且可验证的,但它不是最小的。如果您可以将代码量减少到恰好产生错误的程度,那么其他人更容易阅读,并且很可能会引导您自己发现确切的错误。
  • 致:McLemore、Jean-Francois Fabre 和 Yunnosch:非常感谢。甚至 dbush 也给出了非常笼统但很好的评论。给刚刚通过链接的人+两个字“需要”。当您只看我的代码而不费心阅读它时,为什么还要打扰评论呢? ------ 我真诚地感谢 Stackoverflow 社区,因为每次我遇到问题时,你们都有答案,但像 Eugene Sh 这样的人真的只是想获得积分或排名,而没有真正帮助社区。​​span>

标签: c loops linked-list


【解决方案1】:

您通过未初始化 head 来调用未定义的行为。考虑第一次插入元素时,调用insertToHead .. 然后执行newElement -&gt; next = *head;head 未初始化,因此 *head 是垃圾,您的第一个元素 -&gt;next 值被“初始化”为某个不确定的值。例如,您的 displayForLoop 函数会一直循环,直到 -&gt;next 为 NULL。这可能不是唯一的问题,但它肯定是一个问题。每当您遍历您的链表寻找-&gt;next == NULL 作为列表末尾的标记时,这都会导致问题。用intLinkedList *head = NULL; 初始化head 来解决这个问题。

【讨论】:

  • @VeronykaMunteanu 不用担心,希望你能成功!
猜你喜欢
  • 2021-11-18
  • 2016-03-14
  • 1970-01-01
  • 2013-04-08
  • 2021-08-07
  • 1970-01-01
  • 1970-01-01
  • 2020-04-15
  • 2020-12-24
相关资源
最近更新 更多