#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void test_struct_size();
/*结构体定义*/
struct grade
{
int math;
int english;
float chinese;
};
/*结构体定义*/
struct student
{
char name[16];
int age;
int class;
int id;
int score;
char provience[16];
/*结构体嵌套*/
struct grade grade;
};
/*typedef简化定义,此处只是定义了类型,cla_1,cla_2*/
typedef struct class
{
struct student stu[60];
char teacher[60];
} cla_1,cla_2;
/*直接结构体声明全局变量*/
struct school
{
cla_1 cla1_1[30];
cla_2 cla2_2[30];
} sh;
/*直接定义结构体变量,不声明结构体类型*/
struct
{
char subject[8];
int score;
} test;
void main()
{
printf("这是结构体基础知识练习\n");
/*简化结构体,声明变量*/
cla_1 class_1;
cla_2 class_2;
/*结构体初始化值的方式1*/
struct student stu1 ={"XM",16,3,22,44,"CQ"};
struct student stu2;
strncpy(stu2.name, "XW",sizeof(stu2.name));
stu2.age = 18;
stu2.class = 6;
stu2.id = 16;
strncpy(stu2.provience,"CD",sizeof(stu2.provience));
printf("stu2.name:%s\n", stu2.name);
/*结构体数组*/
struct student stu[3];
/*此处sizeof(数组名)就是数组所占空间的大小,sizeof(struct student)就是一个结构体的长度,注意记得加struct */
for(int i=0;i<sizeof(stu)/sizeof(struct student);i++)
{
printf("请输入第%d个学生的名字\n",i+1);
scanf("%s",stu[i].name);
printf("请输入第%d个学生的成绩\n",i+1);
scanf("%d",&stu[i].score);
}
for(int i=0; i<sizeof(stu)/sizeof(struct student);i++)
{
printf("student[%d].name:%s;\nstudent[%d].sorce:%d\n\n",i+1,stu[i].name,i+1,stu[i].score);
}
/*结构体指针*/
struct student *stu_point = NULL;
/*结构体指针初始化,使用malloc方法*/
stu_point =(struct student *)malloc(sizeof(struct student));
strncpy(stu_point->name, "XK", sizeof(stu_point->name));
stu_point->class = 100;
stu_point->id = 90;
printf("stu_point->name:%s\n",stu_point->name);
printf("stu_point->class:%d\n",stu_point->class);
printf("stu_point->id:%d\n",stu_point->id);
if(stu_point)
free(stu_point);
/*结构体指针数组*/
struct student *stu_point2[3];
for(int i = 0; i<sizeof(stu_point2)/sizeof(struct student*);i++)
{
stu_point2[i] = (struct student*)malloc(sizeof(struct student));
printf("请输入第%d个学生的名字\n",i+1);
scanf("%s",stu_point2[i]->name);
printf("请输入第%d个学生的成绩\n",i+1);
scanf("%d",&stu_point2[i]->score);
}
for(int i = 0; i<sizeof(stu_point2)/sizeof(struct student*);i++)
{
printf("学生:%s, 成绩:%d\n",stu_point2[i]->name, stu_point2[i]->score);
if(stu_point2[i])
free(stu_point2[i]);
}
test_struct_size();
}
/*
结构体字节对齐问题:
结构体计算大小由于要遵循计算机的访问规则,所以我们引入了内存对齐和偏移量的概念。
结构体内存对齐规则
1.第一个成员在结构体变量偏移量为0的地址处。
2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数 = 编译器默认的对齐数与该成员大小的较小值。
3.结构体总大小为最大对齐数的整数倍(每个成员变量都有一个对齐数)。
4.如果嵌套了结构体,嵌套的结构体对齐到自己最大对齐数的整数倍处,结构体的整体大小就是所有所有最大的对齐数的整数倍(包含嵌套结构体的对齐数)。
*/
struct s1
{
char ch1; //一个字节
char ch2; //一个字节
int ch3; //四个字节,因此要遵循第一条规则,2个char一共偏移2个字节
}; //不是4的整数倍,因此要再多偏移两个字节,一共偏移8个字节
void test_struct_size()
{
printf("siezof(struct s1)=%ld\n",sizeof(struct s1));/*输出的是8个字节*/
printf("sizeof(struct class)=%ld\n", sizeof(struct class));
printf("sizeof(cla_1)=%ld\n", sizeof(cla_1));
}