1、结构类型的总大小必须是结构体中“最大成员变量类型大小”的整数倍。
2、结构体成员相对于首地址的偏移量必须是其类型大小的整数倍。
3、结构体的首地址的偏移量必须是结构体最大成员类型大小的整数倍。
typeof 的作用是获取修饰变量的数据类型,例如: int val=0; typeof(val)的作用就是获取val的数据类型。 (data_type)0的作用是将0 转换为data_type类型的指针。这里我们使用(typeof(data) *)0->member的作用是将0转换为data 类型的指针,用来引用data的成员变量member。 (size_t)(&(((typeof(data)*)0->member)))中& 的作用是获取Stu的成员变量member的地址,并将其转换为Size_t(unsigned int)的类型。整个(size_t)(&(((typeof(data)*)0->member)))我们认定其为member的偏移值,因为这里我们规定起始地址是0;
#include结构体和共用体的区别#define GET_offset(data,member) (size_t)(&(((typeof(data)*)0)->member)) typedef struct Student { char name[20]; int age; int sex;//0代表男,1代表女 }Stu; int main() { int offset_age=0; Stu s1; offset_age=GET_offset(s1,age); printf("%dn",offset_age); return 0; }
结构体和共用体都是人造的数据类型,他们的区别我们可以从以下几点进行讨论,既类型的大小,储存方式,对齐方式
| 储存方式 | |
|---|---|
| 结构体在储存上每个成员变量都有自己的空间,其整个结构体在内存上是连续的;共用体所有的成员变量公用一块内存空间,调用哪个成员就按照哪个成员的方式读取内存 | |
| 对齐方式 | 类型大小 |
| – | – |
| 结构体中每个成员相对首地址的偏移量是该成员的类型大小的整数倍;共用体每个成员的偏移量相对于共用体类型的首地址偏移量都是0 | 结构体类型的大小是其最大成员变量类型大小的整数倍,其总大小等于所有最后一个成员的偏移量加上最后一个成员的大小(还要符合结构体类型的大小是其最大成员变量类型大小的整数倍);共用体类型的大小等于最大的成员变量的大小 |
typedef struct Stu
{
int A;//4 偏移量0
char B;//1 偏移量4
int C[20];//40 偏移量40
char* d;//4 偏移量 80
};//总的结构体的大小为120
typedef union Teacher
{
int A;//4 偏移量0
char* B;//1 偏移量0
char C[8];//40 偏移量0
}Tea;//总的大小应该为8
int main()
{
Tea T1;
T1.A=0x12345678;
T1.C[1]=?;//此时T1.C[1]=78 因为是大端储存(高位存在低地址,低位存在高地址)
}
简述堆区和栈区的区别
1、管理方式:
栈区由操作系统管理,栈的使用和回收都由操作系统来进行负责;
堆区是由程序员操作的内存空间,通过new,malloc,calloc,realloc等函数是申请空间,该空间被使用完毕之后不会自己进行释放,需要程序员自己手动进行释放。
2、储存方式
栈区:不管是函数的运行还是变量的申请,其在栈上的储存都是连续的,当他们不用的时候系统会自动回收相应的空间。栈用来函数操作和储存局部变量。
堆区:堆上的储存是不连续的。
3、大小:栈的默认大小一般是10M,堆的默认大小一般是1G。
补充:
1栈内存存储的是局部变量而堆内存存储的是实体;
2.栈内存的更新速度要快于堆内存,因为局部变量的生命周期很短;
打印杨辉三角(使用一位数组进行打印)3.栈内存存放的变量生命周期一旦结束就会被释放,而堆内存存放的实体会被垃圾回收机制不
#include#define N 10 int main() { int i=0,j=0; int arr[N]={1,1}; prinft("1n"); arr[1]=arr[2]=1; printf("%d,%dn",arr[1],arr[2]); for(i=3;i 1;j--) { arr[j]arr[j]+arr[j-1]; } for(j=1;j<=i;++j) { printf("%3d",arr[j]); } printf("n"); } return 0; }



