目录
结构体
结构体(Struct)是一种在编程中用来存储不同数据类型存放在一块连续的地址上的集合的方式(C语言)。
使用(.)和(->)的区别,看结构体变量是不是地址,地址用->.
#include <stdio.h>
#include <string.h>
struct Person {
char name[50];
int age;
float height;
};
int main()
{
struct Person person1;
strcpy(person1.name, "Alice");
person1.age = 30;
person1.height = 1.75;
printf("Name: %s\n", person1.name);
printf("Age: %d\n", person1.age);
printf("Height: %.2f meters\n", person1.height);
return 0;
}
#include <stdio.h>
#include <string.h>
struct Person {
char name[50];
int age;
float height;
};
int main()
{
struct Person person1;
strcpy((&person1)->name, "Alice");
(&person1)->age = 30;
(&person1)->height = 1.75;
printf("Name: %s\n", (&person1)->name);
printf("Age: %d\n", (&person1)->age);
printf("Height: %.2f meters\n", (&person1)->height);
return 0;
}
结构体数组
结构体数组是指在编程中将多个结构体变量组织成一个数组的方式。
#include <stdio.h>
#include <string.h>
struct Person {
char name[50];
int age;
float height;
};
struct Person people[3]; // 创建一个包含3个Person结构体的数组
int main()
{
struct Person people[3] = {
{"Alice", 25, 1.65},
{"Bob", 30, 1.80},
{"Carol", 28, 1.70}
};
for (int i = 0; i < 3; ++i) {
printf("Person %d: Name: %s, Age: %d, Height: %.2f\n", i+1, people[i].name, people[i].age, people[i].height);
}
return 0;
}
结构体指针
注意:不要让结构体指针成为野指针,如果使用动态分配内存,在 malloc()
分配内存后,我们将指针指向的结构体成员进行初始化,并最终通过 free()
函数释放动态分配的内存。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义结构体 Person
struct Person {
char name[50];
int age;
float height;
};
int main() {
// 声明一个指向结构体 Person 的指针
struct Person *ptr = NULL;
// 动态分配内存给结构体指针
ptr = (struct Person *)malloc(sizeof(struct Person));
// 检查内存分配是否成功
if (ptr == NULL) {
fprintf(stderr, "Memory allocation failed.\n");
return 1; // 返回非零值表示程序异常结束
}
// 初始化结构体指针成员
strcpy(ptr->name, "John");
ptr->age = 30;
ptr->height = 1.75;
// 访问结构体指针成员并打印
printf("Name: %s, Age: %d, Height: %.2f\n", ptr->name, ptr->age, ptr->height);
// 释放动态分配的内存
free(ptr);
ptr = NULL; // 将指针置为空指针,以避免悬挂指针
return 0;
}
const修饰
情况一:struct cl3 const *p = &a;
struct cl3 const *p = &a;
p->id = 100; // 这里会导致编译错误
在这段代码中,struct cl3 const *p
表示 p
是一个指向 const struct cl3
类型的指针。这意味着 p
指向的数据是常量,不能通过 p
修改它指向的对象的数据。因此,尝试给 p->id
赋值会导致编译错误,因为 p
指向的对象是常量,其成员不能被修改。
情况二:struct cl3 *const p = &a;
struct cl3 *const p = &a;
p = &b; // 这里会导致编译错误
在这段代码中,struct cl3 *const p
表示 p
是一个常量指针,指向 struct cl3
类型的对象。这意味着 p
本身不能被修改,即不能让 p
指向其他地址。因此,尝试给 p
赋新值(如 p = &b;
)会导致编译错误,因为 p
是一个常量,其指向不能改变。
结构体指针套成员指针变量
注意:释放内存的顺序(有里到外)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Person {
char *name;
int age;
float height;
};
int main() {
// 分配结构体指针变量
struct Person *personPtr = malloc(sizeof(struct Person));
// 分配和设置成员指针变量
personPtr->name = malloc(20 * sizeof(char)); // 假设名字最多为 19 个字符加上字符串结束符 '\0'
strcpy(personPtr->name, "John Doe"); // 设置名字
personPtr->age = 30; // 设置年龄
personPtr->height = 1.75; // 设置身高
// 访问并打印结构体成员
printf("Name: %s\n", personPtr->name);
printf("Age: %d\n", personPtr->age);
printf("Height: %.2f meters\n", personPtr->height);
// 释放内存
free(personPtr->name); // 释放名字的内存
free(personPtr); // 释放结构体指针的内存
return 0;
}
结构体结构体
在C语言中,允许您在一个结构体中嵌套另一个结构体作为其成员。
#include <stdio.h>
#include <string.h>
// 定义日期结构体
struct Date {
int day;
int month;
int year;
};
// 定义员工结构体,其中包含日期结构体
struct Employee {
char name[50];
int empId;
struct Date birthDate;
double salary;
};
int main() {
// 声明一个 Employee 结构体变量
struct Employee emp1;
// 初始化 emp1 的数据
strcpy(emp1.name, "John Doe");
emp1.empId = 1001;
emp1.birthDate.day = 15;
emp1.birthDate.month = 8;
emp1.birthDate.year = 1990;
emp1.salary = 55000.0;
// 打印员工信息
printf("Employee Name: %s\n", emp1.name);
printf("Employee ID: %d\n", emp1.empId);
printf("Birth Date: %d/%d/%d\n", emp1.birthDate.day, emp1.birthDate.month, emp1.birthDate.year);
printf("Salary: %.2f\n", emp1.salary);
return 0;
}
共用体
共用体(Union)是一种特殊的数据结构,允许在相同的内存位置存储不同的数据类型。它和结构体相似,但是不同成员共享同一块内存空间,因此同一时间只能保存一个成员的值。
#include <stdio.h>
#include <string.h>
// 定义一个共用体 UnionExample
union UnionExample {
int intValue;
float floatValue;
char stringValue[20];
};
int main() {
// 声明一个 UnionExample 类型的共用体变量
union UnionExample u;
// 设置 intValue 成员
u.intValue = 10;
// 访问 intValue 成员
printf("Value of intValue: %d\n", u.intValue);
// 设置 floatValue 成员
u.floatValue = 25.5;
// 访问 floatValue 成员
printf("Value of floatValue: %.2f\n", u.floatValue);
// 设置 stringValue 成员
strcpy(u.stringValue, "Hello");
// 访问 stringValue 成员
printf("Value of stringValue: %s\n", u.stringValue);
// 注意:此时 intValue 和 floatValue 的值不可预测,因为它们共享同一块内存空间
return 0;
}
注意事项:共用体的每个成员共享同一块内存空间,因此改变一个成员的值会影响其他成员的值。在使用共用体时,应谨慎确保每次访问时都正确地使用了当前存储的数据类型。
枚举
枚举(Enumeration,简称Enum)是一种用于定义具名整数常量集合的数据类型,它可以帮助增加代码的可读性和可维护性。在C语言中,枚举通过 enum
关键字来定义。
#include <stdio.h>
// 定义一个枚举类型 Season
enum Season {
Spring,
Summer,
Autumn,
Winter
};
int main() {
// 声明一个 Season 类型的变量
enum Season currentSeason;
// 设置当前季节为 Summer
currentSeason = Summer;
// 使用 switch 语句处理枚举值
switch (currentSeason) {
case Spring:
printf("It's Spring!\n");
break;
case Summer:
printf("It's Summer!\n");
break;
case Autumn:
printf("It's Autumn!\n");
break;
case Winter:
printf("It's Winter!\n");
break;
default:
printf("Invalid season.\n");
}
return 0;
}
这里定义了一个名为 Season
的枚举类型,它包含了四个枚举常量:Spring
、Summer
、Autumn
和 Winter
。在这种情况下,它们会依次被赋予值 0、1、2 和 3,如果需要,我们也可以手动指定它们的值。如Spring
、Summer=5
、Autumn=9
和 Winter
。那么Spring=0,Summer=5
、Autumn=9,而Winter=10.
tyepdef
创建类型别名
typedef
是 C 语言中的一个关键字,它用于为已有的数据类型定义一个新的名字,使得代码更加清晰和易读。主要用途是创建类型别名。
#include <stdio.h>
#include <string.h>
// 定义一个结构体
struct Student {
char name[50];
int age;
};
// 使用 typedef 为 struct Student 创建一个新的类型别名
typedef struct Student StudentInfo;
int main() {
// 声明一个 StudentInfo 类型的结构体变量
StudentInfo s1;
// 设置结构体成员的值
strcpy(s1.name, "John Doe");
s1.age = 20;
// 访问并打印结构体成员
printf("Student name: %s\n", s1.name);
printf("Student age: %d\n", s1.age);
return 0;
}
使用 typedef
关键字创建了一个新的类型别名 StudentInfo
,它现在可以用来声明 struct Student
类型的变量,而不需要每次都写完整的 struct Student
。