在复习数据结构的时候尝试写单链表的代码。
因为想使用纯C语言,不使用C++d的内容,所以在创建链表初始化的时候就遇到了问题。
以下是我写的第一版本的代码
#include<stdio.h>
// 链表定义
typedef struct LNode{
int data;
struct LNode * next;
}LNode,*LinkList;
// 初始化函数
int InitList(LinkList *L){
L = NULL;
return 1;
}
int main(){
LinkList L;
InitList(&L);
return 0;
}
这一部分无法在执行InitList函数后对链表L进行更改,主要是实参和形参的问题,但是我不知道怎么解决。
以下是运行截图:
执行前为0x10
执行后仍为0x10
在我上网搜寻了一些资料后,找到了解决办法,就是把链表用struct再封装一次,然后再使用一次指针。
第二版:
#include<stdio.h>
// 链表定义
typedef struct LNode{
int data;
struct LNode * next;
}LNode,*PNode;
//封装的单链表,包含头结点
typedef struct LinkList
{
PNode Head;
}LinkList;
//初始化函数
int InitList(LinkList *L){
L->Head = NULL;
return 1;
}
int main(){
LinkList L;
InitList(&L);
return 0;
}
运行截图
初始化前
初始化后内部的头节点变为0x0
使用这样的结构就可以解决问题,但是我不知道为什么需要这样做。
希望有哪位朋友懂的可以在此点拨一下。
第一种你传递的是指针的指针,你要修改的是指针的值,不是指针的指针值。
第二种你修改的是结构内部成员的值
第一种如下修改就可以了。
#include<stdio.h>
// 链表定义
typedef struct LNode{
int data;
struct LNode * next;
}LNode,*LinkList;
// 初始化函数
int InitList(LinkList *L){
*L = (LinkList)malloc(sizeof(LNode));
return 1;
}
int main(){
LinkList L;
InitList(&L);
L->data = 10;
L->next = NULL;
return 0;
}
记住一点:函数传入的参数,参数本身会复制一份,你不能修改该参数,但你可以修改该参数指向的地址空间内容。
比如参数为 int * pData,那么pData指针自身你修改不了,但你可以修改pData指向的地址空间内容,即 pData = 10无效,但*pData = 10有效
第一种:int main(){
LinkList L;//这里定义的是一个结构体指针
InitList(&L);//初始化只是对这个指针赋 NULL
return 0;
}
第二种:int main(){
LinkList L;//定义的是一个结构体变量
InitList(&L);//初始化时,这个变量是有空间地址的
return 0;
}
#include<stdio.h>
#include<malloc.h>
// 链表定义
typedef struct LNode {
int data;
struct LNode* next;
}LNode, * LinkList;
// 初始化函数
int InitList(LinkList* L) {
(*L) = (LinkList)malloc(sizeof(LNode));//动态申请一个结构体空间,并用*L指向这个空间。
(*L)->data = 9;
(*L)->next = NULL;
return 1;
}
int InitList_1(LinkList L) { //静态
L->data = 1;
L->next = NULL;
return 1;
}
int main() {
LNode l; //变量
LinkList L = NULL, p = NULL;//指针
InitList(&L);//动态
p = L;
while (p) {
printf("%d ",p->data);
p = p->next;
}
InitList_1(&l);//静态
p = &l;
while (p) {
printf("%d ", p->data);
p = p->next;
}
return 0;
}