【C语言】结构体

【C语言】结构体

img

一、什么是结构体

C 数组允许定义可存储相同类型数据项的变量,结构是 C 编程中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。

结构体中的数据成员可以是基本数据类型(如 int、float、char 等),也可以是其他结构体类型、指针类型等。

结构用于表示一条记录,假设您想要跟踪图书馆中书本的动态,您可能需要跟踪每本书的下列属性:

  • Title
  • Author
  • Subject
  • Book ID

二、结构体的定义

结构体定义由关键字 struct 和结构体名组成,结构体名可以根据需要自行定义。

struct 语句定义了一个包含多个成员的新的数据类型,struct 语句的格式如下:

    // 结构体的一般定义形式为:

    struct 结构体名{

        类型名1 成员名1;

        类型名2 成员名2;
        
        ······

        类型名n 成员名n;

    }

struct 是关键字,是结构类型的标志。

    // 举个例子
    struct Student
    {
        char *name;     // 姓名
        int age;        // 年龄
        float height;   // 身高
    };

上面定义了一个叫做 Student 的结构体,共有 name、age、height 3个成员。看到这里是否有点面向对象的味道呢?其实这跟面向对象完全是两码事,只能说感觉有点像。

三、结构体变量的定义

前面只是定义了名字为 Student 的结构体,并非定义了一个结构体变量,就像 int 一样,只是一种类型。

接下来定义一个结构体变量,方式有好多种。

1、先定义结构体类型,再定义变量

    struct Student
    {
        char *name;
        
        int age;
    };              // 结构体最后有个分号别忘了

    struct  Student stu;  // 定义了一个结构体变量,变量名为stu。struct和Student是连着使用的

2、定义结构体类型的同时定义变量

struct Student
{
    char *name;
    
    int age;
} stu;         // 结构体的变量名为stu

3、直接定义结构体类型变量,省略类型名

struct 
{
    char *name;
    
    int age;
} stu;         // 结构体的变量名为stu

四、结构体的注意点

1、不允许对结构体本身递归定义

如下列做法是 错误 的:

struct Student
{
    int age;
    struct Student stu;
};

PS:结构体最后的分号一定不要忘了

2、结构体内可以包含别的结构体

struct Date
{
    int year;
    int month;
    int day;
};

struct Student
{
    char *name;
    struct Date birthday;   // 可以包含别的结构体
};

3、定义结构体类型,只是说明了该类型的组成情况,并没有给它分配存储空间,就像系统不为 int 类型本身分配空间一样。只有当定义属于结构体类型的变量时,系统才会分配存储空间给该变量

// 新学一招, markdown 笔记使用 (``` + c) 可以直接创建 c 类型的代码块

struct Student 
{
    char *name;    // 姓名
    int age;	   // 年龄
};

// 截止到这里,系统并没有给结构体分配空间

struct Student stu;
// 截止到这里,系统给结构体分配了空间

4、结构体变量占用的内存空间是其成员所占内存之和,而且各成员在内存中按定义的顺序依次排列

比如下面的 Student 结构体:

struct Student
{
    char *name;		// 姓名
    int age;		// 年龄
    float height;	// 身高
};

在16位环境下,一个 Student 变量共占用内存:2 + 2 + 4 = 8字节。

在32位环境下,一个 Student 变量共占用内存:4 + 4 + 4 = 12字节。

在64位环境中,一个 Student 变量共占用内存:8 + 4 + 4 = 16字节

image-20251209164730164

五、结构体的初始量

将各成员的初值,按顺序地放在一对大括号 { } 中,并用逗号分隔,一一对应赋值。

比如初始化 Student 结构体变量 stu

struct Student
{
	char *name;
    int age;
};

struct Student stu = {"MJ", 27};

只能在定义变量的同时进行初始赋值,初始化赋值和变量的定义不能分开,下面的做法是 错误 的:

struct Student stu;
stu = {"MJ", 27};

六、结构体的使用

1、一般对结构体变量的操作是以成员为单位进行的,引用的一般形式为: 结构体变量名.成员名

struct Student
{
    char *name;
    int age;
};

struct Student stu;

// 访问 stu 的 age 成员

stu.age = 27;

最后1行 对结构体的age成员进行了赋值。"."称为成员运算符,它在所有运算符中优先级最高

2、如果某个成员也是结构体变量,可以连续使用成员运算符 “ . ” 访问最低一级成员

struct Sate
{
    int year;
    int month;
    int day;
};

struct Student 
{
    char *name;
    struct Date birthday;
};

struct Student stu;

// 注意下面代码
stu.birthday.year = 2001;
stu.birthday.month = 2;
stu.birthday.day = 10;

3、相同类型的结构体变量之间可以进行整体赋值

struct Student
{
    char *name;
    int age;
};

struct Student stu1 = {"MJ", 27};

// 将 stu1 直接赋值给 stu2

struct Student stu2 = stu1;

printf("age is %d", stu2.age);

输出结果为:
img

七、结构体数组

1、定义

跟结构体变量一样,结构体数组也有3种定义方式

struct Student
{
    char *name;
    int age;
}

struct Student stu[5];  // 定义1
struct Student
{
    char *name;
    int age;
}stu[5]; 	// 定义2
struct
{
    char *name;
    int age;
}stu[5];	 // 定义3

上面3种方式,都是定义了一个变量名为 stu 的结构体数组,数组元素个数是5

2初始化

struct 
{
    char *name;
    int age;
}stu = {{"MJ", 27},{"WW", 24}};

也可以用数组下标访问每一个结构体元素,跟普通数组的用法一样

八、结构体作为函数参数

将结构体变量作为函数参数进行传递时,其实传递的是全部成员的值,也就是将实参中的成员的值一一赋值给对应的形参成员。因此,变量的改变不会影响实参。

#include <stdio.h>

// 定义一个结构体
struct  Student
{
    int age;
};

// 声明函数
void test(struct Student stu)
{
    printf("修改前的形参:%d \n",stu.age);

    // 修改实参中的age

    stu.age = 10;

    printf("修改后的形参:%d \n",stu.age);


}

int main()
{
    struct Student stu = {30};
    printf("修改前的实参:%d \n",stu.age);

    // 调用 test函数
    test(stu);

    printf("修改后的实参:%d \n",stu.age);

    return 0;
}

输出结果为:

img

形参是改变了,但是实参一直没有变过

九、指向结构体的指针

* 每个结构体变量都有自己的存储空间和地址,因此指针也可以指向结构体变量

* 结构体指针变量的定义形式:struct 结构体名称 *指针变量名

* 有了指向结构体的指针,那么就有3种访问结构体成员的方式

  • 结构体变量名.成员名
  • (*指针变量名).成员名
  • 指针变量名->成员名
#include <stdio.h>

int main()
{
    // 定义一个结构体
    struct Student 
    {
        char *name;
        int age;
    };

    // 定义一个结构体变量
    struct Student stu = {"MJ", 27};

    // 定义一个指向结构体的指针变量
    struct Student *p;

    // 指向结构体变量 stu
    p = &stu;

    /*
        这时候可以使用3种方式访问结构体的成员
    */

    // 方式1:结构体变量名.成员名
    printf("name = %s,age = %d \n",stu.name,stu.age);

    // 方式2:(*指针变量).成员名
    printf("name = %s,age = %d \n",(*p).name,(*p).age);

    // 方式3:指针变量 -> 成员名
    printf("name = %s,age = %d \n",p -> name,p -> age);

    return 0;

}

输出结果:

img

posted @ 2025-12-09 17:58  Q&25  阅读(3)  评论(0)    收藏  举报