结构体类型
// 定义一个结构体数据类型,没有分配内存空间
//struct Teacher
//{
// char name[64];
// int age;
// int id;
//};
typedef struct Teacher
{
char name[64];
int age;
int id;
} Teacher;
int main() {
//struct Teacher Teacher;
Teacher teacher;// 告诉编译器分配内存空间
system("pause");
}
变量声明的三种方法
方式一:
定义,初始化结构体变量分开
typedef struct Student
{
char name[10];
char age;
}Student;
Student stu;
方式二:
附加结构体变量初始化
struct Student
{
char name[10];
char age;
}stu;
方式三:
匿名定义变量
struct
{
char name[10];
char age;
}stu;
变量赋值三种方式
方式一:
定义变量的时候初始化
Student stu = {"hyk", 25};
Student stu = {.age = 25, .name = "hyk"};
或
struct Student
{
char name[10];
char age;
}stu={"hyk", 25};
或
struct
{
char name[10];
char age;
}stu={"hyk", 25};
方式二:
赋值
Student stu;
strcpy(stu.name, "hyk");
stu.age = 25;// 通过点的方式赋值。这里的“.”是寻址操作,计算age 相对于 stu这个大变量的偏移量,这里的计算是在cpu里运行的,没有操作内存
Student *p = NULL;
P = &stu;
p->age = 30;// 通过指针的方式赋值。这里的“->”也是寻址操作,计算age 相对于 stu这个大变量的偏移量,这里的计算是在cpu里运行的,没有操作内存
方式三:
内存拷贝
Student stu = { "hyk", 25 };
Student stu2 = stu;// 实际是两个结构体内存的拷贝,将stu内存的值拷贝给了stu2,如果结构体成员有指针元素,那么就不能直接赋值。
结构体内部指针成员变量赋值
一个结构中可以有数组成员,也可以有指针成员,如果是指针成员结构体在初始化和赋值的时候需要提前为指针成员分配内存。
指定结构体元素的位字段
定义一个结构体时可以指定具体元素的位长。
struct Test{
char a : 2;//指定元素为2位(bit)长,不是2个字节长
char b : 4;
char c : 4;
};// 整个结构体占2+4+4=10bit, 2个字节长(内存最小的单位为字节)
结构体成员内存对齐图解
结构体嵌套对齐图解:
结构体数组
struct Student
{
int a[3];
int b;
};
int main() {
struct Student stu[3] = {
{ {1, 2, 3 }, 10 },
{ {4, 5, 6 }, 11 },
{ {7, 8, 9 }, 12 }
};
// 可以简写为:
struct Student stu[3] = {
{ 1, 2, 3, 10 },
{ 4, 5, 6, 11 },
{ 7, 8, 9, 12 }
};
return 0;
}
结构体数组与指针
栈数组:
struct Student
{
int a;
int b;
};
int main() {
struct Student stu[3];
struct Student *p = stu;
int i;
for (i = 0; i < 3; i++) {
p->a = 10 + i;
p->b = 20 + i;
p++;
}
// 等价于
//for(i = 0; i < 3; i++) {
// p[i].a = 10 + i;
// p[i].b = 20 + i;
//}
printf("%d,%d\n", stu[0].a, stu[0].b);
printf("%d,%d\n", stu[1].a, stu[1].b);
printf("%d,%d\n", stu[2].a, stu[2].b);
return 0;
}
堆数组:
struct Student
{
int a;
int b;
};
int main() {
struct Student *p;
p = malloc(sizeof(struct Student) * 3);
struct Student *arr = p;//arr指针记录了p的初始指针
p->a = 1;
p->b = 2;
p++;// 导致p指针的位置发生偏移,
p->a = 3;
p->b = 4;
printf("%d,%d\n", arr[0].a, arr[0].b);
printf("%d,%d\n", arr[1].a, arr[1].b);
//free(p);// 因为p的指针发生偏移,free(p)会发生异常
free(arr);// 可以正常释放malloc申请的堆内存
return 0;
}