文章目录
一、声明结构体类型
1.结构体是什么
结构体是C语言中一种用户自定义的数据类型,它允许我们将不同类型的变量组合在一起,形成一个新的数据类型。
2.如何声明结构体
一般形式
声明结构体类型一般形式为
struct 结构体名称{
成员
};
而每一个成员都应该进行类型声明, 即struct example{ int a; };
空结构体
空结构体即结构体中没有成员属性,在之后再填写,实现它的内容。
匿名结构体
匿名结构体即将结构体的变量名放在大括号后面,前面删去名字。
struct {
int a;
}example;
但是有变量名的结构体可以反复定义变量,而匿名结构体只用一次,因此更经常用有名字的结构体。
typedef的使用
我们不能直接使用自己所创建的结构体的名字,要使用结构标签去引用结构,在名字前面要加上struct。但是每次使用时加入结构标签就比较麻烦,我们可以使用typedef,如:
typedef struct example example;
实际上typedef就是给一个类型取名,给struct example取名为example,这样在下面运用的时候就可以直接使用example了。
而且我们还可以更简便,直接在声明结构体的时候,在struct前面加上typedef,在大括号后面加上你想起的名字,即:
typedef struct example{
int a;
}exmaple;
嵌套
结构体也支持多层嵌套,具体例子如下:
typedef struct {
int day;
int month;
int year;
} Date;
typedef struct {
char name[50];
int age;
Date birthDate;
} Person;
二、结构体变量
1.声明结构体变量
当我们声明一个结构体的时候,该结构体是没有占用内存的,在我们定义变量的时候才会占用内存。声明变量有两种方法。
第一种和一般变量一样,如int a;
第二种我们可以在结构体后面直接跟上变量名,如
typedef struct example{
int a;
}exmaple, name;
2.结构体变量的赋值
结构体变量的赋值因为其中有几个变量,所以赋值时我们加上一个大括号,在里面挨个填写数值(如果是嵌套的话,就在里面再加一个大括号),即
typedef struct {
int day;
int month;
int year;
} Date;
typedef struct {
char name[50];
int age;
Date birthDate;
} Person;
int main()
{
Person person1 = {"Alice", 25, {12, 5, 1998}};
}
3.访问结构体成员变量
访问时我们通过.操作符,采取结构体变量名.所对应变量名的结构来操作(嵌套的话应是以结构体变量名.嵌套结构体变量名.所对应变量名的形式表示,以此类推)
printf("Birth Date: %d/%d/%d\n", person1.birthDate.day,
person1.birthDate.month, person1.birthDate.year);
三、结构体指针
声明结构体的指针和一般的有一些不同点。
函数在声明的时候需要声明是一个指针,在名字前加上*;
访问结构体成员变量时不能使用.操作符,要使用->(在嵌套结构体中仍然用.操作符)
#include <stdio.h>
typedef struct {
int day;
int month;
int year;
} Date;
typedef struct {
char name[50];
int age;
Date birthDate;
} Person;
void printPerson(Person *person) {
printf("Name: %s\n", person->name);
printf("Age: %d\n", person->age);
printf("Birth Date: %d/%d/%d\n", person->birthDate.day, person->birthDate.month, person->birthDate.year);
}
int main() {
Person person1 = {"Alice", 25, {12, 5, 1998}};
printPerson(&person1);
return 0;
}
四、结构体数组
定义结构体数组一般形式是
(1)struct 结构体名
{成员表列} 数组名[数组长度];
(2)先声明一个结构体类型,然后再用此类型定义结构体数组:
结构体类型 数组名[数组长度];
#include <stdio.h>
struct Student {
char name[50];
int age;
};
int main() {
// 定义结构体数组
struct Student students[5];
// 设置结构体数组成员的值
for (int i = 0; i < 5; i++) {
sprintf(students[i].name, "Student%d", i+1);
students[i].age = 18 + i;
}
// 打印结构体数组的值
for (int i = 0; i < 5; i++) {
printf("Student name: %s, age: %d\n", students[i].name, students[i].age);
}
return 0;
}
五、结构体内存计算
结构体内存就是把成员内存相加,但是计算中会存在内存对齐的情况,结构体内存对齐是指编译器在分配内存给结构体时,按照一定的规则将结构体成员对齐到特定的内存地址上的过程。这么做的目的是为了提高内存访问的效率,因为在许多计算机体系结构中,访问未对齐的内存地址会导致性能损失甚至错误。
在进行内存对齐时,编译器通常会根据结构体成员的类型以及所处的位置来确定合适的对齐方式。例如,在32位系统中,大多数编译器默认采用4字节对齐,也就是说结构体成员的起始地址必须是4的倍数;在64位系统中,通常采用8字节对齐。
#include <stdio.h>
typedef struct {
char name;
int age;
} Person;
int main()
{
printf("%d", sizeof(Person));
return 0;
}
例如我的系统是64位的,就对齐到8个字节了。输出如下:
8
Process exited after 0.04653 seconds with return value 0
请按任意键继续. . .