本文已参与「新人创作礼」活动,一起开启掘金创作之路
目录
前言
本文主要讲解点:
- 初步了解关键字分类
- 深刻理解变量
- 深刻理解定义与声明
- 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 = 10;
char 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;
}