结构指针的使用

本文详细介绍了结构指针的概念,包括指针变量的使用、结构体变量的地址存储、结构指针在链表中的应用,以及指针作为参数传递给函数时的不同情况,包括拷贝和修改指针值的情况。
摘要由CSDN通过智能技术生成

结构指针的使用

指针类型变量:

指针类型,是变量类型的一种,它是专门用来存储变量的地址的。

例如 int *p;  表示p是一个指针变量,它用来存储某个整型变量的地址。

int  a=5;

int *p=&a;

这样,就将整型变量a的地址存储在了p中。

如图示所示:

变量a中存储的是5,它自身的地址是 0x001A

变量p中存储的是0x001A,也就是a的地址,它自身的地址是0x10AB

下面是一个结构指针:

//定义结点数据类型:

typedef  struct

{

 float  coef;

 int   expn;

}term, ElemType;

//定义结点,及指向结点的指针

typedef  struct  LNode

{

 ElemType  data;

 struct  LNode  *next;   

}LNode, *LinkList;

这里,定义了一个链表的结点,它的数据项包括 coef, expn,就是系数和指数。还包括一个指向下一个结点的指针。

给这个结构定义了两个别名:

一个是LNode,用来代替struct  LNode

还有一个是LinkList,是指向结点的指针,用来代替 struct  LNode  *

如果定义了这样一个变量p: LinkList  p;

那么它就是一个指向结点的指针,它在内存中的存储可以用下图表示:

这个指针变量p是用来存储结构型变量的地址的。

具体说就是这种结构型变量的地址:struct  LNode别名为LNode。现在,它的值是空的,因为还没有为它赋值。指针变量本身也需要占用内存空间,因此,指针变量p本身的内存地址是0xA01C。

现在,定义一个结构型变量:

LNode  n1;  假设它的地址是 0x013B

给这个结构型变量赋值:

n1.coef=1.5;

n1.expn=2;

n1.next=NULL

那么它在内存中的存储情况如图:

之后,把结点n1的地址赋值给指针 p

p=&n1;  &是取地址符号

当使用*p时候,*称为引用符号,就是对结构型变量n1的引用,就是顺着p存储的地址0x013B找到结构型变量n1,并使用它。例如,(*P).coef 是1.5  (*p).expn是2。

还有一种使用结构指针的方法,就是用 ->代替 (*).因为前者意义明确,书写简洁。可以写成这样:p->coef  或 p->expn

示例程序如下:

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

typedef struct 
{
 float coef;
 int   expn;
}term, ElemType;


typedef struct LNode
{
 ElemType      data;
 struct LNode *next;	
}LNode, *LinkList;



main()
{
 LNode n1;
 LinkList p;
 
 n1.data.coef = 1.5; 
 n1.data.expn = 2; 
 n1.next = NULL; 
 
 p=&n1;
 
 printf("coef=%f  expn=%d \n",(*p).data.coef, (*p).data.expn);		
}

指针作为参数传递给函数:

一种情况是,传递指针的拷贝。即指针作为实参,被调用函数中是形参。形参就像临时变量一样,当函数调用结束后就自动销毁掉了。

例如,有这样一个结构体变量n1,它在内存中的地址是0x013B,它包括两个数据成员coef=1.5,expn=2,和一个指向下一个结点的指针next=NULL。

有一个指针变量p它的地址是0xA01C,将结构体变量n1的地址赋值给p

p=&n1;  此时,p的值为0x013B。

现在,想要在一个函数func中打印结构体n1的数据,那么指针p的值将作为实参,拷贝一份给形参pf。注意,这里实参p和形参pf的地址是不一样的。

在func函数中可以引用pf中的地址值,找到结构体n1的位置,从而打印数据。

如图所示:

示例程序:

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

typedef struct 
{
 float coef;
 int   expn;
}term, ElemType;


typedef struct LNode
{
 ElemType      data;
 struct LNode *next;	
}LNode, *LinkList;


void func(LinkList pf)
{
 printf("coef=%f  expn=%d \n",(*pf).data.coef, (*pf).data.expn);		
}

main()
{
 LNode n1;
 LinkList p;
 
 n1.data.coef = 1.5; 
 n1.data.expn = 2; 
 n1.next = NULL; 
 
 p=&n1;
 
 func(p);	
}

还有一种情况:

如果需要改变指针本身的值,就不能只是传递指针的拷贝,而是需要传递指针的地址:

例如,定义了两个结构体结点n1,n2。如果需要在函数func中将指针p的值修改为n2的地址,那么就需要传递指针的地址过去,如果只是修改形参的值,不会对实参p起到任何影响,如图所示:

如何在函数func中修改实参p的值为0x015F,使它指向结点n2呢?那就需要在给func传递参数的时候,传递的是p的地址:func(&p)。&是取地址符号,也就是传递的是0xA01C,之后在func中对此地址进行引用,就能修改p的值了。

但是这时,形参的类型不再是LinkList型了,而是 LinkList *,也就是指向指针的指针,也就是一个二级指针,如果不用别名,而是写完整的话,应该是:

func(struct LNode **pf )  用定义好的别名简写成 func(LinkList * pf)

pf是一个指针,它存储的是某种数据类型的地址。

哪种数据呢?是一个指针类型。

指向什么的指针呢?指向结构struct LNode的指针。

对pf的引用,首先找到p,即*pf

再对p引用,又找到n2,即*(*pf)

因此(**pf).data.coef 应该是 2.5  (**pf).data.expn 应该是3

如图所示:

示例程序如下:

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

typedef struct 
{
 float coef;
 int   expn;
}term, ElemType;


typedef struct LNode
{
 ElemType      data;
 struct LNode *next;	
}LNode, *LinkList;

LNode n1,n2; 

//在函数中修改指针所指向的值 
void func(LinkList *pf)
{
 *pf=&n2;	
 printf("在函数func中打印 coef= %f  expn = %d\n",(**pf).data.coef, (**pf).data.expn);
}


main()
{
 LinkList p;
 
 n1.data.coef = 1.5; 
 n1.data.expn = 2; 
 n1.next = NULL; 
 
 n2.data.coef = 2.5;
 n2.data.expn = 3;
 n2.next = NULL;
 
 //是p指向 结点 n1 
 p=&n1;
 //打印其值 
 printf("coef=%f  expn=%d\n",p->data.coef , p->data.expn );
 
 //改变指针p的指向 
 printf("改变p值后\n");
 func(&p);	
 
 //打印其值 
 printf("在主函数中打印\n");
 printf("coef=%f  expn=%d\n",p->data.coef , p->data.expn );
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值