结构体类型

##结构体类型创建

定义:结构体是一个聚合数据类型;将相同或不同类型的元素放到一起,结构体内存布局和数组基本一致,结构体内部第一个成员变量的地址最低;

####结构体声明


struct A
{
  int a;
  char b[20];
   short c;
};//分号不能丢

上面一段代码就可以被称为一个结构体,struct A为结构体名,{ }内为成员变量,}后必须加;

其他形式的结构体声明

1.匿名结构体声明:用于结构体只使用一次是用匿名声明


struct
{
    int a;
    char b;
    float c;
}x;//x 为结构体变量
struct
{
int a;
char b;
float c;
}a[20],*p;//a[20]为结构体数组,p为结构体指针,指向结构体

2.类型重定义结构体声明

typedef struct A
{
    int a;
    char b;
}Node;//Node为结构体名,struct A也为结构体名进行了类型重定义

结构体自引用

首先看错误的声明方法

struct Node
{
  int data;
    struct Node next;
};//结构体一被使用,就会一直创建结构体,会崩溃

所以应该这样声明

struct Node
{
  int data;
    Node* next;//结点
};

结构体定义


struct A
{
  int a;
  char b[20];
   short c;
};//分号不能丢
struct A p1;//定义d定义结构体
struct A
{
int a;
char b;
float c;
}a[20],*p;//此种方式也为结构体定义

结构体初始化

结构体的初始化与数组的初始化完全一致

结构体可以被整体初始化,但不能被整体赋值

都用{}来初始化,{}里面放不同类型

//例子
struct A
{
  int a;
  char b[20];
   short c;
};//分号不能丢
struct A p1={1,{a},2};
//例子
struct A
{
  int a;
  char b[20];
   short c;
} p1={1{a}2}

结构体内存对齐

方法:

1.第一个成员变量与结构体变量偏移量为0地址处(第一个成员变量的地址=结构体地址)

2.其他成员变量要对齐到某个数字(对其数)的整数倍的地址处。

对齐数=编译器默认的对其属与该成员大小 的较小值 。(在vs中对齐数为8,Linux为4)

对齐:存放该变量的起始偏移量要整除改变量的对齐数(通常是能整除该变量的最小整数)

3.结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。

4.如果嵌套了结构体,嵌套结构体对齐到自己的最大对其属的整数倍,结构体的整体大小就是所有最大对齐数(内嵌套结构体的对齐数)的整数倍。(一个结构体对齐数,内部最大对齐数)。

为什么要内存对齐?

内存对齐是一种用空间换取时间的行为的

修改默认对齐数操作

#pragma pack(8)//设置最大对齐数
struct A
{
    char c1;//1+3
    int i;//4+4
    char c2;//8+1+3
};//分号不能丢
#pragma pack()
#pragma pack(1)
struct B
{
   char c1;//1
    int i;//1+4
    char c2;//5+1
};//分号不能丢

上面两段代码 成员变量类型完全相同,struct A 大小是12,struct B大小是6

结构体传参

结构体传参推荐传结构体的地址,而不是传结构体

因为函数传参时会拷贝一份临时变量,如果穿结构体就会直接拷贝整个结构体浪费空间;

如果传入结构体地址,就会拿一个结构体指针来接收;指针在32位平台下,都是4个字节,会大大节省了空间

位段,位段计算机大小

位段用于计算机网络,定义协议

1.位段的成员必须是int,unsigned,char

2.位段的成员变量名后边有一个冒号和一个数字。

和结构体相比,位段可以达到同样的效果,但可以很好的节省空间,但有跨平台问题

struct A
{
    char a:3;
    char b:4;
    char c:5;
    char d:4;
};
struct Ss={0};
s.a=10;
s.b=12;
s.c=3;
s.d=4;

内存分配

枚举+联合

枚举 --------列举。把可能的取值----列举

如 一周七天可以列举,一个物体有几个颜色也可以列举

enum Day
{
Mon,//里面的成员变量都是枚举常量
Tues,
Wed,
Thur,
Fri,
Sat,
Sun,
};
enum Day day=Fri;
day=5//也可以 但是无意义

枚举常量的值默认从0 开始,一次递增,如果赋初值,则从初值处一次递增;

联合(共用体)

联合是一种特殊的自定义类型,有一系列成员变量,特征是这些成员共用一块空间

特点:联合体所有成员共用一块空间 ,所以所有成员变量的地址都是一样的都为联合体的地址;

union Un
{
char c;
int i;
}
union Un un;
printf("%d\n",sizeof(un);

联合体任然要遵循内存对齐

1.联合体的大小至少是最大成员的大小;

2.当最大成员不是最大对齐数的整数倍时,就把联合体扩大到最大对齐数的整数倍;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值