自定义类型(结构体、枚举、联合体)的学习

自定义类型:结构体,枚举,联合体

结构体的基础知识

结构体是一些值的集合

struct tag
{
  member_list;
}variable-list;
struct Stu
{
  char name[20];
  int age;
  double score;
};
struct Book
{
  char name[20];
  float price;
  char id[12];
};
struct Stu s1;//全局
int main()
{
  struct Stu s2;//局部
  return 0;
}

特殊的声明

struct   //匿名结构体 ,这里只能用一次
{
  char name[20];
  char id[12];
}ss;
struct   
{
  char name[20];
  char id[12];
}a[20],*p;

// p = &ss //err  匿名结构体的成员如果一样,在编译器看来也是不同的类型的结构体

结构的自引用

数据域:存放数据的区域

指针域:存放下一个节点的地址

struct Node
{
  int data;//数据
  //struct Node n;//error
  struct Node * next;//最后一个地址是NULL
};
typeof struct Node   //typeof 是类型重命名
{
  int data;
  struct Node* next;
}Node,* pNode;
//pNode --> struct Node*
int main()
{
  struct Node n1;
  Node n2; //n2与n1类型一样
}

结构体创建与初始化

struct Book
{
  char name[20];
  float price;
  char id[20];
}s={"c语言",55.5f,"PGC001"};
struct Node
{
  struct Book b;
  struct Node* next;
};
int main()
{
  struct Book s2 = {"love2study",66.6f,"bbd"};
  struct Node n = {{"Java",66.8,"TG001"},NULL};
  
  return 0;
  
}

结构体内存对齐

  • 第一个成员放在结构体内存偏移量为0的地址处

  • 其他成员要对齐到某个数字(对齐数)的整数倍的地址处

    对齐数 = 编译器默认的一个对齐数与该成员大小的较小值

  • 结构体的总大小必须为最大对齐数(每个成员变量都有自己的对齐数)的整数倍

  • 如果嵌套了结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

struct S1
{
  char c1;
  int i;
  char c2;
};//12个字节
struct S2
{
  char c1;
  char c2;
  int i;
};//8个字节
//offsetof   //<stddef.h>
//size_t offsetof( structName, memberName );
//计算结构体成员相对于起始地址的便宜量

修改默认对齐数

#pragma pack(4)//设置  一般2的几次方
struct S
{
  char c;
  double d;
};
#pragma pack()//取消  中间的结构体就是按照更改的对齐数来排序

位段

  • 位段的成员必须是int,unsigned int ,signed int.

  • 位段的成员名后边有一个冒号和一个数字。

struct A
  {
    int _a:2;  //_a这个成员只占2个bit位
    int _b:5;  //_b这个成员只占5个bit位
    int _c:10; //_c这个成员只占10个bit位
    int _d:30; //_d这个成员只占30个bit位
  };

位段的开辟空间

  • 位段的成员可以是int,unsigned int,signed int 或者是char类型

  • 位段的空间上是按照需要以四个字节(int)或者是1个字节(char)的方式来开辟的。

  • 位段涉及很多不确定因素,位段是不跨平台的,注意可移植的程序应该避免使用位段。

枚举

enum Sex
{
   MALE,//0
   FEMALE,//1
   SECRET,//2
};// 枚举的可能
enum Day
{
	Mon,
	Tues,
	Wed,
	Thur,
	Fri,
	Sat,
	Sun,
};
int main()
{
  enum Sex s = MALE;
  enum Sex s2 = FEMALE:
  enum Day d =Fri;
}
// 枚举的值: 默认是从0开始,一次递增1,定义的时候也可以赋初值

联合(共用体)

联合的定义

包含一系列的成员,这些成员共有一块空间

nion Un
{
	char c; //1
	int i;  //4
};
int main()
{
  union Un u;
  printf("%d\n",sizeof(u));//4
  printf("%p",&u);
  printf("%p",(&u.c));
  printf("%p",(&u.i));
  //三个地址值相同
  return 0;
}
// 不会同时出现的时候可以选择联合体

联合的特点

联合体的大小,至少是最大成员的大小。

当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对其数的整数倍

利用联合体判断大小端: 

int check_sys()
{
  union Un
  {
    cahr c;
    int i;
  };
  c.i = 1;
  return u.c;
}
int main()
{
  if (1 == check_sys())
    printf("小端\n");
  else
    printf("大端\n")
  return 0;
}

 联合体也存在内存对齐的情况

union Un
{
	char arr[5];//看类型,都是1
	int i;
};//内存是8个字节,存在内存对齐

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

love2study

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值