⭐️ 关键字深度剖析 ⭐️第一章(变量&关键字auto/register)

119 阅读7分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

目录

前言

关键字分类

第一个C程序

变量

什么是变量

如何定义变量

为什么定义变量

 变量定义的本质

变量声明的本质

变量的分类

变量的作用域

变量的生命周期

作用域 vs 生命周期

关键字-auto

关键字 - register

寄存器

register修饰变量

使用对象


前言


本文主要讲解点:

  • 初步了解关键字分类
  • 深刻理解变量
  • 深刻理解定义与声明
  • auto关键字的理解
  • 站在存储结构角度,理解register

关键字分类


一般的书上,都是 32 个, 但是这个都是 C90(C89) 的标准

其实 C99 后又新增了5 个关键字(目前主流的编译器,对 C99 支持的并不好)

默认情况使用 C90 即认为 32 个

关键字说明
auto声明自动变量
short声明短整型变量或函数
int声明整型变量或函数
long声明长整型变量或函数
float声明浮点型变量或函数
double声明双精度变量或函数
char声明字符型变量或函数
struct声明结构体变量或函数
union声明共用数据类型
enum声明枚举类型
typedef用以给数据类型取别名
const声明只读变量
unsigned声明无符号类型变量或函数
signed声明有符号类型变量或函数
extern声明变量是在其他文件正声明
register声明寄存器变量
static声明静态变量
volatile说明变量在程序执行中可被隐含地改变
void声明函数无返回值或无参数,声明无类型指针
if条件语句
else条件语句否定分支(与 if 连用)
switch用于开关语句
case开关语句分支
for一种循环语句
do循环语句的循环体
while循环语句的循环条件
goto无条件跳转语句
continue结束当前循环,开始下一轮循环
break跳出当前循环
default开关语句中的“ 其他 ” 分支
sizeof计算数据类型长度
return子程序返回语句(可以带参数,也可不带参数)循环条件
后面的章节将全部覆盖这32个关键字

第一个C程序


//1. vs2013中建立项目 
//2. 编写第一个C程序"hello world" 
#include <stdio.h> 
#include <windows.h> //windows.h系统头文件,仅仅是为了停屏 
int main()
 { 
    printf("hello world!\n");
    system("pause"); //pause停屏,会用就行 
    return 0; 
 }
//运行程序的方式,当然可以用vs直接启动 
//当然,也可以在vs项目中,找到代码生成的二进制可执行程序,双击即可。 
//所以:我们的角色是写代码,编译器的角色是把文本代码变成二进制可执行程序。 
//双击?不就是windows下启动程序的做法吗? 
//那么启动程序的本质是什么呢?  将程序数据,加载到内存中,让计算机运行

变量


什么是变量

在内存中开辟特定大小的空间,用来保存数据

如何定义变量

int x = 10char c = 'a'; 
double d = 3.14; 

类型 变量名 = 默认值

为什么定义变量

计算机是用来计算的,计算就需要数据,并不是所有数据要立马计算

因此,变量将有需要的数据保存起来,等待进一步处理(这样效率高)

变量定义的本质

首先我们要知道程序运行要加载到内存中,程序计算需要数据

而变量定义即是在内存中开辟一个空间,来保存数据

一定是内存:因为定义变量,也是程序逻辑的一部分,程序已经被加载到内存

变量声明的本质

定义:开辟空间(有且只有一次)

声明:告知(广而告之)(可以多次) 

变量的分类

  • 局部变量

包含在代码块中的变量叫做局部变量

局部变量具有临时性:进入代码块,自动形成局部变量,退出代码块自动释放

对于 函数中的变量是局部变量,不能说错,但说法是不准确的

  • 全局变量

在所有函数外定义的变量,叫做全局变量

全局变量具有全局性

代码块:用 {} 括起来的区域,就叫做代码块

int g_x = 100; //全局变量 
int main()
 { 
    int x = 10; //局部变量,main函数也是函数,也有代码块{} 
    printf("x:%d\n", x); 
    return 0;
 }

变量的作用域

作用域概念:指的是该变量的可以被正常访问的代码区域

int main() 
{ 
    int x = 10;
    if (x == 10)
{ 
    int y = 20; 
    printf("局部: x: %d, y: %d\n", x, y);//y只能在本代码块内有效 
}
    printf("局部: x: %d, y: %d\n", x, y); //报错,y不能被访问 
    return 0;
}
局部变量:只在本代码块内有效  
全局变量:整个程序运行期间,都有效
int g_x = 100; //全局变量 
int main() 
{ 
    int g_x = 10; //局部变量,与全局同名
    printf("g_x:%d\n", g_x); //输出的是局部,也就是局部和全部同名的时候,优先局部
    return 0; 
}

变量的生命周期

  • 概念

指的是该变量从定义到被释放的时间范围

所谓的释放,指的是曾经开辟的空间 ” 被释放 “

局部变量: 进入代码块,形成局部变量 [ 开辟空间 ] ,退出代码块, " 释放 " 局部变量

全局变量 : 定义完成之后,程序运行的整个生命周期内,该变量一直都有效

作用域 vs 生命周期

作用域相当于影响力

生命周期相当于从运行到结束的时间

关键字-auto


  • 使用

一般在代码块中定义的变量,即局部变量,默认都是 auto 修饰的,不过一般省略

不是默认的所有变量都是auto,auto一般用来修饰局部变量(已经很老,基本永不使用)

统称局部变量:局部变量,自动变量,临时变量,都是一回事

关键字 - register


寄存器

现代 CPU 内,都集成了一组叫做寄存器的硬件,用来做临时数据的保存

距离 CPU 越近的存储硬件,速度越快

register修饰变量

尽量 将所修饰变量,放入 CPU 寄存区中,从而达到提高效率的目的

使用对象

1. 局部的 ( 全局会导致 CPU 寄存器被长时间占用 )

2. 不会被写入的 ( 写入就需要写回内存 )

3. 高频被读取的 ( 提高效率所在 )

4. 如果要使用,请不要大量使用,因为寄存器数量有限

注意:register修饰的变量不能取地址

变量已经处在寄存器中,而地址是内存相关的概念

意见:早时期需要register来手动优化,现在编码器智能化优化更好,不必怎么人为使用

int main() 
{ 
    register int a = 0; 
    printf("&a = %p\n", &a); 
//编译器报错:错误 1 error C2103: 寄存器变量上的“&” 
//注意,这里不是所有的编译器都报错,目前我们的vs2013是报错的。 
    return 0;
}

第二章传送门:⭐️ 关键字深度剖析 ⭐️第二章(多文件\数据类型&关键字extern/static)