由于最近一段时间一直在忙于WEB的前端开发,很久都没有写过C方面的程序,感觉很陌生了一样,真的是一天不练,都被拉到千里之外,趁现在正好手上有一个关于C方面的项目,特地的总结了一下C语言关键字的使用及注意事项。
C语言标准定义的32个关键字
auto | 声明自动变量,缺省时编译器一般默认为auto |
int | 声明整理变量 |
double | 声明双精度变量 |
long | 声明长整型变量 |
char | 声明字符型变量 |
float | 声明单精度浮点变量 |
short | 声明短整型变量 |
signed | 声明有符号类型变量 |
unsigned | 声明无符号类型变量 |
struct | 声明结构体变量 |
union | 声明联合数据类型 |
enum | 声明枚举类型 |
static | 声明静态变量 |
switch | 用于开关语句 |
case | 开关语句分支 |
default | 开关语句的其它分支 |
break | 跳出当前循环 |
register | 声明寄存器变量 |
const | 声明只读变量 |
volatile | 说明变量在程序执行中可被隐含地改变 |
typedef | 用以给数据类型取别名 |
extern | 声明变量是在其他文件中声明(也可看作引用变量) |
return | 子程序返回语句(可以带参数,也可以不带参数) |
void | 声明函数无返回值或无参数、声明空类型指针 |
continue | 结束当前循环,开始下一轮循环 |
do | 循环语句的循环条件 |
while | 循环语句的循环条件 |
if | 条件语句 |
else | 条件语句否定分支 |
for | 一种循环语句(可意会不可言传) |
goto | 无条件跳转语句 |
sizeof | 计算对象所占内存空间大小 |
下面挑选一些比较重要,容易将用法和概念混淆的关键字进行总结,以下内容是本人查找资料进行整理的。
一、Const
const从字面是恒定不变的意思,也翻译成常量和常数,可能正因为这一点,很多人都认为被const修饰的值是常量,这不精确,精确来说应该是只读变量,其值在编译时不能被使用。
1、Const作用
(1)可以定义定义const常量:const int MAX = 100;
(2)便于进行类型检查:const常量有数据类型,而宏常量没有数据类型,
(3)可以保护被修饰的东西:防止意外的修改,增强程序的健壮性。
(4)可以很方便的进行参数的调整:同宏定义一样,可以做到不变则已,一变都变。
(5)提高了效率:编译器通常不为普通const常量分配存储空间,而是将它们保存在符号表中。
示例程序:
#define M 3 //宏常量
const int N = 5; //此时并未将N放入内存中
.......
int i = N; //此时为N分配内存,以后不再分配
int I = M; //预编译期间进行宏替换,分配内存
int j = N; //没有内存分配
int J = M; //再进行宏替换,又一次分配内存
2、Const的变量和指针使用
(1)定义常量:const修饰类型的变量value是不可变的,以下两种定义形式在本质上是一样的。
int const ValueName = value;
const int ValueName = value;
(2)指针使用const
a. 指针本身是常量不可变
char* const pContent;
b. 指针所指向的内容是常量不可变
char const* pContent;
c. 两者都不可变
const char* const pContent;
d. 区别方法
在*中间画一条线,如const在*左边,则const修饰指向的变量,如cosnt在*右边,const修饰指针本身。
3、函数中使用Const
(1)const修饰函数参数
a. 传递过来的参数在函数内不可变(无意义,因为Var本身就是形参)
void function(const int Var);
b. 参数指针所指内容为常量不可变
void function(const char* Var);
c. 参数指针本身不可变(无意义,因为char * Var也是形参)
void function(char* const Var);
d. 参数为引用,为了增加效率同时防止修改,参数不可变--C++特性
void function(const Class & Var);
(2)const修饰函数返回值
const修饰函数返回值其实用的并不是很多,它的含义和const修饰普通变量以及指针的含义基本相同。
a. const int fun1() ; //这个其实无意义,因为参数返回本身就是赋值
b. const int * fun2(); //调用时使用const int *pValue = fun2();
//我们可以把fun2()看成一个变量,即指针内容不可变
c. int * const fun3(); //调用时使用int* const pValue = fun3();
//我们可以把fun3()看成一个变量,即指针本身不可变
二、Static
从字面意思是静止的、不变的,下面主要从作用域、存储域方面进行讲解。
1、修饰变量
修饰变量又分为修饰局部变量和修饰全局变量。
(1)修饰局部变量
作用域:只限在本文件使用(又称内部变量),外部文件不能使用,准确的说,作用域是从定义之处开始,到文件结束,定义之前的代码不能使用它。
存储域:存储在静态区,同时在所处模块初次运行时进行初始化工作,且只初始化一次。
(2)修饰全局变量
作用域:只限在本文件使用,外部文件不能使用。
存储域:存储在静态区,如果不赋初值,编译期会自动赋初值0或空字符。
(3)普通变量
作用域:局部变量生存周期在模块执行时,执行结束就被立刻释放,全局变量在整个文件和外部文件(使用extern声明)都可使用。
存储域:局部变量存储在栈区,全局变量存储在静态区。
示例程序一:
#include <stdio.h>
void staticAddVal()
{
static int a;
printf("a=%d ",a);
a ++;
}
int main()
{
staticAddVal(); <span style="color:#009900;">//第一次调用输出a=0;</span>
staticAddVal(); <span style="color:#009900;">//第二次调用记忆了第一次退出的值,输出a=1</span>
return 0;
}
示例程序二:
//file1.c
int varA = 1;
static int varB;
void funA(){}
.....
//file2.c
extern int varA; <span style="color:#009900;">//使用file1.cpp中定义的全局变量</span>
extern int varB; <span style="color:#009900;">//错误!varB是static类型,无法在其它文件中使用</span>
.....
int main()
{
....
}
2、修饰函数
修饰函数使得函数成为静态函数,但此处的"static"的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(又称内部函数),利用这一特性可以在不同的文件中定义同名函数,而不必担心命名冲突。
示例程序三:
//file1.c
void funA()
{
....
}
static void funB()
{
....
}
//file2.c
extern void funA(); <span style="color:#009900;">//使用file1.c中定义的函数</span>
extern void funB(); <span style="color:#009900;">//错误!无法使用file1.c文件中的static函数</span>
.....
int main()
{
.....
}
三、Extern
修饰符extern用在变量或者函数的声明前,用来说明此变量/函数是在别处定义过的,要在本文件中引用。
注:定义的全局变量或函数默认的是extern,具有外连性。
1、extern修饰变量/函数
示例程序一:
//file1.c
int iNum = 10;
int iVar = 9.9;
void funA(void)
{
.....
}
static void funB(void)
{
.....
}
//file2.c
extern int iNum; <span style="color:#009900;">//使用file1.c中的变量iNum</span><span style="color:#006600;"> </span>
extern double iVar; <span style="color:#009900;">//错误!类型不一样</span>
extern void funA(void); <span style="color:#009900;">//调用file1.c中的函数funA</span>
extern void funB(void); <span style="color:#009900;">//错误!static修饰的函数具有隐藏性,不可外用</span>
.....
int main()
{
...
}
2、extern "C"的使用
在C++环境下使用C函数时,常常会出现编译器无法找到obj模块中的C函数定义,从而导致链接失败的情况。
示例程序二:
#ifdef __cplusplus
extern "C" {
#endif
/*...*/
#ifdef __cplusplus
}
#endif
四、Volatile
volatile是易变的、不稳定的意思,遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。
示例程序一:
int i = 10;
int j = i; //①语句
int k = i; //②语句
此时编译器对代码进行优化,这是因为①②语句中,i没有被赋值,这是编译器认为i的值没有发生改变,所以在①语句时从内存中取出i的值赋给j之后,这个值并没有被丢掉,而是在②语句时继续赋值给k。
示例程序二:
volatile int i = 10;
int j = i; //①语句
int k = i; //②语句
volatile关键字告诉编译器,i随时可能发生变化的,每次使用他的时候必须从内存中取出i的值,因而编译器生存的汇编代码会重新从i的地址处读取数据放在k中。