如何跟踪 C 中的初始头指针?
How to keep track of the initial head pointer in C?
我试图在列表的末尾附加 return head 在此函数的末尾。
这是一个单链表。所以,我穿越到最后脑袋都晕了
file.c
#define NAME_LEN 30
struct equipment{
char type[NAME_LEN+1];
char description[NAME_LEN+1];
int quantity;
struct equipment *next;
};
struct equipment *append_to_list(struct equipment *list){
char type[NAME_LEN + 1], description[NAME_LEN + 1];
int quantity;
printf("Enter equipment type: ");
fgets(type, NAME_LEN, stdin);
printf("Enter description of the equipment: ");
fgets(description, NAME_LEN, stdin);
printf("Enter quantity: ");
scanf("%d", &quantity);
struct equipment *temp = (struct equipment *)malloc(sizeof(struct equipment));
strcpy(temp->type, type);
strcpy(temp->description, description);
temp->quantity = quantity;
temp->next = NULL;
bool doesExist = false;
if ( list == NULL ){
list = temp;
}
else{
while ( list->next != NULL ){
if ( list == temp ){
printf("This equipment is already in the list\n");
}
list = list->next;
}
list->next = temp;
}
// return head of this list here;
}
在这个int main函数中,e_list在调用append_to_list(e_list).
int main(void)
{
struct equipment *e_list = NULL;
e_list = append_to_list(e_list);
}
如何创建引用并遍历该虚拟头部?这样我就不会失去原来的头脑。
你需要一个临时变量,在else
中添加
struct equipment *tmp;
tmp = list;
并替换 else
中出现的所有 list
。最后 return 你 list
变量。
因为您已经将新创建的 structure
temp
放在 末尾 。您的 head 不会在 main
中的不同调用之间改变,因为 head 位于 end 的另一侧.
您需要一个静态变量来跟踪头部。这是测试代码:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define NAME_LEN 30
struct equipment
{
char type[NAME_LEN + 1];
char description[NAME_LEN + 1];
int quantity;
struct equipment *next;
};
struct equipment *
append_to_list (struct equipment *list)
{
char type[NAME_LEN + 1], description[NAME_LEN + 1];
int quantity;
printf ("Enter equipment type: ");
fgets (type, NAME_LEN, stdin);
printf ("Enter description of the equipment: ");
fgets (description, NAME_LEN, stdin);
printf ("Enter quantity: ");
scanf ("%d", &quantity);
struct equipment *temp =
(struct equipment *) malloc (sizeof (struct equipment));
strcpy (temp->type, type);
strcpy (temp->description, description);
temp->quantity = quantity;
temp->next = NULL;
bool doesExist = false;
static struct equipment * head = NULL; //New variable
if (list == NULL)
{
list = temp;
head = list;
}
else
{
while (list->next != NULL)
{
if (list == temp)
{
printf ("This equipment is already in the list\n");
}
list = list->next;
}
list->next = temp;
}
return head; //return head here
}
int main()
{
struct equipment *e_list = NULL;
e_list = append_to_list(e_list);
e_list = append_to_list(e_list);
e_list = append_to_list(e_list);
return 0;
}
你真的可以在这里做一些事情。
不过首先,您的代码相当不安全。您的缓冲区太小,不要使用 scanf 转换整数(它不会检查是否失败),也不要使用 strcpy(尤其是当您的缓冲区很小时)。此外,如果您只是使用文字字符串,则对 printf 的调用有点毫无意义 - 应该考虑使用 puts() - 并且不要从 malloc() 转换 return。这样可能更安全一些。
#include <bsd/bsd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#define NAME_LEN 32
#define nputs(STR) fputs((STR), stdout)
struct equipment {
char type[NAME_LEN];
char description[NAME_LEN];
int quantity;
struct equipment *next;
};
struct equipment *
append_to_list(struct equipment *list)
{
char type[BUFSIZ], description[BUFSIZ], quantity_string[BUFSIZ];
int quantity;
nputs("Enter equipment type: ");
fgets(type, BUFSIZ, stdin);
nputs("Enter description of the equipment: ");
fgets(description, BUFSIZ, stdin);
nputs("Enter quantity: ");
fgets(quantity_string, BUFSIZ, stdin);
char *endptr;
quantity = strtol(quantity_string, &endptr, 10);
if (quantity_string == endptr) {
fprintf(stderr, "Error: invalid integer input '%s'\n", quantity_string);
exit(1);
}
struct equipment *temp = malloc(sizeof *temp);
strlcpy(temp->type, type, NAME_LEN);
strlcpy(temp->description, description, NAME_LEN);
temp->quantity = quantity;
temp->next = NULL;
bool doesExist = false;
if (list == NULL) {
list = temp;
} else {
while (list->next != NULL) {
if (list == temp)
puts("This equipment is already in the list");
list = list->next;
}
list->next = temp;
}
// return head of this list here;
}
至于跟踪头部,您可以使用不同的函数来初始化树而不是附加到它,从而为您提供一个稍微独特的根对象。您可以向每个存储根位置的结构添加一个字段,或者您可以创建一个单独的结构来完全保存根以及一些关于它的元数据。有很多选择。我同意上面的一些评论,您在这里的要求并不完全清楚。
我试图在列表的末尾附加 return head 在此函数的末尾。
这是一个单链表。所以,我穿越到最后脑袋都晕了
file.c
#define NAME_LEN 30
struct equipment{
char type[NAME_LEN+1];
char description[NAME_LEN+1];
int quantity;
struct equipment *next;
};
struct equipment *append_to_list(struct equipment *list){
char type[NAME_LEN + 1], description[NAME_LEN + 1];
int quantity;
printf("Enter equipment type: ");
fgets(type, NAME_LEN, stdin);
printf("Enter description of the equipment: ");
fgets(description, NAME_LEN, stdin);
printf("Enter quantity: ");
scanf("%d", &quantity);
struct equipment *temp = (struct equipment *)malloc(sizeof(struct equipment));
strcpy(temp->type, type);
strcpy(temp->description, description);
temp->quantity = quantity;
temp->next = NULL;
bool doesExist = false;
if ( list == NULL ){
list = temp;
}
else{
while ( list->next != NULL ){
if ( list == temp ){
printf("This equipment is already in the list\n");
}
list = list->next;
}
list->next = temp;
}
// return head of this list here;
}
在这个int main函数中,e_list在调用append_to_list(e_list).
int main(void)
{
struct equipment *e_list = NULL;
e_list = append_to_list(e_list);
}
如何创建引用并遍历该虚拟头部?这样我就不会失去原来的头脑。
你需要一个临时变量,在else
中添加
struct equipment *tmp;
tmp = list;
并替换 else
中出现的所有 list
。最后 return 你 list
变量。
因为您已经将新创建的 structure
temp
放在 末尾 。您的 head 不会在 main
中的不同调用之间改变,因为 head 位于 end 的另一侧.
您需要一个静态变量来跟踪头部。这是测试代码:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define NAME_LEN 30
struct equipment
{
char type[NAME_LEN + 1];
char description[NAME_LEN + 1];
int quantity;
struct equipment *next;
};
struct equipment *
append_to_list (struct equipment *list)
{
char type[NAME_LEN + 1], description[NAME_LEN + 1];
int quantity;
printf ("Enter equipment type: ");
fgets (type, NAME_LEN, stdin);
printf ("Enter description of the equipment: ");
fgets (description, NAME_LEN, stdin);
printf ("Enter quantity: ");
scanf ("%d", &quantity);
struct equipment *temp =
(struct equipment *) malloc (sizeof (struct equipment));
strcpy (temp->type, type);
strcpy (temp->description, description);
temp->quantity = quantity;
temp->next = NULL;
bool doesExist = false;
static struct equipment * head = NULL; //New variable
if (list == NULL)
{
list = temp;
head = list;
}
else
{
while (list->next != NULL)
{
if (list == temp)
{
printf ("This equipment is already in the list\n");
}
list = list->next;
}
list->next = temp;
}
return head; //return head here
}
int main()
{
struct equipment *e_list = NULL;
e_list = append_to_list(e_list);
e_list = append_to_list(e_list);
e_list = append_to_list(e_list);
return 0;
}
你真的可以在这里做一些事情。
不过首先,您的代码相当不安全。您的缓冲区太小,不要使用 scanf 转换整数(它不会检查是否失败),也不要使用 strcpy(尤其是当您的缓冲区很小时)。此外,如果您只是使用文字字符串,则对 printf 的调用有点毫无意义 - 应该考虑使用 puts() - 并且不要从 malloc() 转换 return。这样可能更安全一些。
#include <bsd/bsd.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#define NAME_LEN 32
#define nputs(STR) fputs((STR), stdout)
struct equipment {
char type[NAME_LEN];
char description[NAME_LEN];
int quantity;
struct equipment *next;
};
struct equipment *
append_to_list(struct equipment *list)
{
char type[BUFSIZ], description[BUFSIZ], quantity_string[BUFSIZ];
int quantity;
nputs("Enter equipment type: ");
fgets(type, BUFSIZ, stdin);
nputs("Enter description of the equipment: ");
fgets(description, BUFSIZ, stdin);
nputs("Enter quantity: ");
fgets(quantity_string, BUFSIZ, stdin);
char *endptr;
quantity = strtol(quantity_string, &endptr, 10);
if (quantity_string == endptr) {
fprintf(stderr, "Error: invalid integer input '%s'\n", quantity_string);
exit(1);
}
struct equipment *temp = malloc(sizeof *temp);
strlcpy(temp->type, type, NAME_LEN);
strlcpy(temp->description, description, NAME_LEN);
temp->quantity = quantity;
temp->next = NULL;
bool doesExist = false;
if (list == NULL) {
list = temp;
} else {
while (list->next != NULL) {
if (list == temp)
puts("This equipment is already in the list");
list = list->next;
}
list->next = temp;
}
// return head of this list here;
}
至于跟踪头部,您可以使用不同的函数来初始化树而不是附加到它,从而为您提供一个稍微独特的根对象。您可以向每个存储根位置的结构添加一个字段,或者您可以创建一个单独的结构来完全保存根以及一些关于它的元数据。有很多选择。我同意上面的一些评论,您在这里的要求并不完全清楚。