STATIC关键字
static关键字内核中到处都在用。还有以前上课时老师讲的goto尽量不用,结果内核中也大量使用~
static 修饰函数
当修饰函数时,代表这个函数的可见域为当前文件。在其他文件中想访问此函数则不行了.
这样的意义在于可以很好的解决不同文件中同名函数的问题,让此函数变得当前文件私有,其他文件不可见.
static int func(void)
{
}
static 修饰变量
1.static 修饰全局变量:静态全局变量
这边的意义在于将此全局变量限定于本文件内有效,其他文件不可见。也就是说同样限定了它的作用域为本文件。
static int a=1;
void main()
{
printf("%d.",a);
}
2.static修饰局部变量:静态局部变量
void test(void)
{
static int i=0;
i++;
printf("%d.\n",i);
}
void main()
{
while(1)
{
test();
}
}
test函数中 如果变量i没有被static修饰,那么每次打印的值都是0.
如果被static修饰,那么则是0,1,2,3,4……..
局部变量:
普通的局部变量在栈空间上分配,这个局部变量所在的函数被多次调用时,每次调用这个局部变量在栈上的位置都不一定相同。局部变量也可在堆上动态分配,但是记得使用完这个堆空间后要释放.
静态局部变量:
在内存中的位置: data段,全局数据区,声明周期为整个程序运行期间.
作用域:当前文件的 局部变量所属的函数.其他文件肯定不可见。当前文件的其他函数也不可见.
值:静态局部变量如果没有被用户初始化,则会被编译器自动赋值为0,以后每次调用静态局部变量的时候都用上次调用后的值。这个比较好理解,每次函数调用静态局部变量的时候都修改它然后离开,下次读的时候从全局存储区读出的静态局部变量就是上次修改后的值。
extern关键字
在windows下用keil c version2时经常有这样的写法:
void main()
{
test();
}
void test(void)
{
}
如果这样写是会报错的,而应该:
void test(void)
{
}
void main()
{
test();
}
或者:
void test(void);
void main()
{
test();
}
void test(void)
{
}
这样才是OK的,当然这和编译器的行为有关.
下来来讲extern关键字.
extern用来声明一个函数或者变量在其他文件中。也就是说extern的使用会扩大函数或者变量的作用域.
例如:
1.c中
int a=3;
int b;
void func1(void)
{
}
void func2(void)
{
}
那么如果想要在2.c文件中访问1.c文件中的变量a和函数 func1的话:
extern int a;
extern void func1(void);
void main()
{
printf("%d.\n",a);
func1();
}
const关键字
定义一个变量,却不想被别人修改,只读模式,不能改。则用const修饰.
const int a=1;
int const a=1;
这样都是可以的.
const int a=5;
a=8;
这样是不行的,会报错。const修饰的变量不允许被再次修改.
int a1=4;
int a2=5;
int a3=6;
const int *b1=&a1;
int const *b2=&a2;
int * const b3=&a3;
1) b1的指针可以被赋值。但是*b1不能被赋值.如果此时进行如下操作
a1=8;
b1 =&a2;
printf("*b1:%d,a2:%d,a1:%d.\n",*b1,a2,a1);
这些操作均是允许的,结果*b1 =5,a2=5,a1=8
2)b2的指针可以被赋值,但是*b2不能被赋值。b2和b1是等价的.
3)b3的指针不能被赋值 b3=&a1是不允许的.
*b3=100;
printf("*b3:%d.\n",*b3);
这样的操作是允许的.
volatile 关键字
正常的,编译器都有自带优化代码的能力.volatile关键字防止编译器进行优化.
当一些变量在程序运行的过程中因为某些特定的因素会被不停的改变(操作系统、硬件或者其它线程等).
用volatile修饰保证每次访问此变量都会从内存中重新抓取.保证每次获得数据都是正确的,实时的.这样做阻止了编译器对其的优化.从而保证对特殊地址访问的正确性.
访问内部寄存器的效率高于访问内存。所以当编译器进行优化时,可能将内存变量缓存到寄存器中,当访问这个变量时,实则访问的是寄存器中缓存的数据.
如果我们要获取一个外部普通输入GPIO管脚的状态,应该从内存中去读出它的实时值。所以告诉编译器这个变量是可变的,然后用volatile修饰来让cpu每次访问时都从内存中获取它的值.
register 关键字
这个关键字请求编译器尽可能的将变量存在CPU内部寄存器中,而不是通过内存寻址访问,以提高效率。注意是尽可能,不是绝对.