register
作用:请求编译器尽可能地将变量存在CPU内存寄存器中。而不是通过内存寻址访问的 方法,
好处:省去了CPU处理访问内存数据的时间。
注意事项:
1,register修饰变量的类型必须是CPU能够接受,register变量必须是一个单个的值,并
且长度应该小于或者等于整型的长度,
2,register变量可能不是在内存中存储,所以不能用&来取地址,因为&用来获取的是内
存的地址,
因为寄存器的数目有限,而且智能接受特定类型的数据,真正起作用的register修饰
符都是依赖运行程序的机器,大部分多余的register修饰符都会在编程的时候被自动忽
略,尽管这样是合法的,但是这个修饰符仅仅是暗示,而不是命令。
static
修饰变量和函数,延迟其生命周期,在程序结束的释放
变量分为局部变量和全局变量,
修饰全局变量:只能在本文件内可见,其他文件不可见。
修饰局部变量:保存在数据区的静态数据区,只被初始化一次,之后每次调用函 数时,该变量值为上次函数退出时的值。即,改变量的生存扩展 到整个程序运行时间段内。
修饰函数: 只能在本文件内调用该函数
例程
如果用static修饰局部变量,那么函数的释放在程序结束时,此前就保留上次函数执行的数值。
注意事项
1, 写程序的时候尽量少用全局变量,因为全局变量很危险,能够被所有文件访问
2, 若全局变量只想在本文件内调用,则可以用static调用,此时static起到了保护的
作用
extern
外部声明不是本源文件的变量,就是告诉编译器,这个标识符虽然没有在本文件中定义,但是在其他文件中被定义为全局变量,你可以放行。
如果在a.c函数中调用b.c,则需要在a.c中声明b.c
extern char b()
extern int count;
void print()
{
Printf(“count= %d\n”,count);
}
注意点:声明函数或者变量可以有N次,但是它们只能定义一次,如果某个全局变量在多个文件中被定义,那么会编译器会报错,因为出现了重定义
const
(1)修饰只读变量,该变量对应的空间值可以变化,但是不可以通过修饰的变量名 来修改
const int *p = #
p++;
(*p)++;(不可变)
Num++;
int const *p = #
p++;
(*p)++;(不可变)
Num++;
int * const p = #
p++; (不可变)
(*p)++;
Num ++;
总结:const离哪个近,就不可以通过它的名字来求改变量的值;
(2)便于编译器对数据类型的检查,如,定义一个const int i,编译器知道i是一个不可以修改的变量
(3)可以避免意义模糊的数字出现,同样可以很方便地进行参数的调整和修改。 同宏定义一样,可以做到不变则已,一变都变!
(4)可以保护被修饰的东西,防止意外的修改,增强程序的健壮性。
在函数前加const作用:函数实现者的好处,在编写函数时,不可修改该函数的形参
char *strcpy( char *dest,const char *src)
(6) 可以节省空间,避免不必要的内存分配。 例如
#define PI 3.14159 //常量
const doulbe Pi=3.14159; //此时并未将Pi放入ROM中 ......
double i=Pi; //此时为Pi分配内存,以后不再分配!
double I=PI; //编译期间进行宏替换,分配内存
double j=Pi; //没有内存分配
double J=PI; //再进行宏替换,又一次分配内存!
const定义常量从汇编的角度来看,只是给出了对应的内存地址
,而不是象#define一样给出的是立即数,所以,const定义的常量
在程序运行过程中只有一份拷贝,而#define定义的常量在内存中
有若干个拷贝。
使用条件:一般用于修饰函数的形参:避免在函数实现中,修改函数实参的值
typedef
为一种数据类型定义一个新名字
1, 提高代码的移植性。
2, 方便在编程过程中定义变量
3, 解释某些变量的意思,(起到注释的作用)