定义
有时候,简单基本类型满足不了需求,需要用到一个比较复杂的数据结构,一个不同类型变量的集合 结构体 来实现。
//创建一个结构体,表示人物信息
struct people {
//结构体成员
char name[20];
int age;
};
复制代码
这样我们就创建了一个结构体类型,此时并没有分配内存空间,直到使用这个结构体,去创建变量。
struct people amen; //struct people 是类型,amen 是变量名
复制代码
声明结构体就相当于对结构体成员进行一一声明。
初始化方法有
struct people amen = {"Ada",18}; //结构体声明是成员从上至下对应赋值
struct people bmen;
bmen.name = "Bda"; // 这里出错了,why?
bmen.age = 19;
复制代码
在代码的第三行,bmen.name = "Bda";
这里,发生一个编译错误,因为在结构体 people
中的成员 char name[20]
,这是一个字符数组,表达的是一个字符串,而 数组名字 name
即 &name[0]
相当于一个指针常量,固定地指向数组的首元素地址。而 bmen.name = "Bda";
这个赋值语句,相当于修改了指针常量 name
的指向,这是不允许的,所以代码需要这样修改
struct people bmen;
strcpy(bmen.name,"Bda");
bmen.age = 19;
复制代码
存储相关
两个同类型的结构,即使它们的成员所有的值都相同,它们也不是同一个变量,占用不同的内存区。
struct sct {
char a;
int b;
};
struct sct s;
s.a = 'a';
s.b = 1;
struct sct z;
z.a = 'a';
z.b = 1;
printf("%p %p\n",&s,&z); //0x7ffeefbff5c0 0x7ffeefbff5b8
printf("%p %p\n",&s.a,&z.a); //0x7ffeefbff5c0 0x7ffeefbff5b8
printf("%p %p\n",&s.b,&z.b); //0x7ffeefbff5c4 0x7ffeefbff5bc
复制代码
既然结构体是一个类型,那也就存在
结构体指针
struct sct {
int a;
char b;
};
struct sct sd = {1,'x'};
struct sct *p = &sd;
复制代码
初始化完了,现在要对 sd
里的成员值进行修改
sd.a = 2;
sd.b = 'y';
//通过指针修改
(*p).a = 3;
(*p).b = 'z';
//换种写法
p->a = 0;
p->b = 'A';
复制代码
结构体数组
struct people {
char name[20];
int age;
};
struct people mens[3];
复制代码
这个时候,数组 mens
里的每个元素都是一个结构体 people
类型的变量。
使用结构体的时候,每次都得带上 struct
关键字,略麻烦,这时候我们可以用 typedef
关键字,来简化。
typedef struct stu {
char name[20];
int num;
int age;
int score;
}stu_t;
//或者
typedef struct stu stu_t;
复制代码
这里创建了一个结构体 struct stu
,用 typedef
为其创建了一个别名 stu_t
,之后,我们可以用 stu_t
来代替 struct stu
的使用。
struct stu user ;
⬇️⬇️⬇️
stu_t user;
复制代码
如果不加 typedef
,则是声明结构体的同时创建了一个结构体类型的全局变量,变量名是 stu_t
struct stu {
char name[20];
int num;
int age;
int score;
}stu_t;
stu_t.age = 10;
复制代码