其实就象读者所熟悉的const一样,volatile是一个类型修饰符。在开始讲解volatile之前我们先来讲解下接下来要用到的一个函数,知道如何使用该函数的读者可以跳过该函数的讲解部分。
原型:int gettimeofday ( struct timeval * tv , struct timezone * tz );
头文件:#include
功能:获取当前时间
返回值:如果成功返回0,失败返回-1,错误代码存于errno中。
gettimeofday()会把目前的时间用tv所指的结构返回,当地时区的信息则放到tz所指的结构中。
1.timeval结构定义为:
2.struct timeval{ 3. long tv_sec; 4. long tv_usec; 5.};
6.timezone 结构定义为:
7.struct timezone{ 8. int tz_minuteswest; 9. int tz_dsttime; 10.};
先来说说timeval结构体,其中的tv_sec存放的是秒,而tv_usec存放的是微秒。其中的timezone成员变量我们很少使用,在此简单的说说它在gettimeofday()函数中的作用是把当地时区的信息则放到tz所指的结构中,在其中tz_minuteswest变量里存放的是和Greenwich 时间差了多少分钟,tz_dsttime日光节约时间的状态。我们在此主要的是关注前一个成员变量timeval,后一个我们在此不使用,所以使用gettimeofday()函数的时候我们把有一个参数设定为NULL,下面先来看看一段简单的代码。
1.#include
2.#include 3.
4.int main(int argc, char * argv[]) 5.{
6. struct timeval start,end; 7. gettimeofday( &start, NULL ); /*测试起始时间*/ 8. double timeuse; 9. int j; 10. for(j=0;j<1000000;j++) 11. ;
12. gettimeofday( &end, NULL ); /*测试终止时间*/ 13. timeuse = 1000000 * ( end.tv_sec - start.tv_sec ) + end.tv_sec - start.tv_sec ;
14. timeuse /= 1000000;
15.printf("运行时间为:%f ",timeuse); 16.
17. return 0; 18.
19.}
运行结果为:
1.root@ubuntu:/home# ./p
2.运行时间为:0.002736
现在来简单的分析下代码,通过end.tv_sec - start.tv_sec 我们得到了终止时间跟起始时间以秒为单位的时间间隔,然后使用end.tv_sec - start.tv_sec 得到终止时间跟起始时间以微妙为单位的时间间隔。因为时间单位的原因,所以我们在此对于( end.tv_sec - start.tv_sec ) 得到的结果乘以1000000转换为微秒进行计算,之后再使用timeuse /= 1000000;将其转换为秒。现在了解了如何通过gettimeofday()函数来测试start到end代码之间的运行时间,那么我们现在接下来看看volatile修饰符。
通常在代码中我们为了防止一个变量在意想不到的情况下被改变,我们会将变量定义为volatile,这从而就使得编译器就不会自作主张的去“动”这个变量的值了。准确点说就是每次在用到这个变量时必须每次都重新从内存中直接读取这个变量的值,而不是使用保存在寄存器里的备份。
在举例之前我们先大概的说下Debug和Release 模式下编译方式的区别,Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。大致的知道了Debug和Release的区别之后,我们下面来看看一段代码。
1.#include
2.
3.void main() 4.{
5.int a=12; 6.printf("a的值为:%d ",a); 7.__asm {mov dword ptr [ebp-4], 0h}
8.int b = a; 9.printf("b的值为:%d ",b); 10.}