深入理解关键字
32个关键字
在c89,c90中存在32个关键字。
数据类型关键字(12个)
char :声明字符型变量或函数
short :声明短整型变量或函数
int : 声明整型变量或函数
long:声明长整型变量或函数
signed :声明有符号类型变量或函数
unsigned :声明无符号类型变量或函数
float:声明浮点型变量或函数
double :声明双精度变量或函数
struct :声明结构体变量或函数
union :声明共用体(联合)数据类型
enum :声明枚举类型
void :声明函数无返回值或无参数,声明无类型指针
控制语句关键字(12个)
- 循环控制(5个)
for :一种循环语句
do :循环语句的循环体
while :循环语句的循环条件
break :跳出当前循环
continue :结束当前循环,开始下一轮循环
- 条件语句(3个)
if : 条件语句
else :条件语句否定分支
goto :无条件跳转语句
- 开关语句 (3个)
switch :用于开关语句
case :开关语句分支
default :开关语句中的“其他”分支
- 返回语句(1个)
return :函数返回语句(可以带参数,也看不带参数)
存储类型关键字(5个)
auto :声明自动变量,一般不使用
extern :声明变量是在其他文件中声明
register :声明寄存器变量
static :声明静态变量
typedef :用以给数据类型取别名(但是该关键字被分到存储关键字分类中,虽然看起来没什么相关性)
其他关键字(3个)
const :声明只读变量
sizeof :计算数据类型长度
volatile :说明变量在程序执行中可被隐含地改变
🛺auto
🍕变量
🤔为什么要存在变量?
计算机对数据进行计算是在CPU内完成的,CPU在处理数据的时候是一个数据一个数据的处理,并不是一下子将所有的数据就处理完了,就好比人吃饭一样,是一口一口的吃。
这个时候就能体现变量的作用了。既然CPU是一个数据一个数据的处理,那些还未处理的数据该如何做呢?当然是通过变量存储起来,需要使用的时候,再去将这个变量传到CPU内。
那这个时候就可以回答上面的问题了。变量存在的意义是存储数据,以供后续使用
🤔变量定义的本质是什么
既然知道了变量的意义,是用来存数据的,那是不是需要空间呢?当然需要。
定义变量的本质是开辟空间,存储数据
需要强调一点,定义只能一次,换句话说,同一个变量只能定义一次,不可以多次定义同一个变量。
在哪开辟空间呢?在内存中开辟空间。
✨局部变量和全局变量
什么是局部变量?
在函数内部或者在{}中定义的变量就叫做局部变量。
那全局变量呢?
在所有函数外部定义的变量叫全局变量。
🎈变量的生命周期
什么是生命周期?从变量定义开始,到变量释放,这一时间段就是变量的生命周期。
🎈局部变量的生命周期
上面有说到,局部变量是在函数内部或者{}定义的变量叫做局部变量。生命周期如何体现呢?
我们来看下图的红色波浪线,以及报错
总结
局部变量的生命周期:进入代码块,形成局部变量[开辟空间],退出代码块,"释放"局部变量
至于局部变量为什么要释放,这跟它存储位置有关,局部变量存放在栈区,栈区的存放的变量是具有临时性,也就是会释放它所占有的空间。
那局部变量的生命周期就很好理解了,只在它定义的范围内有效。
可以在通过一个例子来理解
可以看到打印结果是0,1,0,1的重复。这是因为test函数中的变量i在不断的定义和释放。
🎈全局变量的生命周期
看到“全局”二字,我们就有所猜测了。
全局变量的生命周期是跟随程序的整个进程。也就是说只要程序存在,全局变量就“活”着。
这也和全局变量的存储位置有关,它存放在全局数据区,放在全局数据区的数据,都是会和程序”同生共死“。
🎈变量的作用域
作用域是指该变量的可以被正常访问的代码区域。
也可以这样理解,作用域是该变量能够影响的范围。
局部变量:只在本代码块内有效
全局变量:整个程序运行期间,都有效
看到这你可能会疑惑,感觉生命周期和作用域是一个东西,其实不是。待会讲到static,在去讲这两者会更好理解。
✨铺垫做完,auto开始
aoto是用来修饰局部变量的,全局变量不可被aoto修饰。
一般都是被省略的。
这个关键字很老了,已经“退休”了,一般不怎么使用
🚗register
🎈铺垫工作:存储分级
知道为什么所有人都买得起电脑吗?是因为存储分级的存在,电脑的价格才降下来的。
我们知道CPU是对数据进行计算的,在计算的时候,CPU一般先从内存中读取数据。读取过来的数据,需要存放,所以CPU是具备一定的存储能力,即通过寄存器来存储这些数据。
寄存器离CPU很近,那么每次CPU获取数据的时候就会很快。
这些和register有什么关系吗?有关系。
💡register作用
可以称register是“最快的男人” ,register修饰变量的作用:尽量将这个变量,存到寄存器中,从而达到提高效率的目的。
哪些变量可以使用register呢?
1.局部变量(全局变量不可使用,因为生命周期随着程序进程,会导致寄存器长期占用)
2.高频使用的变量
3.不需要写入的数据(写入就需要回内存,这样用register修饰还有何意义呢)
如果使用register,不能高频使用,因为寄存器有限。
🤔register修饰的变量能被取地址吗?
答案是不能,地址是内存特有的概念,寄存器不属于内存。
🚕static
✨铺垫工作
🤔变量和函数可以跨文件使用吗?
答案是可以!
函数为什么可以不声明?
程序翻译过程是:预处理–>编译–>汇编–>链接–>可执行二进制文件。
我们只需要了解链接即可,链接的过程是将多个文件整合在一起的过程。
这里是将 test.c,test2.c和stdio.h整合在一起。
test.c中主函数中调用show函数的时候没有找到,但是在链接后,可以找到show这个函数,所以可以调用它。
全局变量如果不声明的话,是会报错的,还没走到链接这一环节,就报错了。
所以函数和变量是可以跨文件使用的!
一般的我们也要将函数的声明写上。
🎈头文件的引入
假如现在有一百多个文件,一百多个文件中都有全局变量,和函数。
这一百多个文件中每个文件要使用其他文件的函数和全局变量,那每个文件中,都需要写对应函数变量的声明。
声明还好,如果你对函数或者全局变量进行修改,那么对应的声明也要修改,这样的维护成本太高。
为了解决这个问题就引入了头文件。头文件里放声明,其他文件来引用这个头文件,那么维护成本就大幅度降低。
那头文件(自定义的头文件)一般都放些什么呢?
1.头文件(库函数的头文件)
2.函数声明,全局变量的声明
3.宏定义
4.结构体,联合体,枚举
右击–>添加–>新建项–>选中头文件
头文件的引用,自定义头文件的一般使用“”,库函数的头文件一般用<>。
在vs2019中新建一个头文件
会默认有一段代码#pragma once
这是一个预处理命令,作用是防止头文件被多次引用。
如果没有这段代码,可以手动加上。
三子棋、五子棋多文件实例
💡static修饰全局变量和函数
我们已经知道了,全局变量和函数是可以跨文件的,如果我不想让它们跨文件该如何?就是用static修饰。
🎈static修饰全局变量
作用是改变了全局变量的作用域,只能在本文件中有效。外部文件不能直接使用,全局变量的生命周期没改变!
🎈static修饰函数
作用是该函数只能在本文件中有效,外部文件不能直接使用。
🎈static修饰局部变量
static修饰局部变量的作用是:改变该变量的生命周期,由局部的变为全局性的。但是作用域没有改变!
这个时候就可以很好的区分生命周期和作用域的概念了
第一张图:k在不断的定义释放,所以结果都是1。(进函数定义,出函数销毁)
第二张图:我们可以看到定义只发生了一次,没有被销毁!
为什么说只定义了一次,没有被销毁?因为打印的时候1只出现了一次,也就验证了上述所说的。
这里就是生命周期发生改变了,从原来的临时性变为全局性。
相应的存储位置也发生了变化。由原来的栈区存储,改为在全局数据区存储。
通过下面一张图来看看,作用域发生改变了没有。
可以发现作用域是没改变的,尽管k的生命周期变成了全局性,但是它影响的范围只在test函数中,也是其对应的代码块内。
🚌sizeof
sizeof的作用是求元素类型的大小。元素的类型不仅仅是指int,double,这类内置类型,也包括其他复杂类型。
比如说,int(*)[10], int[10]…
🎈sizeof返回值的问题
其次要注意sizeof的返回值类型是 unsigned int 通过下面题带你理解
因为sizeof返回的结果是无符号的,在和i进行运算的时候中间发生了算数转换。i从原来的有符号整形提升为无符号整形。
🤔sizeof 是函数吗?
sizeof不是函数,是关键字,也可以说是操作符。
验证了sizeof求的是类型的大小。
两个关键字不可以连用,需要带上()
验证了sizeof不是函数! 因为函数需要()
🤔sizeof中的表达式计算吗?
答案是不计算,为什么呢?上面有讲到程序的翻译过程
预处理–>编译–>汇编–>二进制可执行程序。
sizeof在编译的时候,就能知道类型的大小,并且将计算的结果赋值给b,在编译后面的环节中,就没有sizeof了,所以sizeof它压根不在意表达式是什么。
🎉总结
auto是用来修饰局部变量的,一般省略。
register作用是尽量将修饰的变量,放到寄存器中,提高效率。
static修饰全局变量,该变量的作用域发生改变,生命周期未改变,只在本文件中使用,不能被外部文件直接使用。
static修饰函数,该函数只能在本文件中使用,不能被外部文件直接使用。
static修饰局部变量,该变量的生命周期变为全局生命周期,但其作用域未发生改变。
sizeof求元素类型所占的空间大小,单位是字节。