【c语言】结构体的访问

🎈个人主页:豌豆射手^

🎉欢迎 👍点赞✍评论⭐收藏

🤗收录专栏:C语言

🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步!

【c语言】结构体的访问

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

引言:

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

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

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

c 复制代码
struct_variable.member_name;

其中:

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

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

c 复制代码
#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 成员的值。

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

例如:

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

c 复制代码
#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. 使用 "->" 操作符:当你有一个指向结构体的指针时,可以使用 "->" 操作符来直接访问结构体的成员。

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

c 复制代码
typedef struct {
    int id;
    char name[50];
} Person;

Person p1;
Person *ptr = &p1;

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

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

例如:

c 复制代码
(*ptr).id = 1;
strcpy((*ptr).name, "John Doe");

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

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

2.2 原理

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

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

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

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

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

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

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

总结

这篇文章到这里就结束了
谢谢大家的阅读!
如果觉得这篇博客对你有用的话,别忘记三连哦。
我是豌豆射手^,让我们我们下次再见

相关推荐
敲代码不忘补水14 分钟前
生成式GPT商品推荐:精准满足用户需求
开发语言·python·gpt·产品运营·产品经理
BT-BOX33 分钟前
STM32仿真proteus位带操作和keil增加头文件C文件
c语言·stm32·proteus
清风fu杨柳39 分钟前
centos7 arm版本编译qt5.6.3详细说明
开发语言·arm开发·qt
醉颜凉42 分钟前
【NOIP提高组】潜伏者
java·c语言·开发语言·c++·算法
_小柏_44 分钟前
C/C++基础知识复习(20)
开发语言
程序员小明z1 小时前
基于Java的药店管理系统
java·开发语言·spring boot·毕业设计·毕设
我是哈哈hh1 小时前
HTML5和CSS3的进阶_HTML5和CSS3的新增特性
开发语言·前端·css·html·css3·html5·web
Dontla2 小时前
Rust泛型系统类型推导原理(Rust类型推导、泛型类型推导、泛型推导)为什么在某些情况必须手动添加泛型特征约束?(泛型trait约束)
开发语言·算法·rust
Neophyte06083 小时前
C++算法练习-day40——617.合并二叉树
开发语言·c++·算法
慕容复之巅3 小时前
基于MATLAB的条形码的识别图像处理报告
开发语言·图像处理·matlab