C语言:结构体的认识

一、结构体的基本概念


  1. 什么是结构体?
    结构体(struct)是C语言中一种用户自定义的数据类型,用于将多个不同类型的数据组合成一个逻辑整体。
    例如:学生信息可以包含name(字符串)、age(整型)、score(浮点型)等不同数据。

  2. 为什么需要结构体?

    • 将相关数据聚合,提高代码可读性和维护性。

    • 便于传递复杂数据(如函数参数或返回值)。

    • 模拟面向对象编程中的“对象”概念。

结构体是一些值的集合,这些值被称为成员变量,结构体的每个成员可以是不同类型的变量;如:数组,指针,甚至是其他结构体。 

二、结构体的声明与定义


 1.声明结构体类型

struct Student {
    char name[20];  // 姓名
    int age;        // 年龄
    float score;    // 成绩
};  // 注意分号不能省略

2.定义结构体变量 

方式1:先声明类型,再定义变量 

struct Student stu1;  // stu1是结构体变量

 方式2:声明类型时直接定义变量

struct Student {
    // 成员...
} stu1, stu2;  // 同时定义stu1和stu2

3.初始化结构体

// 按成员顺序初始化
struct Student stu1 = {"Alice", 18, 95.5};

// C99支持指定成员初始化(顺序无关)
struct Student stu2 = {
    .age = 20,
    .name = "Bob",
    .score = 88.0
};

 三、结构体成员的访问


1.使用点运算符(.)访问成员  

struct Student stu1;
strcpy(stu1.name, "Tom");  // 字符串赋值需用strcpy
stu1.age = 19;
stu1.score = 92.5;

2.使用指针访问成员(箭头运算符 -> 

struct Student *p = &stu1;
printf("Name: %s\n", p->name);  // 等价于(*p).name

四、结构体的内存对齐


1.对齐原则

  • 结构体成员的地址必须是其自身大小的整数倍。

  • 结构体总大小是最大成员大小的整数倍。

struct Example {
    char a;     // 1字节(偏移0)
    int b;      // 4字节(偏移4,因为1不是4的倍数)
    double c;   // 8字节(偏移8)
};  // 总大小:1 + 3(填充) + 4 + 8 = 16字节

2.手动控制对齐

使用预处理指令:

#pragma pack(1)  // 按1字节对齐(取消对齐)
struct Example {
    // 成员...
};
#pragma pack()   // 恢复默认对齐

五.结构体的嵌套 


1.结构体包含其他结构体

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

struct Student {
    char name[20];
    struct Date birthday;  // 嵌套结构体
};

2.自引用结构体(用于链表、树等)

struct Node {
    int data;
    struct Node *next;  // 指向自身类型的指针
};

 六.结构体与函数


1.结构体作为函数参数

void printStudent(struct Student stu) {
    printf("Name: %s\n", stu.name);
}
// 注意:传递结构体会产生拷贝,大结构体建议用指针

2.结构体作为返回值 

struct Student createStudent() {
    struct Student s = {"Lucy", 20, 90};
    return s;
}

3. 结构体指针作为参数

void modifyStudent(struct Student *p) {
    p->age += 1;  // 直接修改原结构体
}

七.结构体的不同用法


1.匿名的结构体类型 

在声明结构体的时候可以使用不完全声明。匿名的结构体类型,如果没有对结构体类型重命名的话,基本只能使用一次。

struct 
{
    int a;
    char b;
}x;

 2.typedef简化结构体类型名

typedef struct Student {
    // 成员...
} Student;  // 直接使用Student代替struct Student

Student stu3;  // 无需写struct关键字

3.柔性数组成员(C99) 

结构体最后一个成员可以是未知大小的数组 

struct FlexArray {
    int length;
    int data[];  // 柔性数组
};

注意事项

  1. 结构体赋值是深拷贝(逐成员复制)。

  2. 结构体大小需用sizeof获取,而非手动相加。

  3. 结构体中的数组成员(如char name[20])不能直接赋值,需用strcpy

  4. 避免结构体包含过大的数据(如大数组),以免栈溢出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值