C语言关键字 - 专一王子:volatile

专一王子:volatile

描述:每个变量和他的名字一样很善变,有时候它善变是发自内心的,有时是外部因素决定的,只有volatile变量才会表里如一,因此获得了专一王子的美誉。

作用:volatile字面意思是易挥发,易变化的意思,它修辞的变量表示该变量的值很容易由于外部因素发生改变,强烈请求编译器要老老实实的在每次对变量进行访问时去内存里读取。可能上面说的还不是很清楚,我们换个例子来说,你明天一个朋友过生日,今天把要送的礼物打包好了,一般情况下,我们明天起来不再需要再打开验证一下里面礼物是否存在,因为我们知道,只要礼物的外包装没有动过,里面东西应该不会被动。其实编译器和人一样聪明,为了提高效率也会玩省事,如下面的例子:

1  int a = 10;

2  int b = a;

3  int c = a;

编译器扫描了代码发现上面,第一行代码在将10赋给了整形变量a,之后a变量的值没有再发生改变。在后面第二行中,将a变量里的值取出来赋给b变量。在第三行代码里将a变量的值赋给c的时候,因为CPU访问内存速度较慢(看register关键字介绍),编译器为了提高效率,玩了“省事”,直接将10赋给了c。

单从上述代码我们来看是没有问题的,就如同从外包装看生日礼物完好一样。但是,上述代码如果运行在多线程中,在一个线程上下文中没有改变它的值,但是我们不能保证变量的值没有被其它线程改变。就好比是,生日礼物放到其它人那里保存,我们不敢100%保证它里面的东西还完好。当然这种数据不一致的机制不仅仅出现在多线程中,同样在设备的状态寄存器里也会存在。比如:网卡里的某状态寄存器里的值是否为1表示是否有网络数据到达,在当前时刻其值为1,不能代表着下一时刻其值还为1,它的值是由外界条件决定的,编译器肯定不能在这种情况下玩“省事”

为了防止在类似的情况下,编译器玩省事,可以将这些变量声明为volatile,这样,不管它的值有没有变化,每次对其值进行访问时,都会从内存里,寄存器里读取,从而保证数据的一致,做到表里如一。


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
耗资源////////////////////////////////////////////////// // // // AT89C51时钟程序 // // // // 作者: 吴鹏 // // 时间;2006年2月3日 // // 大年初六 完成 // ////////////////////////////////////////////////// #include <REG52.H> #define uchar unsigned char sbit P3_6=P3^6; sbit P3_7=P3^7; sbit P2_6=P2^6; sbit P2_7=P2^7; uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};// 0-9 十个数字显示 uchar code dispbit[]={0x7f,0xbf,0xf7,0xfb,0xfd,0xfe};// 点亮 数码管 uchar code rjg[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};// 点亮 跑马灯 uchar buffer[]={0,0,0,0,0,0};// 时钟and定时显示置 uchar hour,minute,second,count; uchar dhour=0,dminute=0,dsecond=0; uchar j=0,R,T; void ding(void) ; //定时程序 void delay(uchar c,uchar d) //延时程序 {uchar x,y; for(x=c;x>0;x--) for(y=d;y>0;y--); } void warning(void) //闹钟报警程序 { uchar p=2; while(p--!=0) { P1=0; P0=0; delay(100,100); P1=0xff; P0=0xff; delay(100,100); } } void main(void) { TMOD=0x11;//选择定时器的模式 TH0=0xd8; //定的时间高8位 TL0=0xf0; //定的时间低8位 IE=0x82; //中断触发的设定 TR0=1; //TIMER0开始计时 count=0; second=0; minute=0; hour=0; while(1) {if(P3_7==0) //按下P3_7? {delay(1,100); //延时 hour++; if(hour==24) hour=0; while(P3_7==0);//判断是否被按下 } if(P2_7==0) {delay(1,100); minute++; if(minute==60) {minute=0;} while(P2_7==0); } if(P2_6==0) {delay(1,100); second++; if(second==60) {second=0;} while(P2_6==0); } if(P3_6==0) {delay(1,100); // TR0=0; //??? //注意: 在做显示时,要慎用全局变量,如在做本程序的两个显示部分时, // 原来都统一用的是一个全局变量,那么这就会出现冲突,后来两部分 // 分别改为局部变量,这就OK了!!!! while(P3_6==0); T=1; //作标志,使其进入"ding()" R=1; //作标志,因为两部分显示都存在"buffer[]"里,所以加以区分,否则会出现冲突 } if(T==1) //检测T值 ding(); } } void tim(void) interrupt 1 //int0 t0 int1 t1 rs { // 0 1 2 3 4 uchar a1,b1,i1; //这里我使用局部变量 TH0=0xd8; TL0=0xf0; count++; //由于其是全局函数,当程序运行100次后,秒加1 R=0; if (count==100) { count=0; second++; j++; P1=rjg[j%8]; //由于有8个LED所以对8取余,使其逐个且有序的亮起来,很巧吧!! if(second>=60) { second=0; minute++; if (minute>=60) { minute=0; hour++; if (hour>=24) { second=0; hour=0; minute=0; } } } if(R==0) //检测R值 { buffer[0]=second%10; buffer[1]=second/10; buffer[2]=minute%10; buffer[3]=minute/10; buffer[4]=hour%10; buffer[5]=hour/10; } } if(R==0) //检测R值 {for(i1=0;i1<6;i1++) { P2=dispbit[i1]; P0=table[buffer[i1]]; for(a1=4;a1>0;a1--) for(b1=248;b1>0;b1--); } } if((hour==dhour && minute==dminute && second==dsecond)&&(hour!=0||minute!=0||second!=0)) {warning();} //闹钟报警部分 } void ding(void) //interrupt 3 //int0 t0 int1 t1 rs { // 0 1 2 3 4 int i2,a2,b2; P2=0xff; while(1) //闹钟调时 { if(P3_7==0) {delay(1,100); dhour++; if(dhour==24) {dhour=0;} while(P3_7==0); } if(P2_7==0) {delay(1,100); dminute++; if(dminute==60) {dminute=0;} while(P2_7==0); } if(P2_6==0) {delay(1,100); dsecond++; if(dsecond==60) {dsecond=0;} while(P2_6==0); } if(R==1) //检测R值 { buffer[0]=dsecond%10; buffer[1]=dsecond/10; buffer[2]=dminute%10; buffer[3]=dminute/10; buffer[4]=dhour%10; buffer[5]=dhour/10; } for(i2=0;i2<6;i2++) { P2=dispbit[i2]; P0=table[buffer[i2]]; for(a2=4;a2>0;a2--) for(b2=248;b2>0;b2--); } if (P3_6==0) //定时退出部分 {delay(1,100); while (P3_6==0); T=0; //使T归0 R=0; //使R归0 break; //从while(1)循环中跳出 } } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值