C语言复习笔记(二)- C语言关键字详解

C语言复习笔记(二)

  • 关键字
    • 类型说明保留字
    • 语句定义保留字
    • 存储类说明关键字
    • 其他关键字

关键字

C语言的关键字有32个

类型说明保留字

关键字 作用
int 声明整型变量或指针
long 声明整型变量或指针
short 声明短整型变量或指针
unsigned 声明无符号型变量
signed 声明有符号型变量
char 声明字符型变量或指针
double 声明双精度浮点型变量或指针
float 声明单精度浮点型变量或指针
const 声明只读变量
void 声明函数无返回值或无参数或空类型指针
volatile 说明变量在程序执行中可被隐含地改变,防止编译器优化
  • const关键字
  1. 便于进行类型检查,使编译器对处理内容有更多了解,消除了一些隐患
	void f(const int i) {} //编译器就会知道i是一个常量,不允许修改
  1. 可以保护被修饰的东西,防止意外的修改,增强程序的安全性,还是上面的例子,如果在函数体内修改了i,编译器就会报错;
	void f(const int i) {i=10;} //error!
  1. 可以节省空间,避免不必要的内存分配,const定义常量从汇编的角度来看,只是给出了对应的内存地址,而不是像#define一样给出的是立即数,所以,const定义的常量在程序运行过程中只有一份拷贝,而#define定义的常量在内存中有若干份拷贝(注意:宏是不占内存的,但宏替换是要给变量分配内存的)
	#define PI 3.14159 //常量宏
  const double Pi=3.14159; //放在常量表中
  double I=PI; //编译期间进行宏替换,分配内存
  double j=Pi; //给出对应地址
  double J=PI; //再进行宏替换,又一次分配内存!
  1. 编译器通常不为普通const常量分配存储空间,而是将它们保存在常量表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高,编译器也可能产生更紧凑的代码
  2. const声明解读
    方法:将类型名去掉就是const关键字限定的内容
	const a							//变量a内容不可修改
	const int *p = int const *p		//p可以指向其他变量,p指向内容不可修改
	int* const p					//p不可以指向其他变量,p指向内容可以修改
	const int* const p				//p不可以指向其他变量,p指向内容也不可以修改
  • const与define区别
  1. define是预编译指令,而const是普通变量的定义。define定义的宏是在预处理阶段展开的,而const定义的只读变量是在编译运行阶段使用的
  2. const定义的是变量,而宏定义的是常量,所以const定义的对象有数据类型,而宏定义的对象没有数据类型。所以编译器可以对前者进行类型安全检查,而对后者只是机械地进行字符替换,没有类型安全检查,这样就很容易出问题,即“边际问题”或者说是“括号问题”
  • volatile关键字
    volatile的本意是“易变的”, 因为访问寄存器要比访问内存单元快的多,所以编译器一般都会作减少存取内存的优化,但有可能会读脏数据。当要求使用volatile声明变量值的时候,系统总是重新从它所在的内存读取数据。精确地说就是,遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,并且每次都去内存取值;如果不使用valatile,则编译器将对所声明的语句进行优化。
    下面是volatile变量的几个例子
    1、并行设备的硬件寄存器
    2、一个中断服务子程序中会访问的非自动变量
    3、多线程应用中被几个任务共享的变量
    下面是关于volatile的几个问题
    1、一个参数既可以是const还可以是volatile吗?为什么
    可以,假如一个变量不希望本程序改变,通常会给它加上const,但如果该变量可能被其他程序改变而本程序又在检测这个变量的值,就需要给它加上volatile,于是变量就同时有const和volatile的双重属性
    2、一个指针可以是volatile 吗?解释为什么
    可以,指针也会像变量一样变化,也需要防止编译器优化
    3、下面的函数被用来计算某个整数的平方,它能实现预期设计目标吗?如果不能,试回答存在什么问题:
	int square(volatile int *ptr) { 
		return *ptr * *ptr; 
	} 

这段代码的目的是用来返指针ptr指向值的平方,但是,由于ptr指向的是一个volatile型参数,编译器将产生类似下面的代码:

	int square(volatile int *ptr) { 
		int a,b; 
		a = *ptr; 
		b = *ptr; 
		return a * b; 
	} 

由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果返回的可能不是平方值!正确的代码如下:

	long square(volatile int *ptr) { 
		int a; 
		a = *ptr; 
		return a * a; 
	}

语句定义保留字

关键字 作用
If 条件语句
else 条件语句的否认连枝,与if连用
goto 无条件跳转语句
switch 开关语句
case 开关语句分止
do 循环语句的循环体
while 循环语句的循环条件
for 一般循环语句
continue 结束当前循环,进入下一轮循环
break 跳出当前循环
return 子程序返回语句,可带参数,也可不带
default 开关语句的其他分支
typedef 给数据类型取别名
  • typedef与define区别
区别
用法 typedef主要用来定义一种数据类型的别名,增强程序的可读性
define主要用来定义常量,以及使用频率高书写复杂的宏
执行时间 typedef是编译过程中的一部分,有类型检查
define是预编译,进行字符串替换,不进行类型检查
作用域 typedef有作用域限制
define没有作用域限制
声明 typedef是语句,结尾要加分号
define不是语句,结尾不能添加分号
封装 typedef可以看做彻底的封装,声明之后不能添加别的声明
define可以
	typedef int banana;
	unsigned banana i;//不允许
	//
	define banana int
	unsigned banana i;//允许

存储类说明关键字

关键字 作用
auto 声明自动变量,缺省时默认所有变量为自动变量
register 声明寄存器变量
extern 声明变量从其他文件引用
static 声明静态变量或函数
  • register关键字
    1、尽可能将变量放在CPU寄存器中访问,必须为单个值,且小于整型长度;
    2、由于不存在于内存中,不能用&运算符
  • static关键字
  1. 修饰局部变量,static修饰的局部变量存放在全局数据区的静态变量区,默认初始化为0,static修饰的静态局部变量只初始化一次,延长了局部变量的生命周期,直到程序运行结束以后才释放。
  2. 修饰全局变量的时候,这个全局变量只能在本文件中访问,不能在其它文件中访问,即便是extern外部声明也不可以。
  3. 修饰函数,这个函数的只能在本文件中调用,不能被其他文件调用
	int main(){
		static int a;
		b = func();
		c = func();
		printf("%d %d %d",a, b, c); 
		return 0;
	}
	int func(void){
		static int count = 10;
		count--;
	}
	0 9 8

其他关键字

关键字 作用
sizeof 返回对象所占内存空间大小

你可能感兴趣的:(c语言,嵌入式,编程语言)