关于指针在结构体中的调用

2024-06-06 06:08
文章标签 指针 调用 结构 体中

本文主要是介绍关于指针在结构体中的调用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在学习《数据结构》编程时遇到一些问题,是关于C语言指针的。

这里就没有必要上传整个工程源码了,而只将问题本质总结如下:(若有问题还请各位指正)

typedef struct
{int dat;int *ptr;
}Sample;Sample	temp;printf("%d\n",&temp.dat);	//输出temp.dat的地址
printf("%d\n",&temp.ptr);	//输出temp.ptr的地址
printf("%d\n",temp.dat);	//输出temp.dat中存放的数值,该数值就是一个普通数值。
printf("%d\n",temp.ptr);	//输出temp.ptr中存放的数值,该数值也是一个地址,但是是默认分配的地址,未被初始化。

执行结果如下:

 

下面开始分析。

为便于分析,可将上述执行结果总结在下表中:

&temp.dat1245020

temp.dat-858993460

&temp.ptr1245024

temp.ptr-858993460

 

下面两条语句都不正确:

printf("%d\n",*temp.dat); //非法的,因为dat并非指针变量
printf("%d\n",*temp.ptr); //编译无错,但是执行时会出错,因为此时指针ptr没有被初始化,它不指向任何内存,temp.ptr中存放的是默认的数值-858993460。而*temp.ptr是取指针变量所指存储空间的内容,暂时就认为-858993460
所指存储空间并不存在或者该存储空间的内容不可取,具体原因也许哪一天会通过别的渠道得知。

 

若执行下面两条语句:

 scanf("%d",&temp.dat);
 scanf("%d",&temp.ptr);

比如说执行时输入1和2,则上表变内容变成如下所示:

&temp.dat1245020

temp.dat1

&temp.ptr1245024

temp.ptr2

若此时再执行下面四条语句:

printf("%d\n",&temp.dat); //输出temp.dat的地址,当然还是1245020

printf("%d\n",&temp.ptr); //输出temp.ptr的地址,当然还是1245024

printf("%d\n",temp.dat); //输出temp.dat中存放的数值1,该数值就是一个普通数值

printf("%d\n",temp.ptr); //输出temp.ptr中存放的数值2,该数值是一个地址,即地址单元为2存储空间。

地址为2的存储单元一般是不可写也不可读的。

比如在执行语句scanf("%d",temp.ptr)和语句printf("%d\n",*temp.ptr)时都是错误的,但当temp.ptr指向了确定的存储空间时,这两条语句便是正确的了。

 

若执行语句 temp.ptr = (int *)malloc(sizeof(int)) 后,再执行scanf("%d",temp.ptr)和printf("%d\n",*temp.ptr),就是可以的了,因为此时temp.ptr执向一个确定的存储空间,该存储空间是由malloc函数分配的。

 

上面所有的分析都是基于定义了Sample temp,即定义了Sample类型的变量temp,倘若要是定义Sample类型的指针变量*temp呢?

若定义的是Sample类型的指针变量*temp,则也要对其初始化,使其指向一个确定的存储空间,否则temp自己都不指向确定的存储空间,更别说temp下的dat和ptr了。

初始化方式如下(也可叫作分配存储空间):

temp = (Sample *)malloc(sizeof(Sample));

在初始化后,便可操作temp结构了,但要注意此时的temp.ptr并没有初始化,它并没有指向任何确定的存储空间,temp.ptr的初始化方式在前面已经说了。

在初始化temp之后,后面的操作与上文类似。

这篇关于关于指针在结构体中的调用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1035288

相关文章

go 指针接收者和值接收者的区别小结

《go指针接收者和值接收者的区别小结》在Go语言中,值接收者和指针接收者是方法定义中的两种接收者类型,本文主要介绍了go指针接收者和值接收者的区别小结,文中通过示例代码介绍的非常详细,需要的朋友们下... 目录go 指针接收者和值接收者的区别易错点辨析go 指针接收者和值接收者的区别指针接收者和值接收者的

Java Optional避免空指针异常的实现

《JavaOptional避免空指针异常的实现》空指针异常一直是困扰开发者的常见问题之一,本文主要介绍了JavaOptional避免空指针异常的实现,帮助开发者编写更健壮、可读性更高的代码,减少因... 目录一、Optional 概述二、Optional 的创建三、Optional 的常用方法四、Optio

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

使用Java实现通用树形结构构建工具类

《使用Java实现通用树形结构构建工具类》这篇文章主要为大家详细介绍了如何使用Java实现通用树形结构构建工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录完整代码一、设计思想与核心功能二、核心实现原理1. 数据结构准备阶段2. 循环依赖检测算法3. 树形结构构建4. 搜索子

在C#中调用Python代码的两种实现方式

《在C#中调用Python代码的两种实现方式》:本文主要介绍在C#中调用Python代码的两种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#调用python代码的方式1. 使用 Python.NET2. 使用外部进程调用 Python 脚本总结C#调

利用Python开发Markdown表格结构转换为Excel工具

《利用Python开发Markdown表格结构转换为Excel工具》在数据管理和文档编写过程中,我们经常使用Markdown来记录表格数据,但它没有Excel使用方便,所以本文将使用Python编写一... 目录1.完整代码2. 项目概述3. 代码解析3.1 依赖库3.2 GUI 设计3.3 解析 Mark

SpringCloud之LoadBalancer负载均衡服务调用过程

《SpringCloud之LoadBalancer负载均衡服务调用过程》:本文主要介绍SpringCloud之LoadBalancer负载均衡服务调用过程,具有很好的参考价值,希望对大家有所帮助,... 目录前言一、LoadBalancer是什么?二、使用步骤1、启动consul2、客户端加入依赖3、以服务

Vue 调用摄像头扫描条码功能实现代码

《Vue调用摄像头扫描条码功能实现代码》本文介绍了如何使用Vue.js和jsQR库来实现调用摄像头并扫描条码的功能,通过安装依赖、获取摄像头视频流、解析条码等步骤,实现了从开始扫描到停止扫描的完整流... 目录实现步骤:代码实现1. 安装依赖2. vue 页面代码功能说明注意事项以下是一个基于 Vue.js

讯飞webapi语音识别接口调用示例代码(python)

《讯飞webapi语音识别接口调用示例代码(python)》:本文主要介绍如何使用Python3调用讯飞WebAPI语音识别接口,重点解决了在处理语音识别结果时判断是否为最后一帧的问题,通过运行代... 目录前言一、环境二、引入库三、代码实例四、运行结果五、总结前言基于python3 讯飞webAPI语音

C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)

《C#集成DeepSeek模型实现AI私有化的流程步骤(本地部署与API调用教程)》本文主要介绍了C#集成DeepSeek模型实现AI私有化的方法,包括搭建基础环境,如安装Ollama和下载DeepS... 目录前言搭建基础环境1、安装 Ollama2、下载 DeepSeek R1 模型客户端 ChatBo