cstruct
#
定义
#
// 结构体定义
struct Student {
int id;
char name[20];
float score;
int age;
};
声明方式
#
// 方式1:先定义后声明
struct Student {
int id;
char name[20];
};
struct Student stu1;
// 方式2:定义时声明
struct Student {
int id;
char name[20];
} stu1, stu2;
// 方式3:使用typedef
typedef struct {
int id;
char name[20];
} Student;
Student stu1;
初始化方法
#
// 顺序初始化
struct Student stu1 = {1001, "张三", 85.5, 20};
// 指定成员初始化(C99标准)
struct Student stu2 = {
.id = 1002,
.name = "李四",
.age = 21
};
// 部分初始化
struct Student stu3 = {1003}; // 其余成员自动初始化为0
普通变量访问
#
struct Student stu;
stu.id = 1001;
strcpy(stu.name, "王五");
stu.score = 90.5;
printf("学号:%d\n", stu.id);
printf("姓名:%s\n", stu.name);
指针变量访问
#
struct Student stu;
struct Student *p = &stu;
// 方式1:使用->运算符
p->id = 1002;
strcpy(p->name, "赵六");
// 方式2:使用*和.运算符
(*p).score = 88.5;
结构体数组
#
// 定义结构体数组
struct Student class[3] = {
{1001, "张三", 85.5, 20},
{1002, "李四", 92.0, 19},
{1003, "王五", 78.5, 21}
};
// 访问结构体数组元素
for(int i = 0; i < 3; i++) {
printf("学生%d:%s,成绩:%.1f\n",
class[i].id, class[i].name, class[i].score);
}
结构体作为函数参数
#
// 值传递
void printStudent(struct Student stu) {
printf("学号:%d,姓名:%s\n", stu.id, stu.name);
}
// 地址传递(推荐)
void modifyStudent(struct Student *pStu) {
pStu->score += 5.0;
}
结构体作为函数返回值
#
struct Student createStudent(int id, char *name, float score) {
struct Student stu;
stu.id = id;
strcpy(stu.name, name);
stu.score = score;
return stu;
}
结构体嵌套
#
struct Date {
int year;
int month;
int day;
};
struct Employee {
int id;
char name[20];
struct Date birthday; // 结构体嵌套
float salary;
};
// 初始化嵌套结构体
struct Employee emp = {
1001,
"张三",
{1990, 5, 15}, // 嵌套结构体初始化
8000.0
};
// 访问嵌套成员
printf("出生年份:%d\n", emp.birthday.year);
结构体指针数组
#
struct Student *pStu[3];
for(int i = 0; i < 3; i++) {
pStu[i] = &class[i]; // class为结构体数组
}
动态分配结构体
#
#include <stdlib.h>
// 动态分配单个结构体
struct Student *p = (struct Student*)malloc(sizeof(struct Student));
// 动态分配结构体数组
struct Student *pArray = (struct Student*)malloc(10 * sizeof(struct Student));
// 使用后释放内存
free(p);
free(pArray);
结构体对齐(内存对齐)
#
struct Example1 { // 占用12字节
char a; // 1字节
int b; // 4字节(偏移量从4开始)
char c; // 1字节
}; // 补齐到12字节
struct Example2 { // 占用8字节
char a; // 1字节
char c; // 1字节
int b; // 4字节
}; // 补齐到8字节
位域(Bit Fields)
#
struct Status {
unsigned int isReady : 1; // 1位
unsigned int isError : 1; // 1位
unsigned int code : 4; // 4位
unsigned int : 2; // 2位未使用
};
柔性数组(C99)
#
struct DynamicArray {
int length;
int data[]; // 柔性数组成员
};
结构体比较
#
// 不能直接比较结构体,需要逐个比较成员
int compareStudents(struct Student s1, struct Student s2) {
return s1.id == s2.id && strcmp(s1.name, s2.name) == 0;
}
结构体复制
#
// 可以直接赋值(浅拷贝)
struct Student stu1 = {1001, "张三", 85.5};
struct Student stu2 = stu1;
// 深拷贝需要手动实现
void deepCopyStudent(struct Student *dest, const struct Student *src) {
dest->id = src->id;
strcpy(dest->name, src->name);
dest->score = src->score;
}