结构体——枚举——联合体(共用体)

我把这三个自定义数据类型放在一起进行一个对比和记忆

一、结构体

当我们需要记录一个人或者事物的信息时,我们要记录他(它)的一些方面的信息。

比如说一个人的时候,我们需要知道他的名字,年龄,性别,电话号码等内容

但是单靠以前我们学过的int ,char,float ,double....只能描述其中的一方面

如果选择我们需要的几个类型,并把它集中起来,可以用来描述一个人或者事物的相关信息。

这时候结构体就起到了作用!!

首先,结构体的关键字是struct

那么如何定义一个结构体,又或者说结构体的格式是什么样子的?

1.结构体的格式

struct B
{
	char c;
	short s;
	double d;
};

这里我列举了一个结构体类型。

格式为在struct关键字后面加上 该结构体类型名 

在花括号内,是不同的类型的集合。

最后用;结束。

联系我们以前学的数组,

int a[20]={0};
char a[]="abcd";

一个变量里的类型都是一样的,要么是int类型,要么是char类型。

这里的结构体类型中,其中包含的类型可以相同,可以不同。

2.结构体的初始化

这里我们写一个关于同学信息的结构体变量

struct stu
{
	//结构的成员变量
	char name[20];//名字c
	int age;//年龄
	char id[20];//学号
};

首先给这个结构体类型编一个变量名a或者b等等。。。

这里我们用s

struct stu s = { "张三",30,"20200534"};

初定义时,用花括号括起来,在里面,根据前面的结构体类型里面的几个类型输入相应的变量,并用逗号隔开。这就完成了定义。

3.如何打印(展示)定义的内容

这时候需要用到的操作符是   "  .  "

看下列代码,假如我们要打印这个张三同学的各个信息

	printf("%c\n", s.name);
    printf("%d\n",s.age);
	printf("%s\n",s.id);
	

找到变量名s 

在用   进行索引,找到相应的变量名,就可以了。


当把指针引入其中。

创建一个指针变量  *ps

指向的内容是  struct stu 

所以结构体指针的写法为:

struct stu *ps=&s;

当用指针找到相应的结构体变量时

这时候也需要用到一个新的操作符:->

比如现在我们用指针变量ps指向s;

用指针打印出相应的内容:

struct stu *ps=&s;
		printf("%c", ps->sb.c);
        printf("%c\n",(*ps).sb.c);

同时对ps进行解引用,相当于又回到s.

4.结构体内容占内存大小(结构体对齐)

struct B
{
	char c;
	short s;
	double d;
};

如何计算上面结构体的大小呢?

如果我们猜测一下:char类型占1个字节,short占2个字节,double占8个字节

加起来之后是11个字节。

如图:

错!

这里涉及到偏移量问题。

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

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

3.结构体整体的大小是各个类型最大对齐数的倍数

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

用我的话描述一下这个过程:

像上图一样从第一个格子开始数,char类型占一个字节,就一个绿色。

当short类型开始排队时,应该从2的倍数处开始排。

占2个格子之后到第4个。

然后排double类型 (占8个字节),但是short后面是4.需要放弃4个格子,从8开始,占8个,最后是16个。

因为16是8的倍数。所以不再舍弃字节。

如图:

5.结构体数组

在以前的数组学习中。

比如我们建立一个整型数组:

int a[10] = { 1,2,3,4,5,6,7,8,9,10 };

数组里面存放的是一个个数,

而放在一个结构体中,数组中的每一项代表一个结构体变量名。

比如说:

struct stu
{
	char name[20];
	int age;
	char id[30];
}a[3];

 这里的a[3]代表三个变量名  分别是a[0],a[1],a[2]。

在这里相当于上面的struct stu s中的s

二.  枚举

1.枚举的格式

如何编写一个枚举的格式,这和结构体类型非常相似,但有一点是不同的。

看下列代码:

enum color
{
	red,
	green,
	blue
};

可以看出,和结构体再外表结构上不同的是,枚举类型把分号改成了逗号。

2.枚举类型中的变量

说是一个个变量,其实每一个变量都是代表的一个个数字常量

我们打印上面的red,green,blue 观察结果

enum color
{
	red,
	green,
	blue
};
int main()
{
	enum color s = red;
	printf("%d %d %d \n", red, green, blue);
    return 0;
}

结果为 0,1,2。

这好像和我们以前学的define有点相似:

#define W 1
#define Y 2
#define Z 3
int main()
{
	printf("%d %d %d", W, Y, Z);
	return 0;
}

代码结果为:1 ,2 ,3。

那为啥还要用枚举常量?

      1.枚举更具有可读性,更加的容易理解

      2.提高代码维护性,确保变量合法(可自行体会)

2.枚举常量的赋值

是不是其中的变量只能从0开始?

其实不然。

我们可以给他定义一个数字

这里跟define一样的意思。

enum color
{
	red=8,
	green,
	blue=9
};

其中一种上述情况,当green没有初定义时,会再上一个常量的基础上+1  ,此时green也就是9。

第一个常量没有定义时,默认为0.

三、联合体

1.联合体格式

联合体的格式和结构体的差不多。在结构体的基础上将关键字struct改为union关键字即可。

但是和结构体不同的是,其中的变量通常为 int ,unsigned int,signed int  ,char。

union UN
{
	char c;//1
	int i;//4
};
int main()
{
	union UN u;
	printf("%d ", sizeof(u));
	printf("%p ", &u);
	printf("%p ", &(u.c));
	printf("%p ", &(u.i));
	return 0;
}

同时联合体也叫做共用体。

为何叫做共用体,其实是有说法的。


其实,联合体叫做共用体是因为char类型变量和int类型变量公用一块内存空间。

运行上述代码,可以观察到u的大小为4,是int类型的占字节大小。。。。

所以,联合体所占空间最小是变量中最大占字节数。


同时运行结果为u 和 u.c  和u.i的地址相同。

当然,不是说两个数同时存在同一个地方,这不合理。

在引用的时候,只能定义一个数,另一个数根据占字节大小,大小为另一个数的其中一部份的大小

具体例子为:

union un
{
	char c;
	int i;
};

int main()
{
	union un u;
	u.i = 10000;
	printf("%d %d", u.c, u.i);
	return 0;
}

运行结果为  16  和10000;

2.判断当前处理器的大小端问题

什么是大小端?

举个例子

r如图:

#include<stdio.h>
int check_sys()
{
  int a = 0x11223344;//16为进制
  char* p = (char*)&a;
 
    return *p;
  }
int main()
{
   if(check_sys() == 68)//4*16+4
   {
      printf("小端\n");
   }
   else
   {
      printf("大端\n");
   }
}

因为这里是*p=68  ,所以符合小端储存模式

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值