第9章 宏定义1

合集下载

DSP原理及应用课后答案电子工业

DSP原理及应用课后答案电子工业

第二章3、处理器工作方式状态寄存器PMST 中的MP/MC、OVLY 和DROM 三个状态位对C54x的存储空间结构各有何影响?当OVLY= 0 时,程序存储空间不使用内部RAM。

当OVLY= 1 时,程序存储空间使用内部RAM。

内部RAM 同时被映射到程序存储空间和数据存储空间。

当MP/ MC=0 时,4000H~EFFFH 程序存储空间定义为外部存储器;F000H~FEFFH 程序存储空间定义为内部ROM;当MP/ MC=1 时,4000H~FFFFH 程序存储空间定义为外部存储。

DROM=0:0000H~3FFFH—— 内部RAM ;4000H~FFFFH—— 外部存储器;DROM=1 :0000H~3FFFH——内部RAM;4000H~EFFFH——外部存储器;F000H~FEFFH——片内ROM;FF00H~FFFFH——保留。

4 、TMS320C54x 芯片的片内外设主要包括哪些电路?①通用I/O 引脚②定时器③时钟发生器④主机接口HPI⑤串行通信接口⑥软件可编程等待状态发生器⑦可编程分区转换逻辑5、TMS320C54x 芯片的流水线操作共有多少个操作阶段?每个阶段执行什么任务?完成一条指令都需要哪些操作周期?六个操作阶段:①预取指P;将PC 中的内容加载PAB ②取指F; 将读取到的指令字加载PB③译码D; 若需要,数据1 读地址加载DAB;若需要,数据2 读地址加载CAB;修正辅助寄存器和堆栈指针④寻址A; 数据1 加载DB;数据2 加载CB;若需要,数据3 写地址加载EAB⑤读数R; 数据 1 加载DB;数据 2 加载CB;若需要,数据 3 写地址加载EAB;⑥执行X。

执行指令,写数据加载EB。

6、TMS320C54x 芯片的流水线冲突是怎样产生的?有哪些方法可以避免流水线冲突?答:’C54x 的流水线结构,允许多条指令同时利用CPU 的内部资源。

由于CPU 的资源有限,当多于一个流水线上的指令同时访问同一资源时,可能产生时序冲突。

大学C语言笔记

大学C语言笔记

第一章概述1.C语言的特点①语言简洁、紧凑,使用方便、灵活。

共有32个关键字,9种控制语句。

②运算符丰富,公有34种运算符。

③数据结构丰富,数据类型有:整型、实型、字符型、数组、指针、结构体、共用体等。

④具有结构化的控制语句(如if…else、while、do…while、switch、for)⑤语法限制不太严格,程序设计自由度大。

⑥允许直接访问物理地址,能进行位(bit)操作,可以直接对硬件操作。

⑦生成目标代码质量高,程序执行效率高。

⑧可移植性好。

2.C语言的用途C虽不擅长科学计算和管理领域,但对操作系统和系统实用程序以及对硬件进行操作方面,C有明显的优势。

现在很多大型应用软件也用C编写。

Top of Page第二章数据类型、运算符与表达式1.C的数据类型C的数据类型包括:整型、字符型、实型或浮点型(单精度和双精度)、枚举类型、数组类型、结构体类型、共用体类型、指针类型和空类型。

2.常量与变量常量其值不可改变,符号常量名通常用大写。

变量其值可以改变,变量名只能由字母、数字和下划线组成,且第一个字符必须为字母或下划线。

否则为不合法的变量名。

变量在编译时为其分配相应存储单元。

3.整型数据整型常量的表示方法:十进制不用说了,八进制以0开头,如0123,十六进制以0x开头,如0x1e。

整型变量分为:基本型(int)、短整型(short int)、长整型(long int)和无符号型。

不同机器上各类数据所占内存字节数不同,一般int型为2个字节,long型为4个字节。

4.实型数据实型常量表示形式:十进制形式由数字和小数点组成(必须有小数点),如:0.12、.123、1230.0等。

指数形式如123e3代表123×10的三次方。

实型变量分为单精度(float)和双精度(double)两类。

在一般系统中float型占4字节,7位有效数字,double型占8字节,15~16位有效数字。

5.字符型数据字符变量用单引号括起来,如'a','b'等。

C语言 第九章 预处理命令

C语言 第九章 预处理命令
第九章 预处理命令
目的: 简化程序的编写 ; 提高程序的模块化、可读性、可移植性。
有三种类型的预处理命令: 1. 宏定义命令; 2. 文件包含命令; 3. 条件编译命令。
为了与C语句区别,这些命令均以“ # ”开头。
处理流程: 第一次编译扫描时,将预编译命令处理完, 然后再进行正式编译,生成目标代码。
#define f(a)
(a)* b
若有:f(x+y) 则应有:
(x+y)b
若有:f(x+y+z) 则应有:
预编译后, z = f(x+y) 变成: z = x+y*b 结果为: z=31
(x+y+z)b
(这个结果与初始设想不一致)
“带参数宏定义” 必须注意以下几个方面: 1. 宏定义时要考虑实参(替换)的各种可能, 防止出 现二义性。
3. #include后的文件名既可用“ ”,也可用< >, 二者区别:
“ ”首先在当前目录中找,然后再去标准目录中找。
< > 只在标准目录(include目录)中找。
为提高预处理的搜索效率,通常对自定义的 非标准头文件使用方式一;而对系统提供的标准 头文件(如:math.h、stdio.h等)使用方式二。
将返回值 6 将返回值 8
但二者还是有区别的:
1) 宏替换在预编译时进行;
而函数调用在程序运行时进行
2) 宏展开时,仅仅是将宏体中的形参简单 地置换为实参,不计算实参值,也不会带来任何 返回值; 而函数调用要进行: l 计算实参值(假定用 2+3、 9–1作为实参将 被计算出来)、 l参数传递(将 5、8 传给形参x、y)、
这些文件要用到公用信息时,只要在文件 中加入#include “f.h”这么一行命令既可。这样 就不必在f1.c、…… 、fn.c每个文件中都去重 复定义这些公用的信息。

C程序5

C程序5
5.2*4.5* 3.0
10
v= S(5.2, 4.5, 3.0) ;
说明: 说明:
1.宏展开时,只是将实参串代替形参串. 宏展开时,只是将实参串代替形参串. 宏展开时 如: # define S( r)
PI*r*r; 若S(a+b)→ PI*a+b*a+b. +
出错,定义时应写成: 出错,定义时应写成:
20
练习
定义一个带参数的宏, 定义一个带参数的宏,实现两个 数的互换,并输出交换后的值。 数的互换,并输出交换后的值。 宏名: 宏名:S) t=b;b=a;a=t main() { int a,b,t; scanf(“%d,%d”,&a,&b); SWAP(a,b); printf(“a=%d,b=%d\n”,a,b); }
4
#define M 10 main( ) { int a[M],i; for(i=0;i<M;i++) scanf(“%d”,&a[i];}
预编译时,程序中所有的M被10替换。 预编译时,程序中所有的M 替换。 替换 要改变数组的个数,只需改变M的值。 要改变数组的个数,只需改变M的值。
5
说明
13
int max(int x,int y) { int z; z=x>y?x, y; return(z); } main( ) { int a,b,c,d,t; scanf(“%d,%d,%d,%d”,&a,&b,&c,&d); t=max(a+b,c+d); printf(“max=%d”,t); } ,
f1.c
#include “f3.c” #include “f2.c”

第九章预处理命令(5503)

第九章预处理命令(5503)

1.下面叙述中正确的是(A )。

A.带参数的宏定义中参数是没有类型的B.宏展开将占用程序的运行时间C.宏定义命令是C语言中的一种特殊语句D.使用#include命令包含的头文件必须以“.h”为后缀2.在宏定义#define PI3.14159中,用宏名代替一个( D )A.常量B.单精度数C.双精度数D.字符串3.下面有关宏替换的叙述不正确的是( D )A.宏替换不占用运行时间B.宏名无类型C.宏替换只是字符替换D.宏名必须用大写字母表示4.C语言的编译系统对宏命令的处理是( D )A.在程序运行时进行的B.和C程序中的其他语句同时进行编译的C.在程序连接时进行的D.在对源程序中其它成分正式编译之前进行的5.下列定义不正确的是(C )。

A.#define PI 3.141592B.#define S345C.int max(x,y); int x,y; { }D.static char c6.有如下宏定义 #define s(a) a*3 ,则执行表达式x=s(1+2)后,变量x的值为( D)。

A.10B.9C.8D.77.以下说法中正确的是( D)。

A.#define是C语句B.#define是库函数C.#define是自定义函数D.#define是预处理命令8.在“文件包含”预处理语句的使用形式中,当#include后面的文件用了“”(双引号)时,寻找被包含文件的方式是(B)。

A.直接按系统设定的标准方式搜索目录B.先在源程序所在目录搜索,再按系统设定的标准方式搜索C.仅仅搜索源程序所在目录D.仅仅搜索当前目录9.以下叙述正确的是( B )。

A.可以把define和if定义为用户标识符B.可以把define定义为用户标识符,但不能把if定义为用户标识符C.可以把if定义为用户标识符,但不能把define定义为用户标识符D.define和if都不能定义为用户标识符10.以下叙述中正确的是( B )。

预处理命令

预处理命令

二、表演区 (一)什么是表演区 表演区以幼儿表演游戏为设计核心,通过道具吸引幼儿积极参加故事表 演、游戏等活动。 (二)表演区的环境布置与材料投放 表演区可以分为固定式和活动式表演区角两类。 固定式的表演区角是指在活动室内辟出一定区域,存放表演所需要的用 具。 活动式的表演区角则是根据表演需要,临时在走廊、门厅、过道或室外 等地方设置表演场所,便于及时放置和收拢。
第9章 预处理命令
• 9. 1 概述 • 9. 2 宏定义 • 9. 3 文件包含 • 9. 4 条件编译
9. 2 宏定义
• 9. 2. 1 无参宏定义
• 无参宏的宏名后不带参数。 • 其定义的一般形式为 • #define 标识符字符串 • 其中, #表示这是一条预处理命令; 凡是以#开头的指令均为预处理命
果果:“老师,一分钟是多久呢?” 教师:“就是一会儿,我一转身。” 贝贝:“我知道,最细的秒针走一圈,挺长的。” 佳佳:“一分钟就是我们从门口走到后面的窗子那里。” 教师:“一分钟能做什么?” 佳佳:“给花浇水。” 果果:“唱完一首歌。” 贝贝:“搬来一把椅子。”……
学习目标
1. 了解幼儿日常交谈的主要特点及指导要求。 2. 掌握语言区角的环境布置与材料投放要求,能科学地开展语言区角活 动的指导。 3. 学会设计听说游戏的玩法,并能评析幼儿园听说游戏。
上一页 下一页 返回
9. 2 宏定义
• 【例9 - 2】不作宏代换程序举例。
上一页 下一页 说明: • 虽然已定义宏名OK 表示100, 但在printf 语句中OK 被引号括起来, 因
此不作宏代换。 • 程序的运行结果为“OK”, 这表示把“OK” 当字符串处理。
上一页 下一页 返回
义时, 必须十分注意, 应保证在宏代换之后不发生错误。

C语言程序设计 第3版 第9章 编译预处理

C语言程序设计 第3版 第9章 编译预处理
int s; s=sum(5); printf("s%d\n",s); }
#include "test2.c" static int sum(int n) {
int i,s=0; for(i=1;i<=n;i++)
s=s+fact(i); return s; }
static int fact(int n) {
C语言程序设计
第9章 编译预处理
第1讲:编译预处理基本形式
提纲
1.宏定义 2.文件包含 3.条件编译
1.宏定义
不带参数宏定义 带参数宏定义
格式:
#define 标识符 字符串
功能:
指定标识符代替一个较复杂的字符串。
注意说明:
(1)宏名一般习惯用大写字母,例如宏名PI。 (2)宏名用做代替一个字符串,不作语法检查。 (3)宏定义无需在末尾加“;” (4)宏定义的有效范围为#undef命令终止。 (5)在进行宏定义时,可以引用已定义的宏名。
char web[50]; int i=0; gets(web); while(web[i]!='\0') {
#if(R==1) if(web[i]>='A'&&web[i]<='Z') {web[i]=web[i]+32; i++;}
#else if(web[i]>='a'&&web[i]<='z') {web[i]=web[i]-32; i++;}
形式3:
#ifndef 标识符 程序段1
#else 程序段2

第9章预处理定义

第9章预处理定义
⑷宏定义不是C语句#d,ef不ine必a在rra行y_末siz加e 2分00号0,如果加了分号则 连分号一起进行置在换该。场合下array_size所代表的是2000, ⑸#define命令出现在使程用序宏函定数义的,外可面以,提宏高名程的序有的效通范用围性为。定 义命令之后到本源文件结束。
C语言程序设计(第三版) My email:chenguot@
area=S(a); printf(“r=%f\narea=%f\n”,a,area);
area=3.1415926*a*a;
}
C语言程序设计(第三版) My email:chenguot@
10
§9.1 宏定义(7)
如下宏定义:
说明:
#define S (r) PI*r*r
⑴对带参数的宏的展开只是将语对句于中语的句宏名后面括号内的实
file1.c 或
file2.c
#include<file2.c>
#include <文件名> B
A
file1.c
A B
C语言程序设计(第三版) My email:chenguot@
16
§将包9.宏含2代到表用“文输户出程件格序包式中做:含出”头文处件理,并(2) (2)主文件file1.c
(好1处):将“格文式件宏包做含成”头命文令件可fo以rm节at.省h 程序设计void人m员ain的() 重复劳动。
#如inc:lud某e <单std位io.的h>人员往往使用一组固定的符号{ 常量(g=9.81,
#pdie=fi3n.e1P4R15p9ri2nt6f,e=2.718,c=…),可以把这些宏int定a,b义,c,d命; 令组成 ##一量定ddeeff个包义iinnee头含这ND文到些L“%“件自符\dn””,己号然所常后写量各的,人源相都文当可件于以中工用。业这上#in样的cl每标ud个准e命人零令cah=就件a1将r;b可,s=t这r2i以拿n;cg些=[不来]3=;符d“必就C=4号H;重用IN常A复。”;
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

注意:
实参r的值已知,可以从宏带回3个值(l,S, v)。其实,只不过是字符代替而已,将字符r 代替R,l代替L,S代替S,v代替V,而并未 在宏展开时求出l、S、v的值。
5.带参的宏和带参函数区别
(5) 使用宏次数多时,宏展开后源程序长,因为每展开一次都使程序 增长,而函数调用不使源程序变长。 (6) 宏替换不占运行时间,只占编译时间。而函数调用则占运行时间 (分配单元、保留现场、值传递、返回)。 一般用宏来代表简短的表达式比较合适。有些问题,用宏和 函数都可以。如: #define MAX(x,y) (x)>(y)?(x)∶(y) 赋值语句展开后为 main() t=(a+b)>(c+d)?(a+b)∶(c+d); {int a,b,c,d,t; t=MAX(a+b,c+d); } 注意:MAX不是函数,这里只有一个 main函数,中就能求出t的值。
7):宏定义只作字符替换,不分配内存空间 8) :对程序中用双撇号括起来的字符串原样输出
3、无参宏的应用举例
例 9.1 不带参数的宏的程序
#include <stdio. h> #define PI 3.115926 #define STRING This is a test main( ) { float r, s; printf (“ STRING \n"); scanf ("%f", &r); s=PI*r*r; printf (“ s=%10.3f\n",s); }
例:使用带参数的宏
#include<stdio.h> #define PI 3.1415926 #define s(r) PI*r*r void main() { float a,area; a=3.6; area=s(a); printf(“r=%f\narea=%f\n”,a,area); }
说明:
4): 文件包含可用双撇号,也可用尖括号。 它们的区别是: 尖括号:系统到存放c库函数头文件的目录中寻找要 包含的文件 双撇号:系统先在用户当前目录中寻找,找不到再 按尖括号的方式寻找。 5):被包含的文件与其所在的文件在预编译后已变成同一 文件
条件编译:
1):一般情况下,源程序中所有的行都参加编译。但是有时希望对其 中一部分内容只在满足一定条件才进行编译,也就是对一部分内容 指定编译的条件,这就是“条件编译”。 2):表达形式: #ifdef 标识符 程序段1 #else 程序段2 #endif #ifndef 标识符 程序段1 #else 程序段2 #endif #if 表达式 程序段1 #else 程序段2 #endif
条件编译实例2
#include <stdio.h> #define MAX 10 main() { #if MAX>99 printf("compile for array greater than 99"); #else printf("compile for small array"); #endif }
5.带参的宏和带参函数区别
(1)在函数调用时,是先求出实参表达式的值,再传递给形参, 而宏定义只是简单的字符替换;例如上面的S(a+b),在宏展开时并不 求a+b的值,而只将实参字符“a+b”代替形参r (2)函数调用是在程序运行时处理的,分配存储单元,而宏展开 (调用)是在编译预处理时进行的,展开时不分配内存单元,不进行 值传递,没有返回值的概念; (3)对函数实参和形参都要定义类型,而宏不存在类型,宏定义 时字符串可以是任何类型数据,一律看成字符串,宏名也没类型,只 是一个符号表示,展开时代入指定的符号即可。 如:#define CHAR1 CHINA(字符) #define a 3.6 (数值)
#include<stdio.h> #define PI 3.1415926 void main() { float s,v,r,l; printf("请输入半径长度:"); scanf("%f",&r); l=2.0*PI*r; s=PI*r*r; v=4.0/3*PI*r*r*r; printf("l=%10.4f\ns=%10.4f\nv=%10.4f\n",l,s,v); }
宏定义:
1:不带参数的宏定义 1) 用一个指定的标识符来代替一个字符串 2) 它的一般形式: #define 标识符 字符串 3) 作用:把标识符定义为字符串。在进行编译预处理时,• 译 编 系统就能够把程序中出现的标识符,一律用字符串去替换,然后 再对替换处理后的源程序进行编译。
例:使用不带参数的宏定义
第9章
编译预处理
学习目标:
掌握宏定义、无参宏、有参宏、符号常量 掌握文件包含的意义 教学重、难点: 宏定义(重) 文件包含的使用(重) 条件编译(重、难点)
编译预处理是指,在对源程序进行编译之前, 系统将自动引用预处理程序对源程序中的预处理部 分作处理;然后再将处理的结果,和源程序一起进 行编译,以得到目标代码。
NUM宏展开: 2*N+1+1 再宏展开: 2*2+1+1
带参数的宏定义
1) :带参数的宏定义不是简单的字符替换,还要进 行参数替 换。 2) : 它的一般定义形式: #define 宏名(参数表) 字符串 字符串中包含在括弧中所指定的参数。如: #define s(a,b) a*b area=s(3,2); 定义矩形面积S,a和B是边长。在程序中用了s(3,2),把3、2分别 代替宏定义中的形式
2. 关于不带参数的宏定义的几点说明:
(1)宏名一般用大写字母表示,便于与变量名区别;一般将字符个数较多的字 符串用一个宏名替换,减少程序中多处引用字符串书写错误。 (2)宏定义是用宏名来表示一个字符串,在宏展开时以该字符串取代宏名, 这只是一种简单的代换, 预处理程序对它不作任何检查。如有错误,只能在编 译已被宏展开后的源程序时发现。 (3)宏定义不是语句,在行末不加分号,如加上分号则连分号也一起置换。 (4)宏定义必须写在函数之外,其作用域为宏定义命令起到源程序结束。如
5.带参的宏和带参函数区别
(4) 调用函数只可得到一个返回值,而用宏可以设法得到几个结果。 #define PI3.1415926 #define CIRCLE(r,l,s, v)L=2*PI*R;S=PI*R*R;v=4.0/3.0*PI*R*R*R main() {float r,l,s,v; scanf("%f",&r); CIRCLE(r,l,S,v); printf("r=%6.2f,l=%6.2f, S=%6.2f, v=%6.2f\n",r,l,S, 运行情况如下:3.5 v);} r= 3.50,l= 21.99, S= 38.48,v= 179.59
例如:
#define G 9.8 void main() { … } #undef G f1() { …
}
_______ ↑ G的有效范围 -----↓----
2. 关于不带参数的宏定义的几点说明:
(5) 宏定义可以嵌套,但嵌套的宏定义名要是已经定义的宏名。在宏展 开时由预处理程序层层替换。例如: #define R 14.256 #define PI 3.1415926 #define S PI*R*R /* PI、R是已定义的宏名*/ 则语句 printf ("%f", s);在宏代换后变为 printf ("%f",3.1415926*14.256*14.256); (6)可用宏定义表示数据类型,使书写方便。 例如: #define STU int 在程序中可用STU替换数据类型int。
运行结果如下: r=3.600000 area=40.715038
带参宏定义说明:
(1) 对带参数的宏的展开只是将语句中的宏名后面括号内的实参字符 串代替#define命令行中的形参。但是,如果有以下语句: area=S(a+B);这时把实参a+B代替PI*r*r中的形参r,成为 area=PI*a+B*a+B;请注意在a+B外面没有括弧,显然这与程序设 计者的原意不符。原意希望得到area=PI*(a+B)*(a+B);为了得到 这个结果,应当在定义时,在字符串中的形式参数外面加一个 括弧。即#define S(r) PI*(r)*(r)在对S(a+B)进行宏展开时,将 a+B代替r,就成了PI*(a+B)*(a+B)这就达到了目的。 (2) 在宏定义时,在宏名与带参数的括弧之间不应加空格,否则将 空格以后的字符都作为替代字符串的一部分。例如,如果有 #define s (r)PI*r*r 被认为s是符号常量(不带参的宏名),它代表字符串“(r) PI*r*r”。 如果在语句中有area=S (a); 则被展开为area=(r) PI*r*r (a) 显然不对了。
说明:
1): 一个#include命令只能指定一个被包含文件,如果 要包含n个文件,要用n个#include命令。 2) :如果文件1包含文件2,而在文件2中要用到文件 3的内容,则可在文件1中用两个include命令分别包 含文件2和文件3,而且文件3应出现在文件2之前。 3): 在一个被包含文件中又可以包含另一个被包含文件, 即文件包含是可以嵌套的。
宏定义不是C语句,所以不能在行尾加 Nhomakorabea号。否则,宏
展开时,会将分号作为宏体中 的1个字符。
在宏展开时,预处理程 序仅以宏体替换宏名,而不 作任何检查
【提问】以下这道题目的结果是多少?
例9.3 #define N 2 #define M N+1 #define NUM 2M+1 main( ) { int i; for (i=1; i<=NUM; i++) printf (“ %d \n”, i ); } 宏展开后的等价程序如下: main( ) { int i; for (i=1; i<=6; i++) printf(“ %d \n”, i ); }
相关文档
最新文档