结构指针的使用

结构指针的使用

指针类型变量:

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

例如 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 );
}
相关推荐
薄荷故人_14 分钟前
从零开始的C++之旅——红黑树及其实现
数据结构·c++
努力学习编程的伍大侠25 分钟前
基础排序算法
数据结构·c++·算法
XiaoLeisj1 小时前
【递归,搜索与回溯算法 & 综合练习】深入理解暴搜决策树:递归,搜索与回溯算法综合小专题(二)
数据结构·算法·leetcode·决策树·深度优先·剪枝
Jackey_Song_Odd2 小时前
C语言 单向链表反转问题
c语言·数据结构·算法·链表
乐之者v2 小时前
leetCode43.字符串相乘
java·数据结构·算法
A懿轩A3 小时前
C/C++ 数据结构与算法【数组】 数组详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·数组
️南城丶北离4 小时前
[数据结构]图——C++描述
数据结构··最小生成树·最短路径·aov网络·aoe网络
✿ ༺ ོIT技术༻4 小时前
C++11:新特性&右值引用&移动语义
linux·数据结构·c++
菜鸡中的奋斗鸡→挣扎鸡11 小时前
滑动窗口 + 算法复习
数据结构·算法
axxy200013 小时前
leetcode之hot100---240搜索二维矩阵II(C++)
数据结构·算法