欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > PPT文档下载  

    第3章 C语言程序设计基础ppt课件.ppt

    • 资源ID:2133297       资源大小:2.50MB        全文页数:145页
    • 资源格式: PPT        下载积分:16金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要16金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    第3章 C语言程序设计基础ppt课件.ppt

    退出,嵌入式单片机原理及应用,电气工程学院仪器科学与工程系,1 ARM嵌入式系统概述2 STM32单片机结构和最小系统 3 基于标准外设库的C语言程序设计基础 4 STM32通用输入输出GPIO5 STM32外部中断6 STM32通用定时器7 STM32通用同步/异步收发器USART8 直接存储器存取DMA9 STM32的模数转换器ADC10 STM32的集成电路总线I2C11 STM32的串行外设接口SPI,第3章 基于标准外设库的C语言程序设计基础,3.1 嵌入式C语言基础文件结构、程序版式、C语言知识精编3.2 CMSISCortex-M3微控制器软件接口标准CMSIS概述、STM32F10 x标准外设库3.3 基于MDK的STM32开发,退出,C语言的特点,1、语言简单、紧凑、灵活。(32个关键字,9种控制语句)2、运算符丰富(34种表达式)3、数据结构丰富4、具有结构化的控制语句5、目标代码质量高,程序执行效率高。6、可移值性好7、兼有低级语言和高级语言的特点,3.1 嵌入式C语言基础,3.1 嵌入式C语言基础,每个C程序通常分为两个文件,一个文件用于保存程序的声明,称为头文件,以“.h”为后缀。另一个文件用于保存程序的实现,称为源文件,以“.c”为后缀。如果一个工程中头文件数目较多,通常将头文件和源文件分别保存在不同的目录以便于维护。例如可以将头文件保存于inc目录,源文件保存于src目录。,退出,版权和版本声明,/*Copyright(c)2014,燕山大学电气工程学院*All rights reserved.*文件名称:filename.h*摘 要:简要描述本文件的内容*当前版本:1.1*作 者:输入作者(或修改者)名字*完成日期:2014年7月20日*取代版本:1.0*原作者:输入原作者(或修改者)名字*完成日期:2014年1月10日*/,头文件结构头文件版权和版本声明、预处理块和函数声明,源文件结构源文件版权和版本声明、头文件的引用和程序的实现体,简单的C程序介绍,例1:最简单的程序#include/包含头文件 int main(void)/*主函数*/printf(“this is a c program!n”);/*输出了一句话*/,例2 求两个数之和,#include/包含头文件 int main(void)/*主函数*/int a,b,sum;/*定义变量*/a=100;b=200;/*给变量赋值*/sum=a+b/*求a与b的和*/printf(“sum=%dn”,sum);/*输出结果*/,scanf(“%d%d”,例3 求两个数中的最大数,#include/包含头文件int max(int x,int y);/*定义max函数,函数值为整型,x,y为型参,整型*/int z;/*函数内用到内部变量z,也要加以定义*/if(xy)z=x;/*比较x,y的大小,如果x大于y,则执行z=x*/else z=y;/*否则执行z=y*/return(z);/*将z的值返回,通过max带回调用处*/int main(void)/*主函数*/int a,b,c;/*定义变量*/scanf(“%d%d”,/*输出c的值*/,C程序的结构特点和书写格式,1、函数是组成C程序的基本结构2、一个函数由两部分组成:函数说明部分函数体函数体:说明部分 执行部分 3、一个程序总是从main函数开始执行4、语句以分号;结束5、书写格式自由6、用/*/做注释,字符集,什么是字符集在C语言程序中允许出现的所有基本字符的组合称为C语言的字符集。字符集分类(1)大小写英文字母(52个)(2)数字符号(10个)(3)键盘符号(33个)(4)转义字符,标识符,什么是标识符标识符是用户自定义的一种字符序列,通常用来表示程序中需要辨认的对象名称。标识符的命名规则标识符是由字母或下划线开头的字母、数字、下划线组成的一串符号;保留字不能作为标识符。“_”可以作为标识符的第一个字母,但是往往用于库代码正确标识符:sum i a2 a_2 _a2 _a_2错误的标识符:2a a?c.g a-2 if while,C语言的数据类型,数据是操作的对象,数据类型是指数据的内在表现形式(代码、存储、运算)C语言程序的数据类型如下:,退出,C语言的数据类型,常量,什么是常量又称为字面量,表述常数常量类型整型常量实型常量字符常量字符串常量,常量和变量,一、常量和符号常量1、常量:在程序运行过程中,其值不能被改变的量常量区分为不同类型(表现形式)如:12、3.2、a,二、变量1、变量:其值是可以改变的量,它用标识符(变量名)来表示,在内存中占据一定的存储单元。2、变量的定义方法类型符标识符3、注意:1.见字知意2.先定义后使用3.习惯:符号常量大写,变量名小写,如:int a,b,max;char c1,c2,s;float x,y,z;double i,j;,变量,变量数据类型,变量存储类型,变量的定义和初始化,变量的初始化变量在定义时就要初始化变量赋初值的语句格式存储类型符 数据类型符 变量名=初值;,结构型的定义,定义语句struct 结构名称 数据类型1 成员1名;数据类型2 成员2名;.数据类型n 成员n名;结构的本质是不同类型元素的集合,结构型变量的定义和引用,结构型变量的定义方法:先定义结构型、后定义变量struct student int id;char name20;int age;struct student x,y;,结构型变量成员的引用,引用方法结构型变量成员的引用方法引用格式:结构型变量名.成员名结构型变量成员地址的引用方法引用格式:&结构型变量名.成员名结构型变量地址的引用方法引用格式:&结构型变量名,指向结构型数据的指针变量的定义和引用,指向结构型变量的指针定义方法:同结构型变量的定义方法,区别在于定义时变量名前面加。引用方法方法1:(指针变量).成员名方法2:指针变量成员名,C语言中的运算符,运算符,什么是运算符用来表示各种运算的符号称为运算符。运算符特点运算符必须有运算对象,运算对象都有规定的数据类型,同时运算结果也有确定的数据类型。每个运算符都有自己特定的运算规则。当表达式中出现多个运算符时则必须考虑运算符的优先级。同级别的运算符还规定了结合性。,算术运算符,增1、减1运算符,有哪些运算符号j=i+;相当于 j=i;i=i+1;j=+i;相当于 i=i+1;j=i;,关系运算符,关系运算符要点,关系运算符可以用来比较两个数值型数据的大小,也可以比较两个字符型数据的大小。关系运算符的运算结果是逻辑值,若为“真”用整数1表示,若为“假”用整数0表示。,逻辑运算符,逻辑运算符的特点,逻辑运算符运算对象是数值型或字符型等;如果是非0表示逻辑真,0表示逻辑假。运算结果是逻辑值,如运算结果为真用1表示,若为假则用0表示。,用“&”对两个表达式进行计算时,若第1个表达式的值为“假”,则与第2个表达式的值无关,结果肯定为“假”,所以C语言规定此时第2个表达式不再计算用“|”对两个表达式进行计算时,若第1个表达式的值为“真”,则与第2个表达式的值无关,结果肯定为“真”,所以C语言规定此时第2个表达式不再计算,赋值运算符和赋值表达式,一、赋值运算符“=”用法:变量=表达式作用:将表达式的值赋给变量如:a=5;ave=(a+b)/10;二、赋值结果和类型转换1、实型数据(包括单、双精度)赋给整型变量时,舍弃实数的小数部分。2、整型数据赋给单、双精度变量时,数值不变,但以浮点数形式存储到变量中,#include“stdio.h”void main()int i;float f;i=1.23;f=45;printf(“%d%fn”,i,f);,结果:i=1 f=45.000000,逗号运算符和逗号表达式,形式:表达式1,表达式2,表达式n作用:用于连接表达式,如:3+5,6-5计算过程:1、求解表达式12、再求解表达式2,表达式n3、整个逗号表达式的值是表达式n的值.一个逗号表达式又可以与另一个表达式组成一个新的逗号表达式。,如:(a=3*5,a*4),a+5 x=a=3,6*a,注意:并不是任何地方出现的逗号都是逗号运算符 如:printf(“%d,%dn”,a,b),条件运算符,该运算符是三目运算符,其三个运算对象是表达式(e1?e2:e3);运算规则是如果e1表达式为“真”,取e2表达式的值,否则取e3表达式的值。,位运算符,什么是位运算是一种对运算对象按二进制位进行操作的运算。位运算的特点位运算不允许只操作其中的某一位,而是对整个数据按二进制位进行运算;位运算的对象只能是整型数据(包括字符型),运算结果仍是整型数据位运算符分为位逻辑运算符、位移位运算符、位自反赋值运算符三种,位运算符,位移位运算符,位运算符,按位与,表达式,什么是表达式用运算符将运算对象连接形成的式子就是表达式。表达式的特点每个表达式都可以按照其中运算符的优先级和运算规则依次对运算对象进行运算,最终获得一个数据,该数据称为表达式的值。表达式值的数据类型就称为表达式的数据类型。表达式的分类主要有六种:算术表达式、关系表达式、逻辑表达式、条件表达式、赋值表达式和逗号表达式。,表达式类型转换方法,表达式计算中数据类型的自动转换原则特点:参加运算的各个数据都转换成数据长度最长的数据类型,然后计算。计算结果值当然就是数据长度最长的数据类型例如:设i为int,f为float,d为double,e为long则10+a+i*f-d/e的结果是double。运算结果存入变量时数据类型的自动转换原则特点:先将运算结果的数据类型自动转换成变量的数据类型,然后再赋予该变量,不同类型数据间的混合运算,整型、实型(包括单、双精度)、字符型数据间可以混合运算。如:10+a+12.3-4.56*x是合法的运算时,不同类型的数据要先转换成同一类型,然后进行运算。转换规则如下:,float,double,long,unsigned,int,char,short,高,低,float型数据在运算时一律先转换成double型,不同类型进行混合运算时,按照类型级别由低到高的顺序转换,字符型和short型在运算时一律转换成int型,结构程序设计,退出,在C语言中,分支结构主要是利用if语句来实现的,if语句是对给定的条件进行判断,然后决定执行某个分支。C语言的if语句有3种形式:if语句if else语句else if语句,分支结构程序设计,If语句,条件执行一般形式为:If(表达式)语句含义:如果表达式的值为真,则执行其后的语句;否则不执行该语句。,语句,表达式,真(非0),假(0),If(x0)printf(“hello!”);,例:输入两个数,输出其中较大的数,Main()int a,b,max;printf(“n input two numbers:”);scanf(“%d%d”,if-else语句,分支选择一般形式为:if(表达式)语句A;else语句B;含义:如果表达式的值为真,则执行语句A;否则执行语句B.,表达式,语句A,语句B,真(非0),假(0),注意:在C语言中,表达式e的值为非0时,系统均按“真值“处理。如:if(a)printf(“OK”);x=-5;if(x)printf(“OK”);y=0;if(y=0)printf(“OK”);,例:输入3个整数,输出最大数最小数,main()int a,b,c,max,min;printf(“input three numbers:”);scanf(“%d%d%d”,else-if语句,前面两种形式的if语句一般都用于两个分支情况。在实际程序设计时经常需要进行多分支处理,C语言中进行多分支处理时,可采用else-if语句实现。阶梯式的if语句一般形式 if(表达式1)语句1;else if(表达式2)语句2;else if(表达式3)语句3;else if(表达式m)语句m;else语句m+1;含义:依次判断各个表达式的值,当出现某个值为真时,则执行其对应的语句,然后跳出else-if结构。如果所有的表达式的值均为假,则执行语句m+1,然后执行后续程序。,语句1,真,例:根据键盘输入字符的类型输出相应的信息,#include main()char c;printf(input a character:);c=getchar();if(c=0,if语句的嵌套,当if语句中的执行语句同时也是if语句时,则构成了if语句嵌套的情形。一般形式:if(表达式)if语句;或者为if(表达式)if语句;elseif语句;在嵌套if语句里特别要注意的是if和else的配对问题。,例:比较两个数的大小关系并输出相应的信息,main()int a,b;printf(“please input A,B:”);scanf(“%d%d”,条件运算符,如果if语句中,无论表达式的值是“真”还是“假”,均只执行单个的赋值语句,且给同一个变量赋值时,常使用条件表达式来实现。如:if(ab)max=a;else max=b;可以采用条件运算符实现:max=(ab)?a:b;,条件运算符是一个3目运算符,即有3个参与运算的量。由条件运算符组成的表达式称为条件表达式:表达式1?表达式2:表达式3使用条件表达式时,还应注意以下几点:(1)条件运算符的运算优先级低于关系运算符和算术运算符,但高于赋值运算符。(2)条件运算符?和:是一对运算符,不能分开单独使用。(3)条件运算符的结合方向是自右至左。如:ab?a:cd?c:d,例:比较两个数的大小并输出较大值,main()int a,b;printf(“n input two numbers:”);scanf(“%d%d”,switch-case语句,在实际中经常需要处理多分支问题,如统计学生成绩分布等,虽然可以用else-if和嵌套if语句来实现多分支程序设计,但是当分支较多时,程序变得冗长且可读性低。在C语言中提供了直接处理多分支的方法:switch-case语句。,一、格式:switch(表达式)case常量表达式1:语句1;case常量表达式2:语句2;case常量表达式n:语句n;default:语句n+1;,二、执行过程1.计算表达式的值2.若与常量表达式n值一致,则从该语句开始执行;直到遇到break语句或switch语句的3、若与任何常量表达式值均不一致时,则执行default语句或执行后续语句,其中:表达式可以是整型、字符型、枚举型常量表达式必须与表达式类型一致(整型与字符型通用)常量表达式中的数据仅起语句标号作用,不作求值判断常量表达式的值必须是唯一的,没有先后顺序多个case语句可以共用一组执行语句,循环结构程序设计,内容提要:循环就是在满足一定条件时重复执行一段程序概述构成循环的语句while、do-while、for、if-goto循环结构的比较break语句和continue语句,While语句,用while语句实现循环while语句的一般形式:while(表达式)语句;,当表达式的值为真(非0)时,执行其中的内嵌语句(循环体),然后回过头来再判断表达式的值,如此重复;当表达式为假(0)时结束循环。,while语句的一般形式:while(表达式)语句;如:k=1;while(k=100)s+=k;k+;,循环控制表达式,循环控制变量,循环体,注意:若循环体包含一条以上的语句,应以复合语句形式出现 循环体,必须给循环控制变量赋值 循环体中,必须有改变循环控制变量值的语句(使循环趋向结束的语句)循环体可以为空如:while(c=getchar()!=A);等价:c=getchar();while(c!=A)c=getchar();,do-while循环,do-while语句用来实现“直到型”循环,它的一般形式为:,do语句While(表达式);,不可以省略切记切记!,语句,表达式,下一语句,假,真,NS图,注意点与while相同,for循环,for循环的一般形式:for(表达式1;表达式2;表达式3)语句,求解表达式1,表达式2,语句,求解表达式3,下一语句,假,真,表达式1在进入循环之前求解(循环变量赋初值)表达式3是循环体的一部分,for循环的其他形式:for(;表达式2;)语句表达式3;,表达式1,表达式1;,表达式3,表达式2为空值永远为真成为死循环,变量赋初值,这个分号不能移走,相当于循环体的一部分可以移到语句后面来,说明,1、表达式1省略时,应在for前给循环变量赋初值。如:k=1;for(;k=3;k+)s+=k;2、表达式2省略时,不判断循环条件,将成为“死循环”,需要在循环体内引入break语句以退出循环3、表达式3省略时,循环体内应有使循环条件改变的语句如:for(k=1;k=3;)s+=k;k+;4、同时省略表达式1和表达式3,只有表达式2,此时相当于while语句。如:k=1;k=1;for(;k=3;)while(k=3)s+=k;k+s+=k;k+,5、表达式2一般是关系表达式或逻辑表达式,但也可以是数值表达式或字符表达式,只要其值不等于0就执行循环体如:for(k=1;k-4;k+)s+=k;仅当k的值等于4的时候终止循环。k-4是数值表达式。,求100以内的奇数、偶数之和,循环的嵌套,一个循环体内包含着另一个完整的循环结构,就称为循环嵌套内嵌的循环中又可以嵌套循环,从而构成多重循环。三种循环可以互相嵌套下面给出几种合法的嵌套形式:(1)while嵌套while(2)do-while嵌套do-whilewhile()dowhile()dowhile();while();,(3)for嵌套for(4)while嵌套do-whilefor(;)while()for(;)do while();(5)for嵌套while(6)do-while嵌套forfor(;)do while()for;while();,循环嵌套的说明,嵌套的循环控制变量不能相同内循环变化快,外循环变化慢正确确定循环体循环控制变量常与求解的问题挂钩,有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?,main()int i,j,k;printf(n);for(i=1;i5;i+)/*以下为三重循环*/for(j=1;j5;j+)for(k=1;k5;k+)if(i!=k,几种循环的比较,关于循环的控制,循环控制条件,修改循环条件,循环条件初始化,break语句和continue语句,一、break语句用break语句可以结束switch结构和三种循环、,for(n=1;n1000)break;printf(“%f”,n);,二、continue语句用continue语句可以结束本次循环,既忽略循环体中剩余语句。如:把100200之间不能被3整除的数输出,本次循环结束循环体的剩余语句被忽略执行表达式3,进入下一循环continue总是作if的内嵌语句,通用转移语句goto语句,Goto语句随意跳转到任意位置Goto语句一般配合标号语句使用Goto语句容易导致代码混乱精心设计的goto语句可以带来代码的高效Goto语句在嵌入式编程中用的很多,3.1.3 C语言知识精编 关键词,退出,3.1.3 C语言知识精编 预处理,退出,“预处理”是指在对C语言源程序进行编译之前,要先对程序中的“宏定义、文件包含、条件编译”等特殊命令进行预先处理。宏定义:定义一个标识符来表示一个字符串,称为“宏定义”,该标识符称为“宏名”。在编译预处理时,对程序中所有出现的“宏名”的地方都用字符串去代换。宏定义分类:分为有参数宏定义和无参数宏定义两种。,宏的定义不带参数的宏定义宏定义的一般格式为:#define 文本串/*#define就是宏定义命令*/功能:将宏名的值定义为指定的文本串。在预处理时凡出现宏名的地方,都用指定的文本串替换。在预处理时将宏名替换成指定的文本串的过程称为“宏展开”,或称为“宏替换”。,【例】求圆周长、面积和相同半径圆球体积。#define PI 3.14159void main()float r,l,s,v;printf(“input radius:”);scanf(“%f”,程序运行结果:input radius:6l=37.70s=113.10v=508.94,注意:(1)宏名为了与变量名区别一般用大写字母表示。(2)宏展开时只用文本串替换宏名,不作正确性检查。(3)宏定义行末尾不能加分号。加分号,宏展时会当作文 本串字符一同代入。(4)宏名的有效范围是:从定义位置开始到本文件结束(5)可以用#undef命令终止宏定义的作用域。(6)在宏定义时,可以引用已定义的宏名。,【例】在宏定义时引用已定义的宏名#define R 4.0#define PI 3.14159#define L 2*PI*R#define S PI*R*Rvoid main()printf(“L=%6.2fnS=%6.2fn”,L,S);,运行结果如下:L=25.13S=50.27,带参数的宏定义带参数的宏定义格式如下:#define(参数表)文本串功能:定义一个带参数的宏。例如:#define S(x,y)3*x+2*yarea=S(3,2);宏展开:用实参从左到右逐个字符进行替换文本串中的形参字符。如图所示。执行:area=S(3,2)宏展开后变成:area=3*3+2*2;,【例】求圆的面积。#define PI 3.14159#define S(r)PI*r*r void main()float a,area;a=3.6;area=S(a);printf(“area=%6.2fn”,area);,运行结果:area=40.72,说明:(1)宏名与括弧之间不能有空格。(2)宏调用时,实参的个数必须与形参的个数相同。(3)带参数的宏替换时不作语法检查。(4)宏定义时最好在参数两侧加括号和整个字符串外加括号,防止宏替换出错。,【例】分析以下程序运行结果#define SQ(y)(y)*(y)void main()int a,sq;printf(input a number:);scanf(%d,比较下面【例6】和【例7】程序的不同之处。,【例6】#define SQ(y)y*yvoid main()int a,sq;printf(input a number:);scanf(%d,运行结果为:input a number:3sq=7/*宏代换后得到:sq=a+1*a+1;*/,【例7】#define SQ(y)(y)*(y)void main()int a,sq;printf(input a number:);scanf(%d,*/,宏调用和函数调用的主要区别:,文件包含:就是将指定文件全部内容包含(装入)到本文件中来。一般格式:#include“文件名”或#include功能:将指定的源文件全部内容包含进来,即装入#include命令所处位置上使其成为一个程序。,2 文件包含,对文件包含命令还要说明以下几点:1.指定文件名可以用双引号或尖括号括起来。例如:#includestdio.h#include二者的区别:用尖括弧时,直接在库函数头文件目录中查找包含文件,称为标准方式;用双引号时,在用户当前目录中寻找包含的文件,若找不到,再按标准方式查找。一般情况下:包含库函数用尖括弧节省时间;包含用户自己编写的文件用双引号。2.一个#include命令只能指定一个被包含文件。3.文件包含允许嵌套,即在一个被包含的文件中又可以包含另一个文件。,功能:一个源文件可将另一个源文件的内容全部包含进来一般形式:#include“文件名”或#include,处理过程:预编译时,用被包含文件的内容取代该预处理命令,再对“包含”后的文件作一个源文件编译,直接按标准目录搜索“”先在当前目录搜索,再搜索标准目录可指定路径,文件包含,源文件(*.c)头文件(*.h),宏定义数据结构定义函数说明等,文件包含可嵌套,被包含文件内容,例 文件包含举例,【例8】给定半径,计算圆的周长和圆的面积。设计三个包含文件,或称为头文件:第1个为:myin1.h#include#define PI 3.14159第2个为:myin2.hfloat getlen(float r)return 2*getsr(r)/r;第3个为:myin3.hfloat getsr(float r)return PI*r*r;,主函数的程序如下:#include“myin1.h”#include“myin3.h”#include“myin2.h”void main()float x=3.0;printf(“L=%fn”,getlen(x);printf(“S=%fn”,getsr(x);,因为:函数的调用关系,头文件的包含顺序应该必须是:myin1.h,然后myin3.h,最后是myin2.h。,一般情况下,对源程序进行全部编译。条件编译:根据具体条件和需要只编译源程序中的某些部分为条件编译。条件编译用途:可以用源程序产生不同版本。,3 条件编译,1条件编译的三种形式:形式一:#ifdef 标识符 程序段1#else 程序段2#endif功能:标识符已被#define命令定义过则对程序段1进行编译;否则对程序段2进行编译。,形式二:#ifndef 标识符 程序段1#else 程序段2#endif功能:如果标识符未被#define命令定义过则对程序段1进行编译,否则对程序段2进行编译。,形式三:#if 常量表达式 程序段1#else 程序段2#endif功能是,如常量表达式的值为真(非0),则对程序段1 进行编译,否则对程序段2进行编译。,#include#define LETTER 1int main()char str=C language;char c;int i;for(i=0;stri!=0;i+)c=stri;#if LETTER if(c=a,运行结果:C LANGUAGE 上题如果将第一行改为:#define LETTER 0则在预处理时,对第二个IF语句处理,使大写变为小写。,1、变量是对程序中数据存储空间(地址和值)的抽象 int num=100;printf(“num is%d,num addr is%pn”,num,3、问题是,怎么通过addr间接获取该地址内保存的值(100)?,变量与地址,指针,1、C定义了一种专门用于表示地址的变量指针 int*addr;/定义指针变量2、将内存中数据的地址赋值给指针变量:表示将指针指向该数据 addr=,指针的由来,用好指针可以:使程序简洁、紧凑、高效有效地表示复杂的数据结构动态分配内存得到多于一个的函数返回值直接操作地址造就了C/C+的强大用不好指针造成:非法内存访问,程序死机或异常内存泄露,减低系统性能指针属于间接访问,指来指去最终变得不可维护,指针是把双刃剑,指针的定义,实例:int*pi;char*pc;double*pd;info_t*pinfo;static int*pi;static char*pc;static info_t*pinfo;关键概念:1、指针类型与指针指向对象类型2、指针的值与指针指向对象的值,指针内存大小,指针变量用来表示内存地址,32位CPU上用4byte空间表示地址int*pi;char*pc;double*pd;info_t*pinfo;sizeof(pi)=?sizeof(pc)=?sizeof(pd)=?sizeof(pinfo)=?,指针初始化与赋值,1、初始化为指向对象的地址 int num=100;int*paddr=,指针运算,1、取值运算符 int num=100;int*paddr=*paddr=?paddr+1=?*(int*)paddr=?(int*)paddr+1=?,通用(void)指针,指针变量的类型表示指针所指向对象的类型能不能定义一种通用指针,将来根据需要再指向特定对象?void*point=NULL;/void指针,定义不指定指针指向哪种类型数据sizeof(point)=?point+?point-?使用时需要进行强制类型转换:int num=100;char ch=a;void*point=NULL;point=,数组与指针,1、数组与指针的关系数组名表示数组首地址,可以把数组名看作指针常量 int arr3=1,2,3;int*p=arr;p+?arr+?*p=?*(p+1)=?*(p+2)=?数组下标操作符内部实现机制:通过指针取值运算符实现 arr2 相当于*(arr+2)数组作为函数参数,实际是转化为指针实现str_cpy(char src,char des)=str_cpy(char*src,char*des)数组作为函数返回值,必须通过指针实现char*str_cpy(char*src,char*des),数组与指针,2、指针数组:即数组的元素为指针类型。int*var10;/10个int型指针的数组 sizeof(var)=?var+1?3、数组指针:即指针的类型为数组(指向数组的指针)。char(*var)10;/指向10个int型数组的指针 sizeof(var)=?var+1?4、字符串与指针字符串是属于典型的字符数组,因而通常通过char型指针处理字符串,数组与指针,将字符串直接赋值给指针,表示指针指向字符串内存首地址注意:字符串常量内存分配在只读数据区(RODATA)实例:char*p=“xnf”;char arr=“xnf”;*p?*p+?*+p?*p=X?arr0=X?strcpy(p,“XNF”)?strcpy(arr,“XNF”)?,数组与指针,通过指针数组表示字符串数组char a16=“welcome”,“to”,“xnf”;主函数参数就是通过指针数组实现的:int main(int argc,char*argv),结构与指针,1、结构包含指针:结构体中包含指针域变量 如:学生信息中name与phone定义为指针 注意:在程序中动态修改学生信息表中的 name和phone域可行么?,结构与指针,2、指向结构体的指针 结构体变量域通过.访问,而结构体指针域通过-访问 sizeof(info)=?sizeof(p)=?,_,结构与指针,通过结构体指针传递参数比直接传递结构体变量更高效 实参传递给形参时只拷贝了4个字节,指针的指针,1、指向指针变量的指针 int i=100;int*p=实现指针二级访问:,函数与指针,1、指针作为函数的参数向函数传递数组、字符串、结构:如strc_py、show_info作为函数的输出参数例如:实现交换两个整数的函数 void swap(int a,int b)传值,形参值改变并不能带回给实参 传址,在函数内改变地址内保存的内容,3.2 Cortex-M3微控制器软件接口标准,什么是CMSIS,微控制器软件接口标准,即(Cortex Microcontroller Software Interface Standard,CMSIS),为什么推出CMSIS,一个ARM内核会授权给多个厂家,生产种类繁多的产品,开发者增加了软件开发成本将所有Cortex芯片厂商产品的软件接口标准化,制定了CMSIS标准。芯片厂商就能够将他们的资源专注于产品外设特性的差异化,从而达到降低开发成本的目的。,3.2 Cortex-M3微控制器软件接口标准,CMSIS软件架构,3.2 Cortex-M3微控制器软件接口标准,CMSIS层由三部分构成,(1)核内外设访问层(CPAL,Core Peripheral Access Layer):该层由ARM 负责实现。包括对寄存器名称、地址的定义,对核寄存器、NVIC、调试子系统的访问接口定义以及对特殊用途寄存器的访问接口(例如:CONTROL,xPSR)定义。(2)片上外设访问层(DPAL,Device Peripheral Access Layer):该层由芯片厂商负责实现。该层的实现与CPAL 类似,负责对硬件寄存器地址以及外设访问接口进行定义。该层可调用CPAL 层提供的接口函数同时根据设备特性对异常向量表进行扩展,以处理相应外设的中断请求。(3)外设访问函数(AFP,Access Functions for Peripherals):该层也由芯片厂商负责实现,主要是提供访问片上外设的访问函数,这一部分是可选的。,概述,STM32标准外设库之前的版本也称固件函数库或简称固件库,是一个固件函数包,它由程序、数据结构和宏组成,包括了微控制器所有外设的性能特征。每个外设驱动都由一组函数组成,这组函数覆盖了该外设所有功能。每个器件的开发都由一个通用API(application programming interface 应用编程界面)驱动,API对该驱动程序的结构,函数和参数名称都进行了标准化。ST公司2007年10月发布了V1.0版本的固件库,MDK ARM3.22之前的版本均支持该库。2008年6月发布了V2.0版的固件库,从2008年9月推出的MDK ARM3.23版本至今均使用V2.0版本的固件库。V3.0以后的版本相对之前的版本改动较大,本书使用目前较新的V3.4版本。,STM32F10 x标准外设库,概述,STM32标准外设库之前的版本也称固件函数库或简称固件库,是一个固件函数包,它由程序、数据结构和宏组成,包括了微控制器所有外设的性能特征。每个外设驱动都由一组函数组成,这组函数覆盖了该外设所有功能。每个器件的开发都由一个通用API(application programming interface 应用编程界面)驱动,API对该驱动程序的结构,函数和参数名称都进行了标准化。ST公司2007年10月发布了V1.0版本的固件库,MDK ARM3.22之前的版本均支持该库。2008年6月发布了V2.0版的固件库,从2008年9月推出的MDK ARM3.23版本至今均使用V2.0版本的固件库。V3.0以后的版本相对之前的版本改动较大,本书使用目前较新的V3.4版本。,STM32F10 x标准外设库,STM32F10 x标准外设库,标准外设库中包含了众多的变量定义和功能函数,如果不能了解他们的命名规范和使用规律将会给编程带来很大的麻烦,命名规则,标准外设库遵从以下命名规则 PPP表示任一外设缩写,例如:ADC。源程序文件和头文件命名都以“stm32f10 x_”作为开头,例如:stm32f10 x_conf.h。常量仅被应用于一个文件的,定义于该文件中;被应用于多个文件的,在对应头文件中定义。所有常量都由英文字母大写书写。寄存器作为常量处理。他们的命名都由英文字母大写书写。在大多数情况下,他们采用与缩写规范一致。外设函数的命名以该外设的缩写加下划线为开头。每个单词的第一个字母都由英文字母大写书写,例如:SPI_SendData。在函数名中,只允许存在一个下划线,用以分隔外设缩写和函数名的其它部分。,STM32F10 x标准外设库,命名规则,名为PPP_Init的函数,其功能是根据PPP_InitTypeDef中指定的参数,初始化外设PPP,例如TIM_Init.名为PPP_DeInit的函数,其功能为复位外设PPP的所有寄存器至缺省值,例如TIM_DeInit.名为PPP_Init的函数,其功能为通过设置PPP_InitTypeDef 结构中的各种参数来定义外设的功能,例如:USART_Init.名为PPP_Cmd的函数,其功能为使能或者失能外设PPP,例如:SPI_Cmd.名为PPP_ITConfig的函数,其功能为使能或者失能来自外设PPP某中断源,例如:RCC_ITConfig.名为PPP_DMAConfig的函数,其功能为使能或者失能外设PPP的DMA接口,例如:TIM1_DMAConfig.,STM32F10 x标准外设库,命名规则,用以配置外设功能的函数,总是以字符串“Config”结尾,例如GPIO_PinRemapConfig.名为PPP_GetFlagStat

    注意事项

    本文(第3章 C语言程序设计基础ppt课件.ppt)为本站会员(小飞机)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开