C:即使条件仍然满足,循环也会弹出

时间:2017-12-07 21:24:44

标签: c loops linked-list

这是用C语言编写的链表的演示。

描述:代码是关于操纵链接,如插入,删除,显示链表。

问题:

  1. 我选择1将值插入节点(例如:1)然后输入值; 2,3,4 ...
  2. 然后我删除代码退出的head元素。它应该继续运行,因为循环的条件仍然满足。
  3. 如果您打算显示链接列表,

    同样的问题。

    // ==============================
    // 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;
    }
    

1 个答案:

答案 0 :(得分:0)

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