对于C中的单个链表,我有以下非常简单的实现:
typedef struct Node{
int data;
struct Node *next;
} node;
void printLL(node * start);
void addNode(node * head, node * add);
int main()
{
node first;
first.data = 99;
first.next = NULL;
node second;
second.data = 11;
addNode(&first, &second);
printLL(&first);
}
void addNode(node * head, node * add)
{
if(head->next)
{
addNode(head->next, add);
}
else
{
head->next = add;
}
}
void printLL(node * start)
{
printf("Data is %d\n", start->data);
if (start->next) {
printLL(start->next);
}
}
我很困惑的是,如果我没有显式设置first.next = NULL,我会收到一个EXE_BAD_ACCESS错误。当我尝试检查是否设置了该属性以确定是否应该递归调用时,会发生这种情况。另一件我不明白的是,如果我将first.next设置为指向'second',那么即使对于'second',所有函数都可以正常工作。我没有明确地将它设置为NULL。因此,似乎结构中定义的指针的默认值存在一些不一致。当然,我可能做了一些完全错误的事情,但如果有人能够阐明这件事,我将不胜感激。为了解决所有问题,我的问题是:
答案 0 :(得分:2)
因此,似乎结构中定义的指针的默认值存在一些不一致。
这正是问题 - 编译器没有将自动(本地)变量设置为任何默认值。因此,您可能会得到导致EXE_BAD_ACCESS
的内容,或者您可能会得到一些似乎有效的内容。这是抽奖的好运(即使看起来有效也是一个错误)。
C的一个缺点是您有责任确保正确初始化变量。编译器可以协助警告,并非所有编译器在这方面都与其他编译器一样好。
有一种在结构定义中设置默认值的简单方法吗?
在结构的定义中没有办法做到这一点。但是,您可以在声明该类型的变量时初始化结构:
node first = { 99, NULL };
答案 1 :(得分:1)
任何指针都没有默认值,它包含垃圾值。除非使用您自己的默认值初始化所有指针。
答案 2 :(得分:0)
默认值可能取决于C编译器,因此最好提供它们。
在创建结构实例(如second.next = NULL
。
答案 3 :(得分:0)
结构中的任何内容都没有默认值(除非它是静态创建的)。并且没有办法提供一个 - 如果你想要那个,你应该使用C ++,它提供构造函数来做到这一点。如果坚持使用C,则需要明确初始化结构。
答案 4 :(得分:0)
在调用addNode(&first, &second);
时,在if
条件下,您正在执行导致问题的head->next
。{1}} next
未默认初始化,并且在运行时导致EXE_BAD_ACCESS。
但是当你将它设置为 NULL 时,if
语句中的条件会失败,并且会转到你实际分配指针的else
语句。
答案 5 :(得分:0)
如果需要默认指针值,可以创建一个工厂方法,该方法返回结构的新实例,并将值设置为所需的默认值。
答案 6 :(得分:0)
没有默认值。除非明确修改,否则每个内存位置将保持其具有的任何值。虽然此行为本身依赖于编译器。底线,你不能假设它将包含一个特定的值。
要设置默认值,一个好的做法是在创建实例时为struct
属性显式指定值。
如果您使用的是C++
,那么您将拥有构建器,您可以/应该设置成员的默认值。
答案 7 :(得分:0)
自动变量在C中根本不会初始化,无论它们是否为struct
。你必须自己初始化它们。
但与此处的大多数答案似乎暗示相比,任何数据类型(包括指针)的初始化都有默认。这样做就像任何组件将由普通值'0'显式初始化一样。对于你的例子
node first = { .data = 99 };
会完成这个伎俩。然后保证next
正确初始化。 (如果您没有C99省略.data =
并希望您永远不会更改struct
的布局:)
另请注意,这可能与使用struct
左右的memset
归零有所不同。在某些体系结构中,全0位模式可能不是空指针或double
的正确初始化。因此,最好坚持语言本身提供的初始化机制。