1,结构体是一种自己定义的数据类型;是创建变量的模板;不占有内存空间;结构体变量才包含数据存储的空间;
2,结构体与数组相似但数组中的数据类型全部相同,结构体中的数据类型不一定相同;
3,结构体变量在内存中的位置关系(不考虑内存对齐的问题)
#include
struct Student
{
char s_id[8];
char s_name[8];
char s_sex[5];
int s_age;
}Student;
int main()
{
int a=10,b=20;
Student s1={"10906","ljl","man","18"};
return 0;
}
内存分布如下
#include<stdio.h>
struct Student
{
注意vs2019不支持(vs2012支持)
char *s_id;
char *s_name;
char *s_sex;
int *s_age;
2019应写为
const char *s_id;
const char *s_name;
const char *s_sex;
int s_age;
}Student;
int main()
{
int a=10,b=20;
Student s1={"10906","ljl","man","18"};
return 0;
}
内存分布如下
4,结构体的自定义会导致程序崩溃
5,结构体的嵌套
#include<stdio.h>
#include<string.h>
struct Date
{
int year;
int month;
int day;
};
struct Student
{
char s_id[8];
char s_name[8];
cahr s_sex[5];
struct Date brithday;
int s_age;
}Student;
int main()
{
int a=10,b=20;
Student s1={"10906","ljl","man",{1999,07,08},"18"};
或者不加{}
Student s1={"10906","ljl","man",1999,07,08,"18"};
return 0;
}
6.相同的结构体变量可以相互赋值
#include<stdlib.h>
#include<string.h>
struct Student
{
char s_id[8];
char s_name[8];
cahr s_sex[5];
int s_age;
}Student;
int main()
{
int a=10,b=20;
Student s1={"10906","ljl","man","18"};
Student s2,s3;
s2=s1;
s3=s2;
但是不可以进行以下操作(数组不可以相互赋值)
s2.s_id=s1.s_id;
strcpy_s(s2.s_id,s1.s_id);
return 0;
}
结构体为什么要采用对齐方式:
1,cpu并非逐字节的读写内存而是以2,4,或8的倍数的字节快来读取
例如:有一个int类型从三字节开始存放,cpu以2的倍数访问就需要4次才可以读取完该int类型的变量;
2,有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数据。显然在读取效率上下降很多。
3,不同的平台采用的对齐方式可能就会不同,因此同样的结构体在不同的平台可能大小也不相同;
计算结构体大小的三条规则:
1,结构体变量的首地址必须是结构体变量中最大的基本数据类型所占字节的整数倍;
2,结构体中的每个成员相对于结构体首地址的偏移量都必须是每个变量本身基本数据类型所占字节个数的整数倍;
3,结构体变量的总大小为结构体中最大变量其基本数据类型所占字节数的整数倍;
例如:
1,大小 为12
struct node
{
char a;
int b;
char c;
};
2,大小为24
struct node
{
char a;
double b;
char c;
};
3,大小为8
4,结构体的嵌套大小为40
注意上图中最大基本类型仍为8,在处理birthday时应偏移量与data结构体中的最大类型
5,结构体大小为48
6,结构体大小为80
7,计算结构体成员的偏移量
允许设计结构体变量
#include <stdio.h>
struct Eemployr
{
char a[27];
char b[30];
long int c;
long int d;
double e;
};
int main()
{
struct Eemployr s;
int offer=(char*)&s.d-(char*)&s;
printf("%d",offer);
return 0;
}
打印结果为64
不允许设计结构体变量
#include <stdio.h>
struct Employr
{
char a[27];
char b[30];
long int c;
long int d;
double e;
};
int main()
{
将0强转为结构体指针类型在指向d之后再将其地址强转为整型;
int offer=(int)&((struct Employr *)0)->d;
printf("%d",offer);
return 0;
}
打印结果为64
#define(type,exa) ((int)&((struct *)0)->exa)