0
点赞
收藏
分享

微信扫一扫

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

产品喵dandan米娜 2022-03-25 阅读 120
c语言

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

结构体的基础知识

结构体是一些值的集合

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",
printf("%p",(
printf("%p",(
//三个地址值相同
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个字节,存在内存对齐
举报

相关推荐

0 条评论