1. 遇到的问题

用 DEV C++ 写C语言实现单链表时,编译没有报错,但是就是走到初始化(InitList)这里就不走了,很明显代码出现了问题。

于是开始断点调试,但是调试也不行,报如下错误:

几番折腾后解决方法如下↓↓↓↓


2. 解决方法

2.1 代码及解释

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct LNode{
   	// 定义一个单链表的节点类型 
	int data;	// 每个节点的数据域 
	struct LNode* next;	// 每个节点的指针域,指针指向下一个节点 
}LNode, *LinkList;
// LNode* 强调的是节点 LinkList 强调的是单链表 

// 初始化(带头节点)
void InitList(LinkList* L){
    
	*L = (LNode*)malloc(sizeof(LNode));	// 分配一个头节点 (头节点是不存储数据的)
	if(*L == NULL){
   
		printf("分配空间失败!\n");
	}else{
   
		(*L)->next = NULL;
		printf("分配空间成功!\n");
	}
}
/* 先说明: 一个变量由地址和存储的值组成。 指针也是一个变量,它也有地址,它存储的是它所指向的空间的地址值 &L 取指针L的地址值 *L 取指针L所指向的变量的值 这么写的原因是main函数中定义的 L 是一个指针,它还没有指向任何一个空间,即它的存储空间没有数据。 如果要让它指向一个新的空间,就必须将他的地址传给函数 malloc返回的是一个指向 创建好的空间 的指针 *L = (LNode*)malloc(sizeof(LNode));中的 *L 相当于就是main函数中定义的 L 所以此时 L 中存储的就是 创建好的空间的地址,即 L 指向了 malloc创建的空间 */ 

// 判断单链表是否为空(带头节点) 
void Empty(LinkList L){
   
	if (L->next == NULL){
   
		printf("单链表为空!\n");
	}else{
   
		printf("单链表不为空!\n");
	}
}

// 按位序插入(带头节点)
// 在 L 的第 i 个节点插入元素 e 
void ListInsert(LinkList L, int i, int e){
   
	// 如果要插入的位置小于1则报错 
	if(i<1){
   
		printf("位序i不合法,插入错误!");
		exit(1); 
	}
	LNode* p = L;	// 指针p指向当前扫描到的节点(初始化指向第一个节点) 
	int j = 0; 	// 记录当前p指向的是第几个节点
	
	while(p != NULL && j < i - 1){
   	// 找到插入的位置 
		p = p->next;
		j++;
	} 
	
	// 如果要插入的位置大于 L 的实际长度,则报错 
	if (p == NULL){
   
		printf("位序i不合法,插入错误!");
		exit(1);
	} 
	LNode* s = (LNode*)malloc(sizeof(LNode)); 
	if (s == NULL){
   
		printf("分配空间失败!!!");
		exit(1); 
	}
	s->data = e;	// 插入元素 
	s->next = p->next;
	p->next = s;
	printf("插入成功!\n");
} 

// 打印单链表
void PrintList(LinkList L){
   
	LNode* p = L->next;		// p指向实际存储数据的第一个节点 
	while(p != NULL){
   
		printf("%d\n",p->data);
		p = p->next; 
	}
} 

void main(){
   
	LinkList L;		// 声明一个指向单链表的指针
	InitList(&L); 
	
	Empty(L); 
	ListInsert(L ,1 ,78);
	ListInsert(L ,2 ,48);
	ListInsert(L ,3 ,12345);
	
	PrintList(L);
}

2.2 图解