版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、嵌入式系统C语言程序设计基础,杨,目录,关于在本课程中复习C语言程序设计规范和开发高效程序的技巧,为什么学习本课程,学习C语法和用C语言编写程序是两个概念,而C语言的灵活性和由此产生的陷阱很多。编程世界中最美丽也是最危险的语言!本课程介绍嵌入式系统中最基本(最常用)的概念和技能。小测验1,所有嵌入式系统的主要进程最终进入一个无限循环。如何用C语言实现无限循环?测验2和()有什么区别?和do.while()?测验3,给出变量a的定义:一个整数,一个整数指针,一个10个整数的数组,一个10个指针的数组,指向一个整数,测验4,关键字static的作用是什么?测验5,关键字const的功能是什么?测验
2、6定义了一个标准的宏MIN,它输入两个参数并返回较小的一个。测验7,在嵌入式系统中,位操作通常在变量或寄存器上执行。给定一个int变量a,写两段代码,第一段将a的位3设置为1,第二段将a的位3设置为0。在以上两个操作中,保持其他位不变。嵌入式系统具有经常直接访问物理地址的特点。在项目中,需要设置一个整数变量,其绝对地址为0 x5a00到0 xaa55。编写代码来完成这项任务。测验9,下列代码的输出是什么?void foo(void)无符号整数a=6;int b=-20;(a b 6)?看跌(6) :看跌(6);测验10,请评论以下程序代码:void test()char string 10;c
3、har * str= 0123456789strcpy(字符串,字符串);测验11,请评论以下程序代码:void getmemory(char * p)p=(char *)malloc(0x 20);无效测试(无效)字符*字符串=空;GetMemory(字符串);“你好,世界!”);printf(str);中断是嵌入式系统的重要组成部分。请评论以下中断服务子程序代码:_中断双计算_面积(双半径)双面积=*半径*半径;printf(nArea=%f,面积);返回区域;回答!quiz1answer,而(1)。quiz2answer,而()。是进入条件循环,即在执行每个循环之前检查判断条件;Do.w
4、hile()是退出条件循环,即在执行循环后检查判断条件。小测验3答案,a)整数;b)int * a;c)int a10;d)int * a10;在c语言中,关键字static有三个明显的功能:1)在函数体中,声明为static的变量在调用这个函数的过程中保持其值不变。2)在模块中(但在函数外部),声明为静态的变量可以被模块中使用的函数访问,但不能被模块外部的其他函数访问。它是一个局部全局变量。3)在模块中,声明为静态的函数只能由该模块中的其他函数调用。也就是说,这个函数被限制在声明它的模块的本地范围内。小测验5答案,常量是常量的缩写,意思是“常量”。由const修改的所有内容都受到强制保护,这
5、可以防止意外的更改并提高程序的健壮性。Const常量和#define常量:前者有数据类型,而后者只是字符替换(可能会产生意外错误),因此编译器可以检查前者的安全性。测验6答案,#定义最小值(A,B) (A)=(B)?(一):(B)#定义宏的副作用,执行以下代码后会发生什么:泄漏=最小(* p,B);测验7答案,常量int BIT 3=0x 013;静态int a;void SetBit3(void)a |=BIt3;测试8答案,int * PtTemp=(int *)0 x5a 00;* ptTemp=0 xaa55,测验9答案,输出为“6”,因为当表达式中存在有符号类型和无符号类型时,所有操
6、作数都会自动转换为无符号类型。因此,-20变成一个非常大的正整数,所以这个表达式计算的结果大于6。这对经常使用无符号数据类型的嵌入式系统非常重要。,测验10答案,字符串字符串需要存储11个字节(包括最后的0),而字符串只有10个字节,因此strcpy将导致数组越界。测验11答案,编译器总是临时复制函数的每个参数,指针参数p的副本是p,编译器使p=p。在这个例子中,p应用于新的内存,但是只有p的值改变了,但是p的值根本没有改变,仍然为空。事实上,每次执行GetMemory时,都会有一个内存块泄漏。测验12答案,1)ISR不能返回值;2)无法将参数传递给ISR3)ISR应该是短而高效的,因此在IS
7、R中进行浮点运算和使用printf是不明智的,并且经常会出现重入和性能问题。还是先复习一下c吧!c语言回顾,1)循环和分支,2)范围和存储类,3)内存和指针,4)位操作,5)预编译处理,循环和分支,1)几个循环语句:测试;更新)正文;而(测试)体;多博迪;同时(测试);2)循环辅助手段:用break语句跳出循环,用continue语句结束循环。循环和分支,3)if语句的三种形式:if(表达式)。if(表达式)。否则。if(表达式1)。else if(表达式).否则。循环和分支,4)条件运算符?表达式1?表达式2 :表达式3如果表达式1为真,则整个表达式的值为表达式2,否则为表达式3;是if.e
8、lse的缩写,但是编译器可以生成比if.else更优化的代码.5)多重选择:switch switch (expression) case常量1:语句;打破;case constant2:语句;打破; default:语句;打破;开关确定表达式必须具有整数值,并且大小写标签必须是整数常量或整数常量表达式。c语言评论,1)循环和分支2)范围和存储类3)内存和指针4)位操作5)预编译处理,范围和存储类1)范围代码块范围(局部变量)代码块:包含在左花括号和相应的右花括号中的一段代码。范围:从定义变量的位置到代码块的末尾。文件范围(全局变量)在所有函数之外定义的变量都有文件范围。范围:从定义变量的位置
9、到包含定义的文件的末尾。使用变量在其他地方应用extern来声明变量。2)存储周期静态存储周期:它总是存在于程序运行期间,并且固定的存储空间被分配给变量;所有全局变量都有一个静态存储期(并非所有全局变量都有静态存储期),但是修改全局变量的关键字static表示链接类型,而不是存储期。动态(自动)存储期:在运行过程中根据需要动态分配存储空间给变量。范围和存储类,3)五个存储类,C语言回顾,1)循环和分支,2)范围和存储类,3)内存和指针,4)位操作,5)预编译处理,内存和指针,1)静态存储区内存分配。程序编译时分配内存,内存存在于程序的整个运行期间。例如,全局变量和静态变量;从堆栈中创建。当函数
10、被执行时,函数中局部变量的存储单元可以在堆栈上创建,并且这些存储单元在函数被执行时被自动释放。堆栈内存分配操作内置于处理器的指令集中,非常有效,但分配的内存容量有限;动态内存分配。当程序运行时,程序员负责应用和释放内存。内存和指针,2)内存陷阱C语言的灵活性、指针的应用和C语法的容错性很容易导致代码错误,其中最重要的是内存单元的溢出。a)堆栈溢出b)数组越界。锁定函数中的错误后,我们应该首先注意内存问题。以内存和指针为例,看看下面的代码char * DosMexing()char i32 * 1024有什么问题;返回I;主要有两个问题:1 .临时变量是在堆栈上创建的,太大的临时变量数组将刷新堆
11、栈;2.返回堆栈中的地址没有意义,因为堆栈中的内容总是不确定的。内存和指针,数组出界的危险临时数组:它是在堆栈上创建的,所以临时数组出界可能会导致一些局部变量莫名其妙地改变,函数返回时会崩溃,等等全局数组:它是在静态存储区创建的,所以全局数据出界可能会导致一些全局变量莫名其妙地改变,被刷新的动态内存无法释放。内存和指针,3)指针什么是指针?指针是一个变量,其值是另一个变量的地址。指针的类型指针所指向的变量的类型就是指针的类型。例如,右边的操作有什么区别:int X2,*pX=,内存和指针,指针1的三个元素,指针指向的地址;2.指针指向地址上的内容;3.指针本身的地址;例如:int A,* Pa
12、A,* * ppAPA=、内存和指针以及指针大小(指针变量占用的内存空间)。下面是一个在ARM平台下的32位C程序。请计算的大小。char str= Hellochar * p=strint n=10sizeof(str)=?sizeof(p)=?sizeof(n)=?sizeof(str)=6 sizeof(p)=4 sizeof(n)=4,内存和指针,指针的初始化指针变量在初始化前是随机的;指向未知指针是非常危险的。创建指针时,系统只分配存储指针本身的内存空间,而不分配存储数据的内存空间。在使用指针之前,必须给它分配一个内存地址。内存和指针、指针和数组示例,以下操作是否合法:int a4,
13、* p;p=a;*(a2)=0x 00;p2=0x 01;/相当于p=/错误a;/错误,当内存和指针、指针和数组相同时,下面是一个ARM平台下的32位C程序,请计算sizeof的值。void Func(char a100)sizeof(a)=?sizeof(a)=4,(1)当数组名被用作函数参数时,它在函数体中就失去了它自己的内涵,只是一个指针;(2)不幸的是,在失去其内涵的同时,它也失去了其不断的特性,这些特性可以自我增加、自我减少和自我修改。内存和指针,数组和指针使用规则,数组,声明,使用,定义,例如,char a10不能作为指针写入,例如,extern,extern char a不能作为
14、指针写入,func(char a);或者func(char *a)函数参数可以以指针的形式编写,c=ai或c=*(a I);它可以以指针、1)循环和分支、2)范围和存储类、3)存储器和指针、4)位操作、5)预编译处理、位操作、1)使用位操作硬件寄存器控制的形式编写;压缩和加密操作;提高程序运行的效率;因为位是程序可以操作的最小数据单元,所以理论上可以使用“位操作”来完成所有操作。位操作,2)位运算符位逻辑运算符或标志|=MASK关闭位:标志=标志,位操作,5)用法:检查位的值。错误用法:if(flag=MASK)正确用法:if(flag/0000111无符号字符1;I=ch 2;向左和向右移动
15、,C语言复习,1)循环和分支,2)范围和存储类,3)内存和指针,4)位操作,5)预编译处理,预编译处理,C编译系统在编译前对程序进行预处理。c提供了三个主要的预处理功能:宏定义文件包括条件编译和预编译处理;1)宏定义类对象宏示例:# definestx002类函数宏示例:#define SQUARE(x) (x)*(x)几种解释:a .宏定义不是c语句,因此它不会在行尾添加加号;宏名的有效范围是从定义到原始文件的结尾;定义宏时,可以引用已经定义的宏名称;宏替换不占用运行时间,只占用编译时间;预编译处理,2)文件包含:#include在预处理器发现#include之后,它将找到以下文件并将该文件的内容复制到当前位置以替换#include指令;使用#指令的一些例子包括:预编译处理,3)条件编译条件编译意味着不编译整个程序,而是编译满足条件的部分。条件编译有以下形式:a. #ifdef标识符程序段1;#else程序段2;#endif其功能:如果标识符已经在上面定义,编译程序段1,否则编译程序段2。预编译处理,b. #ifndef标识符程序段1;#else程序段2;#endif它的功能与#ifdef相反。如果之前没有定义标识符,编译程序段1,否则编译程序段2。预编译处理,c. # if表达式程序段1;#else程序段2;#endif其函数:
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 火车内部制度
- 煤矿内部安全环保制度
- 煤矿综采队内部管理制度
- 环保局内部宣传工作制度
- 理事会内部制度
- 监理内部安全陪训制度
- 监理项目内部考核制度范本
- 科室内部会议制度汇编
- 立讯机器人内部管理制度
- 篮球教练内部培训制度范本
- QBJS 10-2023 轻工业工程设计概算编制办法 (正式版)
- 个人承包土地合同书
- 12345市长热线为民服务平台建设方案
- 《传播学教程》教学大纲
- 《人类行为与社会环境》课件
- (高清版)DZT 0205-1999 地面γ能谱测量技术规程
- 标志桩安装质量评定表
- 企业通用全面预算表格模板
- 装配式支吊架试验方法标准
- 服装设计的程序灵感来源思维方式
- 初中数学教师高级职称考试试题(含解析)
评论
0/150
提交评论