嵌入式系统C语言编程基础-课件_第1页
嵌入式系统C语言编程基础-课件_第2页
嵌入式系统C语言编程基础-课件_第3页
嵌入式系统C语言编程基础-课件_第4页
嵌入式系统C语言编程基础-课件_第5页
已阅读5页,还剩76页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

嵌入式系统C语言编程基础SNBC目录

关于本课程

C语言复习编程规范开发高效程序的技巧ppt课件为什么学习本课程会C语法与会用C语言写程序是两个概念C的灵活性以及由此而产生的陷阱非常多TheMostBeautifulLanguageandMostDangerousLanguageintheProgrammingWorld!本课程将嵌入式系统中最基本的(最经常用到的)概念与技巧介绍给大家ppt课件小测验?ppt课件Quiz1所有嵌入式系统的主流程最后都进入一个死循环,怎样用C语言实现一个死循环?ppt课件Quiz2while(){….}和do{….}while()有什么区别?ppt课件Quiz3用变量a给出下列定义:一个整型数一个指向整型数的指针一个有10个整型数的的数组一个有10个指针的数组,该指针是指向一个整型数的ppt课件Quiz4关键字static的作用是什么?ppt课件Quiz5关键字const的作用是什么?ppt课件Quiz6定义一个标准宏MIN,这个宏输入两个参数并返回较小的一个。ppt课件Quiz7嵌入式系统中经常要对变量或寄存器进行位操作。给定一个int型变量a,写两段代码,第一个将a的bit3置为1,第二个将a的bit3置为0。以上两个操作中,要保持其它位不变。ppt课件Quiz8嵌入式系统具有经常去直接访问物理地址的特点。在某工程中,要求设置一绝对地址为0x5a00的整型变量的值为0xaa55。写代码去完成这一任务。ppt课件Quiz9下面这段代码的输出是什么?

voidfoo(void)

{

unsignedinta=6;

intb=-20;

(a+b>6)?puts(">6"):puts("<6");

}ppt课件Quiz10请评论下面一段程序代码:

voidtest()

{

charstring[10];

char*str=“0123456789”;

strcpy(string,str);

}ppt课件Quiz11请评论下面一段程序代码:

voidGetMemory(char*p){

p=(char*)malloc(0x20);

}

voidTest(void){

char*str=NULL;

GetMemory(str);

strcpy(str,”HelloWorld!”);

printf(str);

}ppt课件Quiz12中断是嵌入式系统的重要组成部分。请评论下面一段中断服务子程序代码:__interruptdoublecompute_area(doubleradius)

{

doublearea=PI*radius*radius;

printf("\nArea=%f",area);

returnarea;

}ppt课件Answer!ppt课件Quiz1Answerwhile(1){….}ppt课件Quiz2Answerwhile(){….}为入口条件循环,即在每次执行循环之前先检查判断条件;do{….}while()为退出条件循环,即在执行循环之后再检查判断条件。ppt课件Quiz3Answera)inta;

b)int*a;

c)inta[10];

d)int*a[10];ppt课件Quiz4Answer在C语言中,关键字static有三个明显的作用:

1)在函数体内,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。

2)在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。

3)在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。ppt课件Quiz5Answerconst是constant的缩写,“恒定不变”的意思。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。const常量与#define常量:前者有数据类型,后者只是字符替换(而且可能产生意料不到的错误),所以编译器可以对前者进行安全性检查。ppt课件Quiz6Answer#defineMIN(A,B)((A)<=(B)?(A):(B))#define宏的副作用,下面的代码执行后会发生什么事:

least=MIN(*p++,b);ppt课件Quiz7AnswerconstintBIT3=0x01<<3;

staticinta;

voidSetBit3(void){

a|=BIT3;

}

voidClearBit3(void){

a&=~BIT3;

}ppt课件Quiz8Answerint*ptTemp=(int*)0x5a00;

*ptTemp=0xaa55;ppt课件Quiz9Answer输出为“>6”,原因是当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。因此-20变成了一个非常大的正整数,所以该表达式计算出的结果大于6。这一点对于频繁用到无符号数据类型的嵌入式系统来说是丰常重要的。ppt课件Quiz10Answer字符串str需要11个字节才能存放下(包括末尾的’\0’),而string只有10个字节的空间,所以strcpy会导致数组越界。ppt课件Quiz11Answer编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是_p,编译器使_p=p。本例中,_p申请了新的内存,但只是_p的值改变了,p的值却丝毫未变,仍然为NULL。事实上,每执行一次GetMemory就会泄漏一块内存。ppt课件Quiz12Answer1)ISR不能返回值;

2)不能向ISR传递参数;

3)ISR应该是短而有效率的,因而在ISR中做浮点运算、使用printf等是不明智的,会经常有重入和性能上的问题。ppt课件还是先复习一下C吧!ppt课件C语言复习1)循环与分支

2)作用域与存储类

3)内存与指针

4)位操作

5)预编译处理ppt课件循环与分支1)几种循环语句:

for(initialize;test;update){body;}

while(test){body;}

do{body;}while(test);2)循环辅助手段:

break语句用于跳出循环,continue语句用于结束本次循环。ppt课件循环与分支3)三种形式的if语句:

if(expression){….}

if(expression){….}else{….}

if(expression1){….}

elseif(expression){….}

….

else{….}ppt课件循环与分支4)条件运算符?:expression1?expression2:expression3如果expression1为真,整个表达式的值为expression2的值,否则为expression3的值;是if….else….的简写形式,但是编译器可以产生比if….else….更优化的代码。ppt课件循环与分支5)多重选择:switch

switch(expression){

caseconstant1:statements;break; caseconstant2:statements;break;

….

default:statements;break;

}

switch判断表达式必须具有整数值,case标签必须是整数常量或整数常量表达式。ppt课件C语言复习1)循环与分支

2)作用域与存储类

3)内存与指针

4)位操作

5)预编译处理ppt课件作用域与存储类1)作用域代码块作用域(局部变量)

代码块:包含在开始花括号和对应结束花括号之内的一段代码。

作用域:从定义变量位置到该代码块的末尾。文件作用域(全局变量)

在所有函数之外定义的变量具有文件作用域。

作用域:从定义变量位置到包含该定义的文件的结尾处。在其它位置使用该变量应用extern来声明该变量。ppt课件作用域与存储类2)存储时期静态存储时期:程序运行期间一直存在,给变量分配固定的存储空间;

所有全局变量具有静态存储时期(具有静态存储时期的并不都是全局变量),但是修饰全局变量的关键词static表明的是链接类型,并非存储时期。动态(自动)存储时期:运行期间根据需要动态的给变量分配存储空间。ppt课件作用域与存储类3)5种存储类存储类存储时期作用域链接声明方式自动自动代码块空代码块内寄存器自动代码块空代码块内,使用关键字register外部静态静态文件外部所有函数之外内部静态静态文件内部所有函数之外,使用关键字static代码块静态静态代码块空代码块内,使用关键字staticppt课件C语言复习1)循环与分支

2)作用域与存储类

3)内存与指针

4)位操作

5)预编译处理ppt课件内存与指针1)内存分配方式从静态存储区分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量;从栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限;动态内存分配。程序在运行的时候由程序员自己负责申请和释放内存。ppt课件内存与指针2)内存陷阱C语言的灵活性,指针的应用,以及C语法的宽容性很容易造成代码的错误,这其中最主要的就是内存单元的溢出。

a)堆栈溢出

b)数组越界

….将错误锁定在一个函数中以后,首先应该关注内存的问题。ppt课件内存与指针举例,看看下面这段代码有什么问题

char*DoSomething()

{

chari[32*1024];

….

returni;

}两个重大问题:

1、临时变量在堆栈上创建,太大的临时变量数组会冲掉堆栈;

2、返回堆栈中的地址是没有意义的,因为堆栈中的内容永远是不确定的。ppt课件内存与指针数组越界的危险临时数组:在栈上创建,因此临时数组越界有可能导致某些局部变量莫明其妙被改,函数返回时崩溃等等;全局数组:在静态存储区创建,因此全局数据越界有可能导致某些全局变量莫明其妙被改,被冲的动态内存无法释放等等。ppt课件内存与指针3)指针指针是什么?

指针是一个变量,它的值是另外一个变量的地址。指针的类型

指针所指向的变量的类型,就是指针的类型。

举例,右边的运算有何不同:

intX[2],*pX=&X[0]; pX++;

charY[2],*pY=&Y[0]; pY++;ppt课件内存与指针指针的三要素1、指针指向的地址;

2、指针指向地址上的内容;

3、指针本身的地址;举例:

intA,*pA,**ppA;

pA=&A;

ppA=&pA;ppt课件内存与指针指针的大小(指针变量占用的内存空间)举例,以下为ARM平台下的一段32位C程序,请计算sizeof的值。

charstr[]=“Hello”;

char*p=str;

intn=10;

sizeof(str)=?

sizeof(p)=?

sizeof(n)=?sizeof(str)=6

sizeof(p)=4

sizeof(n)=4ppt课件内存与指针指针的初始化指针变量在没有被初始化之前,它的值是随机的;一个指向不明的指针是非常危险的。当创建一个指针时,系统只分配了用来存储指针本身的内存空间,并不分配用来存储数据的内存空间。使用指针之前,必须给它赋予一个已分配的内存地址。ppt课件内存与指针指针与数组

举例,下列操作是否合法:

inta[4],*p;

p=a;

*(a+2)=0x00;

p[2]=0x01;//等价于p=&a[0];

//等价于a[2];

//等价于*(p+2);但是数组名不同于指针:

数组名a是指向数组起始位置的“常量”。

因此不能对数组名进行赋值操作。

a=p; //错误

a++; //错误ppt课件内存与指针指针与数组什么时候是相同的

举例,以下为ARM平台下的一段32位C程序,请计算sizeof的值。

voidFunc(chara[100]){

sizeof(a)=?

}sizeof(a)=4(1)数组名作为函数形参时,在函数体内,其失去了本身的内涵,仅仅只是一个指针;

(2)很遗憾,在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。ppt课件内存与指针数组与指针运用规则数组声明使用定义,如chara[10]

不能写成指针的形式extern,如externchara[]

不能写成指针的形式func(chara[]);或func(char*a)

函数参数可以写成指针的形式c=a[i];或c=*(a+i);

可以写成指针的形式ppt课件C语言复习1)循环与分支

2)作用域与存储类

3)内存与指针

4)位操作

5)预编译处理ppt课件位操作1)位操作的用途硬件寄存器控制;压缩和加密操作;提高程序运行效率;….因为位是程序可以操作的最小数据单位,所以理论上可以用“位操作”完成所有的运算与操作。ppt课件位操作2)位运算符位逻辑运算符

&位与(两个数对应位都为1结果才为1)

|位或(两个数对应位有一个为1结果则为1)

^

位异或(两个数对应位不同结果则为1)

~

按位取反(单目运算符)移位运算符

<<

左移

>>

右移ppt课件位操作3)用法:掩码

位操作符通常跟掩码一起用。掩码是某些位为开而某些位为关的位组合。例:

flag&=MASK;000000101011011000000010MASKflag&=ppt课件位操作4)用法:打开位、关闭位、转置位打开位:

flag=flag|MASK;或flag|=MASK;关闭位:

flag=flag&~MASK;或flag&=~MASK;转置位:

flag=flag^MASK;或flag^=MASK;ppt课件位操作5)用法:查看某一位的值错误用法:

if(flag==MASK)正确用法:

if((flag&MASK)==MASK)

位运算符的优先级低于==,因此需要在flag&MASK的两侧加上圆括号。ppt课件位操作6)用法:移位操作unsignedcharch=0x07; //00000111unsignedchari;i=ch<<6;i=ch>>2;000001111100000000000001左移右移ppt课件C语言复习1)循环与分支

2)作用域与存储类

3)内存与指针

4)位操作

5)预编译处理ppt课件预编译处理C编译系统在对程序进行编译之前,先进行预处理。C提供的预处理功能主要有以下三种:宏定义文件包含条件编译ppt课件预编译处理1)宏定义类对象宏

例:#defineSTX0x02类函数宏

例:#defineSQUARE(x)((x)*(x))几点说明:

a.宏定义不是C语句,不在行末加分号;

b.宏名有效范围为从定义处到本源文件结束;

c.在宏定义时,可以引用已经定义的宏名;

d.宏替换不占运行时间,只占编译时间;ppt课件预编译处理2)文件包含:#include预处理器发现#include后,就会寻找后跟的这个文件并把这个文件的内容复制到当前位置替换#include指令;使用#include指令的一些例子:#include<stdio.h>从标准库路径开始搜索文件#include“def.h”从当前工作路径开始搜索文件#include“/usr/head/def.h”搜索“/usr/head/”目录ppt课件预编译处理3)条件编译条件编译指不对整个程序编译,而是编译满足条件的那部分。条件编译有以下几种形式:

a.#ifdef标识符

程序段1;

#else

程序段2;

#endif

它的作用:当标识符在前面已经定义过,则对程序段1进行编译,否则对程序段2进行编译。ppt课件预编译处理b.#ifndef标识符

程序段1;

#else

程序段2;

#endif

它的作用和#ifdef相反,当标识符之前没被定义过,则对程序段1进行编译,否则就对程序段2进行编译。ppt课件预编译处理c.#if表达式

程序段1;

#else

程序段2;

#endif

它的作用:当表达式的值为真时,对程序段1进行编译,都则就对程序段2进行编译;ppt课件预编译处理

举例,下面是某工程中.h文件中的一段程序,请说明#ifndef/#define/#endif结构的作用。

#ifndef DEF_H

#define DEF_H

#include<math.h>

#include “graphics.h”

….

#endif防止头文件被重复引用ppt课件编程规范ppt课件编程规范1)规范的作用改善代码质量提高开发速度增进团队精神养成良好习惯ppt课件编程规范2)编程规范养成良好的编程习惯ppt课件开发高效程序的技巧ppt课件开发高效程序的技巧1)ARM编程中局部变量的使用举例,请看一面一段程序:

intchecksum(int*data)

{

chari;

….

for(i=0;i<64;i++){

….;

}

….

}….

ADD r1,r1,#1

AND r1,r1,#0xFF

CMP r1,#0x40

….ppt课件开发高效程序的技巧把上面的程序段将i声明为unsignedint类型,比较一下:….

ADD r1,r1,#1

CMP r1,#0x40

….ARM编程中局部变量类型的使用:

char或short类型并不比int类型占用更小的寄存器空间或者堆栈空间,应尽量不要使用char或short作为局部变量,以防止做不必要的转换;除非要使用char或short的溢出归零特性,如255+1=0。ppt课件开发高效程序的技巧2)ARM编程中函数参数的传递4寄存器原则(four-registerrule):

ARM-Thumb过程调用标准(ATPCS)定义了{R0-R3}四个寄存器作为参数传递和结果返回寄存器,如果参数超过4个,则使用堆栈进行传递(额外的指令和慢速的存储器操作)。因为内部寄存器的访问速度要远远大于存储器,所以我们应尽量把函数的参数控制在4个以下。ppt课件开发高效程序的技巧….参数6参数5参数4参数3参数2参数1参数0r3

r2

r1

r0…

sp+8

sp+4

sp返回值图:ATPCS参数传递ppt课件开发高效程序的技巧3)结构体安排举例,对下面两个结构体进行比较

structA{

chara;

intb;

charc;

shortd;

}

structB{

chara;

charc;

shortd;

intb;

}padpadpada[7,0]b[31,24]b[23,16]b[15,8]b[7,0]d[15,8]d[7,0]padc[7,0]d[15,8]d[7,0]c[7,0]a[7,0]b[31,24]b[23,16]b[15,8]b[7,0]ppt课件开发高效程序的技巧4)C语言中的封装思想举例,给出这样一个人机界面:打印速度

-100+液晶显示屏按键要求:以中间的按键切换液晶显示菜单,左右两个按键对当前项的值进行增减操作。ppt课件开发高效程序的技巧我曾经这样做:

voidonLeftKey()

{

switch(currentFocus){

caseMENU1:

menu1onLeft();

break;

caseMENU2:

menu2onLeft();

break;

….

}

}

voidonMidKey()

{

currentFocus++;

switch(currentFocus){

caseMENU1:

MenuText=“….”;

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论