一、存储类型
类型名称 |
含义 |
auto |
声明自动变量 一般不使用 |
extern |
声明变量是在其他文件正声明(也可以看做是引用变量) |
register |
声明积存器变量 |
static |
声明静态变量 |
const |
声明只读变量 |
sizeof |
计算数据类型长度 |
typedef |
用以给数据类型取别名(当然还有其他作用) |
volatile |
说明变量在程序执行中可被隐含地改变 |
#define |
定义常量和宏 |
1.1 auto
- 关键字auto用于声明一个变量为自动变量
自动变量也称局部变量,所有局部变量默认都是auto,一般省略不写;
全局变量定义不在结构体、枚举类型、联合体和函数中定义,因此如果用auto声明全局变量,编译出错
- 如果只使用auto修饰变量,变量的类型默认为整型
- auto 变量必须在定义时初始化,类似于const关键字
1.2 extern
- 如果想在定义全局变量之前或者在其它源文件中引用该全局变量,需要用关键字 extern 对该变量作“外部变量声明“
- 如果文件 a.c 需要引用 b.c 中的函数 fun(int a),那么就可以在a.c中声明 extern int fun(int a),然后就能在a.c中使用 fun 函数
- extern 的引用方式比包含头文件要简洁,加速程序的预处理过程
1.3 register
- 用 register 声明的变量是寄存器变量,存放在CPU的寄存器中,其它声明的变量都是存放在内存中,因此,register 类型变量运算速度很快,register变量所产生的代码比静态内存中的变量和堆栈中的变量所产生的代码执行速度更快,但是不能取地址,编译会报错
- 用关键字 register 将变量变成寄存器变量,可以将数值保存在CPU的内部寄存器中,省去了CPU从内存抓取数据的时间,提高了程序的运行效率,适用频繁被访问的变量或循环变量
- register 只能修饰局部变量,不能修饰全局变量和函数
- register修饰的变量必须是CPU所接受的
1.4 static
- 普通局部变量存储于进程栈空间,使用完毕会立即释放,使用 static 修饰符定义静态局部变量,即使在声明时未赋初值,编译器也会把它初始化为0,并且静态局部变量存储于进程的全局数据区,即使函数返回,它的值也会保持不变,其作用域为局部作用域,当定义它的函数结束时,其作用域也随之结束
- 全局变量定义在函数体外部,在全局数据区分配存储空间,编译器自动对其初始化,其他文件可以使用 extern 外部声明后直接使用。静态全局变量仅对当前文件可见,其他文件不可访问,其他文件可以定义与其同名的变量,两者互不影响。全局变量加上static关键字能够有效地降低程序模块之间的耦合,避免不同文件同名变量的冲突
- 在函数的返回类型前加上static,就是静态函数,只能在声明它的文件中可见,其他文件不能引用该函数,不同的文件可以使用相同名字的静态函数,互不影响
1.5 const
作用:限定一个变量初始化完成后不可被修改
- 常量指针:不能通过指针修改指针所指向的变量的值,但是指针可以指向别的变量
int a = 5;
int b = 10;
const int *p = &a;
*p = 20;
p = &b;
- 指向常量的指针(指针常量):指针常量的值不能被修改,即不能存一个新的地址,不能指向别的变量,但是可以通过指针修改它所指向的变量的值
int a = 5;
int b = 10;
int *const p = &a;
*p = 20;
p = &b;
- const 修饰函数返回值,不能修改返回值
- const 修饰函数形参,函数体内不能修改形参a的值
- 常引用: const 类型说明符 &引用名
- const 变量仅在文件内有效, 如果想在多个文件之间共享const对象,必须在变量的定义之前添加 extern 关键字
1.6 sizeof
- 用于数据类型:sizeof(type),如 sizeof(int)
- 用于变量:sizeof(var)
- sizeof 操作符不能用于函数类型,不完全类型(未知存储大小)或位字段
操作符 |
操作数 |
结果 |
sizeof |
char |
1 |
sizeof |
unsigned char |
1 |
sizeof |
signed char |
1 |
sizeof |
int |
2 |
sizeof |
unsigned int |
2 |
sizeof |
short int |
2 |
sizeof |
unsigned short |
2 |
sizeof |
long int |
4 |
sizeof |
unsigned long |
4 |
sizeof |
float |
4 |
sizeof |
double |
8 |
sizeof |
long double |
10 |
sizeof |
指针 |
4(32位系统) |
sizeof |
数组类型 |
总字节数 |
sizeof |
联合体 |
最大字节成员的字节数 |
sizeof |
结构体 |
对齐后的总字节数 |
1.7 volatile
volatile 提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,告诉编译器对该变量不做优化,都会直接从变量内存地址中读取数据,从而可以提供对特殊地址的稳定访问
- 中断服务程序中修改的供其它程序检测的变量,需要加volatile
- 多任务环境下各任务间共享的标志,应该加volatile
- 存储器映射的硬件寄存器通常也要加volatile说明
- 一个参数既可以是const,也可以是volatile吗,例如只读的状态寄存器,是volatile类型,因为它可能被意想不到地改变,也可以是const类型,因为程序不应该去修改它
1.8 typedef和#define
typedef与#define
二、控制语句
类型名称 |
含义 |
break |
跳出当前循环 |
continue |
结束当前循环,开始下一轮循环 |
goto |
无条件跳转语句 |
三、数据类型
类型名称 |
含义 |
enum |
声明枚举类型 |
signed |
声明有符号类型变量或函数 |
struct |
声明结构体变量或函数 |
union |
声明联合数据类型 |
unsigned |
声明无符号类型变量或函数 |
void |
声明函数无返回值或无参数,声明无类型指针(基本上就这三个作用) |