【发布时间】:2015-02-01 05:56:13
【问题描述】:
我发现了如何解决我的问题,但我不知道它是如何工作或为什么工作。我会非常感谢有人来看看这个:
我正在创建一个链接列表,其中包含一个指向列表头部的全局指针。我在主线程中创建了一个虚拟节点。我想要发生的是能够调用 printList() 并且如果除了虚拟节点之外没有其他节点,则打印“Person:0”(基本上说列表是空的)。
[edit -> 这是我的简洁问题:为什么 printList() 在 main() 中识别 Person *head = NULL 而不是全局指针,当它使用它来设置当前指针等于 head 时?]
使用此代码,我得到以下输出
int main(){
setvbuf(stdout, NULL, _IONBF, 0);
//Person *head = NULL;
printf("\nmain head:%p \n", head);
head = (Person *)malloc(sizeof(Person));
printf("\nmain head:%p \n", head);
head->name[0] = '\0';
head->next = NULL;
head->previous = NULL;
输出:
main head:0000000000000000
main head:00000000003F1390
Enter add, insert or delete for Person functions: print
printList head:00000000003F1390 Person:1 Total People:1
Enter add, insert or delete for Person functions:
在 main() 中声明 Person*head 并将其初始化为 NULL,我得到了想要的结果。 为什么会这样?为什么我无法初始化全局指针并获得相同的预期结果?
int main(){
setvbuf(stdout, NULL, _IONBF, 0);
Person *head = NULL;
printf("\nmain head:%p \n", head);
head = (Person *)malloc(sizeof(Person));
printf("\nmain head:%p \n", head);
head->name[0] = '\0';
head->next = NULL;
head->previous = NULL;
以下输出:
main head:0000000000000000
main head:00000000005E1390
Enter add, insert or delete for Person functions: print
printList head:0000000000000000 Total People:0
Enter add, insert or delete for Person functions:
这是整个程序供参考:
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
typedef struct S_PersonInLine{
char name[16];
struct S_PersonInLine *next;
struct S_PersonInLine *previous;
}Person;
//pointer to head of the list
//This isn't a global head pointer(wrong). It doesn't go into main (wrong). False it does go into main but it doesn't give the intended result from the printList
Person *head = NULL; //this allows the functions to access the head pointer
//prototypes
Person *makePerson();
void *addPerson();
void *insert();
void *delete();
void printList();
void cleanUp();
int main(){
setvbuf(stdout, NULL, _IONBF, 0); //Figure out what this thing does again and why its necessary
Person *head = NULL;
printf("\nmain head:%p \n", head);
head = (Person *)malloc(sizeof(Person));
printf("\nmain head:%p \n", head);
head->name[0] = '\0';
head->next = NULL;
head->previous = NULL;
char input[16];
char command[16];
printf("Enter add, insert or delete for Person functions: ");
while( fgets(input , 15 , stdin) ){
sscanf(input, "%s", command);
if ( strcmp(command, "quit") == 0 ){
printf("\n\nBreaking....");
break;
} else if ( strcmp(command, "print") == 0 ){
printList();
}
printf("Enter add, insert or delete for Person functions: ");
}
return 0;
}
void printList(){
Person *current = head;
printf("\nprintList head:%p ", head);
int count = 0;
while(current != NULL){
count++;
printf("Person:%d %s", count, current->name);
current = current->next;
}
printf("Total People:%d\n", count);
}
【问题讨论】:
-
这一行:'setvbuf(stdout, NULL, _IONBF, 0);'将 stdout 的输出缓冲设置为“不存在”,因此通过 printf 等输出的任何内容都会立即输出到终端,而不是等待程序退出或输出“\n”或 fflush(stdout);或从标准输入读取
-
始终检查 malloc(和系列)的返回值,以确保操作成功。在 C 中,不要从 malloc 中转换返回值。它是一个 void *,因此可以与任何接收变量一起使用
-
这一行:'while( fgets(input , 15 , stdin) ){ ' fgets 正确处理接收缓冲区(没有溢出并为终止 NUL 字节留出空间),因此该行应该是:' while( fgets(input , sizeof(input) , stdin) ){ '
-
@Sankofa 如果您不在
main()中声明一个并重新考虑虚拟节点的不必要想法,printList肯定会正常工作(就像其他所有期望head == NULL表示列表为空)。有些人更喜欢列出带有虚拟节点的房屋指针。我的偏好不是。 ymmv。 -
为什么会发生what?它们是两个不同的指针。对
main()中的本地head所做的任何事情都不会修改全局。删除main中的本地并使用虚拟节点启动全局head意味着您所有期望head指向NULL 的代码意味着必须更改一个空列表。你不能同时拥有它(一个虚拟的非 NULL 头指针和期望head作为NULL的函数是一个空列表)。你可以做Person *current = head ? head->next : NULL;并保留你当前的列表打印代码,但是yuck。
标签: c pointers linked-list logic