(转载)Static,Const,Typedef,Volatile
小气的Static,坚强的Const,疑惑的Typedef,还有居安思危的Volatile
学了一学期的C program,有时候遇到很多程序上面出现了“Static” “Const”,都没怎么搞清楚,都是得过且过,今天查阅了相关的资料,终于把他们分清楚啦,嚯嚯,查看资料的过程中又幸学到了新的东西typedef 和 Volatile…废话到此,接下来就是分享时间:
Static:中文名叫“静态局部变量”被Static修饰的变量只能在本模块中使用,不能被外界的函数或者是模块调用,本模块外的任何访问都是非法的…普通的变量在执行完函数后,其内存的空间将会被释放,但是Static所修饰的变量的内存空间将不会被释放,比如说:
{
unsigned uchar A=0;
static unsigned char B=0;
A++;
B++;
}
每次调用该函数的时候,A++被执行后,其值只能是1;但是B就不同了,他会一直的加下去,直到加到255,达到最大值溢出变成0,虽然调用函数的时候,可是对B进行了初始化动作将会被跳过。
Const: Const是Constant(常量)的缩写,其实更准确的说Const是不能被修改的,是非常的坚强的,始终都是不变的,一旦申明后就不能被修改了,谈到了C program,就不得不谈到指针了,当然Const也可以修饰指针的,但是到底是修饰指针所指向的内容呢?还是指针变量呢?
嚯嚯,这个就要遵行 就近原则 啦:
const unsigned char *str; const 离数据类型比较近,所以他修饰的是数据类型,也就是说,*str所指向的内存单元内容是不能被修改的。
unsigned char const *str; const离指针比较近,所以指针变量是固定不可被修改的,此时指针所指向的哪个内存单元是固定的~~~但是,内容却是可以被修改的~~~
还有说到了内存的空间,总要说一下单片机的存储空间了,AVR中有寄存器,SARM,E2PROM,还有FLASH,便于理解,将SRAM理解成电脑的内存,FLASH可以理解成电脑的硬盘,内存果断要比硬盘不知道少多少倍,所以const修饰的常量一般放在FLASH,而FLASH,E2PROM,SRAM他们都是独立编址的,三者的地址之间没有任何关系,此时的指针就不能乱用啦,一般Const修饰的都因该放在FLASH中,他修饰的指针不能指向SRAM,或者是E2PROM..
typedef:typedef 常用于自定义变量类型,比如说:
#define uint unsigned int
uint number=0;
或者是:
typedef unsigned int uint
uint number=0;
既然两种方法都一样,那C program 为什么要多此一举呢?其实不然,请往下看:
#define point_zhizhen unsigned int *
point_zhizhen point_A,point_B;
此时将他展开会是什么样子呢?结果很明显:
unsignede int *point_A,point_B;
而用typedef时就截然不同了…
typedef unsigned int * point_zhizhen
point_zhizhen point_A,point_B;
此时我们就得到了两个相同数据类型的指针啦(*^__^*) 嘻嘻……
Volatile:中文解释是易变的,不稳定的。在我们的编辑器中,常常会将我们的代码优化,提高代码的执行速度,关于编辑器是怎样优化代码而导致错的,请查阅《深入浅出AVR》其中就有详细的说明,这里就说说怎么避免错误的产生吧,代码编辑器优化代码的时候,会深入到内存空间,但如果有一个语句没有写操作,或者是读取操作,编辑器就自作聪明的保存了该内存空间的某一时刻的值, 用于以后的计算,虽然该内存单元中内容改变了,但是程序中用到的变量还是该时刻的保存值,多以会出现一些意想不到的错误,而Volatile的作用就是提醒编译器,这个内存单元空间中的内容是在变动的,你千万不要优化这个变量呀~~~恩,编译器当然会听话咯~所以在以下几种情况中,都必须使用volatile:
1:对于在主函循环中使用的全局变量,如果其值可能在某一中断处理程序中被更新
2:对于映射到内存单元的寄存器
3:多线程系统中,被多个线程共享的变量,
嚯嚯,写得好累,休息休息,未完待续~~~