C语言中volatile、register、const、static、extern、 auto关键字的作用
写在前面
register,寄存器变量,告诉编译器它所声明的变量在程序中使用的频率非常高,请编译器尽量将此变量放在寄存器中,这样程序执行速度更快。但实际上编译器不一定这么做,可以忽略此选项。
register 修饰符的几点注意点:
- 变量必须是 CPU 接受的类型,单个值,长度小于等于整数的长度
- 只能使用于局部变量和函数形参,全局(register)变量是非法的
- 无论寄存器变量是否存放在寄存器中,它地址都是不能访问的(取&)
- 其实过量的寄存器声明并没有什么坏处,寄存器可以忽略
const 修饰符
有时候我们希望定义一个变量,它的值在整个作用域都不能变,比如定义缓冲区大小等,可以用 const 来修饰。
// 定义常量 strlen
const int strlen = 4096;
// 试图修改 strlen 变量,编译器会报错
strlen = 2048;
一般常量在定义时同时进行初始化,否则在定义完之后不能对其进行赋值操作,常见的初始化方式有:
const int num = get_num(); // 运行时初始化
const int num = n; // 运行时初始化
const int num = 10; // 编译时初始化
const 变量真的就不能修改吗?看个例子:
const int bufsize = 1024;
int *p = &bufsize;
*p = 2048;
printf("bufsize = %d\n", bufsize);
打印结果是2048。其实 const 修饰的变量不变的本质含义是程序中通过引用变量符号 bufsize 时不能够进行修改,而不是 bufsize 变量所指向那段内存数据不能修改。
const修改指针变量
其实C语言中使用 const 定义常量并没有什么优势,完全可以使用#define来替代。const 通常用在函数形参中,当形参是一个指针,为了防止函数内部修改指针指向的内容时,就可以用 const 限制。
size_t strlen(const char *s);
int strcmp(const char *s1, const char *s2);
常见C语言标准库中都有const限制,在我们自定义函数中也可以适当使用 const 来保证程序的健壮性。
const 类型与非 const 类型转换
static 修饰符在程序中使用最为广泛,它大概有如下几种用法:
- 修饰局部变量:增加了局部变量的生命周期,若定义未初始化,则默认初始化为0
- 修饰全局变量:缩小了全局变量的作用域,限制在本模块(文件)中访问
- 修饰函数:缩小了函数的作用于,限制函数只能被本模块调用
volatile 修饰符
关键字 extern 常用在变量和函数声明前,用来说明此变量或函数是在别处定义过的,要在此处引用。
在 hello.c 中:
void hello()
{
printf("Hello.\n");
}
在 main.c 文件中:
extern void hello();
hello(); // 声明之后调用 hello 函数
在 main.c 文件被编译时,告诉编译器hello()在别的地方定义过了,这里只是引用一下,放心编译好了,在程序最后链接的时候会去找hello实际定义的函数。
auto 修饰符
关键字 auto 其实可以理解为就是局部变量的显示说明,程序中很少去显示声明某个变量为 auto 的。
?