结构指针的使用

结构指针的使用

指针类型变量:

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

例如 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

示例程序如下:

cpp 复制代码
#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的位置,从而打印数据。

如图所示:

示例程序:

cpp 复制代码
#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

如图所示:

示例程序如下:

cpp 复制代码
#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 );
}
相关推荐
wheeldown7 小时前
【数据结构】选择排序
数据结构·算法·排序算法
躺不平的理查德11 小时前
数据结构-链表【chapter1】【c语言版】
c语言·开发语言·数据结构·链表·visual studio
阿洵Rain11 小时前
【C++】哈希
数据结构·c++·算法·list·哈希算法
Leo.yuan12 小时前
39页PDF | 华为数据架构建设交流材料(限免下载)
数据结构·华为
半夜不咋不困12 小时前
单链表OJ题(3):合并两个有序链表、链表分割、链表的回文结构
数据结构·链表
忘梓.13 小时前
排序的秘密(1)——排序简介以及插入排序
数据结构·c++·算法·排序算法
y_m_h15 小时前
leetcode912.排序数组的题解
数据结构·算法
1 9 J15 小时前
数据结构 C/C++(实验三:队列)
c语言·数据结构·c++·算法
921正在学习编程15 小时前
数据结构之二叉树前序,中序,后序习题分析(递归图)
c语言·数据结构·算法·二叉树
毕竟秋山澪16 小时前
岛屿数量 广搜版BFS C#
数据结构·算法·宽度优先