线性表的注意点(二)

先看一个大家都熟悉的单链表结构体

typedef struct node{
      int data;
      struct  node * next;
} PNode,*LinkList;
// 简化后就是
struct node{ 
      int data; 
      struct node * next;
};
typedef struct node PNode;
typedef struct node *Linklist;

对于LinkList L: L是指向定义的node结构体的指针,可以用->运算符来访问结构体成员,即L->data,而(L)就是个node型的结构体了,可以用点运算符访问该结构体成员,即(L).data**;

对于LinkList L:L是指向定义的Node结构体指针的指针,所以(L)是指向Node结构体的指针,可以用->运算符来访问结构体成员,即(L)->data,当然,(**L) 就是node*型结构体了,所以可以用点运算符来访问结构体成员,即(**L).data;

在链表操作中,我们常常要用链表变量作物函数的参数,这时,用LinkList L还是LinkList L 就很值得考虑深究了,一个用不好,函数就会出现逻辑错误,其准则是:
如果函数会改变指针L的值,而你希望函数结束调用后保存L的值,那你就要用
LinkList L,这样,向函数传递的就是指针的地址,结束调用后,自然就可以去改变指针的值;
而如果函数只会修改指针所指向的内容,而不会更改指针的值,那么用LinkList L就行了;

下面说个具体实例吧!

#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct Node{
 ElemType elem;
 struct Node * next;
}Node, * LinkList;

//初始化链表,函数调用完毕后,L会指向一个空的链表,即会改变指针的值,所以要用*L

void InitList(LinkList *L) {
       *L = (LinkList)malloc(sizeof(Node));
       (*L)->next = NULL;
}

//清空链表L,使L重新变为空链表,函数调用完后不会改变指针L的值,只会改变指针L所指向的内容(即L->next的值)

void ClearList(LinkList L){ LinkList p; while(p = L->next) free(p);}

//销毁链表L,释放链表L申请的内存,使L的值重新变为NULL,所以会改变L的值,得用*L

void DestroyList(LinkList *L)
{
 LinkList p;
 while(p = (*L)->next )
  free(p);
 free(*L);
 *L = NULL;
}

void main()
{
 LinkList L = NULL;
 InitList(&L);
 ClearList(L);
 DestroyList(&L);
}

对比数据结构上面的例子自己体会吧。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容