gpt4 book ai didi

c - 正在使用通用链表/变量而未初始化

转载 作者:太空宇宙 更新时间:2023-11-04 06:50:15 25 4
gpt4 key购买 nike

所以我正在尝试为赋值编写一个通用程序,但该程序一直告诉我正在使用列表变量而未初始化。我已经尝试了几乎所有我能做的事情,但仍然没有什么不同,所以如果有人能告诉我我做错了什么,我将非常感激。

代码有点长,请多多包涵。

标题内容:

#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"

typedef struct set // Set struct for bi-directional list
{
void* data;
struct set *next, *prev;
}Set, *PSet;

typedef struct list // List struct
{
int ListSize;
Set *head;
Set *tail;
compare_func compare;
print_func print;
free_func free;
}List, *PList;


PList createSet(PList LIST, compare_func cmp_fnc, print_func prnt_fnc, free_func free_fnc) // Function for initializing and creating a set
{
PList list;
list = (PList)malloc(sizeof(List));
LIST->ListSize = 0;
LIST->head = NULL;
LIST->tail = NULL;
LIST->compare = cmp_fnc;
LIST->print = prnt_fnc;
LIST->free = free_fnc;
return list;
}


void* findMax(PList List) // Function for finding the biggest value in a set
{
if (List->head == NULL) // If the set is empty
return NULL;

PSet temp;
void* max = List->head->data;
temp = List->head;
while (temp)
{
if (List->compare(temp->data, max) == 1) // Finding the biggest value
max = temp->data;
temp = temp->next; // Moving to the next node
}
return max;
}


void* findMin(PList List) // Function for finding the smallest value in a set
{
if (List->head == NULL) // If the set is empty
return NULL;

PSet temp;
void* min = List->head->data;
temp = List->head;
while (temp)
{
if (List->compare(temp->data, min) == -1) // Finding the smallest value
min = temp->data;
temp = temp->next; // Moving to the next node
}
return min;
}


BOOL findInSet(PList List, void* val) // Function for checking whether a given character is in the set
{
if (List->head == NULL) // If the list is empty
return FALSE;

PSet temp;
temp = List->head;
while (temp)
{
if (List->compare(temp->data, val) == 0) // If the character exists
return TRUE;
temp = temp->next; // Moving to the next node
}
return FALSE;
}


int setSize(PList list)
{
return list->ListSize;
}


BOOL addToSet(PList List, void *data) // Function for adding an item to the set
{
PSet temp, CurrentNode;
CurrentNode = List->head;
temp = (PSet)malloc(sizeof(Set));
if (temp == NULL) // If the allocation failed return false
return FALSE;

temp->data = data; // Filling the temp with the data
temp->next = NULL;
temp->prev = NULL;

if (List->head == NULL) // If the list is empty
{
List->head = temp;
List->tail = temp;
List->ListSize++;
return TRUE;
}
else {
while (CurrentNode) // Loop for checking whether the inserted character exists in the list
{
if (List->compare(data, CurrentNode->data) == 0) return FALSE;
CurrentNode = CurrentNode->next;
}
List->tail->next = temp; // Adding the node to the list
temp->prev = List->tail;
List->tail = temp; // Updating the tail
List->ListSize++;
return TRUE;
}
}


BOOL deleteFromSet(PList list, void *todel) // Function for deleteing an item from a set
{
PSet nodeToDel;

if (list->head == NULL) // If the list is empty
return FALSE;

if (list->compare(todel, list->head->data) == 0) // If the node to be deleted is the head
{
nodeToDel = list->head;
list->head = list->head->next;
if (list->head != NULL)
list->head->prev = NULL;
list->free(nodeToDel->data);
free(nodeToDel);
list->ListSize--;
return TRUE;
}
else if (list->compare(todel, list->tail->data) == 0) // If the node to be deleted is the tail
{
nodeToDel = list->tail;
list->tail = list->tail->prev;
list->tail->next = NULL;
list->free(nodeToDel->data);
free(nodeToDel);
list->ListSize--;
return TRUE;
}
else
{
nodeToDel = list->head;
while (nodeToDel->next) // Any node other than the head or the tail
{
if (list->compare(todel, nodeToDel->data) == 0) // If the character exists in the list
{
nodeToDel->next->prev = nodeToDel->prev;
nodeToDel->prev->next = nodeToDel->next;
list->free(nodeToDel->data);
free(nodeToDel);
list->ListSize--;
return TRUE;
}
nodeToDel = nodeToDel->next; // Moving to the next node
}
}
return FALSE; // If the character wasn't found in the list return false
}


void printAll(PList list) // Funciton for printing all items in a set
{
PSet temp;
if (list->head == NULL) // If the list is empty
printf("\nThe list is empty.");
else
{
printf("\nThe list is:\n");
temp = list->head;
while (temp) // While there are still nodes left
{
list->print(temp->data); // Call specific function for printing
temp = temp->next; // Move to the next node
}
printf("\n");
}
}


void deleteSet(PList list) // Function for deleting a set
{
PSet temp;
if (!(list->head)) // If the list is empty
printf("\nThe set is empty.");
else
{
while (list->head)
{
temp = (list->head);
list->head = list->head->next; // Moving to the next node
if (list->head != NULL)
list->head->prev = NULL;
list->free(temp->data); // Call specific function for freeing memory
free(temp);
list->ListSize--;
}
printf("The set has been deleted.\n");
}
}

主要功能:

#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;
}

当我尝试运行该程序时,我收到错误消息,指出 main 函数中的列表变量在未初始化的情况下被使用,但我不明白为什么它首先需要初始化。可能是什么问题?

最佳答案

每个变量在被读取之前都应该被初始化,否则你从它读取的任何东西都是垃圾。在 C 中,变量不会像在某些其他语言中那样默认初始化。

在您的 createSet() 函数中,您取消了对变量 LIST 的引用,但是 main 中的 list 只是声明为一个指针,而没有将其初始化为实际上指向某物。

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

此外,您当前的 createSet() 函数将两种初始化对象的方法混合在一起。

你可以传递一个PList给它,然后初始化PList指向的List,所以:

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 - 正在使用通用链表/变量而未初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52571492/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com