关键字深度剖析,集齐所有关键字可召唤神龙?【完】

今天继续上一次的关键字,学习《C语言深度剖析》,由于深度剖析,简单的东西就不赘述,继续集齐剩下的龙珠吧!平安夜圣诞节加肝一小期,结束我们的关键字,也祝考研人一战成硕

img

⚡️union 的内存级布局理解
⚡️enum 关键字的基本理解
⚡️typedef 的理解与分类
⚡️关键字总结

1. union关键字

1.1 联合体union

🌀union 关键字的用法与struct 的用法非常类似。
🌀union 维护足够的空间来置放多个数据成员中的“一种”,而不是为每一个数据成员配置空间,在union 中所有的数据成员共用一个空间,同一时间只能储存其中一个数据成员,所有的数据成员具有相同的起始地址。
🌀如果一些数据不可能在同一时间同时被用到,则可以使用union。

1.2 union和内存布局

union在开辟空间的时候,一元素中最大的为准,也就是说

union un
{
	int a;
	char b;
};

在这样一个联合体中,int由于是最大的数据类型,所以说会开辟总共四个空间
那么说到开辟空间就不得不谈一谈开辟的空间下内存的布局空间

上面这种情况下,是如下的哪一种布局呢?

image-20211224220103600

其实是联合体内其实都是从低地址开始开辟的,且共用空间,完全重叠 ,然剩下的空间会以放射状,向高地址发散,每一个数据都认为自己是联合体中的第一个元素

image-20211224220248285

1.3 大小端对于union的影响

union
{
	int i;
	char a[2];
}*p, u;

int main
{
	p = &u;
	p->a[0] = 0x39;
	p->a[1] = 0x38;
	printf("%d", p->i);
	return 0;
}

image-20211224221503721

如何用程序确认当前系统的存储模式?

	union un x;
	x.a = 1;
	if (x.b == 1) {
		printf("小端\n");
	}
	else {
		printf("大端\n");
	}

大端小端的这里问题不多谈,我们主要讲的是union

2. enum 关键字

2.1 枚举

枚举(enum)是个很有用的数据类型。

enum 变量类型还可以给其中的常量符号赋值,如果不赋值则会从被赋初值的那个常量开始
依次加1,如果都没有赋值,它们的值从0 开始依次递增1

2.1.1 其实枚举就像整形常量

enum color {
	RED = 10,
	YELLOW,
	BLACK = 100,
	GREEN,
	BLUE
};

int main()
{
	int c = BLUE; //注释

	enum color c = BLUE;

	printf("%d\n", RED);
	printf("%d\n", YELLOW);
	printf("%d\n", BLACK);
	printf("%d\n", GREEN);
	printf("%d\n", BLUE);

	return 0;
}

2.1.2 枚举常量的意义

作用是:

⚡️解释一组强相关性的整形常量

⚡️起到代码的自描述性,与其直接赋值成数字,还要注释,不如将其化为枚举常量,一次性搞定,不用换在做过多解释

2.2 定义宏和枚举

❄️ 定义的宏本身是一个个定义的,但是枚举常量不是,枚举常量体现出一种相关性,这是宏所表现不出来的
❄️#define 宏常量是在预编译阶段进行简单替换。枚举常量则是在编译的时候确定其值。
❄️ 一般在编译器里,可以调试枚举常量,但是不能调试宏常量。
❄️ 枚举可以一次定义大量相关的常量,而#define 宏一次只能定义一个。

小结:

未来能用到枚举的情况不是很多

3.伟大的缝纫师----typedef 关键字

3.0 书中的一个笑话

关于马甲的笑话
有这样一个笑话:一个猎人在河边抓捕一条蛇,蛇逃进了水里。过一会,一个乌龟爬
到岸边。猎人一把抓住这个乌龟,大声的说道:小样,别你为你穿了个马甲我就不认识你
了!
typedef 关键字是个伟大的缝纫师,擅长做马甲,任何东西穿上这个马甲就立马变样。
它可以把狼变成一头羊,也能把羊变成一头狼。甚至还可以把长着翅膀的鸟人变成天使,
同样也能把美丽的天使变成鸟人。所以,你千万不要得罪它,一定要掌握它的脾气,不然
哪天我把你当鸟人,你可别怪我。_

3.1 历史的误会----也许应该是typerename

很多人认为typedef 是定义新的数据类型,这可能与这个关键字有关。本来嘛,type 是
数据类型的意思;def(ine)是定义的意思,合起来就是定义数据类型啦。不过很遗憾,这种
理解是不正确的。也许这个关键字该被替换为“typerename”或是别的词。
typedef 的真正意思是给一个已经存在的数据类型(注意:是类型不是变量)取一个别
名,而非定义一个新的数据类型。

新的名字与原来的名字相比,就更能表达出想要表达的意思,这就是typedef的意义

比如说 下面的类型重命名

typedef unsigned int u_int;
typedef int * int_p;

说i了那么多typedef,其实就是一个含义:类型重命名

  1. 对一般类型进行重命名
  2. 对结构体类型进行重命名
  3. 对指针进行重命名
  4. 对复杂结构进行重命名

3.1.1 重命名示例

//对结构体类型进行重命名
typedef struct stu {
	char name[16];
	int age;
	char gender;
}stu_t;
//对复杂结构进行重命名
typedef int a[10];
//对一般类型进行重命名
typedef int int32;
//对复杂结构进行重命名
typedef static int s_int;
//对指针进行重命名 
typedef int * int_p;
int main()
{
	stu_t s;//不用 struct stu s 
	return 0;
}

3.2 typedef 与#define 的区别

3.2.1 问题一

typedef int* int_p;
#define ptr_t int *

看上去好像都是int* ,实则语法上并不是,还是有些许差别的

这里的情况需要特别注意

但现在正在typedef重命名这个int* 的时候,注意看下面监视里面的数据类型

typedef int* int_p;

int main()

{
	int_p a, b;
	int*  c, d;
	return 0;
}

image-20211224234222706

可以看到typedef下,定义的变量都是指针变量,而int *的两个变量只有前者是指针变量,而后者并不是

但是#define就不一样了,我们都知道#define是会在预编译的过程中被替换的,所以#define之后会和原先一模一样,这就体现了typedef 和 #define之间的不同

#define ptr_t int *
int main()
{
	ptr_t a, b, c;	
	return 0;
}

image-20211225135229020

3.2.2 问题二

下面的这个typedef使用可不可以?

#include <stdio.h>
#define INT32 int
typedef int int32;
int main()
{

unsigned int32 a = 10; //C中typedef不支持这种类型的扩展,不能当成简单的宏替换 err
unsigned INT32 a = 20; //宏简单替换,可以
	static int32 =10;//err						
	return 0;
}

不可以!

其实typedef在被重命名之后,不能再拿其他的关键字来进行修饰,而#define是可以的

自然这个也是不行的,在一个变量定义的时候,只能有一个存储关键字

typedef static int  int32_t;

报错是:image-20211225140834868

4. 总结关键字

目前,我们已经把C89(C90) 的所有关键字全部学完,我们也全部讲完,没有遗漏的。下面就要对关键字进行一下分类,方便大家理解:

🍁数据类型关键字(12个)

🌴char :声明字符型变量或函数
🌴short :声明短整型变量或函数
🌴int : 声明整型变量或函数
🌴long :声明长整型变量或函数
🌴signed :声明有符号类型变量或函数
🌴unsigned :声明无符号类型变量或函数
🌴float :声明浮点型变量或函数
🌴double :声明双精度变量或函数
🌴struct :声明结构体变量或函数
🌴union :声明共用体(联合)数据类型
🌴enum :声明枚举类型
🌴void :声明函数无返回值或无参数,声明无类型指针

🍁控制语句关键字(12个)

🌐1. 循环控制(5个)

🌱for :一种循环语句
🌱do :循环语句的循环体
🌱while :循环语句的循环条件
🌱break :跳出当前循环
🌱continue :结束当前循环,开始下一轮循环

🌐2. 条件语句(3个)

🌾if : 条件语句
🌾else :条件语句否定分支
🌾goto :无条件跳转语句

🌐3. 开关语句 (3个)

🌿switch :用于开关语句
🌿case :开关语句分支
🌿default :开关语句中的“其他”分支

🌐4. 返回语句(1个)

🍃return :函数返回语句(可以带参数,也看不带参数)

🍁存储类型关键字(5个)

🌰auto :声明自动变量,一般不使用
🌰extern :声明变量是在其他文件中声明
🌰register :声明寄存🌱器变量
🌰static :声明静态变量
🌰typedef :用以给数据类型取别名(但是该关键字被分到存储关键字分类中,虽然看起来没什么相关性)

注:存储关键字,不可以同时出现,也就是说,在一个变量定义的时候,只能有一个。

🍁其他关键字(3个)

🍀const :声明只读变量
🍀sizeof :计算数据类型长度
🍀volatile :说明变量在程序执行中可被隐含地改变

好了!😄终于集齐所有关键字,接下来召唤神龙🐉

也就是下一章符号,那么下一次就从讲⚡️符号开始⚡️

关键字

image-20211224222831310

好了今天的内容就到这里了哈!!!

下次继续C深剖->符号,请持续关注

干净又卫生,别忘了一键三连

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

言之命至9012

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

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

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

打赏作者

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

抵扣说明:

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

余额充值