嵌入式C语言中必须的关键字
- 格式:doc
- 大小:65.50 KB
- 文档页数:8
在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语句。
32个关键字在c语言中的含义和作用【32个关键字在c语言中的含义和作用解析】在C语言中,有一些关键字是非常重要的,它们在程序中扮演着至关重要的角色。
下面,我将对这32个关键字进行深入解析,让我们来一探究竟。
1. #include在C语言中,#include用于包含头文件,使得在当前文件中可以使用所包含文件中的定义。
2. intint是C语言中的一个基本数据类型,代表整数。
3. charchar也是C语言中的一个基本数据类型,代表字符。
4. floatfloat是C语言中的一个基本数据类型,代表单精度浮点数。
5. doubledouble是C语言中的一个基本数据类型,代表双精度浮点数。
6. ifif是C语言中的条件语句,用于进行条件判断。
7. elseelse也是C语言中的条件语句,用于在条件不成立时执行的语句块。
8. switchswitch语句用于多条件判断,可以替代多个if-else语句。
9. case在switch语句中,case用于列举不同的条件分支。
10. default在switch语句中,default用于表示默认的条件分支。
11. forfor循环用于重复执行一个语句块。
12. whilewhile循环也用于重复执行一个语句块,但条件判断在循环之前进行。
13. dodo-while循环会先执行一次循环体,然后再进行条件判断。
14. breakbreak语句用于跳出循环。
15. continuecontinue语句用于结束当前循环,并开始下一次循环。
16. returnreturn语句用于结束函数的执行,并返回一个值。
17. voidvoid用于声明函数的返回类型,表示该函数没有返回值。
18. sizeofsizeof用于获取变量或类型的长度。
19. typedeftypedef用于给数据类型取一个新的名字。
20. structstruct用于定义结构体类型。
21. unionunion也用于定义数据类型,但它和结构体不同,它的所有成员共用一块内存。
c语言的32个关键字及其含义C语言是一门广泛应用于计算机编程的高级编程语言,其简洁、高效的特点使之成为许多程序员的首选。
而C语言的关键字则是构成C语言语法结构的基石,掌握这些关键字的含义对于编写高质量的C代码至关重要。
本文将会介绍C语言的32个关键字及其含义。
一、自动变量(auto)auto关键字用于声明自动变量,自动变量是在代码块中定义的变量。
它们的生命周期仅限于所在代码块,函数的参数也属于自动变量。
二、断言(assert)assert关键字用于在程序运行时进行断言验证,如果断言条件为假,程序将会中止执行。
断言通常用于调试和排错。
三、带宽限定(band)band关键字用于限定带宽,常用于定义延迟函数、外部中断和总线访问等场景。
四、布尔类型(bool)bool关键字用于声明布尔类型的变量,布尔类型只有两个值:真和假。
一般用于判断语句和循环语句的条件。
五、跳过(break)break关键字用于跳出循环或者switch语句块,提前终止程序的执行。
六、函数调用(call)call关键字用于向函数传递参数并调用函数。
它与return关键字相对应,后者用于从函数返回结果。
七、case标签(case)case关键字用于定义switch语句中不同分支的标签,根据不同的条件执行相应的代码。
八、常量(const)const关键字用于声明常量,常量值在程序执行期间不可更改。
通常用于定义不变的特定值,提高代码的可读性和可维护性。
九、continue(continue)continue关键字用于结束当前循环的当前迭代,并进入下一轮循环的迭代。
通常用于跳过某些不满足条件的循环迭代。
十、默认(default)default关键字用于定义switch语句中默认分支的代码块。
如果没有匹配的case 标签,将会执行默认分支的代码。
十一、定义(define)define关键字用于定义宏。
宏是一种在程序编译之前被展开的符号常量或者代码片段。
c语言32个关键字详解auto: auto关键字是c语言中用来声明局部变量的修饰符,它能够使程序员在一个函数的内部定义一个局部变量。
auto关键字的作用是使得这个局部变量在函数返回后不会消失,而是可以在函数的外部继续存在。
break: break关键字用于强制跳出循环,它可以用于while,do while或者for循环。
当它出现在循环内部时,循环立即终止,并且控制流程将会跳转到循环外部。
case: case关键字可以用来创建一个条件分支,并且它必须出现在switch语句中。
它可以使得程序不必以多重if语句来处理多重分支问题。
char: char关键字用来指定字符变量,它可以表示一个字符或者一个小整数,一般8位字节足以存放一个字符。
const: const关键字用来定义常量,它之后的变量不能被修改,一旦定义的常量将一直保存在程序的整个执行过程中。
continue: continue关键字用来结束当前迭代循环,并且进入下一次迭代循环。
当它出现在循环内部时,当前的循环将会立即终止,控制流程将会继续到循环的下一个迭代中。
default: default关键字用来指定switch中的默认case语句,当没有任何case匹配成功时,将会执行default后面的语句。
do: do关键字用来声明一个do-while循环,do-while循环通常用来保证在程序中某个条件至少被执行一次,它的基本形式为“do{}while()”,执行流程大致如下:首先执行do后面的语句,然后判断while后面的条件是否满足,如果满足,则继续执行do后面的语句,直到while条件不成立。
double: double关键字用来指定双精度浮点类型的变量,它能够表示一个比较大的数字,一般来说8个字节存储就足够了。
else: else关键字用来指定if语句的反条件分支,即当if检查的条件不满足时,会执行else后面的语句。
enum: enum关键字用来指定一组枚举类型的常量,它可以使枚举的常量有规律的递增或者递减,常用于建立某一种特定事物的有限集合。
c语言中volatile的用法引言在C语言中,volatile是一个非常重要的关键字,它告诉编译器某个变量可能会被意外的改变,从而防止编译器对这些变量进行优化。
本文将介绍volatile的定义、用法以及其在多线程、嵌入式开发中的应用。
一、定义与作用volatile关键字是C语言中用来声明变量的一种类型修饰符,它用于告知编译器该变量可能被在程序执行中意外地改变,编译器在编译过程中会尽量避免对volatile 变量的优化。
volatile常见的作用有以下几个方面: 1. 防止编译器优化:编译器在进行优化时,会根据程序的逻辑简化一些操作,如果一个变量的值不会被程序以外的因素改变,编译器可能会进行一些优化,将变量的读取操作删除或进行替换。
而使用volatile 修饰变量,可以告诉编译器不要对该变量进行优化,保证变量的读取和写入操作不被删除或替换。
2.处理硬件映射:在嵌入式开发中,通常会有一些变量与硬件设备进行映射,这些变量的值可能会被硬件设备修改。
如果不使用volatile修饰这些变量,在编译器优化的过程中可能会导致未预料的结果,使用volatile修饰这些变量可以确保程序正确地与硬件设备进行通信。
3.多线程同步:在多线程编程中,不同线程可能同时访问同一个变量,如果不使用volatile修饰该变量,编译器对该变量的优化可能导致线程读取到脏数据。
通过使用volatile修饰变量,可以确保在多线程环境下变量的可见性和一致性。
二、volatile与多线程并发编程中最常见的一个问题就是可见性问题,即一个线程对共享变量的修改对另一个线程是否可见。
而volatile关键字可以用来确保变量在多线程环境下的可见性。
以下是volatile与多线程相关的一些要点:1. 可见性使用volatile修饰的变量在多线程环境下保证了其可见性。
如果一个线程对一个volatile变量进行了修改,那么其他线程在读取该变量时可以立即看到最新的值,而不会使用缓存中的旧值。
c语言的37个关键字C语言是一种广泛应用于计算机编程的高级编程语言,它具有简单、高效、可移植等特点,被广泛应用于操作系统、嵌入式系统、游戏开发等领域。
C语言中有37个关键字,这些关键字在程序中具有特殊的含义,下面我们来逐一介绍这些关键字。
1. auto:用于声明自动变量,即在函数内部定义的变量。
2. break:用于跳出循环语句或switch语句。
3. case:用于switch语句中的分支。
4. char:用于声明字符类型变量。
5. const:用于声明常量,常量的值不能被修改。
6. continue:用于跳过循环中的某次迭代。
7. default:用于switch语句中的默认分支。
8. do:用于循环语句中的循环体。
9. double:用于声明双精度浮点数类型变量。
10. else:用于if语句中的分支。
11. enum:用于声明枚举类型。
12. extern:用于声明外部变量或函数。
13. float:用于声明单精度浮点数类型变量。
14. for:用于循环语句中的循环体。
15. goto:用于无条件跳转到指定标签。
16. if:用于条件语句中的判断。
17. int:用于声明整型变量。
18. long:用于声明长整型变量。
19. register:用于声明寄存器变量,即将变量存储在CPU的寄存器中,以提高程序的执行效率。
20. return:用于函数中返回值。
21. short:用于声明短整型变量。
22. signed:用于声明有符号类型变量。
23. sizeof:用于获取变量或数据类型的大小。
24. static:用于声明静态变量或函数。
25. struct:用于声明结构体类型。
26. switch:用于多分支选择语句。
27. typedef:用于定义新的数据类型。
28. union:用于声明共用体类型。
29. unsigned:用于声明无符号类型变量。
30. void:用于声明无返回值的函数或指针类型变量。
freertos __weak 用法`__weak` 是 C 语言中的一个关键字,用于在嵌入式系统和操作系统中实现弱链接。
在 FreeRTOS 中,`__weak` 关键字通常用于实现可重入函数和中断安全函数。
在 FreeRTOS 中,弱链接的主要用途是解决函数重入和中断安全问题。
由于 FreeRTOS 是一个实时操作系统,它可以支持多个任务同时运行,因此函数必须能够在多任务环境中正确工作。
如果一个函数不是可重入的或不是中断安全的,那么它可能会导致数据竞争或死锁等问题。
通过使用`__weak` 关键字,可以在函数定义中指定一个弱链接版本。
这样,如果该函数已经有一个强链接版本(即没有使用`__weak` 关键字的版本),则弱链接版本将不会被使用。
这使得开发人员可以在不破坏现有代码的情况下添加新的可重入或中断安全版本。
下面是一个简单的示例,演示了如何在 FreeRTOS 中使用 `__weak` 关键字:```cinclude ""include ""// 原始函数定义,没有使用 __weak 关键字void MyFunction(void){// 函数实现}// 使用 __weak 关键字定义弱链接版本__weak void __attribute__((weak)) MyFunction(void){// 弱链接版本的实现}```在这个示例中,原始的 `MyFunction` 函数没有被标记为可重入或中断安全的。
但是,通过使用 `__weak` 关键字和 `__attribute__((weak))` 属性,我们定义了一个弱链接版本的 `MyFunction`。
这个弱链接版本可以覆盖原始函数的实现,并且可以确保它是可重入或中断安全的。
c语言关键字大全(32个)引导语:C 语言可以像汇编语言一样对位、字节和地址进行操作,而这三者是计算机最基本的工作单元。
以下是店铺为大家整理的c语言关键字大全,欢迎阅读!1、auto :声明自动变量2、break:跳出当前循环3、case:开关语句分支4、char :声明字符型变量或函数返回值类型5、const :声明只读变量6、continue:结束当前循环,开始下一轮循环7、default:开关语句中的“其它”分支8、do :循环语句的循环体9、double :声明双精度浮点型变量或函数返回值类型10、else :条件语句否定分支(与 if 连用)11、enum :声明枚举类型12、extern:声明变量或函数是在其它文件或本文件的其他位置定义13、float:声明浮点型变量或函数返回值类型14、for:一种循环语句15、goto:无条件跳转语句16、if:条件语句17、int:声明整型变量或函数18、long :声明长整型变量或函数返回值类型19、register:声明寄存器变量20、return :子程序返回语句(可以带参数,也可不带参数)21、short :声明短整型变量或函数22、signed:声明有符号类型变量或函数23、sizeof:计算数据类型或变量长度(即所占字节数)24、static :声明静态变量25、struct:声明结构体类型26、switch :用于开关语句27、typedef:用以给数据类型取别名28、unsigned:声明无符号类型变量或函数29、union:声明共用体类型30、void :声明函数无返回值或无参数,声明无类型指针31、volatile:说明变量在程序执行中可被隐含地改变32、while :循环语句的循环条件。
16个嵌入式C语言必会知识1. 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL我在这想看到几件事情:1). #define 语法的基本知识(例如:不能以分号结束,括号的使用,等等)2). 懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。
3). 意识到这个表达式将使一个16位机的整型数溢出-因此要用到长整型符号L,告诉编译器这个常数是的长整型数。
4). 如果你在你的表达式中用到UL(表示无符号长整型),那么你有了一个好的起点。
记住,第一印象很重要。
2. 写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。
#define MIN(A,B) ((A) <= (B) (A) : (B))这个测试是为下面的目的而设的:1). 标识#define在宏中应用的基本知识。
这是很重要的,因为直到嵌入(inline)操作符变为标准C的一部分,宏是方便产生嵌入代码的唯一方法,对于嵌入式系统来说,为了能达到要求的性能,嵌入代码经常是必须的方法。
2). 三重条件操作符的知识。
这个操作符存在C语言中的原因是它使得编译器能产生比if- then-else更优化的代码,了解这个用法是很重要的。
3). 懂得在宏中小心地把参数用括号括起来4). 我也用这个问题开始讨论宏的副作用,例如:当你写下面的代码时会发生什么事?least = MIN(*p++, b);3. 预处理器标识#error的目的是什么?停止编译并显示错误信息;参考如下:指令用途# 空指令,无任何效果#include 包含一个源代码文件#define 定义宏#undef 取消已定义的宏#if 如果给定条件为真,则编译下面代码#ifdef 如果宏已经定义,则编译下面代码#ifndef 如果宏没有定义,则编译下面代码#elif 如果前面的#if给定条件不为真,当前条件为真,则编译下面代码#endif 结束一个#if……#else条件编译块#error 停止编译并显示错误信息如果你不知道答案,请看参考文献1。
1.static关键字这个关键字前面也有提到,它的作用是强大的。
要对static关键字深入了解,首先需要掌握标准C程序的组成。
标准C程序一直由下列部分组成:1)正文段——CPU执行的机器指令部分,也就是你的程序。
一个程序只有一个副本;只读,这是为了防止程序由于意外事故而修改自身指令;2)初始化数据段(数据段)——在程序中所有赋了初值的全局变量,存放在这里。
3)非初始化数据段(bss段)——在程序中没有初始化的全局变量;内核将此段初始化为0。
注意:只有全局变量被分配到数据段中。
4)栈——增长方向:自顶向下增长;自动变量以及每次函数调用时所需要保存的信息(返回地址;环境信息)。
这句很关键,常常有笔试题会问到什么东西放到栈里面就足以说明。
5)堆——动态存储分配。
在嵌入式C语言当中,它有三个作用:作用一:在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
这样定义的变量称为局部静态变量:在局部变量之前加上关键字static,局部变量就被定义成为一个局部静态变量。
也就是上面的作用一中提到的在函数体内定义的变量。
除了类型符外,若不加其它关键字修饰,默认都是局部变量。
比如以下代码:void test1(void){unsigned char a;static unsigned char b;…a++;b++;}在这个例子中,变量a是局部变量,变量b为局部静态变量。
作用一说明了局部静态变量b的特性:在函数体,一个被声明为静态的变量(也就是局部静态变量)在这一函数被调用过程中维持其值不变。
这句话什么意思呢?若是连续两次调用上面的函数test1:void main(void){…test1();test1();…}然后使程序暂停下来,读取a和b的值,你会发现,a=1,b=2。
怎么回事呢,每次调用test1函数,局部变量a都会重新初始化为0x00;然后执行a++;而局部静态变量在调用过程中却能维持其值不变。
通常利用这个特性可以统计一个函数被调用的次数。
声明函数的一个局部变量,并设为static类型,作为一个计数器,这样函数每次被调用的时候就可以进行计数。
这是统计函数被调用次数的最好的办法,因为这个变量是和函数息息相关的,而函数可能在多个不同的地方被调用,所以从调用者的角度来统计比较困难。
代码如下:void count();int main(){int i;for (i = 1; i <= 3; i++){count();{return 0;}void count(){static num = 0;num++;printf(" I have been called %d",num,"times/n");}输出结果为:I have been called 1 times.I have been called 2 times.I have been called 3 times.看一下局部静态变量的详细特性,注意它的作用域。
1)内存中的位置:静态存储区2)初始化:未经初始化的全局静态变量会被程序自动初始化为0(自动对象的值是任意的,除非他被显示初始化)3)作用域:作用域仍为局部作用域,当定义它的函数或者语句块结束的时候,作用域随之结束。
注:当static用来修饰局部变量的时候,它就改变了局部变量的存储位置,从原来的栈中存放改为静态存储区。
但是局部静态变量在离开作用域之后,并没有被销毁,而是仍然驻留在内存当中,直到程序结束,只不过我们不能再对他进行访问。
作用二:在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。
它是一个本地的全局变量。
这样定义的变量也称为全局静态变量:在全局变量之前加上关键字static,全局变量就被定义成为一个全局静态变量。
也就是上述作用二中提到的在模块内(但在函数体外)声明的静态变量。
定义全局静态变量的好处:<1>不会被其他文件所访问,修改,是一个本地的局部变量。
<2>其他文件中可以使用相同名字的变量,不会发生冲突。
全局变量的详细特性,注意作用域,可以和局部静态变量相比较:1)内存中的位置:静态存储区(静态存储区在整个程序运行期间都存在)2)初始化:未经初始化的全局静态变量会被程序自动初始化为0(自动对象的值是任意的,除非他被显示初始化)3)作用域:全局静态变量在声明他的文件之外是不可见的。
准确地讲从定义之处开始到文件结尾。
当static用来修饰全局变量的时候,它就改变了全局变量的作用域(在声明他的文件之外是不可见的),但是没有改变它的存放位置,还是在静态存储区中。
作用三:在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。
那就是,这个函数被限制在声明它的模块的本地范围内使用。
这样定义的函数也成为静态函数:在函数的返回类型前加上关键字static,函数就被定义成为静态函数。
函数的定义和声明默认情况下是extern的,但静态函数只是在声明他的文件当中可见,不能被其他文件所用。
定义静态函数的好处:<1> 其他文件中可以定义相同名字的函数,不会发生冲突<2> 静态函数不能被其他文件所用。
它定义一个本地的函数。
这里我一直强调数据和函数的本地化,这对于程序的结构甚至优化都有巨大的好处,更大的作用是,本地化的数据和函数能给人传递很多有用的信息,能约束数据和函数的作用范围。
在C++的对象和类中非常注重的私有和公共数据/函数其实就是本地和全局数据/函数的扩展,这也从侧面反应了本地化数据/函数的优势。
最后说一下存储说明符,在标准C语言中,存储说明符有以下几类:auto、register、extern和static对应两种存储期:自动存储期和静态存储期。
auto和register对应自动存储期。
具有自动存储期的变量在进入声明该变量的程序块时被建立,它在该程序块活动时存在,退出该程序块时撤销。
关键字extern和static用来说明具有静态存储期的变量和函数。
用static声明的局部变量具有静态存储持续期(static storage duration),或静态范围(static extent)。
虽然他的值在函数调用之间保持有效,但是其名字的可视性仍限制在其局部域内。
静态局部对象在程序执行到该对象的声明处时被首次初始化。
2. const 关键字const关键字也是一个优秀程序中经常用到的关键字。
关键字const 的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。
通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。
合理地使用关键字const 可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。
简而言之,这样可以减少bug的出现。
深入理解const关键字,你必须知道:a. const关键字修饰的变量可以认为有只读属性,但它绝不与常量划等号。
如下代码:const int i=5;int j=0;...i=j; //非法,导致编译错误,因为只能被读j=i; //合法b. const关键字修饰的变量在声明时必须进行初始化。
如下代码:const int i=5; //合法const int j; //非法,导致编译错误c. 用const声明的变量虽然增加了分配空间,但是可以保证类型安全。
const 最初是从C++变化得来的,它可以替代define来定义常量。
在旧版本(标准前)的c中,如果想建立一个常量,必须使用预处理器:#define PI 3.14159此后无论在何处使用PI,都会被预处理器以3.14159替代。
编译器不对PI进行类型检查,也就是说可以不受限制的建立宏并用它来替代值,如果使用不慎,很可能由预处理引入错误,这些错误往往很难发现。
而且,我们也不能得到PI的地址(即不能向PI传递指针和引用)。
const的出现,比较好的解决了上述问题。
d. C标准中,const定义的常量是全局的。
e. 必须明白下面语句的含义,我自己是反复记忆了许久才记住,方法是:若是想定义一个只读属性的指针,那么关键字const要放到‘* ’后面。
char *const cp; //指针不可改变,但指向的内容可以改变char const *pc1; //指针可以改变,但指向的内容不能改变const char *pc2; //同上(后两个声明是等同的)f. 将函数传入参数声明为const,以指明使用这种参数仅仅是为了效率的原因,而不是想让调用函数能够修改对象的值。
参数const通常用于参数为指针或引用的情况,且只能修饰输入参数;若输入参数采用“值传递”方式,由于函数将自动产生临时变量用于复制该参数,该参数本就不需要保护,所以不用const修饰。
例子:void fun0(const int * a );void fun1(const int & a);调用函数的时候,用相应的变量初始化const常量,则在函数体中,按照const 所修饰的部分进行常量化,如形参为const int * a,则不能对传递进来的指针所指向的内容进行改变,保护了原指针所指向的内容;如形参为const int & a,则不能对传递进来的引用对象进行改变,保护了原对象的属性。
g. 修饰函数返回值,可以阻止用户修改返回值。
(在嵌入式C中一般不用,主要用于C++)h. const消除了预处理器的值替代的不良影响,并且提供了良好的类型检查形式和安全性,在可能的地方尽可能的使用const对我们的编程有很大的帮助,前提是:你对const有了足够的理解。
最后,举两个常用的标准C库函数声明,它们都是使用const的典范。
1.字符串拷贝函数:char *strcpy(char *strDest,const char *strSrc);2.返回字符串长度函数:int strlen(const char *str);3.volatile关键字一个定义为volatile 的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。
精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。
由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM 的优化。
比如:static int i=0;int main(void){...while (1){if (i)dosomething();}}/* Interrupt service routine. */void ISR_2(void){i=1;}程序的本意是希望ISR_2中断产生时,在main当中调用dosomething函数,但是,由于编译器判断在main函数里面没有修改过i,因此可能只执行一次对从i到某寄存器的读操作,然后每次if判断都只使用这个寄存器里面的“i 副本”,导致dosomething永远也不会被调用。