编译预处理与位运算.ppt

上传人:wuy****n92 文档编号:73987238 上传时间:2023-02-23 格式:PPT 页数:64 大小:1.16MB
返回 下载 相关 举报
编译预处理与位运算.ppt_第1页
第1页 / 共64页
编译预处理与位运算.ppt_第2页
第2页 / 共64页
点击查看更多>>
资源描述

《编译预处理与位运算.ppt》由会员分享,可在线阅读,更多相关《编译预处理与位运算.ppt(64页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、嵌入式嵌入式C语言高级编程篇语言高级编程篇课程目标课程目标了解嵌入式了解嵌入式C语言编程特点和操作细节语言编程特点和操作细节结合嵌入式环境深入理解指针、数组和函数结合嵌入式环境深入理解指针、数组和函数提高编程实践和编程程序规范理解提高编程实践和编程程序规范理解熟悉熟悉C语言标准库应用和特点语言标准库应用和特点课程结构图课程结构图基础知识C语言深入程序规范嵌入式编程熟悉宏定义、嵌熟悉宏定义、嵌入式位操作,初入式位操作,初步理解数据结构,步理解数据结构,同时进一步讲述同时进一步讲述C C编程特点、调试编程特点、调试和解错和解错(第(第1 13 3章)章)详细讲述详细讲述C C语言函语言函数库特点和

2、主要用数库特点和主要用法,以及深入讲述法,以及深入讲述C C语言数组和指针语言数组和指针特点和用途特点和用途(第(第4 45 5章)章)了解了解C C语言高级编程语言高级编程规范,提高程序编规范,提高程序编程健壮行程健壮行(第(第6 6章)章)熟悉嵌入式编程特熟悉嵌入式编程特点,了解嵌入式编点,了解嵌入式编程的主要操作细节程的主要操作细节和调试和调试(第(第7 78 8章)章)编译预处理与位运算编译预处理与位运算编译预处理与位运算编译预处理与位运算编译预处理与位运算编译预处理与位运算 第第第第1 1 1 1章章章章本章目标本章目标本章概述本章概述讲述宏定义的标准用法和位操作的基本应用了解预编译

3、的概念,掌握宏定义的方法。了解“文件包含”与预处理的应用。了解条件编译的几种形式。掌握各种位运算符,运算规则和优先级。了解位运算的实际应用。了解位段的定义和应用。本章目标本章目标了解一些C语言特殊的宏定义熟悉位运算的基本操作重点重点 宏定义操作本章结构本章结构编译预处理编译预处理和位运算编译预处理和位运算位段文件包含宏定义条件编译位运算预处理其他关键词1 编译预处理与位运算编译预处理宏定义文件包含条件编译位运算位段其他预处理关键字1.1编译预处理编译预处理 作用:对源程序编译之前做一些处理,生成扩展C源程序种类宏定义#define#ifdef#ifndef文件包含#include条件编译#if

4、-#else-#endif等其他宏定义#line#error#pragma格式:“#”开头占单独书写行语句尾不加分号1.2 宏定义宏定义 undef无参数宏定义有参数宏定义1.2.1 undef undef定义指令删除前面定义的宏名字。表达一般形式为:#undefmacro-name例子defineMICRO1undefMICRO1.2.2 无参数宏定义无参数宏定义如if(x=YES)printf(“correct!n”);elseif(x=NO)printf(“error!n”);展开后:if(x=1)printf(“correct!n”);elseif(x=0)printf(“error!

5、n”);不带参数宏定义一般形式:#define宏名宏体功能:用指定标识符(宏名)代替字符序列(宏体)如#defineYES1#defineNO0#definePI3.1415926#defineOUTprintf(“Hello,World”);宏体可缺省,表示宏名定义过或取消宏体例#defineMAXMAX+10()例#definePI3.14159printf(“2*PI=%fn”,PI*2);宏展开:printf(“2*PI=%fn”,3.14159*2);例#defineWIDTH80#defineLENGTHWIDTH+40var=LENGTH*2;宏展开:var=80+40*2;()

6、()例#defineWIDTH80#defineLENGTHWIDTH+40var=LENGTH*2;宏展开:var=80+40*2;1.2.2 不带参数宏定义不带参数宏定义宏定义的规则宏名一般习惯用大写字母表示,以便与变量名相区别宏定义不是C语句,不必在行末加分号在进行宏定义时,可以引用已定义的宏名,可以层层替换。只作字符替换,不分配内存空间。#define R 3.0#define PI 3.1415926#define L 2*PI*R#define S PI*R*Rmain()printf(“L=%fnS=%fn”,L,S);结果:结果:L=18.849556 S=28.2743331

7、.2.2 不带参数宏定义不带参数宏定义宏定义的特点宏名一般习惯用大写字母表示提高程序的通用性宏名的有效范围为定义命令之后到本源文件结束可以用#undef命令终止宏定义的作用域宏定义只作简单的替换,不作正确性检查1.2.3 带参数宏定义带参数宏定义一般形式:#define宏名(参数表)宏体例#defineS(r)PI*r*r相当于定义了不带参宏S,代表字符串“(r)PI*r*r”宏展开:形参用实参换,其它字符保留宏体及各形参之间应加空格注意宏体的括号例#define S(a,b)a*b .area=S(3,2);宏展开:area=3*2;不能加空格例#definePOWER(x)x*xx=4;y

8、=6;z=POWER(x+y);宏展开:z=x+y*x+y;一般写成:#definePOWER(x)(x)*(x)宏展开:z=(x+y)*(x+y);1.2.2 带参数宏定义带参数宏定义带参数宏定义的特点带参宏定义中,宏名和形参表之间不能有空格出现例如:#defineMAX(a,b)(ab)?a:b写为:#defineMAX(a,b)(ab)?a:b将被认为是无参宏定义,宏名MAX代表字符串(a,b)(ab)?a:b在带参宏定义中,形式参数不分配内存单元,因此不必作类型定义在宏定义中的形参是标识符,而宏调用中的实参可以是表达式在宏定义中,字符串内的形参通常要用括号括起来以避免出错#define

9、 SQ(y)(y)*(y)main()int a,sq;printf(input a number:);scanf(%d,&a);sq=SQ(a+1);printf(sq=%dn,sq);1.2.2 带参数宏定义带参数宏定义带参的宏和带参函数很相似,但有本质上的不同带参宏函数处理过程不分配内存简单的字符置换分配内存先求实参值,再代入形参处理时间编译时程序运行时参数类型无类型问题定义实参,形参类型程序长度变长不变运行速度不占运行时间调用和返回占时间1.2.2 带参数宏定义带参数宏定义带参的宏和带参函数很相似,但有本质上的不同宏定义例函数例main()int i=1;while(i=5)print

10、f(%dn,SQ(i+);SQ(int y)return(y)*(y);#define SQ(y)(y)*(y)main()int i=1;while(i=5)printf(%dn,SQ(i+);1.3 文件包含文件包含函数例功能:一个源文件可将另一个源文件的内容全部包含进来一般形式:#include“文件名”或#include#include “file2.c”file1.cfile2.cfile1.cfile2.cABA处理过程:预编译时,用被包含文件的内容取代该预处理命令,再对“包含”后的文件作一个源文件编译 直接按标准目录搜索“”先在当前目录搜索,再搜索标准目录1.3 文件包含文件包含

11、被包含文件内容源文件(*.c)头文件(*.h)宏定义数据结构定义函数说明等文件包含可嵌套#include “file2.c”file1.cAfile3.cC#include “file3.c”file2.c Bfile1.cAfile3.cfile2.c1.3 文件包含文件包含例子/*powers.h */#define sqr(x)(x)*(x)#define cube(x)(x)*(x)*(x)#define quad(x)(x)*(x)*(x)*(x)#include#include powers.h#define MAX_POWER 10void main()int n;printf(

12、numbert exp2t exp3t exp4n);printf(-t-t-t-n);for(n=1;n=MAX_POWER;n+)printf(%2dt%3dt%4dt%5dn,n,sqr(n),cube(n),quad(n);1.3 文件包含文件包含文件包含特点一个include命令只能指定一个被包含文件可以用双引号括起来,也可以用尖括号括起来。文件包含允许嵌套被包含文件(file2.h)与其所在的文件(file.c)在预编译之后已成为同一个文件1.4 条件编译条件编译#if、#else、#elif#endif#ifdef和#ifndef1.4.1#if、#else、#elif#endi

13、f 条件编译指令中最常用的或许是#if,#else,#elif和#endif#if的一般形式是:#ifconstant-expressionStatementsequence#endif#endif标记#if块的结束例子:#ifdefCOMPUTER_A#defineINTEGER_SIZE16#else#defineINTEGER_SIZE32#endif1.4.1#if、#else、#elif#endif 条件编译指令中最常用的或许是#if,#else,#elif和#endif#if的一般形式是:#ifconstant-expressionStatementsequence#endif#e

14、ndif标记标记#if块的结束块的结束例子:例子:#ifdefCOMPUTER_A#defineINTEGER_SIZE16#else#defineINTEGER_SIZE32#endif1.4.1#if、#else、#elif#endif#else指令的作用与C语言的else相似,#if指令失败时它可以作为备选指令#else既是标记既是标记#if块的结束,也标记块的结束,也标记#else块的开始块的开始每个#if只能写一个#endif匹配例子:例子:#include#define MAX 100Int main(void)#if MAX99printf(“Compiled for array

15、 greater than 99.n”);#elseprintf(“Complied for small array.n”);#endif return 0;1.4.1#if、#else、#elif#endif#elif指令的意思是“否则,如果”语法格式:语法格式:#if expression#if expressionStatement sequenceStatement sequence#elif expression1#elif expression1Statement sequenceStatement sequence#elif expression2#elif expression

16、2。#elif expression#elif expressionStatement sequenceStatement sequence#endif#endif 1.4.2#ifdef和和#ifndef#ifdef如果已定义#ifdef的一般形式如下:#ifdef标识符程序段1#else程序段2#endif当所指定的标识符已经被#define命令定义过,则在程序编译阶段只编译程序段1,否则编译程序段2。1.4.2#ifdef和和#ifndef#ifndef如果已定义#ifdef的一般形式如下:#ifndef标识符程序段1#else程序段2#endif作用是当所指定的标识符未被#define

17、命令定义过,则在程序编译阶段只编译程序段1,否则编译程序段2。它只是第一行与第一种形式不同。这种形式与第一种形式的作用相反#ifndef1.4.2#ifdef和和#ifndef#ifdef和#ifndef#inlucde#define T 10int main(void)#ifdef t Printf(“Hi Tn”);#else Printf(“Hi anyonen”);#endif#ifndef M Printf(“M Not Definedn”);#endif return 0;1.4.2#ifdef和和#ifndef#if如果已定义#if的一般形式如下:#if常量表达式程序段1#els

18、e程序段2#endif如常量表达式的值为真(非0),则对程序段1进行编译,否则对程序段2进行编译1.4.2#ifdef和和#ifndef#if例子#define R 1main()float c,r,s;printf(input a number:);scanf(%f,&c);#if R r=3.14159*c*c;printf(area of round is:%fn,r);#else s=c*c;printf(area of square is:%fn,s);#endif阶段小节阶段小节宏定义的特点和宏定义的取消带参数宏定义要注意的几个细节条件编译主要应用在那几个方面,它有几种使用方法In

19、clude包含文件的两种方法和他们之间的区别特点1.5 位运算 按位与运算按位或运算按位异或运算求反运算左移运算右移运算1.5 位运算 位运算符的含义位运算符的含义位运算是指进行二进制位的运算。功能:功能:c语言提供对内存单元的二进制位的操作,使得c语言能够编写系统软件.位运算符位运算符&:按位与|:按位或:按位异或 :取反:右移1.5 位运算 要点:要点:位运算除位运算除 以外以外,均为二目运算均为二目运算;运算对象只能为整型或字符型数据运算对象只能为整型或字符型数据.各个位运算符号的使用各个位运算符号的使用:按位与运算 按位与按位与&格式:x&y主要用途:取(或保留)1个数的某(些)位,其

20、余各位置0规则:对应位均为1时才为1,否则为0:3&9=1。例如,3&9=1:0011&10010001=11.5.2 按位或运算 按位或按位或|格式:x|y主要用途:参与运算的两数各对应的二进位相或。只要对应的二个二进位有一个为1时,结果位就为1规则:对应位均为0时才为0,否则为1:3|9=11。例如,3|9=11:0011|10011011=111.5.3 按位异或运算 按位异或按位异或 格式:xy规则:对应位相同时为0,不同时为1:39=10。主要用途:使1个数的某(些)位翻转(即原来为1的位变为0,为0的变为1),其余各位不变例子:000010010000010100001100(十进

21、制为12)求反运算 求反求反 格式:y规则:各位翻转,即原来为1的位变成0,原来为0的位变成1:在IBM-PC机中,00 xffff,9=0 xfff6。主要用途:间接地构造一个数,以增强程序的可移植性1.5.5 左移运算 按位左移 格式:x位数规则:使操作数的各位左移,低位补0,高位溢出:5 格式:x位数规则:使操作数的各位右移,移出的低位舍弃;高位:对无符号数和有符号中的正数,补0;有符号数中的负数,取决于所使用的系统:补0的称为“逻辑右移”,补1的称为“算术右移”。例如,202=5说明x、y和“位数”等操作数,都只能是整型或字符型数据。除按位取反为单目运算符外,其余均为双目运算符。参与运

22、算时,操作数x和y,都必须首先转换成二进制形式,然后再执行相应的按位运算。例如,52=5:1010000101。1.5.6 位运算例子例子例例2 题目:从键盘上输入题目:从键盘上输入1 1个正整数给个正整数给intint变量变量numnum,输出由,输出由8 81111位构成的数(从低位、位构成的数(从低位、0 0号开始编号)号开始编号)基本思路:基本思路:(1 1)使变量)使变量numnum右移右移8 8位,将位,将8 81111位移到低位移到低4 4位上。位上。(2 2)构造)构造1 1个低个低4 4位为位为1 1、其余各位为、其余各位为0 0的整数。的整数。(3 3)与)与numnum进

23、行按位与运算。进行按位与运算。/*/*程序功能:输出一个整数中由程序功能:输出一个整数中由8 81111位构成的数位构成的数*/main()int num,mask;printf(Input a integer number:);scanf(%d,&num);num=8;/*右移右移8位,将位,将811位移到低位移到低4位上位上*/mask=(0 4);/*间接构造间接构造1个低个低4位为位为1、其余各位为、其余各位为0的整数的整数*/printf(result=0 x%xn,num&mask);程序运行情况:Input a integer number:1000 result=0 x3程序说

24、明程序说明:(0 4)按位取0的反,为全1;左移4位后,其低4位为0,其余各位为1;再按位取反,则其低4位为1,其余各位为0。这个整数正是我们所需要的。1.5.6 位运算例子例子例例1 题目:从键盘上输入1个正整数给int变量num,按二进制位输出该数。#include stdio.hmain()unsigned int num,mask,i;printf(Input a integer number:);scanf(%d,&num);mask=131;/*构造构造1个最高位为个最高位为1、其余各位为、其余各位为0的整数的整数(屏蔽字屏蔽字)*/printf(%d=,num);for(i=1;

25、i=32;i+)putchar(num&mask?1:0);/*输出最高位的值输出最高位的值(1/0)*/num a=0;pbit-b&=3;pbit-c|=1;printf(%d,%d,%dn,pbit-a,pbit-b,pbit-c);1.7 其他预处理关键字其他预处理关键字#error使用defined#line#pragma#和#预定义宏1.7.1#error#error指令强制编译程序停止编译,主要用于程序调试#error指令的一般形式是#errorerror-message注意:宏串error-message不用双引号包围可以自定义错误内容1.7.2 使用使用defined 确定是

26、否定义宏名字的方法defined操作符的一般形式如definedmacro-namedefine与ifdef:#ifdefinedMY或#ifdefMY感叹号”!”来反转相应的条件#if!definedDEBUGPrintf(“FinalVersion!n”);#endif1.7.3#line#line指令改变_LINE_和_FILE_的内容#line的一般形式#linenumber“filename”主要用于调试和特殊应用1.7.5#和和#操作符#通常称为字符串化的操作符预处理程序把以下的语句:Printf(mkstr(IlikeC);变成Printf(“IlikeC”);#include#

27、define mkstr(s)#sint main(void)Printf(mkstr(I like C);Return 0;1.7.5#和和#“#”可以把两个独立的字符串连接成一个字符串#include#define SORT(X)sort_function#Xvoid main(void)char*array;int elements,element_size;SORT(3)(array,elements,element_size);结果:结果:SORT(3)转化为转化为sort_function3 SORT(3)(array,elements,element_size)转化为转化为 so

28、rt_function3(array,elements,element_size1.7.6 预定义宏预定义宏 _DATE_进行预处理的日期(“Mmmddyyyy”形式的字符串文字)_FILE_代表当前源代码文件名的字符串文字_LINE_代表当前源代码中的行号的整数常量_TIME_源文件编译时间,格式微“hh:mm:ss”_func_当前所在函数名1.7.6 预定义宏预定义宏 例子#include#include void why_me();int main()printf(The file is%s.n,_FILE_);printf(The date is%s.n,_DATE_);printf

29、(The time is%s.n,_TIME_);printf(This is line%d.n,_LINE_);printf(This function is%s.n,_func_);why_me();return 0;void why_me()printf(This function is%sn,_func_);printf(The file is%s.n,_FILE_);printf(This is line%d.n,_LINE_);阶段小节阶段小节位操作几个运算操作的特点位段的特点和位段数据的引用位段使用的规则C语言扩展宏定义几个具体应用调试与!define本章结构本章结构编译预处理编

30、译预处理和位运算编译预处理和位运算位段文件包含宏定义条件编译位运算预处理其他关键词预处理的基础操作方式预处理的基础操作方式define定义的原则和注意事项及定义的原则和注意事项及应用应用讲述文件包含的特点和用处,以讲述文件包含的特点和用处,以及及include”和和的区别的区别讲述条件编译的三种应用方式和讲述条件编译的三种应用方式和主要功能实现主要功能实现了解位运算的基本操作,重点在了解位运算的基本操作,重点在与和或运算与和或运算了解位段的基本定义了解位段的基本定义讲述了讲述了error以及以及pragma和调和调试输入基本应用试输入基本应用本章总结本章总结宏定义特点和注意细节条件编译特点和主要用处文件包含的路径查询规则位操作运算的几个具体运用C语言扩展宏定义的用法实验实验1题目用宏定义来实现两个数取最大值注意事项?运算符的运用对参数的包含define的语法特点实验结果实验结果掌握宏定义的具体应用,深化对宏定义的操作。实验实验2题目从键盘上输入1个正整数给int变量num,按二进制位输出该数,同时分别对第五位取反,第六位置一,第七位清零注意事项键盘输入操作特点位操作的运算用宏定义实现位操作CLEARSETTINGREVER实验结果实验结果熟悉位操作基本运算,同时为以后嵌入式数据操作提供基础程序编码。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 大学资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁