C语言结构体(Struct)从本质上讲是一种自定义的数据类型,只不过这种数据类型比较复杂,是由 int、char、float 等基本类型组成的。你可以认为结构体是一种聚合类型。
在实际开发中,我们可以将一组类型不同的、但是用来描述同一件事物的变量放到结构体中。例如,在校学生有姓名、年龄、身高、成绩等属性,将它们都放到结构体中即可。
结构体是一种自定义的数据类型,是创建变量的模板,不占用内存空间;结构体变量才包含了实实在在的数据,需要内存空间来存储。
struct 结构体名{
结构体所包含的变量或数组
};
方式一,先定义结构体再声明结构体变量
#include<stdio.h>
struct Student{
char *name;
int age;
};
int main(){
//声明结构体变量
struct Student s1,s2;
return 0;
}
方式二,定义结构体的同时声明结构体变量
#include<stdio.h>
struct Student{
char *name;
int age;
}s1,s2;
int main(){
return 0;
}
结构体名也可以省略
#include<stdio.h>
struct{
char *name;
int age;
}s1,s2;
int main(){
return 0;
}
格式:结构体变量.成员名
#include<stdio.h>
struct Student{
char *name;
int age;
}s1;
int main(){
s1.name = "Lucy";
s1.age = 18;
printf("姓名:%s",s1.name);
printf("年龄:%d",s1.age);
return 0;
}
也可以在声明变量的时候按照成员顺序整体进行赋值
#include<stdio.h>
struct Student{
char *name;
int age;
}s1 = {"lucy",18};
int main(){
struct Student s2 = {"tom",22};
printf("姓名:%s",s1.name);
printf("年龄:%d\n",s1.age);
printf("姓名:%s",s2.name);
printf("年龄:%d",s2.age);
return 0;
}
#include<stdio.h>
struct Student{
char *name;
int age;
};
int main(){
//声明结构体数组
struct Student stus[] = {
{"lucy",18},
{"tom",25},
{"lily",16}
};
for(int i = 0;i < sizeof(stus)/sizeof(stus[0]);i++){
printf("第%d个学生,姓名:%s,年龄:%d\n",i,stus[i].name,stus[i].age);
}
return 0;
}
第0个学生,姓名:lucy,年龄:18
第1个学生,姓名:tom,年龄:25
第2个学生,姓名:lily,年龄:16
定义格式:struct 结构体名 *变量名
#include<stdio.h>
struct Student{
char *name;
int age;
};
int main(){
struct Student s1 = {"lucy",18};
//声明结构体指针
struct Student *p = &s1;
printf("%#x\n",p);
//可以通过->来访问结构体指针指向的结构体成员
printf("姓名:%s,年龄:%d",p->name,p->age);
//解引用
struct Student s = *p;
printf("姓名:%s,年龄:%d",s.name,s.age);
return 0;
}
0x62fe00
姓名:lucy,年龄:18
共用体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型。您可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值。共用体提供了一种使用相同的内存位置的有效方式。
共用体有时也被称为联合或者联合体,这也是 Union 这个单词的本意。
结构体和共用体的区别在于:结构体的各个成员会占用不同的内存,互相之间没有影响;而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。
结构体占用的内存大于等于所有成员占用的内存的总和(成员之间可能会存在缝隙),共用体占用的内存等于最长的成员占用的内存。共用体使用了内存覆盖技术,同一时刻只能保存一个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉。
union 共用体名{
共用体所包含的变量或数组
};
有些数据在存储时并不需要占用一个完整的字节,只需要占用一个或几个二进制位即可。例如开关只有通电和断电两种状态,用 0 和 1 表示足以,也就是用一个二进位。正是基于这种考虑,C语言又提供了一种叫做位域的数据结构。
在结构体定义时,我们可以指定某个成员变量所占用的二进制位数(Bit),这就是位域。
struct 位域结构名 {
位域列表
type [member_name] : width ;
};
元素 | 描述 |
---|---|
type | 只能为 int(整型),unsigned int(无符号整型),signed int(有符号整型) 三种类型,决定了如何解释位域的值。 |
member_name | 位域的名称。 |
width | 位域中位的数量。宽度必须小于或等于指定类型的位宽度。 |
C语言标准规定,位域的宽度不能超过它所依附的数据类型的长度。通俗地讲,成员变量都是有类型的,这个类型限制了成员变量的最大长度,:
后面的数字不能超过这个长度。
C语言允许为一个数据类型起一个新的别名,C语言允许为一个数据类型起一个新的别名,例如,有一个结构体Stu
//声明结构体变量
struct Stu s;
使用typedef可以简化
typedef struct Stu{} Stu;
//声明结构体变量
Stu