教训是惨痛的!!!这是我所学习的第一个简单程序。确定一个链表需要什么?在单链表中,也就是一个头指针;无论是进行什么样的基本操作:插入,删除、遍历、等等。都需要头指针,但是由于对此方面知识的忽略,我一直也没有考虑这个问题,导致了下面的这个程序的莫名其妙的段错误;让我恶心了好几天。
#include<stdio.h>
#include<stdlib.h>
struct List
{
int data;
List * next;
};
void initList(List * L)//初始化链表
{
L = (List *)malloc(sizeof(List));
if (L == NULL)
exit(-1);
else
L->next = NULL;
}
/*在第i个元素前面插入元素element*/
int insertList(List * L, int i, int element)
{
int j = 0;
List * p = L;
List * q;
while (p != NULL && j<i-1)
{
p = p->next;
j++;
}
if (p == NULL || j>i-1)
return -1;
q = (List *)malloc(sizeof(List));
if (q == NULL)
exit(-1);
q->data = element;
q->next = p->next;
p->next = q;
return 1;
}
void traverseList(List *L)
{
List * p = L->next;
while (p != NULL)
{
printf("%d ", p->data);
p = p->next;
}
printf("/n");
}
int main(void)
{
List L1;
/*此句本身并没有什么错误,但是在单链表中就是大错*/
initList(&L1);//L1是一个变量,将这个参数传递之后,malloc()所创建的地址空间就存放在了这个变量中。
for (int i = 1; i<=5; i++)
insertList(&L1, 1, i);//调用insertList()之后,首先创建了一个节点,之后依次创建了2, 3, 4, 5首先生成的节点最后被访问,这为遍历的段错误埋下了坑。
traverseList(&L1);
/*
遍历以L1地址开头的节点:由于初始化没有起到任何作用,所以也就没有了指针域为空的时候,所以会出现段错误,所以在用GDB调试的时候,当i为1,2,3,4,5时输出正确,为什么再一次循环之后,本来应该为空的地址会出现地址值。原因皆在此。
*/
return 0;
}
学习数据结构时,在看别人的代码的时候,首先将原理搞清楚,弄明白;许多让人百思不得起解的问题也许很简单。这是我的感受。