【c语言】结构体的访问

在这里插入图片描述

🎈个人主页:豌豆射手^
🎉欢迎 👍点赞✍评论⭐收藏
🤗收录专栏:C语言
🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步!

【c语言】结构体的访问

  • 一 通过结构体变量直接访问成员
  • 二 通过结构体指针访问成员
    • 2.1 概念
    • 2.2 原理
  • 总结

在这里插入图片描述

引言:

一 通过结构体变量直接访问成员

使用点运算符访问结构体变量成员的格式非常简单明了。

假设我们有一个结构体类型 struct_type 和一个该类型的变量 struct_variable,结构体中定义了一个或多个成员变量。要访问结构体变量中的某个成员,可以使用以下格式:

struct_variable.member_name;

其中:

  • struct_variable 是结构体变量的名称。
  • member_name 是结构体中定义的成员变量的名称。

例如,如果我们有一个结构体类型 Person,它包含 nameage 两个成员变量,我们可以如下定义结构体变量并访问其成员:

#include <stdio.h>

// 定义结构体类型 Person
struct Person {
    char name[50];
    int age;
};

int main() {
    // 定义结构体变量 person
    struct Person person;

    // 初始化结构体变量的成员
    strcpy(person.name, "John Doe"); // 使用 strcpy 函数复制字符串到 name 成员
    person.age = 30; // 直接赋值给 age 成员

    // 访问结构体变量的成员并打印
    printf("Name: %s\n", person.name); // 使用点运算符访问 name 成员
    printf("Age: %d\n", person.age); // 使用点运算符访问 age 成员

    return 0;
}

运行结果:

Name: John Doe
Age: 30

解释:

main 函数中,我们定义了一个 Person 类型的结构体变量 person,并初始化其 name 成员为 “John Doe”,age 成员为 30。然后,我们使用 printf 函数和点运算符 (.) 来访问并打印 personnameage 成员。因此,程序输出这两行文本,分别是结构体变量 personnameage 成员的值。

注意,当成员变量是一个数组或结构体时,你仍然可以使用点运算符来访问数组的元素或结构体的成员。如果成员变量是一个指针,你还可以使用点运算符通过该指针访问它指向的数据。

例如:

以下是一个代码例子,演示了当结构体成员是数组、另一个结构体以及指针时,如何使用点运算符(.)来访问这些成员:

#include <stdio.h>
#include <string.h>

// 定义一个内部结构体
struct Address {
    char street[50];
    char city[50];
};

// 定义一个包含数组、内部结构体和指针的外部结构体
struct Student {
    char name[50];
    int grades[3]; // 数组
    struct Address address; // 内部结构体
    char *hobby; // 指针
};

int main() {
    // 初始化一个Student结构体变量
    struct Student student;

    // 初始化name成员
    strcpy(student.name, "Alice");

    // 初始化grades数组
    student.grades[0] = 90;
    student.grades[1] = 85;
    student.grades[2] = 92;

    // 初始化address结构体成员
    strcpy(student.address.street, "123 Main St");
    strcpy(student.address.city, "New York");

    // 初始化hobby指针成员
    student.hobby = "Reading";

    // 访问并打印成员
    printf("Name: %s\n", student.name);
    printf("Grades: %d, %d, %d\n", student.grades[0], student.grades[1], student.grades[2]);
    printf("Address: %s, %s\n", student.address.street, student.address.city);
    printf("Hobby: %s\n", student.hobby);

    return 0;
}

代码结果:

Name: Alice
Grades: 90, 85, 92
Address: 123 Main St, New York
Hobby: Reading

代码分析:

  1. 我们定义了两个结构体类型,AddressStudentAddress 包含 streetcity 两个成员,用于存储地址信息。Student 包含 name(名字),grades(一个整数数组,存储三门课程的成绩),address(一个 Address 类型的结构体成员,存储地址信息),以及 hobby(一个字符指针,指向存储爱好的字符串)。

  2. main 函数中,我们创建了一个 Student 类型的变量 student 并初始化了它的各个成员。对于数组 grades,我们使用点运算符直接访问其元素。对于 Address 类型的成员 address,我们也使用点运算符访问其 streetcity 成员。对于 hobby 指针成员,我们同样使用点运算符来访问它指向的字符串。

  3. 最后,我们使用 printf 函数和点运算符来打印 student 的各个成员的值。这包括 namegrades 数组中的元素、address 结构体的 streetcity 成员,以及 hobby 指针指向的字符串。

注意,在这个例子中,hobby 是一个指向字符串的指针,而不是字符串本身。因此,当我们使用 student.hobby 时,我们实际上是在访问这个指针,并通过它间接访问存储的字符串。如果 hobby 指向的字符串是动态分配的,那么在不再需要它时,需要确保释放相应的内存以避免内存泄漏。

需要特别注意的是,点运算符只能用于直接访问结构体变量(而不是指向结构体的指针)的成员。如果你有一个指向结构体的指针,你应该使用箭头运算符 (->) 来访问结构体的成员。

二 通过结构体指针访问成员

2.1 概念

结构体指针是指向结构体变量的指针,可以通过该指针来访问结构体的成员。

通过结构体指针访问成员的方式主要涉及到两个操作符:->*

  1. 使用 “->” 操作符:当你有一个指向结构体的指针时,可以使用 “->” 操作符来直接访问结构体的成员。

例如,假设你有以下的结构体定义和指针:

typedef struct {
    int id;
    char name[50];
} Person;

Person p1;
Person *ptr = &p1;

你可以这样使用 “->” 操作符来访问结构体的成员:

ptr->id = 1;
strcpy(ptr->name, "John Doe");
  1. 使用 “*” 操作符与 “.” 操作符组合:你也可以先使用 “*” 操作符来解引用结构体指针,得到一个结构体变量,然后再使用 “.” 操作符来访问其成员。

例如:

(*ptr).id = 1;
strcpy((*ptr).name, "John Doe");

这两种方式是等价的,但通常,使用 “->” 操作符更为简洁和直观。

总结:通过结构体指针访问成员主要涉及到 “->” 操作符或 “*” 与 “.” 的组合。在实际编程中,根据具体情况和个人习惯选择合适的方式。

2.2 原理

通过结构体指针访问成员的原理主要涉及到指针运算和内存布局的概念。

首先,理解指针的基本概念很重要。在C语言中,指针是一个变量,它存储的是另一个变量的内存地址。当你有一个指向结构体类型的指针时,这个指针存储的是该结构体在内存中的起始地址。

结构体在内存中的布局是连续的。结构体中的每个成员都按照它们在结构体定义中的顺序占据一定的内存空间。这些内存空间是连续的,从结构体的起始地址开始,一直延伸到结构体的末尾。

->运算符就是用来通过结构体指针访问其成员的一种语法糖。当你使用pStudent->id这样的表达式时,编译器会执行以下步骤:

  1. 获取pStudent指针所存储的地址,即结构体的起始地址。
  2. 根据id成员在结构体中的偏移量(从结构体起始地址到id成员首地址的距离),计算出id成员在内存中的实际地址。
  3. 通过这个地址访问id成员的值。

偏移量是在编译时确定的,它取决于结构体中每个成员的类型和顺序。编译器知道如何根据结构体的定义来计算每个成员的偏移量。

因此,通过结构体指针访问成员的原理就是利用指针所存储的地址信息,结合结构体成员在内存中的布局和偏移量,来间接访问结构体的成员。这种方式允许程序在不知道结构体具体实例的情况下,通过指针来操作结构体的数据,提高了代码的灵活性和可重用性。

总结

这篇文章到这里就结束了

谢谢大家的阅读!

如果觉得这篇博客对你有用的话,别忘记三连哦。

我是豌豆射手^,让我们我们下次再见

在这里插入图片描述

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

记录 OpenHarmony 使用 request.uploadFile 时踩的坑

​ 开发环境 设备环境&#xff1a;OpenHarmony 4.1.x SDK 版本&#xff1a;API 10 开发模型&#xff1a;Stage 模型 IDLE: Dev Eco 4.1 官方文档 踩坑一&#xff1a;后台服务地址 上传文件依赖后台服务器&#xff0c;如果使用本地搭建的服务&#xff0c;是无法访问的&…

两部电话机怎样能实现对讲?直接连接能互相通话吗?门卫门房传达室岗亭电话怎么搞?

目录 两部电话机能直接连接吗&#xff1f;用三通头分出来一条电话线两部电话机用一根电话线直接连接能互相通话吗&#xff1f; 什么电话机可以直接连接两部IP电话机&#xff08;网络电话机&#xff09;可以直接连接两部普通电话机之间通过一个电话交换机也可以连接跨区域的两部…

Avalonia中嵌入网页程序(CefNet)

Avalonia中嵌入网页程序cefNet 1. 引入CefNetNuget包2. 下载 cef 基础环境3. 将cef基础环境放入程序运行目录下4. 代码中初始化cef5. 添加Webview控件6. 在窗口关闭的时候释放Cef7. 项目结构图CefNet 开源的作者已经停止维护并删除了原始的代码库:GetHub:CefNet,Nuget上还有发…

【简单介绍下单片机】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

Python编程之旅:深入探索强大的容器——列表

在Python编程的世界中&#xff0c;容器&#xff08;Containers&#xff09;是一种用于存储多个项目的数据结构。其中&#xff0c;列表&#xff08;List&#xff09;是最常用且功能强大的容器之一。无论是初学者还是资深开发者&#xff0c;掌握列表的使用方法和技巧都是提升Pyth…

引导和服务(2)

服务 1.systemd服务的简要介绍 &#xff08;1&#xff09;对比5 6 可以解决依赖关系并行启动 &#xff08;2&#xff09;按需启动 &#xff08;3&#xff09;自动解决依赖关系 负责在系统启动或运行时&#xff0c;激活系统资源&#xff0c;服务器进程和其它进程 2.System…

Python 处理地理空间异常值:基于 MAD 的简单方法

就像任何其他数据一样,在处理地理空间数据时,识别和纠正异常值是数据准备中的关键步骤,可确保任何后续分析的准确性。异常值可能会严重扭曲空间分析的结果,从而导致错误的结论。虽然还有其他方法可以解决此问题,但处理这些异常值的一种直接有效的方法是使用中值绝对偏差 (…

第十一届土木与城市工程国际会议(ICCUE 2024)即将召开!

第十一届土木与城市工程国际会议&#xff08;ICCUE 2024&#xff09;将于2024年8月20-22日在意大利罗马召开。土木与城市工程&#xff0c;作为人类社会发展的重要基石&#xff0c;承载着推动城市繁荣、提升人民生活质量的重任。ICCUE 2024的召开&#xff0c;旨在搭建一个国际化…

HDLbits 刷题 --Mux2to1

Create a one-bit wide, 2-to-1 multiplexer. When sel0, choose a. When sel1, choose b. 译&#xff1a; 创建一个1位宽的2对1多路复用器。当sel0时&#xff0c;选择a。当sel1时&#xff0c;选择b。 个人解法&#xff1a; module top_module( input a, b, sel,output out …

IO流-IO框架

简介 java的IO流操作提供了最简单的操作&#xff0c;第三方基于日常使用习惯&#xff0c;写了很多IO框架&#xff0c;更加方便操作避免重复造轮子&#xff0c;提高开发效率 Commons-io 简介 Commons-io是apche提供的IO操作的小框架 部分常用的API 引入依赖 <dependency>…

mbti,ESFP型人格的心理问题分析

什么是ESFP型人格&#xff1f; ESFP分别代表的是外向&#xff0c;实感&#xff0c;情感和依赖&#xff0c;ESFP型人格则是一种性格上活泼开朗&#xff0c;富有同情心的一种性格&#xff0c;具有这种人格的人在日常生活当中&#xff0c;社交能力十分突出&#xff0c;活泼开朗&a…

高级IO和5种IO模型

目录 1. 高级IO1.1 IO的基本概念1.2 OS如何得知外设当中有数据可读取1.3 OS如何处理从网卡中读取到的数据包1.4 IO的步骤 2. 五种IO模型2.1 利用钓鱼来理解2.2 阻塞IO2.3 非阻塞IO2.4 信号驱动IO2.5 IO多路转接2.6 异步IO 3. 高级IO的概念3.1 同步通信 VS 异步通信3.2 阻塞 VS …

《剑指 Offer》专项突破版 - 面试题 107 : 矩阵中的距离(C++ 实现)

题目链接&#xff1a;矩阵中的距离 题目&#xff1a; 输入一个由 0、1 组成的矩阵 M&#xff0c;请输出一个大小相同的矩阵 D&#xff0c;矩阵 D 中的每个格子是矩阵 M 中对应格子离最近的 0 的距离。水平或竖直方向相邻的两个格子的距离为 1。假设矩阵 M 中至少有一个 0。 …

JavaEE:HTTP协议

基本内容 网站 后端&#xff08;HTTP服务器&#xff09; 前端&#xff08;浏览器&#xff09;&#xff0c;而后端和前端都需要遵循HTTP协议 HTTP属于超文本传输协议&#xff0c;存在于应用层 文本&#xff1a;一般能在utf8或者gbk上找到的合法字符串 超文本&#xff1a;不仅…

Jmeter 性能-死锁问题定位+分析

1、环境搭建 ①准备脚本&#xff0c;执行压测 ②用Jstack 打印日志 jstack 112759 >dead.log ③下载日志到本地 sz dead.log 2、问题定位 ①打开dead.log&#xff0c;搜索deadlock ②查看死锁的线程 ③查看死锁位置 3、问题分析 ①下载死锁的类文件 Sz CaseControlle…

为什么公共云的弹性能力很难被发挥出来?

作者&#xff5c;王小瑞 AutoMQ 联合创始人 & CEO 云计算通过资源池化实现单位资源成本更优&#xff0c;使企业能够将 IDC 建设、基础软件研发和运维等工作外包给云厂商&#xff0c;从而更专注于业务创新。资源池不仅包括服务器&#xff0c;还包括人才。云厂商集聚了优秀…

Java链式编程

一&#xff1a;链式编程 可以简化编程。代码简洁。 定义&#xff1a; 链式编程&#xff1a;顾名思义&#xff0c;链子嘛。它是一种编程范式&#xff0c;它允许将多个函数或操作连接在一起&#xff0c;形成一个链条&#xff0c;以执行复杂的操作。 优点&#xff1a; 编程性…

酒店水电智能化管理解决方案

在酒店行业中&#xff0c;水电能源的高效管理是实现可持续发展与降低运营成本的关键。酒店水电智能化管理解决方案通过运用先进技术&#xff0c;实现了对酒店水电资源的高效、智能监控与管理。本文将从解决方案的背景、核心技术以及带来的效益三个方面全面介绍该解决方案。 解…

快速掌握乡村振兴展厅设计要点,打造令人瞩目的展示效果!

基于数字多媒体技术研发的多媒体互动装置&#xff0c;给展览展示行业带来了巨大的创新和改变&#xff0c;这种将现代科技与传统展厅相融合的展示形式&#xff0c;做到了一馆多用的功能建设&#xff0c;而这一特性也为乡村文化和历史传承提供了更好的平台。那么&#xff0c;下面…

keil创建单片机工程

一、创建工程 打开Keil uVision4&#xff0c;依次选择 Project—>New uVision4 Project&#xff0c;选择工程保存路径及填写工程名称&#xff0c;如下图 然后点“保存”。在Select a CPU Data Base File中选择"STC MCU Database"&#xff0c;点 "OK"&am…