【c语言】结构体的访问

news2024/11/22 7:03:11

在这里插入图片描述

🎈个人主页:豌豆射手^
🎉欢迎 👍点赞✍评论⭐收藏
🤗收录专栏: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成员的值。

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

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

总结

这篇文章到这里就结束了

谢谢大家的阅读!

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

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

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

力扣HOT100 - 41. 缺失的第一个正数

解题思路&#xff1a; 原地哈希 就相当于&#xff0c;让每个数字n都回到下标为n-1的家里。 而那些没有回到家里的就成了孤魂野鬼流浪在外&#xff0c;他们要么是根本就没有自己的家&#xff08;数字小于等于0或者大于nums.size()&#xff09;&#xff0c;要么是自己的家被别…

51-37 由浅入深理解 Stable Diffusion 3

2024年3月5日&#xff0c;Stability AI公开Stable Diffusion 3论文&#xff0c;Scaling Rectified Flow Transformers for High-Resolution Image Synthesis。公司像往常一样承诺后续将开源代码&#xff0c;开源之光&#xff01;&#xff01;&#xff01; 在LDW潜在扩散模型论文…

学习51单片机必备:从电子基础到编程技巧全解析

学习51单片机需要掌握一系列的基础知识和技能&#xff0c;以下是一些主要的学习内容&#xff1a; 电子基础知识 了解基本的电子元件和电路原理是学习单片机的基础。这有助于理解单片机如何与外围设备交互以及如何设计电路。 数字逻辑 理解数字逻辑和布尔代数&#xff0c;对于编…

第十三届蓝桥杯真题:x进制减法,数组切分,gcd,青蛙过河

目录 x进制减法 数组切分 gcd 青蛙过河 x进制减法 其实就是一道观察规律的题。你发现如果a这个位置上的数x&#xff0c;b这个位置上的数是y&#xff0c;那么此位置至少是max(x,y)1进制。一定要把位置找对啊 #include <bits/stdc.h> using namespace std; typedef l…

如何恢复 iPhone 删除的照片?

照片是iPhone空间不足的主要原因&#xff0c;因此许多用户选择删除一些重复或不喜欢的图片来释放设备。然而&#xff0c;人们在清洁过程中不小心遗漏了自己喜欢的照片的情况很常见。如果你找不到这些珍贵的照片&#xff0c;你一定很难过。其实&#xff0c;您不必担心这个问题&a…

echarts 多环形图

环形图效果&#xff1a; option {"angleAxis": {"max": 1,"show": false,"splitLine": {"show": false},"axisLabel": {"show": false},"axisTick": {"show": false}},"ra…

Idea显示无法自动装配。找不到‘ xxx’类型的Bean

虽然只标红&#xff0c;不报错&#xff0c;但是看着非常别扭&#xff01; 原因&#xff1a; 当我们在使用Autowired注解的时候&#xff0c;默认requiredtrue,表示注入的时候bean必须存在&#xff0c;否则注入失败。 解决方案一&#xff1a; 在自动转配的注解后面添加(require…

低频电磁仿真 | 新能源汽车性能提升的利器

永磁同步电机 新能源汽车的心脏 近年来&#xff0c;全球变暖的趋势日益加剧&#xff0c;极端天气事件层出不穷&#xff0c;这些现象都反映出当前气候形势的严峻性。为了应对这一全球性挑战&#xff0c;各国纷纷采取行动&#xff0c;制定了一系列降碳、减碳的措施。中国在2020年…

2024年淘宝天猫京东618超级红包领取入口

2024年淘宝天猫京东618超级红包领取入口 1、打开「词令」&#xff0c;输入词令关键词直达口令「超红88」&#xff1b; 2、搜索直达2024年淘宝天猫、京东618超级红包领取入口&#xff1b;

新天龙八部3永恒经典之江山策仿官方_源码架设教程

本教程仅限学习使用&#xff0c;禁止商用&#xff0c;一切后果与本人无关&#xff0c;此声明具有法律效应&#xff01;&#xff01;&#xff01;&#xff01; 教程是本人亲自搭建成功的&#xff0c;绝对是完整可运行的&#xff0c;踩过的坑都给你们填上了 一. 效果演示 新天龙…

解锁电气数据新价值:SolidWorks Electrical助力企业转型

在信息化、数字化的时代&#xff0c;电气数据库已成为企业不可或缺的核心资产。它以其独特的功能和优势&#xff0c;助力企业在激烈的市场竞争中脱颖而出&#xff0c;实现数字化转型的跨越式发展。 SolidWorks Electrical电气数据库具备强大的数据整合能力。它能够将企业内部各…

揭秘大前端开发方向的新机遇!

众所周知&#xff0c;华为开发者大会2023&#xff0c;宣布不再兼容安卓&#xff0c;同时宣布了“鸿飞计划”&#xff0c;欲与iOS、安卓在市场三分天下&#xff0c;这对中国国产操作系统而言&#xff0c;具有划时代的意义。 鸿蒙应用开发的兴起&发展 鸿蒙操作系统是华为自…

【解决】安装模块时报错:ERROR: *.whl is not a valid wheel filename.

其实错误信息已经告诉你了&#xff0c;就是你的文件名有问题。在你下载whl文件时一定要注意原文件的文件名&#xff0c;不要改动文件名。 以我安装pandas模块为例吧。 在我下载whl文件时&#xff0c;因为网速太慢&#xff0c;我就下载了多次&#xff0c;导致文件名变成了这个…

SpringBoot 中的日志原来是这么工作的

在有些场景&#xff0c;能通过调整日志的打印策略来提升我们的系统吞吐量,你知道吗&#xff1f; 我们以Springboot集成Log4j2为例&#xff0c;详细说明Springboot框架下Log4j2是如何工作的&#xff0c;你可能会担心&#xff0c;如果是使用Logback日志框架该怎么办呢&#xff1…

01_QT编译报错:Cannot find file:问题解决

QT编译报错&#xff1a;Cannot find file:问题解决 报错原因&#xff1a;创建路径存在中文字符&#xff0c;将文件路径改为英文字符即可

睿贝外贸ERP appPatchDownLoad 任意文件读取漏洞复现

0x01 产品简介 睿贝外贸ERP软件专门为中小型外贸企业打造的一款界面简洁、易用、操作人性,几乎实现零培训, 彻底颠覆其他软件漫长的实施周期。主要功能包括邮件管理、客户管理、邮营销、产品、供应商,报价、订单、出运、单证、财务、利润分析等一体化管理,以及Excel格式单…

防错设计及原理

目录 1、防错的作用 2、防错的原理 2.1断根原理 2.2保险原理 2.3自动原理 2.4相符原理 2.5顺序原理 2.6隔离原理 2.7层别原理 2.8复制原理 2.9警告原理 2.10缓和原理 防错法&#xff08;Poka-Yoke&#xff09;&#xff0c;又称愚巧法、防呆法&#xff0c;是一种在作…

用python写的文本水印隐藏工具

看见一个文本水印项目&#xff1a;text_blind_watermark https://github.com/guofei9987/text_blind_watermark 假设这种场景是不是合适使用&#xff1a; 小米su7发布之前一周&#xff0c;各大博主已经已经拿到参数配置和价格表了&#xff0c;保密政策不允许博主提前发布&…

Java基础入门--第十一章--JDBC(Java Database Connection)Java数据库连接

JDBC 11.1 什么是JDBC11.1.1 JDBC概述11.1.2 JDBC驱动程序 11.2 JDBC的常用API11.3 JDBC编程11.3.1 JDBC 编程步骤11.3.2 实现第一个JDBC程序 我的MySQL的root密码: root 11.1 什么是JDBC 11.1.1 JDBC概述 JDBC的全称是Java数据库连接&#xff08;Java Database Connectivit…

Python爬虫与API交互:如何爬取并解析JSON数据

目录 前言 一、什么是API和JSON数据 二、准备环境 三、发送API请求并获取数据 四、解析JSON数据 五、完整代码示例 六、总结 前言 随着互联网的发展&#xff0c;越来越多的网站提供了API接口&#xff0c;供开发者获取实时数据。在爬虫领域中&#xff0c;与API交互并解析…