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

标签 c loops linked-list

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

说明:该代码是关于操作链接器,如插入、删除、显示链接列表。

问题:

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

如果您打算显示链接列表,也会出现同样的问题。

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

最佳答案

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

关于C:即使条件仍然满足,循环也会弹出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47704038/

相关文章:

在 C 中将 Char 数组转换为 Long 错误

c - 我怎样才能与 C 预处理器连接两次并扩展一个宏,如 "arg ## _ ## MACRO"?

java - 将 system.out.println 中数组的值打印到屏幕计数器

c - 这个c代码(链表实现)有什么问题?

kotlin - 如何在 Kotlin 链表中仅打印整数

C:指向二维数组的指针

c - 指针值没有被加在一起。

r - 在多个列上嵌套 if else 语句

loops - Haskell - for 循环

c - 如果(条件)从链表中删除一个节点