佛科院计算机软件技术基础——指针与二重指针详解

一、引入——指针与子函数的关系:

  1. 什么是指针?

指针是一种特殊的变量,类似于一般的变量存放着数据,指针存放着地址,通过这个地址可以指向空间,从而操作该空间内的数据

  1. 普通变量、指针变量在子函数中不同表现:

#include "stdio.h"
void swi_normal(int a,int b);
void swi_point(int *a,int *b);
void main()
{int a=1,b=2;//分别用普通变量和指针变量进行操作,并打印出结果swi_normal(a,b);printf("normal:a %d b %d\n",a,b);swi_point(&a,&b);printf("point:a %d b %d\n",a,b);
}
//普通变量操作
void swi_normal(int a,int b)
{int temp;temp = a;a = b;b = temp;
}
//指针变量
void swi_point(int *a,int *b)
{int temp;temp = *a;*a = *b;*b = temp;
}

(1)结果:

通过第一个操作,a,b交换失败;而第二个操作,a,b交换成功

(2)分析:

因为第一个函数是传入数据,然后在子函数中在进行申请空间来存放数据,子函数结束后会自动释放这些空间;第一个函数是传入地址,子函数结束后不会释放这些空间

二、推广到二重指针:

  1. 以建立顺序表为例:

#include "stdio.h"
#include 
#define datatype int
#define MAXSIZE  4
typedef struct
{datatype data[MAXSIZE];        //存储顺序表中的元素int len;                        //顺序表的表长
}SeqList;                             //顺序表类型void CreatList_Normal(SeqList *L);
void CreatList_Point(SeqList **L);
SeqList *Init_SeqList();
void main()
{SeqList *L1,*L2;//初始化L1 = Init_SeqList();L2 = Init_SeqList();//输入数据CreatList_Normal(L1);CreatList_Point(&L2);//打印输入后的情况printf("Normal:%d  %d  %d\n",L1->data[1],L1->data[2],L1->data[3]);printf("Point: %d  %d  %d\n",L2->data[1],L2->data[2],L2->data[3]);
}SeqList *Init_SeqList()
{SeqList *L;L=(SeqList*)malloc(sizeof(SeqList));L->len=0;return L;
}void CreatList_Normal(SeqList *L)
{int i, n;printf("Input length of List: ");scanf("%d", &n);printf("Input elements of List: \n");for(i=1;i<=n;i++)scanf("%d", &L->data[i]);L->len=n;
}void CreatList_Point(SeqList **L)
{int i, n;printf("Input length of List: ");scanf("%d", &n);printf("Input elements of List: \n");for(i=1;i<=n;i++)scanf("%d", &(*L)->data[i]);(*L)->len=n;
}

(1)结果:

(2)分析:

两种方式没有区别,因为顺序表的结构体中只含有数据,只需要指向这些数据的地址就可以改变了,所以只需要一重指针。

  1. 以建立链表为例:

#include 
#include 
#define datatype char
typedef struct node
{datatype data;            //data为结点的数据信息struct node *next;      //next为指向后继结点的指针
}LNode;                                  //单链表结点类型void CreateLinkList_Normal(LNode *head);
void CreateLinkList_Point(LNode **head);
void main()
{LNode *L1,*L2;//对L1初始化,使L1存有某空间地址L1 = (LNode *)malloc(sizeof(LNode));//分别建立链表CreateLinkList_Normal(L1);CreateLinkList_Point(&L2);
}
void CreateLinkList_Normal(LNode *head)
{                       //将主调函数中指向待生成单链表的指针地址(如&p)传给*headchar x;LNode *p;head=(LNode *)malloc(sizeof(LNode)); //在主调函数空间生成链表头结点head->next=NULL;        //*head为链表头指针printf("L1 Input: \n");scanf("%c", &x);      //结点的数据域为char型,读入结点数据while(x!='\n')             //生成链表的其他结点{p=(LNode *)malloc(sizeof(LNode));     //申请一个结点空间p->data=x;p->next=head->next;       //将头结点的next值赋给新结点*p的nexthead->next=p;                //头结点的next指针指向新结点*p实现在表头插入scanf("%c", &x);            //继续生成下一个新结点}
}void CreateLinkList_Point(LNode **head)
{                       //将主调函数中指向待生成单链表的指针地址(如&p)传给**headchar x;LNode *p;*head=(LNode *)malloc(sizeof(LNode)); //在主调函数空间生成链表头结点(*head)->next=NULL;        //*head为链表头指针printf("L2 Input: \n");scanf("%c", &x);      //结点的数据域为char型,读入结点数据while(x!='\n')             //生成链表的其他结点{p=(LNode *)malloc(sizeof(LNode));     //申请一个结点空间p->data=x;p->next=(*head)->next;       //将头结点的next值赋给新结点*p的next(*head)->next=p;    //头结点的next指针指向新结点*p实现在表头插入scanf("%c", &x);            //继续生成下一个新结点}
}

(1)结果:

(2)分析:

我们可以看到L1的数据没有发生变化,还是刚初始化好的值,L2的数据发生了改变,为什么会这样呢?

单链表结点类型中包含了一个指针变量,在顺序表中我们只需要指向整型变量就行,而在链表中我们需要指向指针变量next,类似于第一个例子,我们要改变指针变量的值就要传指针变量的地址进去,我们就要用到指针的指针(地址的地址)——二重指针


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部