结构指针的使用

结构指针的使用

指针类型变量:

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

例如 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 );
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/736013.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

体系班第十三节

1判断完全二叉树递归做法 有四种情况&#xff1a;1 左树完全&#xff0c;右数满&#xff0c;且左高为右高加一 2左满 &#xff0c;右满&#xff0c;左高为右高加一 3左满&#xff0c;右完全&#xff0c;左右高相等 4左右均满且高相等 #include<iostream> #include&l…

转移表回调函数实现

回调函数实现 计算器的模拟&#xff08;函数指针数组的使用&#xff09;&#xff08;回调函数&#xff09; 简化 冗余 老的代码的问题就是 冗余 写死 不能完成不同的任务 函数调用的时候只需要知道地址就可以 calc计算器 这里也称之为转移表 #define _CRT_SECURE_NO_WAR…

出现“error: failed to push some refs to ‘https://github.com/****.git‘”,如何解决问题

一、出错情况&#xff1a; 今天继续推送整理的知识点的时候&#xff0c;出现了一个报错。“error: failed to push some refs to https://github.com/.git”&#xff0c;百思不得其解&#xff0c;之前推送的时候都可以轻松推送成功&#xff0c;如今却说本地库与远程库不一致。…

腾讯云轻量应用服务器“月流量”什么意思?用完了怎么办?

腾讯云轻量应用服务器“月流量”什么意思&#xff1f;就是限制月流量的意思。腾讯云轻量服务器流量用完了怎么办&#xff1f;超额部分的流量另外支付流量费&#xff0c;流量价格为0.8元/GB&#xff0c;会自动扣你的腾讯云余额&#xff0c;如果你的腾讯云账号余额不足&#xff0…

Git win与linux换行符转换的问题

转载&#xff1a;warning: in the working copy of ‘package-lock.json‘, LF will be replaced by CRLF the next time Git_warning: in the working copy of package.json, lf-CSDN博客 warning: in the working copy of ‘package-lock.json‘, LF will be replaced by CRL…

ModStartBlog 稳定版 v9.0.0

ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用&#xff0c;支持后台一键快速安装&#xff0c;让开发者能快的实现业务功能开发。系统完全开源&#xff0c;基于 Apache 2.0 开源协议。 功能特性 丰富的模块市场&#xff0c;后台一键快速安装 会…

C++ Function Templates (函数模板)

C Function Templates [函数模板] 1. Templates and Generic Programming (模板与泛型编程)2. Defining a Function Templates (定义函数模板)2.1. Instantiating a Function Template (实例化函数模板)2.2. Template Type Parameters (模板类型参数)2.3. Nontype Template Par…

【实战项目】Boost搜索引擎项目

目录 1. 项目的相关背景 2. 搜索引擎的相关宏观原理 3. 搜索引擎技术栈和项目环境 4. 正排索引 vs 倒排索引 - 搜索引擎具体原理 4.1 正排索引 4.2 目标文档进行分词 4.3 倒排索引 4.4 模拟一次查找的过程&#xff1a; 5. 编写数据去标签与数据清洗的模块 Parser 5.1…

《操作系统真相还原》读书笔记八:获取物理内存容量以及本书源代码

编写mbr.S汇编代码 ;LOADER_BASE_ADDR equ 0x900 ;LOADER_START_SECTOR equ 0x2 %include "boot.inc"SECTION MBR vstart0x7c00mov ax,csmov ds,axmov es,axmov ss,axmov fs,axmov sp,0x7c00mov ax,0xb800mov gs,axmov ax,0x0600mov bx,0x0700mov cx,0mov dx, 184fh…

力扣图论篇

以下思路来自代码随想录以及官方题解。 文章目录 797.所有可能的路径200.岛屿数量130.被围绕的区域1020.飞地的数量 797.所有可能的路径 给你一个有 n 个节点的 有向无环图&#xff08;DAG&#xff09;&#xff0c;请你找出所有从节点 0 到节点 n-1 的路径并输出&#xff08;不…

USB协议学习(三)大容量存储设备SCSI协议分析

笔者来简单介绍一下SCSI得协议命令 1、SCSI协议认识 SCSI&#xff1a;Small Computer System Interface&#xff0c;用于计算机外部设备得接口标准&#xff0c;定义了与外部设备得一套协议。SCSI标准协议族支持很多钟SCSI设备&#xff0c;像盘&#xff0c;打印机&#xff0c;扫…

Ubuntu23.10安装FFmpeg及编译FFmpeg源码

安装FFmpeg: 打开终端: 输入 sudo apt install ffmpeg 安装成功: 验证FFmpeg 默认安装位置与库与头文件位置 使用FFmpeg源码编译: 1.安装YASM sudo apt-get install yasm

[mmucache]-ARMV8-aarch64的虚拟内存(mmutlbcache)介绍-概念扫盲

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《C》 《Linux》 《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 思考: 1、cache的entry里都是有什么&#xff1f; 2、TLB的entry里都是有什么? 3、MMU操作…

10-ARM gicv3/gicv4的总结-基础篇

目录 1、gic的版本2、GICv3/gicv4的模型图3、gic中断号的划分4、GIC连接方式5、gic的状态6、gic框架7、gic Configuring推荐 本文转自 周贺贺&#xff0c;baron&#xff0c;代码改变世界ctw&#xff0c;Arm精选&#xff0c; armv8/armv9&#xff0c;trustzone/tee&#xff0c;s…

遗传算法(GA)求解基于栅格地图的机器人最优路径规划,可以自行修改地图(提供MATLAB代码)

通过栅格法建立栅格地图作为机器人路径规划的工作环境,采用遗传算法作为机器人路径搜索的规则.将所有机器人放置于初始位置.经过NC次无碰撞迭代运动找到最优路径.到达目标位置.为防止机器人在路径搜索过程中没有达到最大迭代次数时路径大小已不发生变化而陷入局部最优。 一、部…

JavaWeb-Maven基础

Maven是专门用于管理和构建Java项目的工具&#xff0c;是 Apache 下的一个纯 Java 开发的开源项目&#xff0c;基于项目对象模型&#xff08;POM&#xff09;概念。先来学习一下Maven基础&#xff0c;等后面学完开发框架后再学Maven高级&#xff0c;这次的内容如下 一、概述 …

Linux学习——线程的控制

目录 ​编辑 一&#xff0c;线程的创建 二&#xff0c;线程的退出 1&#xff0c;在子线程内return 2,使用pthread_exit(void*) 三&#xff0c;线程等待 四&#xff0c;线程获取自己的id值 五&#xff0c;线程取消 六&#xff0c;线程分离 一&#xff0c;线程的创建 在对…

企微hook源码

企微hook源码已经在QQ群内开源。速度进群下载&#xff0c;避免和谐。 QQ群&#xff1a;649480745 //pc端发送消息回调 void RecvPcMsgRes(DWORD eax) { // OutputDebugStringA("pc发送消息"); PWX_STRING pMsgPb (PWX_STRING)(eax);//消息pb结构体 string pbDa…

打卡--MySQL8.0 一(单机部署)

一路走来&#xff0c;所有遇到的人&#xff0c;帮助过我的、伤害过我的都是朋友&#xff0c;没有一个是敌人。如有侵权&#xff0c;请留言&#xff0c;我及时删除&#xff01; MySQL 8.0 简介 MySQL 8.0与5.7的区别主要体现在&#xff1a;1、性能提升&#xff1b;2、新的默认…

鸿蒙开发学习入门教程之环境配置

最近鸿蒙开发越来越火&#xff0c;各个大厂都有鸿蒙版本的计划和宣传&#xff0c;看这个趋势&#xff0c;可能会在几年内发展壮大&#xff0c;为我们移动端码农开辟一片新的职场。所以现在开始学起来还是很有必要的。今天就一起开始配置环境搞起来吧。 首先&#xff0c;找到官…