C语言的那些小秘密之volatile

合集下载

volatile函数

volatile函数

volatile函数Volatile函数是一种在C和C++中使用的修饰符,它告诉编译器不应优化变量的访问。

Volatile函数可以用于保护共享内存,以确保来自多个线程的并发访问不会引起意外的,未预料的结果。

由于编译器优化,它会假设变量仅在被声明时和程序结束时通过程序来访问。

但是在这两个时间点之间,它不去考虑变量是否会被更改,这将导致程序失灵。

要解决此问题,应使用volatile函数将变量标记为“volatile”。

这会告诉编译器不要优化或缓存变量,而是必须在内存中查找变量的正确值。

使用volatile函数时需要格外小心,因为这会严重影响性能。

由于编译器无法缓存变量,因此必须每次读取变量时都要从内存中检索其值。

因此,使用volatile函数时,必须仔细考虑是否真的需要使用它来保护变量,以节省CPU时间。

通常,只有在变量存储在多个线程之间共享的内存中时才需要使用volatile函数。

类似地,如果多个线程都可以访问该变量,则必须将其标记为volatile。

例如,某些多任务系统需要实现全局变量,以跨多个线程共享信息。

这种情况下,必须将全局变量标记为volatile。

另一个常见情况是,多个线程都可以访问指向外部设备的指针,这时必须将该指针标记为volatile,以确保多个线程之间不会发生冲突。

此外,一些单片机系统也使用volatile函数,以确保变量在多个线程之间不会发生冲突。

总的来说,Volatile函数是一种修饰符,它可以用于保护共享内存,以便在多个线程之间不会发生意外的结果。

尽管它可以保证变量的一致性,但它也会增加程序处理时间,因此应该根据具体情况仔细考虑是否真的需要使用它。

C语言中32个关键字使用详解

C语言中32个关键字使用详解

C语言中32个关键字使用详解C语言的关键字共有32个。

根据关键字的作用,可分其为数据类型关键字、控制语句关键字、存储类型关键字和其它关键字四类。

下面是店铺为大家整理的C语言中32个关键字使用详解,欢迎参考~ C语言一共有32个关键字,如下所述:auto :声明自动变量short :声明短整型变量或函数int:声明整型变量或函数long :声明长整型变量或函数float:声明浮点型变量或函数double :声明双精度变量或函数char :声明字符型变量或函数struct:声明结构体变量或函数union:声明共用数据类型enum :声明枚举类型typedef:用以给数据类型取别名const :声明只读变量unsigned:声明无符号类型变量或函数signed:声明有符号类型变量或函数extern:声明变量是在其他文件正声明register:声明寄存器变量static :声明静态变量volatile:说明变量在程序执行中可被隐含地改变void :声明函数无返回值或无参数,声明无类型指针if:条件语句else :条件语句否定分支(与 if 连用)switch :用于开关语句case:开关语句分支for:一种循环语句do :循环语句的.循环体while :循环语句的循环条件goto:无条件跳转语句continue:结束当前循环,开始下一轮循环break:跳出当前循环default:开关语句中的“其他”分支sizeof:计算数据类型长度return :子程序返回语句(可以带参数,也可不带参数)循环条件[C语言中32个关键字详解]。

C语言中的保留字

C语言中的保留字

C语⾔中的保留字保留字:保留字⼜称关键字。

指在⾼级语⾔中已经定义过的字,使⽤者不能再将这些字作为变量名或过程名使⽤。

其中,C89中有下述:类型说明保留字:int,long,short,float,double,char,unsigned,signed,const,void,volatile,enum,struct,union 语句定义保留字:if,else,goto,switch,case,do,while,for,continue,break,return,default,typedef存储类说明保留字:auto,register,extern,static长度运算符保留字:sizeof()return具体含义如下:auto指定变量的存储类型,是默认值break跳出循环或switch语句case定义switch中的case⼦句char定义字符型变量或指针const定义常量或参数continue在循环语句中,回到循环体的开始处重新执⾏循环default定义switch中的default⼦句do定义do-while语句double定义双精度浮点数变量else定义枚举类型enum声明外部变量或函数extern声明外部变量或函数float定义浮点型变量或指针for定义for语句goto定义goto语句if定义if语句或if-else语句int定义整型变量或指针long定义长整型变量或指针register指定变量的存储类型是寄存器变量,Turbo c中⽤⾃动变量代替return从函数返回short定义短整型变量或指针signed定义有符号的整型变量或指针sizeof获取某种类型的变量或数据所占内存的⼤⼩,是运算符static指定变量的存储类型是静态变量,或指定函数是静态函数static指定变量的存储类型是静态变量,或指定函数是静态函数struct定义结构体类型switch定义switch语句typedef为数据类型定义别名union定义⽆符号的整型或字符型变量或指针unsigned定义⽆符号的整型变量或数据void定义空类型变量或空类型指针,或指定函数没有返回值volatile变量的值可能在程序的外部被改变while定义while或do-while语句。

volatile bool在c语言中的用法

volatile bool在c语言中的用法

volatile bool在c语言中的用法在C语言中,`volatile bool`是一种数据类型,用于声明一个可以被多个线程同时访问并可能在不同的时间点被改变的布尔变量。

它通常用于以下情况:1. 在中断服务程序(ISR)中使用:当一个中断服务程序修改了一个共享的布尔变量时,为了确保其他线程或中断能够正确地检测到该变量的更新,需要将该变量声明为`volatile`。

```cvolatile bool flag = false;void ISR() {flag = true;}int main() {while(1) {if(flag) {// 执行某些操作flag = false; // 重置标志位}}return 0;}```2. 在多线程环境下使用:当多个线程同时访问并修改一个共享的布尔变量时,为了确保每个线程都能正确地读取到最新的变量值,需要将该变量声明为`volatile`。

```cvolatile bool flag = false;void thread1() {flag = true;}void thread2() {while(!flag) {// 等待标志位被设置}// 执行某些操作flag = false; // 重置标志位}int main() {// 创建线程1和线程2// ...return 0;}```通过将布尔变量声明为`volatile`,可以防止编译器对该变量的优化,以确保读取和写入操作的顺序是按照程序的实际执行顺序进行的。

这样可以避免在执行过程中出现错误的结果或不确定的行为。

voliate关键字原理

voliate关键字原理

voliate关键字原理在C 和C++ 中,"volatile" 关键字主要用于告诉编译器,该变量的值可能会在程序执行的过程中被意外地改变,而这种改变不是由当前执行线程引起的。

这样的变量通常是由硬件或其他线程、中断服务例程等异步操作修改的。

"volatile" 关键字的原理包括:1. **禁止编译器优化:**- 使用"volatile" 关键字告诉编译器,该变量的值可能会在程序执行的任何时刻被修改,因此编译器不应该对涉及到这个变量的代码进行优化。

这可以防止编译器在不清楚变量何时修改的情况下进行不必要的优化。

2. **避免寄存器缓存:**- 编译器通常会将变量的值缓存在寄存器中,以提高代码执行效率。

使用"volatile" 关键字可以告诉编译器,不要将变量值缓存在寄存器中,而是每次都从内存中读取,以确保获取的是最新的值。

3. **保证顺序性:**- 在多线程或并发编程中,"volatile" 关键字还可以确保指令的执行顺序,防止编译器对涉及"volatile" 变量的指令进行重排序。

这对于确保多线程环境下的正确性非常重要。

以下是一个简单的C++ 例子,演示了"volatile" 关键字的使用:```cpp#include <iostream>int main() {volatile int counter = 0;while (counter < 10) {// 模拟异步操作// 假设有其他线程在修改counter 的值counter++;std::cout << "Counter: " << counter << std::endl;}return 0;}```在这个例子中,"volatile" 用于确保编译器不会对`counter` 的值进行优化,并且每次循环都会从内存中重新读取最新的值。

32个关键字在c语言中的含义和作用

32个关键字在c语言中的含义和作用

在C语言中,有很多关键字是程序员需要熟悉和理解的,这些关键字在编写C语言程序时扮演着至关重要的角色。

本文将深度探讨其中32个关键字在C语言中的含义和作用,帮助读者更深入地理解这些关键字的用法和功能。

1. int在C语言中,int是一种数据类型,用来声明整数类型的变量。

它可以存储整数值,范围通常是-xxx到xxx。

2. floatfloat是C语言中的另一种数据类型,用来声明单精度浮点数变量。

它可以存储小数值,通常范围是1.2E-38到3.4E+38。

3. charchar是C语言中的字符类型,用来声明一个字符变量。

它通常用来存储ASCII码中的字符。

4. doubledouble是C语言中的双精度浮点数类型,用来声明双精度浮点数变量。

它可以存储更大范围的小数值,通常范围是2.3E-308到1.7E+308。

5. ifif是C语言中的条件语句,用来根据指定条件执行不同的代码块。

它对程序的流程进行控制,根据条件的真假来决定执行哪一部分代码。

6. elseelse是if语句的补充,用来在条件不满足时执行另一段代码。

它可以用于if语句的后续逻辑判断。

7. whilewhile是C语言中的循环语句,用来重复执行一段代码块,直到指定的条件不再满足为止。

它可以用于处理需要重复执行的任务。

8. forfor是另一种循环语句,通常用于已知循环次数的情况下重复执行一段代码块。

它的结构更加简洁和清晰。

9. dodo-while是C语言中的另一种循环语句,与while的区别在于它先执行一次循环体,再进行条件判断。

它保证循环体至少会执行一次。

10. switchswitch是C语言中的多路分支语句,通过不同的case标签来选择不同的执行路径。

它对多个条件进行判断,并执行相应的代码块。

11. casecase是switch语句中的分支标签,用来指定需要执行的代码块。

它是switch语句的重要组成部分。

12. breakbreak是C语言中的控制语句,用来跳出当前循环或switch语句。

volatile在mcu中的用法(一)

volatile在mcu中的用法(一)volatile在MCU中的用法1. 什么是volatile?在C语言中,关键字volatile用来修饰变量,表示该变量可能会被意外地改变。

这种意外的改变往往不是由代码本身直接导致的,而是由于硬件或其他并发操作引起的。

2. volatile的作用当一个变量被声明为volatile时,编译器将确保对该变量的读写操作都会直接访问内存,而不会进行优化。

这样可以防止编译器将变量的值缓存在寄存器中,从而保证对变量的读写操作都能及时地反映在内存中。

3. volatile的常见用法硬件寄存器访问在MCU中,常常需要直接访问硬件寄存器,而这些寄存器的值往往会被外部因素改变。

使用volatile修饰这些变量可以确保每次读写操作都是直接与寄存器进行交互,而不会产生不一致的结果。

volatile unsigned int* const UART_DATA_REG = (unsig ned int*)0x;多线程/中断并发访问在多线程或中断环境下,一个变量可能会被多个线程或中断同时访问。

如果没有使用volatile修饰,编译器可能会进行优化,将变量的值缓存在寄存器中,从而导致并发访问的不一致性。

使用volatile可以确保访问的正确性。

volatile int shared_variable;进行延时操作有些时候,需要在MCU中进行一些精确的延时操作,以控制外设的工作时间。

在进行延时操作时,为了防止编译器对循环进行优化,可以使用volatile修饰循环变量,确保循环不被优化掉。

void delay(volatile unsigned int count) {while(count--);}与外设数据交互在MCU与外设进行数据交互时,往往需要通过读写寄存器来实现。

使用volatile修饰相关变量可以确保数据的正确传输,避免编译器的优化问题。

volatile unsigned int* const SPI_DATA_REG = (unsigned int*)0x;4. 总结使用volatile关键字可以告诉编译器某个变量可能会被意外地改变,从而在对该变量进行读写操作时保证正确性。

volatile详解

volatile一:为什么要讲volatile因为,很多”面试官”自己找不到能够测试应聘者的好的方式,所以就google了一下,发现了”嵌入式经典的0x10个面试题”,于是乎就拿来直接问了。

我想第一个想到用这个来提问应聘者的人绝对是值得我们仰慕的。

二:V olatile官方说明Indicates that a variable can be changed by a background routine.Keyword volatile is an extreme opposite of const. It indicates that a variable may be changed in a way which is absolutely unpredictable by analysing the normal program flow (for example, a variable which may be changed by an interrupt handler). This keyword uses the following syntax: volatile data-definition;Every reference to the variable will reload the contents from memory rather than take advantage of situations where a copy can be in a register.翻译:表示一个变量也许会被后台程序改变.关键字volatile是与const绝然对立的。

它指示一个变量也许会被某种方式修改,这种方式按照正常程序流程分析是无法预知的(例如,一个变量也许会被一个中断服务程序所修改)。

这个关键字使用下列语法定义:volatile data-definition;变量如果加了volatile修饰,则会从内存重新装载内容,而不是直接从寄存器拷贝内容。

volatile的陷阱(栢图实验室)

Volatile的陷阱对于volatile关键字,大部分的C语言教材都是一笔带过,并没有做太过深入的分析,所以这里简单整理了一些关于volatile的使用注意事项。

实际上从语法上来看volatile和const 是一样的,但是如果const用错,几乎不会有什么问题;而volatile用错,后果可能很严重。

所以在volatile的使用上,建议大家还是尽量求稳,少用一些没有切实把握的技巧。

注意volatile修饰的是谁首先来看下面两个定义的区别:uchar * volatile reg;这行代码里volatile修饰的是reg这个变量。

所以这里实际上是定义了一个uchar类型的指针,并且这个指针变量本身是volatile 的。

但是指针所指的内容并不是volatile的!在实际使用的时候,编译器对代码中指针变量reg本身的操作不会进行优化,但是对reg所指的内容*reg却会作为non-volatile内容处理,对*reg的操作还是会被优化。

通常这种写法一般用在对共享指针的声明上,即这个指针变量有可能会被中断等函数修改。

将其定义为volatile 以后,编译器每次取指针变量的值的时候都会从内存中载入,这样即使这个变量已经被别的程序修改了当前函数用的时候也能得到修改后的值(否则通常只在函数开始取一次放在寄存器里,以后就一直使用寄存器内的副本)。

volatile uchar *reg;这行代码里volatile修饰的是指针所指的内容。

所以这里定义了一个uchar类型的指针,并且这个指针指向的是一个volatile的对象。

但是指针变量本身并不是volatile的。

如果对指针变量reg本身进行计算或者赋值等操作,是可能会被编译器优化的。

但是对reg所指向的内容*reg的引用却禁止编译器优化。

因为这个指针所指的是一个volatile的对象,所以编译器必须保证对*reg的操作都不被优化。

通常在驱动程序的开发中,对硬件寄存器指针的定义,都应该采用这种形式。

C语言中volatile关键字的使用

C 语言中volatile 关键字的使用
volatile 的意思是易变的、可变的,作用是限制编译器优化某些变量。

首先看一段C51 程序:
Keil 在优化级别是为8 时得到如下汇编代码(部分未列出):
可以看到,变量d 的值赋给x,y,z 时,只有x 中是直接读取的d 中数值,而y=d,z=d 则直接将寄存器中的数值赋给y,z。

若在此过程中,变量d 的值被改变(比如d 是一个硬件寄存器),则y,z 变量中得到的数据将是错误的,因此在某些应用中程序存在隐患。

这类问题并不是编译器的问题。

由于访问内部寄存器比访问RAM 速度块,因此编译器在编译类似程序时,会对程序进行优化,除第一次编译变量所在在连续读取一个变量时,编译器为了简化程序,只要有可能就会把第一次读取的值放在ACC 或Rx 中,在以后的读取该变量的值时就直接使用第一次的读取值。

如果该变量的值在此过程中已经被外设(如读取外部设备端口时经常将外设端口看作一外部RAM 地址)或其他程序(如中断服务程序)所改变,可能就会出错。

为了解决这类问题,常用的方法就是降低编译器的优化级别或者使用volatile 关键字。

显然降低优化级别不是所期望的,因此用volatile 关键字修饰相关变量很有必要。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

C语言的那些小秘密之volatilevolatile的重要性对于搞嵌入式的程序员来说是不言而喻的,对于volatile的了解程度常常被不少公司在招聘嵌入式编程人员面试的时候作为衡量一个应聘者是否合格的参考标准之一,为什么volatile如此的重要呢?这是因为嵌入式的编程人员要经常同中断、底层硬件等打交道,而这些都用到volatile,所以说嵌入式程序员必须要掌握好volatile的使用。

其实就象读者所熟悉的const一样,volatile是一个类型修饰符。

在开始讲解volatile之前我们先来讲解下接下来要用到的一个函数,知道如何使用该函数的读者可以跳过该函数的讲解部分。

原型:int gettimeofday ( struct timeval * tv , struct timezone * tz );头文件:#include <sys/time.h>功能:获取当前时间返回值:如果成功返回0,失败返回-1,错误代码存于errno中。

gettimeofday()会把目前的时间用tv所指的结构返回,当地时区的信息则放到tz所指的结构中。

[cpp]view plaincopy1.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,下面先来看看一段简单的代码。

[cpp]view plaincopy1.#include <stdio.h>2.#include <sys/time.h>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 * ( _sec - _sec ) + _sec - start.tv_sec ;14. timeuse /= 1000000;15.printf("运行时间为:%f\n",timeuse);16.17.return 0;18.19.}运行结果为:[cpp]view plaincopy1.root@ubuntu:/home# ./p2.运行时间为:0.002736现在来简单的分析下代码,通过_sec - _sec 我们得到了终止时间跟起始时间以秒为单位的时间间隔,然后使用_sec - _sec 得到终止时间跟起始时间以微妙为单位的时间间隔。

因为时间单位的原因,所以我们在此对于( _sec - _sec ) 得到的结果乘以1000000转换为微秒进行计算,之后再使用timeuse /= 1000000;将其转换为秒。

现在了解了如何通过gettimeofday()函数来测试start到end代码之间的运行时间,那么我们现在接下来看看volatile修饰符。

通常在代码中我们为了防止一个变量在意想不到的情况下被改变,我们会将变量定义为volatile,这从而就使得编译器就不会自作主张的去“动”这个变量的值了。

准确点说就是每次在用到这个变量时必须每次都重新从内存中直接读取这个变量的值,而不是使用保存在寄存器里的备份。

在举例之前我们先大概的说下Debug和Release 模式下编译方式的区别,Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。

Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。

大致的知道了Debug和Release的区别之后,我们下面来看看一段代码。

[cpp]view plaincopy1.#include <stdio.h>2.3.void main()4.{5.int a=12;6.printf("a的值为:%d\n",a);7.__asm {mov dword ptr [ebp-4], 0h}8.int b = a;9.printf("b的值为:%d\n",b);10.}先分析下上面的代码,我们使用了一句__asm {mov dword ptr [ebp-4], 0h}来修改变量a在内存中的值,如果有对这句代码功能不清楚的读者可以参考我之前的一篇《C语言的那些小秘密之堆栈》,在此就不做过多的讲解了。

前面已经讲解了Debug和Release 编译方式的区别,那么我们现在来对比看下结果。

注:使用vc6编译运行,如无特殊说明,均在linux 环境下编译运行。

读者自己在编译的时候别忘了选择编译运行的模式。

使用Debug模式的结果为:[cpp]view plaincopy1.a的值为:122.b的值为:03.Press any key to continue使用Release模式的结果为:[cpp]view plaincopy1.a的值为:122.b的值为:123.Press any key to continue看看上面的运行结果我们发现在Release模式进行了优化之后b的值为了12,但是使用Debug模式的时候b的值为0。

为什么会出现这样的情况呢?我们先不说答案,再来看看下面一段代码。

注:使用vc6编译运行[cpp]view plaincopy1.#include <stdio.h>2.3.void main()4.{5.int volatile a=12;6.printf("a的值为:%d\n",a);7.__asm {mov dword ptr [ebp-4], 0h}8.int b = a;9.printf("b的值为:%d\n",b);10.}使用Debug模式的结果为:[cpp]view plaincopy1.a的值为:122.b的值为:03.Press any key to continue使用Release模式的结果为:[cpp]view plaincopy1.a的值为:122.b的值为:03.Press any key to continue我们发现这种情况下不管使用Debug模式还是Release模式都是一样的结果。

现在我们就来分析下,在此之前我们先说了Debug和Release 模式下编译方式的区别。

先分析上一段代码,由于在Debug模式下我们并没有对代码进行优化,所以对于在代码中每次使用a值得时候都是从它的内存地址直接读取的,所以在我们使用了__asm {mov dword ptr [ebp-4], 0h}语句改变了a的值之后,接下来使用a值的时候从内存中直接读取,所以得到的是更新后的a值;但是当我们在Release模式下运行的时候,发现b的值为a 之前的值,而不是我们更新后的a值,这是由于编译器在优化的过程中做了优化处理。

编译器发现在对a赋值之后没有再次改变a的值,所以编译器把a的值备份在了一个寄存器中,在之后的操作中我们再次使用a值的时候就直接操作这个寄存器,而不去读取a的内存地址,因为读取寄存器的速度要快于直接读取内存的速度。

这就使得了读到的a值为之前的12。

而不是更新后的0。

第二段代码中我们使用了一个volatile修饰符,这种情况下不管在什么模式下都得到的是更新后的a的值,因为volatile修饰符的作用就是告诉编译器不要对它所修饰的变量进行任何的优化,每次取值都要直接从内存地址得到。

从这儿我们可以看出,对于我们代码中的那些易变量,我们最好使用volatile修饰,以此来得到每次对其进行更新后的值。

为了加深下大家的印象我们再来看看下面一段代码。

[cpp]view plaincopy1.#include <stdio.h>2.#include <sys/time.h>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<10000000;j++)11. ;12. gettimeofday( &end, NULL ); /*测试终止时间*/13. timeuse = 1000000 * ( _sec - _sec ) + _usec -start.tv_usec;14. timeuse /= 1000000;15.printf("运行时间为:%f\n",timeuse);16.17.return 0;18.19.}与之前我们测试时间的代码一样,我们只是增大了for()循环的次数。

先来看看我们不使用优化的结果:[cpp]view plaincopy1.root@ubuntu:/home# gcc time.c -o p2.root@ubuntu:/home# ./p3.运行时间为:0.028260使用了优化的运行结果:[cpp]view plaincopy1.root@ubuntu:/home# gcc -o p time.c -O22.root@ubuntu:/home# ./p3.运行时间为:0.000001从结果显然可以看出差距如此之大,但是如果我们在上面的代码中修改一下int j为int volatile j之后再来看看如下代码:[cpp]view plaincopy1.#include <stdio.h>2.#include <sys/time.h>3.4.int main(int argc, char * argv[])5.{6.struct timeval start,end;7. gettimeofday( &start, NULL ); /*测试起始时间*/8.double timeuse;9.int volatile j;10.for(j=0;j<10000000;j++)11. ;12. gettimeofday( &end, NULL ); /*测试终止时间*/13. timeuse = 1000000 * ( _sec - _sec ) + _usec -start.tv_usec;14. timeuse /= 1000000;15.printf("运行时间为:%f\n",timeuse);16.17.return 0;18.19.}先来看看我们不使用优化的运行结果为:[cpp]view plaincopy1.root@ubuntu:/home# gcc time.c -o p2.root@ubuntu:/home# ./p3.运行时间为:0.027647使用了优化的运行结果为:[cpp]view plaincopy1.root@ubuntu:/home# gcc -o p time.c -O22.root@ubuntu:/home# ./p3.运行时间为:0.027390我们发现此时此刻不管是否使用优化语句运行,时间几乎没有变化,只是有微小的差异,这微小的差异是由于计算机本身所导致的。

相关文档
最新文档