# 结构体
C语言中的结构体是一种构造数据类型,它可以存储不同类型的数据项,这些数据项可以是基本数据类型,也可以是构造数据类型,甚至可以是结构体类型。
示例
#include <stdio.h>
struct MyStruct
{
int a;
char b;
float c;
};
int main(){
struct MyStruct s1 = {1, 'a', 1.1};
struct MyStruct s2 = {2, 'b', 2.2};
printf("s1.a = %d\n", s1.a);
printf("s1.b = %c\n", s1.b);
printf("s1.c = %f\n", s1.c);
printf("s2.a = %d\n", s2.a);
printf("s2.b = %c\n", s2.b);
printf("s2.c = %f\n", s2.c);
return 0;
}
# 结构体的定义和初始化
定义结构体变量的方式:
struct 结构体类型名 变量名;
struct 结构体类型名 变量名 = {成员1的初始值, 成员2的初始值, ...};
- 直接定义结构体变量的成员(无需结构体类型名)
示例:
#include <stdio.h>
// `struct 结构体类型名 变量名;`
struct MyStruct1
{
int a;
char b;
float c;
};
struct MyStruct1 s0;
// `struct 结构体类型名 变量名 = {成员1的初始值, 成员2的初始值, ...};`
struct MyStruct2
{
int a;
char b;
float c;
} s1 = {1, 'a', 1.1};
// 直接定义结构体变量的成员(无需结构体类型名)
struct
{
int a;
char b;
float c;
} s2 = {2, 'b', 2.2};
结构体类型和结构体变量关系
- 结构体类型:指定一个结构体的类型,可以定义多个结构体变量。没有具体数据,只是一个模板。系统也不分配内存。
- 结构体变量:根据结构体类型定义的变量,有具体的数据,系统会分配内存。
结构体类型定义的方式
struct 结构体类型名 {成员列表};
typedef struct 结构体类型名 {成员列表} 结构体类型别名;
示例:
#include <stdio.h>
// `struct 结构体类型名 {成员列表};`
struct MyStruct1
{
int a;
char b;
float c;
};
// `typedef struct 结构体类型名 {成员列表} 结构体类型别名;`
typedef struct MyStruct2
{
int a;
char b;
float c;
} MyStruct2;
int main(){
struct MyStruct1 s1 = {1, 'a', 1.1};
MyStruct2 s2 = {2, 'b', 2.2};
printf("s1.a = %d\n", s1.a);
printf("s1.b = %c\n", s1.b);
printf("s1.c = %f\n", s1.c);
printf("s2.a = %d\n", s2.a);
printf("s2.b = %c\n", s2.b);
printf("s2.c = %f\n", s2.c);
return 0;
}
# 结构体成员的使用
#include <stdio.h>
#include <string.h>
// 结构体的定义
struct Student
{
char name[20];
int age;
float score;
};
int main(){
// 结构体变量的定义
struct Student s1 = {"张三", 18, 100};
struct Student s2 = {"李四", 19, 90};
// 结构体变量的使用
printf("s1.name = %s\n", s1.name);
printf("s1.age = %d\n", s1.age);
printf("s1.score = %f\n", s1.score);
printf("s2.name = %s\n", s2.name);
printf("s2.age = %d\n", s2.age);
printf("s2.score = %f\n", s2.score);
// 结构体变量的赋值
strcpy(s2.name, "王五");
s2.age = 20;
s2.score = 80;
// 如果是指针变量
strcpy(&s2->name, "王五");
&s2->age = 20;
printf("s2.name = %s\n", s2.name);
printf("s2.age = %d\n", s2.age);
printf("s2.score = %f\n", s2.score);
return 0;
}
# 结构体数组
#include <stdio.h>
#include <string.h>
// 结构体的定义
struct Student
{
char name[20];
int age;
float score;
};
int main(){
// 结构体数组的定义
struct Student arr[3] = {
{"张三", 18, 100},
{"李四", 19, 90},
{"王五", 20, 80}
};
// 结构体数组的使用
for (int i = 0; i < 3; i++)
{
printf("arr[%d].name = %s\n", i, arr[i].name);
printf("arr[%d].age = %d\n", i, arr[i].age);
printf("arr[%d].score = %f\n", i, arr[i].score);
}
// 结构体数组的赋值
strcpy(arr[2].name, "赵六");
arr[2].age = 21;
arr[2].score = 70;
printf("arr[2].name = %s\n", arr[2].name);
printf("arr[2].age = %d\n", arr[2].age);
printf("arr[2].score = %f\n", arr[2].score);
return 0;
}
# 结构体互相嵌套
#include <stdio.h>
#include <string.h>
// 结构体的定义
struct Student
{
char name[20];
int age;
float score;
};
struct Teacher
{
int id;
char name[20];
int age;
struct Student stu;
};
int main(){
// 结构体变量的定义
struct Teacher t1 = {1, "张三", 30, {"李四", 18, 100}};
// 结构体变量的使用
printf("t1.id = %d\n", t1.id);
printf("t1.name = %s\n", t1.name);
printf("t1.age = %d\n", t1.age);
printf("t1.stu.name = %s\n", t1.stu.name);
printf("t1.stu.age = %d\n", t1.stu.age);
printf("t1.stu.score = %f\n", t1.stu.score);
// 结构体变量的赋值
strcpy(t1.stu.name, "王五");
t1.stu.age = 20;
t1.stu.score = 80;
printf("t1.stu.name = %s\n", t1.stu.name);
printf("t1.stu.age = %d\n", t1.stu.age);
printf("t1.stu.score = %f\n", t1.stu.score);
return 0;
}
# 结构体赋值
结构体变量之间可以相互赋值,但是不能相互比较大小
#include <stdio.h>
#include <string.h>
// 结构体的定义
struct Student
{
char name[20];
int age;
float score;
};
int main(){
// 结构体变量的定义
struct Student s1 = {"张三", 18, 100};
struct Student s2;
// 结构体变量的赋值
s2 = s1;
// 结构体变量的使用
printf("s2.name = %s\n", s2.name);
printf("s2.age = %d\n", s2.age);
printf("s2.score = %f\n", s2.score);
return 0;
}
# 结构体指针
# 指向普通结构体变量的指针
#include <stdio.h>
#include <string.h>
// 结构体类型的定义
struct Student
{
char name[20];
int age;
float score;
};
int main(){
// 结构体变量的定义
struct Student s1 = {"张三", 18, 100};
// 结构体指针的定义
struct Student *p = &s1;
// 结构体指针的使用
printf("s1.name = %s\n", s1.name);
printf("s1.age = %d\n", s1.age);
printf("s1.score = %f\n", s1.score);
printf("p->name = %s\n", p->name);
printf("p->age = %d\n", p->age);
printf("p->score = %f\n", p->score);
printf("(*p).name = %s\n", (*p).name);
printf("(*p).age = %d\n", (*p).age);
printf("(*p).score = %f\n", (*p).score);
return 0;
}
# 堆区结构体变量
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// 结构体类型的定义
struct Student
{
char name[20];
int age;
float score;
};
int main(){
// 结构体指针的定义
struct Student *p = malloc(sizeof(struct Student));
// 结构体指针的使用
strcpy(p->name, "张三");
p->age = 18;
p->score = 100;
printf("p->name = %s\n", p->name);
printf("p->age = %d\n", p->age);
printf("p->score = %f\n", p->score);
return 0;
}
# 结构体套一级指针
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// 结构体类型的定义
struct Student
{
char *name[20];
int age;
float score;
};
int main(){
// 结构体指针的定义
struct Student *p = malloc(sizeof(struct Student));
// 结构体指针的使用
strcpy(p->name, "张三");
p->age = 18;
p->score = 100;
printf("p->name = %s\n", p->name);
printf("p->age = %d\n", p->age);
printf("p->score = %f\n", p->score);
return 0;
}
# 结构体做函数参数
# 结构体普通变量做函数参数
#include <stdio.h>
#include <string.h>
// 结构体类型的定义
struct Student
{
char name[20];
int age;
float score;
};
// 结构体变量做函数参数
void printStudent(struct Student s){
printf("s.name = %s\n", s.name);
printf("s.age = %d\n", s.age);
printf("s.score = %f\n", s.score);
}
int main(){
// 结构体变量的定义
struct Student s1 = {"张三", 18, 100};
// 结构体变量做函数参数
printStudent(s1);
return 0;
}
# 结构体指针做函数参数
#include <stdio.h>
#include <string.h>
// 结构体类型的定义
struct Student
{
char name[20];
int age;
float score;
};
// 结构体指针做函数参数
void printStudent(struct Student *p){
printf("p->name = %s\n", p->name);
printf("p->age = %d\n", p->age);
printf("p->score = %f\n", p->score);
}
int main(){
// 结构体变量的定义
struct Student s1 = {"张三", 18, 100};
// 结构体指针做函数参数
printStudent(&s1);
return 0;
}
# 结构体数组做函数参数
#include <stdio.h>
#include <string.h>
// 结构体类型的定义
struct Student
{
char name[20];
int age;
float score;
};
// 结构体数组做函数参数
void printStudent(struct Student arr[], int len){
for (int i = 0; i < len; i++)
{
printf("arr[%d].name = %s\n", i, arr[i].name);
printf("arr[%d].age = %d\n", i, arr[i].age);
printf("arr[%d].score = %f\n", i, arr[i].score);
}
}
int main(){
// 结构体数组的定义
struct Student arr[3] = {
{"张三", 18, 100},
{"李四", 19, 90},
{"王五", 20, 80}
};
// 结构体数组做函数参数
printStudent(arr, 3);
return 0;
}
# 结构体指针数组做函数参数
#include <stdio.h>
#include <string.h>
// 结构体类型的定义
struct Student
{
char name[20];
int age;
float score;
};
// 结构体指针数组做函数参数
void printStudent(struct Student *arr[], int len){
for (int i = 0; i < len; i++)
{
printf("arr[%d]->name = %s\n", i, arr[i]->name);
printf("arr[%d]->age = %d\n", i, arr[i]->age);
printf("arr[%d]->score = %f\n", i, arr[i]->score);
}
}
int main(){
// 结构体数组的定义
struct Student s1 = {"张三", 18, 100};
struct Student s2 = {"李四", 19, 90};
struct Student s3 = {"王五", 20, 80};
struct Student *arr[3] = {&s1, &s2, &s3};
// 结构体指针数组做函数参数
printStudent(arr, 3);
return 0;
}
# const
修饰结构体指针做函数参数
#include <stdio.h>
#include <string.h>
// 结构体类型的定义
struct Student
{
char name[20];
int age;
float score;
};
// 结构体指针做函数参数
void printStudent(const struct Student *p){
printf("p->name = %s\n", p->name);
printf("p->age = %d\n", p->age);
printf("p->score = %f\n", p->score);
p->age = 20; // error
}
int main(){
// 结构体变量的定义
struct Student s1 = {"张三", 18, 100};
// 结构体指针做函数参数
printStudent(&s1);
return 0;
}
# 共用体(联合体)
- 共用体是一种特殊的数据类型,允许在相同的内存位置存储不同的数据类型。
- 可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值,共用体提供了一种使用相同的内存位置的有效方式。
- 共用体占用的内存应足够存储共用体中最大的成员。
- 共用体的声明和结构体类似,但是必须使用
union
关键字。 - 共用体的初始化和结构体类似,但是只能初始化第一个成员。
- 共用体的成员地址和其他成员地址相同,共用体的成员地址和共用体变量地址相同。
示例:
#include <stdio.h>
union MyUnion
{
int a;
char b;
float c;
};
int main(){
union MyUnion u1 = {1};
printf("u1.a = %d\n", u1.a);
printf("u1.b = %c\n", u1.b);
printf("u1.c = %f\n", u1.c);
//所有成员的地址都是一样的
printf("&u1.a = %p\n", &u1.a);
return 0;
}
# 枚举
- 枚举是一种用户自定义的数据类型,用于定义变量,可以将变量的值一一列举出来。
- 枚举的每个值都可以叫做枚举的一个成员,每个成员都可以赋予一个值,如果没有赋值,系统会默认赋值。
- 枚举的定义和结构体类似,但是必须使用
enum
关键字。 - 枚举值是常量,不能在程序中用赋值语句再对它赋值
- 枚举值的默认值从0开始,依次加1,如果前面一个成员赋值,后面没有赋值的成员会在前一个成员的基础上加1。
示例:
#include <stdio.h>
enum Season
{
spring,
summer,
autumn,
winter
};
int main(){
enum Season s1 = spring;
enum Season s2 = summer;
enum Season s3 = autumn;
enum Season s4 = winter;
printf("s1 = %d\n", s1);
printf("s2 = %d\n", s2);
printf("s3 = %d\n", s3);
printf("s4 = %d\n", s4);
return 0;
}
# typedef
typedef
是C语言中的一个关键字,用来为类型取一个新的名字,可以使用typedef
为int
取一个新的名字叫myInt
,这样以后就可以用myInt
来定义变量了。
typedef
的作用是为一种数据类型定义一个新的名字,可以使用这个新的名字来定义变量。typedef
的语法:typedef 数据类型 新名字;
typedef
的本质是给数据类型起一个别名,本质上是一个宏定义。typedef
仅限于为数据类型定义别名,不能为变量定义别名。
示例:
#include <stdio.h>
typedef int myInt;
int main(){
myInt a = 10;
printf("a = %d\n", a);
return 0;
}