C 使用通用链表/变量时未初始化

C 使用通用链表/变量时未初始化,c,C,因此,我试图为赋值编写一个通用程序,该程序一直告诉我,list变量正在使用中,但没有初始化。 我已经尽了我所能,但仍然没有起到任何作用,所以如果有人能告诉我我做错了什么,我将不胜感激 代码有点长,所以请耐心听我说 标题内容: #ifndef _HEADER_H #define _HEADER_H #include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h>

因此,我试图为赋值编写一个通用程序,该程序一直告诉我,list变量正在使用中,但没有初始化。 我已经尽了我所能,但仍然没有起到任何作用,所以如果有人能告诉我我做错了什么,我将不胜感激

代码有点长,所以请耐心听我说

标题内容:

#ifndef _HEADER_H
#define _HEADER_H

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

typedef enum { FALSE, TRUE } BOOL;

/* defining specific function names*/
typedef int(*compare_func)(void*, void*);
typedef void(*print_func)(void*);
typedef void(*free_func)(void*);

/* defining struct names and pointers*/
typedef struct set Set;
typedef struct set* PSet;
typedef struct list List;
typedef struct list* PList;

/* creating and initialzing a set*/
PList createSet(PList List, compare_func cmp_fnc, print_func prnt_fnc, free_func free_fnc);

/* finding the biggest value in the set*/
void* findMax(PList List);

/* finding the smallest value in the set*/
void* findMin(PList List);

/* finding an element in the set*/
BOOL findInSet(PList List, void* val);

/* function for finding the size of the list*/
int setSize(PList list);

/* inserting a new element.*/
BOOL addToSet(PList List, void *data);

/* deleting an element, pointered by todel*/
BOOL deleteFromSet(PList list, void *todel);

/* print the elements in the set */
void printAll(PList list);

/* deleting the entire set */
void deleteSet(PList list);

#endif
主要功能:

#include "Header.h"

void prnt_string(void* str)       // specific function for printing strings
{
    puts(*(char*)str);
    printf(" ");
}

void free_string(void* str)     // specific function for freeing memory
{
    free(str);
}

int cmp_str(void* s1, void* s2)     // specific function for comparing two strings
{
    if (strcmp(*(char*)s1, *(char*)s2) == 0)
        return 0;
    else if (strcmp(*(char*)s1, *(char*)s2 == 1))
        return 1;
    else return -1;
}


void prnt_int(void* a)     // Specific function for printing integers
{
    printf("%d ", a);
}

void free_int(void* a)      // Specific funtion for freeing integers
{
    free(a);
}

int int_comp(void* a, void* b)         // Specific function for printing integers
{
    if (*(int*)a == *(int*)b)
        return 0;
    else if (*(int*)a > *(int*)b)
        return 1;
    else return -1;
}


int main()
{
    char ch, tempstr[31], *str;
    int n, option, *num, item;
    void *temp;
    BOOL status;
    PList list;

    printf("Choose the type you want to work with:\n");
    printf("1. Integers\n");
    printf("2. Strings\n");
    printf("Enter input: ");
    scanf("%d", &n);

    switch (n)
    {
    case 1:
        list = createSet(list, int_comp, prnt_int, free_int);
        do
        {
            printf("Choose the desired action: ('-1' to exit)\n");
            printf("1. Create a Set\n");
            printf("2. Add To Set\n");
            printf("3. Delete From Set\n");
            printf("4. Find an Item in The Set\n");
            printf("5. Find The Biggest Value In The Set\n");
            printf("6. Find The Smallest Value In The Set\n");
            printf("7. Delete The Set\n");
            printf("Enter input: ");
            scanf("%d", &option);

            switch (option)
            {
            case 1:
                list = createSet(list, int_comp, prnt_int, free_int);
                printf("The Set Has Been Initialized.\n");
                break;
            case 2:
                num = (int*)malloc(sizeof(int));
                if (num == NULL)
                {
                    printf("Memory allocation failed!");
                    deleteSet(list);
                    return 1;
                }
                else
                {
                    printf("Enter a number: ");
                    scanf("%d", &num);
                    status = addToSet(list, num);
                    if (status == TRUE)
                    {
                        printf("Number successfully added to set.\n");
                        printAll(list);
                    }
                    else
                    {
                        printf("Operation failed!\nThe number already exists in the set or memory allocation failed.\n");
                        deleteSet(list);
                        return 1;
                    }
                }
                break;
            case 3:
                printf("Enter number: ");
                scanf("%d", &item);
                status = deleteFromSet(list, &item);
                if (status == TRUE)
                {
                    printf("Number successfully deleted.\n");
                    printAll(list);
                }
                else
                {
                    printf("Operation failed!\nThe number does not exist in the set.");
                    printAll(list);
                }
                break;
            case 4:
                printf("Enter number: ");
                scanf("%d", &item);
                if (findInSet(list, &item) == TRUE)
                    printf("Item exists in the set.\n");
                else if (findInSet(list, &item) == FALSE) printf("Item does not exist in the set.\n");
                /*else if (findInSet(list, &item) == NULL) printf("The set is empty.\n");*/
                break;
            case 5:
                printf("The size of the set is %d", setSize(list));
                break;
            case 6:
                temp = findMax(list);
                if (temp == NULL) printf("The set is empty.\n");
                else printf("The biggest value in the set is %d", (int*)temp);
                break;
            case 7:
                temp = findMin(list);
                if (temp == NULL) printf("The set is empty.\n");
                else printf("The smallest value in the set is %d", (int*)temp);
                break;
            case 8:
                deleteSet(list);
                break;
            }
        } while (option != -1);
        deleteSet(list);
        break;
    case 2:
        list = createSet(list, cmp_str, prnt_string, free_string);
        do
        {
            printf("Choose the desired action: ('-1' to exit)\n");
            printf("1. Create a Set\n");
            printf("2. Add To Set\n");
            printf("3. Delete From Set\n");
            printf("4. Find an Item in The Set\n");
            printf("5. Find The Biggest Value In The Set\n");
            printf("6. Find The Smallest Value In The Set\n");
            printf("7. Delete The Set\n");
            printf("Enter input: ");
            scanf("%d", &option);

            switch (option)
            {
            case 1:
                list = createSet(list, cmp_str, prnt_string, free_string);
                printf("The Set Has Been Initialized.\n");
                break;
            case 2:
                    printf("Enter a string(max of 30 characters): ");
                    gets(tempstr);
                    str = (char*)malloc(strlen(tempstr) + 1 * sizeof(char));
                    if (str == NULL)
                    {
                        printf("Memory allocation failed!\n");
                        deleteSet(list);
                        return 1;
                    }
                    strcpy(str, tempstr);
                    status = addToSet(list, str);
                    if (status == TRUE)
                    {
                        printf("String successfully added to set.\n");
                        printAll(list);
                    }
                    else
                    {
                        printf("Operation failed!\nThe string already exists in the set or memory allocation failed.\n");
                        deleteSet(list);
                        return 1;
                    }
                break;
            case 3:
                printf("Enter string(max of 30 characters): ");
                gets(tempstr);
                status = deleteFromSet(list, &tempstr);
                if (status == TRUE)
                {
                    printf("String successfully deleted.\n");
                    printAll(list);
                }
                else
                {
                    printf("Operation failed!\nThe string does not exist in the set.");
                    printAll(list);
                }
                break;
            case 4:
                printf("Enter string: ");
                gets(tempstr);
                if (findInSet(list, &tempstr) == TRUE)
                    printf("Item exists in the set.\n");
                else if (findInSet(list, &tempstr) == FALSE) printf("Item does not exist in the set.\n");
                /*else if (findInSet(list, &tempstr) == NULL) printf("The set is empty.\n");*/
                break;
            case 5:
                printf("The size of the set is %d", setSize(list));
                break;
            case 6:
                temp = findMax(list);
                if (temp == NULL) printf("The set is empty.\n");
                else
                {
                    printf("The biggest value in the set is ");
                    puts((char*)temp);
                }
                break;
            case 7:
                temp = findMin(list);
                if (temp == NULL) printf("The set is empty.\n");
                else
                {
                    printf("The smallest value in the set is ");
                    puts((char*)temp);
                }
                break;
            case 8:
                deleteSet(list);
                break;
            }
        } while (option != -1);
        deleteSet(list);
        break;
    default:
        printf("Wrong input!\n");
        break;
    }

    getch();
    return 0;
}
当我试着运行这个程序时,我得到了一条错误消息,即主函数中的list变量正在使用,但没有初始化,尽管我不明白为什么它首先需要初始化。
问题可能是什么?

每个变量在读取之前都应该初始化,否则从中读取的任何内容都是垃圾。在C语言中,变量在默认情况下不会像在其他一些语言中那样初始化

createSet()
函数中,您取消引用变量
LIST
,但main中的
LIST
只是声明为指针,而没有初始化它以实际指向某个对象

您应该在main中使用
List
来声明
List
,而不是
PList List
。然后将
&list
传递给接受
PList
参数的函数

另外,当前的
createSet()
函数正在混合两种初始化对象的方法

您可以将
PList
传递给它,然后初始化
PList
指向的
列表,以便:

List fooList;
PList pFooList = &fooList;
createSet(pFooList, ...):
然后在
createSet()
中,不要使用
malloc
分配新对象

但是,您也可以在
createList()
中创建对象,但不要传递任何
PList

第一个选项的优点是,如果要动态分配对象,可以使用:

PList pFooList = malloc(sizeof(List));
createSet(pFooList, ...);
但是您不必这样做,因为您仍然可以在堆栈上分配对象


正如@MichaelBeer所评论的,声明的变量
static
实际上会自动初始化,但这并不能解决询问者的问题,因为如果
list
是用
static PList list
声明的,然后
list
将指向
NULL
,而不仅仅是垃圾。

每个变量在读取之前都应该初始化,否则从中读取的任何内容都是垃圾。在C语言中,变量在默认情况下不会像在其他一些语言中那样初始化

createSet()
函数中,您取消引用变量
LIST
,但main中的
LIST
只是声明为指针,而没有初始化它以实际指向某个对象

您应该在main中使用
List
来声明
List
,而不是
PList List
。然后将
&list
传递给接受
PList
参数的函数

另外,当前的
createSet()
函数正在混合两种初始化对象的方法

您可以将
PList
传递给它,然后初始化
PList
指向的
列表,以便:

List fooList;
PList pFooList = &fooList;
createSet(pFooList, ...):
然后在
createSet()
中,不要使用
malloc
分配新对象

但是,您也可以在
createList()
中创建对象,但不要传递任何
PList

第一个选项的优点是,如果要动态分配对象,可以使用:

PList pFooList = malloc(sizeof(List));
createSet(pFooList, ...);
但是您不必这样做,因为您仍然可以在堆栈上分配对象


正如@MichaelBeer所评论的,声明的变量
static
实际上会自动初始化,但这并不能解决询问者的问题,因为如果
list
是用
static PList list
声明的,那么
list
将指向
NULL
,而不仅仅是垃圾。

@MichaelBeer,你确实是对的,但我想确保不提及他们,不提及解决提问者问题的方法:)@MichaelBeer,你确实是对的,但我想确保不提及他们,不提及解决提问者问题的方法:)