第九讲预处理文件结构体等

合集下载

结构体与预处理综述

结构体与预处理综述

⑶ 宏定义时如果在行末有分号,则替换时连分号一起进行替换。例如: #define X 5 ; …… s=X*8; …… 则经过宏展开后,该语句为:s=5;*8。显然出现语法错误。因此在宏定义 时,行末不要加分号。
4. 宏定义时,可以引用已经定义的宏名。例如: #define X 5 #define Y X+1 #define Z Y*X/2
Num
name
sex M
age 18
score addr 87.5 Beijing
100101 Li Fen
把它们组织成一个组合项,在一个组合项中包含若干个类型不同 (当然也可以相同)的数据项。
像这样关系密切但类型不同的多个数据项,被看成一个整体来 处理。C语言中,用来描述这种整体的数据类型就是结构体。
结构体变量成员的引用
引用方式为: 结构体变量名.成员名 如: a.height=175.0 main() { struct student {
char num[12]; char name[10]; char sex; double height; double weight;
(.为成员运算符) 或 printf(“%s”,);
二、文件包含
文件包含的功能是把一个或多个指定文件嵌入到现行的源程序文件中, 再对嵌入后的源程序文件进行编译处理。这样可以有效地减少重复编程。
我们已经使用过的 #include <stdio.h> 、#include <string.h> 、 #include <math.h>等就是文件包含。
文件包含命令的一般格式: #include <文件名> 或者 #include "文件名"

C语言复习PPT C9

C语言复习PPT C9

④宏串中可出现已定义的宏名(宏的嵌套定义 宏串中可出现已定义的宏名 宏的嵌套定义) 宏的嵌套定义 如: #define R 3.0 #define PI 3.141592 #define C 2.0*PI*R #define S PI*R*R main( ) { printf("C=%f\nS=%f\n", C, S); } 最终输出项C替换为: 最终输出项 替换为:2.0*3.141592*3.0 替换为 S替换为:3.141592*3.0*3.0 替换为: 替换为 ⑤字符串中与宏名相同的字符不被替换 printf("C=%f\n S=%f\n", C, S); 与变量不同) ⑥只作字符替换,不分配内存空间(与变量不同 只作字符替换,不分配内存空间 与变量不同
③宏定义中宏名与参数的括号间不能有空格; 宏定义中宏名与参数的括号间不能有空格; 如:#define S (r) 3.141592*(r)*(r) 宏串 由于出现了空格,则认为S是宏名而且无参 是宏名而且无参. 由于出现了空格,则认为 是宏名而且无参. ④ 对宏串中双引号范围内的内容不予替换; 对宏串中双引号范围内的内容不予替换; 如:#define PR(V) printf("V=%d\t", V) main( ) { int a=1, b=2; PR(a); /*printf("V=%d\t", a);*/ PR(b); /*printf("V=%d\t", b);*/ }
二,带参数的宏定义
不是进行简单的字符串替换, 不是进行简单的字符串替换,还要进行参数替换 一般形式: 一般形式: #define 宏名 形参字串表) 宏串 宏名(形参字串表 形参字串表 带参的宏引用: 带参的宏引用: 宏名(实参字串表 宏名 实参字串表) 实参字串表

9-预处理

9-预处理
计算机基础教学部 /cyysj
9.1 宏定义
带参数宏定义
• 一般形式: #define 一般形式: 宏名(参数表 宏名 参数表) 参数表 字符串 例 #define S(a,b) a*b ……….. area=S(3,2); area=3*2; 宏展开: • 宏展开:形参用实参换,其它字符保留 宏展开:形参用实参换, x*x 例 #define POWER(x) x=4; y=6; z=POWER(x+y); 宏展开: 宏展开:z=x+y*x+y; 一般写成: 一般写成: #define POWER(x) 宏展开: 宏展开: z=(x+y)*(x+y);
(x)*(x)
计算机基础教学部 /cyysj
9.1 宏定义
例: 用宏定义和函数实现同样的功能 #define MAX(x,y) (x)>(y)?(x):(y) ……. main() { int a,b,c,d,t; ……. t=MAX(a+b,c+d); …… } 宏展开:t=(a+b)>(c+d)?(a+b):(c+d); int max(int x,int y) { return(x>y?x:y); } main() { int a,b,c,d,t; ……. t=max(a+b,c+d); ……… }
计算机基础教学部 /cyysj
计算机基础教学部 /cyysj
课堂练习
<练>执行下面程序后,输出结果是(c) 练 执行下面程序后 输出结果是( ) 执行下面程序后, #include<stdio.h> #define N 4+1 #define M N*2+N #define RE 5*M+M*N main() { printf("%d\n",RE/2); } A. 150 B. 100 C. 41 D. 以上结果都不对

第九章预处理

第九章预处理

对于宏定义说明以下几点: 对于宏定义说明以下几点:
1. 宏定义是用宏名来表示一个字符串,在宏展 宏定义是用宏名来表示一个字符串, 开时又以该字符串取代宏名, 开时又以该字符串取代宏名,这只是一种简单 的代换,字符串中可以含任何字符, 的代换,字符串中可以含任何字符,可以是常 也可以是表达式, 数,也可以是表达式,预处理程序对它不作任 何检查。如有错误, 何检查。如有错误,只能在编译已被宏展开后 的源程序时发现。 的源程序时发现。 2. 宏定义不是说明或语句,在行末不必加分号, 宏定义不是说明或语句,在行末不必加分号, 如加上分号则连分号也一起置换。 如加上分号则连分号也一起置换。
预处理功能
9、1 、 宏定义
9、2 文件包含 、 9、3 条件编译 、
9.1
宏定义
在C语言源程序中允许用一个标识符来表 示一个字符串,称为“ 被定义为“ 示一个字符串,称为“宏”。被定义为“宏” 的标识符称为“宏名” 在编译预处理时, 的标识符称为“宏名”。在编译预处理时,对 程序中所有出现的“宏名” 程序中所有出现的“宏名”,都用宏定义中的 字符串去代换, 这称为“宏代换” 字符串去代换, 这称为“宏代换”或 宏展开” “宏展开”。 宏定义是由源程序中的宏定义命令完成的。 宏定义是由源程序中的宏定义命令完成的。 宏代换是由预处理程序自动完成的。在C语言 宏代换是由预处理程序自动完成的。 分为有参数和无参数两种。 中,“宏”分为有参数和无参数两种。
无参宏定义
1、格式:#define 标识符 字符串 其中宏名为C语言的标识符,一般用大写的字 母表示。“字符串”可以是常数、表达式、格 式串等。在前面介绍过的符号常量的定义就是 一种无参宏定义。此外,常对程序中反复使用 的表达式进行宏定义。例如: # define M (y*y+3*y) 2、功能:用于将一个指定的标识符替换为一个字 符串。

第九章 数据结构预处理命令

第九章 数据结构预处理命令

展开方式: 在程序中如果有带实参的宏,则按#define命令行中指 定的字符串从左到右进行置换.如果串中包含宏中的 形参,则将程序语句中相应的实参代替形参,如果宏定 义中的字符串中的字符不是参数字符,则保留.
结 束
例如: #define PI 3.1415926 #define AREA( r ) PI*r*r max () 展开为: { PI*a*a3.1415926*a*a float s, a; a = 4.2; s = AREA(a); printf(“ r= %f\n area= %f\n”, a, s); } 运行结果: r = 4.200000 area= 55.417692
结 束
第九章
编译预处理
§9.1 一、不带参数的宏定义 宏定义 用一个指定的标识符来代替一个字符串,一般形式为: #define 标识符 字符串 例如: #define PI 3.1415926 作用:用标识符(称为“宏名”)PI代替字符串 “3.1415926”. 在预编译时,将源程序中出现的宏名PI替换为字符串 “3.1415926”,这一替换过程称为“宏展开”。 #define:宏定义命令
结 束
• 4、宏定义不是C语句,后面不能有分号。如 果加入分号,则连分号一起替换。 • 如:
– – – – – #define PI 3.1415926; area = P*r*r; 在宏扩展后成为: area = 3.1315926;*r*r; 结果,在编译时出现语法错误。
• 5、通常把#define命令放在一个文件的开头, 使其在本文件全部有效。(#define定义的宏 仅在本文件有效,在其它文件中无效,这与全 局变量不同)。
1. #ifdef 标识符 程序段1 #else 程序段2 #endif

《C程序设计》(第三版)第9章 预处理命令

《C程序设计》(第三版)第9章 预处理命令

②为了增加程序的可读性,建议宏名用大写字母, 为了增加程序的可读性,建议宏名用大写字母, 其他的标识符用小写字母。 其他的标识符用小写字母。 双引号中有与宏名相同的字符串不进行替换。 有与宏名相同的字符串不进行替换 ③双引号中有与宏名相同的字符串不进行替换。 已经定义的宏名可以被后定义的宏名引用。 ④已经定义的宏名可以被后定义的宏名引用。在预 处理时将层层进行替换。 处理时将层层进行替换。
main() 替 { float r,s,c; 换 scanf(“%f” scanf(“%f”,&r); s = 3.14 * r * r ; PI printf(“PI=%f,s=%f” PI printf(“PI=%f,s=%f”, 3.14 ,s); }
编译
说明: 说明:
① 宏定义的作用域是从定义处开始到源文件结束, 宏定义的作用域是从定义处开始到源文件结束, 但根据需要可用undef命令终止其作用域 命令终止其作用域。 但根据需要可用undef命令终止其作用域。 形式为: 形式为: #undef 宏名
【例3】分析下面程序运行后的输出结果。 】分析下面程序运行后的输出结果。 #define MA(x) x*(x-1) void main( ) 特别注意: 特别注意: { int a=1,b=2; 由于替换文 本中的x没 本中的 没 printf("%d\n", MA(1+a+b)); 有用括号括 } 因此, 起,因此, 程序输出结果: 程序输出结果:8 1+a+b也不 也不 分两次替换: 分两次替换: 能用括号括 ①MA(1+a+b) 用x*(x-1) 替换。 MA(1+a+b) 替换。 起。 替换x。 ②用1+a+b替换 。 替换 printf语句被展开为: 语句被展开为: 语句被展开为 printf("%d\n", 1+a+b*(1+a+b-1));

C程序设计第九章

C程序设计第九章

包含文件的查找方法: 包含文件的查找方法: #include “文件名” 文件名” 文件名 先在当前工作目录中去查找, 先在当前工作目录中去查找,若找不 到再到指定的标准目录中去查找。 到再到指定的标准目录中去查找。 C编译系统 编译系统, 如:对Turbo C编译系统,先在用户目录下 查找,然后在TC include文件夹中查找 TC\ 文件夹中查找。 查找,然后在TC\include文件夹中查找。 #include <文件名 文件名> 文件名 直接到系统指定的标准目录中去查找。 直接到系统指定的标准目录中去查找。 C编译系统 直接在TC 编译系统, TC\ 如:对Turbo C编译系统,直接在TC\include 文件夹中查找。 文件夹中查找。
main() printf(“%d %d\ ,S(N));} { printf( %d\n”,S(N));} 运行结果为: 运行结果为:17 3+2*3+2*3+2
三、带参数的宏替换与函数的主要区别
⑴函数调用时,先求出实参表达式的值,然后代入 函数调用时,先求出实参表达式的值, 形参。而使用带参的宏只是进行简单的字符替换。 形参。而使用带参的宏只是进行简单的字符替换。 ⑵函数调用是在程序运行时处理的,分配临时的内 函数调用是在程序运行时处理的, 存单元。而宏替换则是在编译时进行的, 存单元。而宏替换则是在编译时进行的,在展开 时并不分配内存单元,不进行值的传递处理, 时并不分配内存单元,不进行值的传递处理,也 没有“返回值”的概念。 没有“返回值”的概念。 宏替换不占运行时间,只占编译时间, ⑶宏替换不占运行时间,只占编译时间,而函数调 用则占运行时间。 用则占运行时间。 函数中函数名及参数均有一定的数据类型, ⑷函数中函数名及参数均有一定的数据类型,而宏 不存在类型问题,宏名及其参数无类型。 不存在类型问题,宏名及其参数无类型。

第9章 编译预处理

第9章 编译预处理

C/C++程序设计第9 章编译预处理计算机学院C/C++程序设计课程组C/C++程序设计第1 章主要内容C语言有三种预处理命令,分别是宏定义、文件包含和条件编译。

本章主要介绍宏定义与引用、文件包含处理和条件编译命令。

C/C++程序设计9.1 宏定义所谓“宏”就是将一个标识符定义成一个字符串符,完成定义的命令称为“宏定义”或预处理命令,其中,“标识符”称为“宏名”;当定义了宏名后,在源程序中就可以“引用宏”。

带有宏的程序,源程序开始编译前,系统将会把源程序清单中所引用的宏名替换成对应的一串字符,然后再编译源程序。

替换的过程称为“宏替换”,也称为“宏展开”。

9.1.1 不带参数的宏定义#define 宏名字符串关于宏定义注意以下几点:(1)字符串不带双引号。

(2)宏名的前后应有空格,以便准确的辨认宏名。

(3)C预处理命令都是以换行符(\n)结尾的,即每条C预处理命令都占用一行;本命令不是语句,其后不要跟分号(;)。

(4)在字符串中如果出现运算符,要注意替换后的结果,通常可以在合适的位置上加括号。

C/C++程序设计【例9.1】求园的周长、面积和球的体积。

#include <stdio.h>#define PI 3.14159//定义宏名PI为3.14159 void main( ) {float l,s,r,v;printf("input redius:\n" );scanf("%f",&r);l=2.0*PI*r;s=P I*r*r;v=3.0/4*PI*r*r*r; // 宏展开后为:v=3.0/4*3.14159*r*r*r printf("l=%10.4f\ns=%10.4f\nv=%10.4f\n",l,s,v);}(5) 宏定义也有定义域,它的定义域是从开始定义处到本程序文件的结尾。

所以一般都将宏定义放在源程序开头。

九章预处理命令

九章预处理命令
#else 程序段2
#endif 若没有宏定义标识符, 则执行程序段1; 否则, 执行程序段2。 3. #if 表达式
程序段1 #else
程序段2 #endif 若表达式的值为真, 则执行程序段1; 否则, 执行程序段2。
会计算出实参值。 (2)宏定义时,包含参数的字符串中的参数外面最好加
一括弧。如: #define s(r号之间不能加空格。
若有定义: #define s (r) PI*r*r 则变为无参宏,展开为:area=(r) PI*r*r(a);
4. 函数与带参宏的区别: (1)函数调用时,要先自右而左计算出实参值;而带参
第九章 预处理命令
第九章 预处理命令
9.1 宏定义 9.2 文件包含 9.3 条件编译
第九章 预处理命令
第九章 预处理命令
第九章 预处理命令
9.1.2 带参的宏定义
1. 形式:#define 宏名(参数表) 包含参数的字符串 例 若有宏定义:#define s(a,b) a*b
且使用该宏:area=s(3,2); 则预编译后,宏展开为:area=3*2;
文件中。
第九章 预处理命令
/*format.h*/ #define PR printf #define NL “\n” #define D “%d” #define D1 D NL /*file1.c*/ #include “format.h” main( ) {int a=1;
PR(D1,a);}
第九章 预处理命令
9.3 条件编译
源程序中的一部分内容只在满足一定条件时才进行编译。
三种形式及功能
1. #ifdef 标识符
2.
程序段1
3. #else

预处理命令ppt

预处理命令ppt

12
第9章 预处理命令
说明 1、正因为带参宏定义本质还是简单字符替换(除了参数 正因为带参宏定义本质还是简单字符替换( 替换),所以容易发生错误。 ),所以容易发生错误 替换),所以容易发生错误。 不再是求 :#define 例:#define S(r) 3.14*r*r 面积了。 面积了。
宏展开
13
第9章 预处理命令
说明 3、带参数的宏定义与函数的本质区别 1)函数调用时,先求表达式的值,然后将值传递给形参; 函数调用时,先求表达式的值,然后将值传递给形参; 带参宏展开只在编译时进行的简单字符置换。 带参宏展开只在编译时进行的简单字符置换。 2)函数调用是在程序运行时处理的,给形参分配临时的 函数调用是在程序运行时处理的, 内存单元;而宏展开是在编译时进行的, 内存单元;而宏展开是在编译时进行的,展开时并不给 形参分配内存,也不进行“值传递”,也没有“返回值” 形参分配内存,也不进行“值传递” 也没有“返回值” 的概念。 的概念。 3)函数的形参要定义类型,且要求形参、实参类型一致。 函数的形参要定义类型,且要求形参、实参类型一致。 宏不存在参数类型问题。 宏不存在参数类型问题。 4)宏占用的是编译时间,函数调用占用的是运行时间。 宏占用的是编译时间,函数调用占用的是运行时间。 在多次调用时,宏使得程序变长,而函数调用不明显。 在多次调用时,宏使得程序变长,而函数调用不明显。
#define 编译预处理 #include 编译 连接 执行 宏定义 文件包含 条件编译
3
第9章 预处理命令
二、宏定义
(一)不带参数的宏定义
(二)带参数宏定义
4
第9章 预处理命令
(一)不带参数的宏定义(简单替换) 不带参数的宏定义(简单替换)

二级c语言第九讲义章预处理命令

二级c语言第九讲义章预处理命令

预处理命令
C语言提供的预处理命令有三种:
1、宏定义 2、文件包含 3、条件编译
2021/1/13
工程训练中心 徐国海
一、宏定义
宏定义是用一个标识符来代表一个字符串,其中标识符称为宏名。在编 译预处理时,将会把宏名替换成它所代表的字符串,这个过程称为宏展开。
(一)无参数宏定义 无参数宏定义的一般格式为: #define 标识符 字符串 其中,标识符为用户自定义的合法的标识符,即宏名。
⑵ 宏定义是用宏名代替一个字符串,只做简单的替代,不做正确性检查。如 果字符串书写错误,预处理时也照样进行替换。
⑶ 用宏名来代替字符串,可以减少程序输入过程中重复输入的某些字符串。
⑷ 宏定义时如果在行末有分号,则替换时连分号一起进行替换。例如:
#define X 5; …… s=X*8; ……
则经过宏展开后,该语句为:s=5;*8。显然出现语法错误。因此在宏定义 时,行末不要加分号。
精品jing
二级c语言第九章预处理命令
预处理命令概述
所谓预处理,就是指源程序被正式编译之前所进行的处理工作,这 是C语言和其他高级语言之间的一个重要区别。
所有的预处理指令均以“#”开头,在它前面不能出现空格以外的字 符,而且在行结尾处没有分号。
“预处理命令” 的作用不是实现程序的功能,它们是发布给编译系 统的信息。它们告诉编译系统,在对源程序进行编译之前应该做些什么, 所以称这类语句为编译预处理命令。
工程训练中心 徐国海
(二)带参数宏定义 (了解) 定义的一般格式为: #define 宏名(形式参数列表) 字符串
其中,字符串应包含括号中所指定的形式参数。 注意:宏名与括号之间不要有空格,否则就被认为是不带参数的宏定义。

C语言程序设计_谭浩强_第二版_CH09

C语言程序设计_谭浩强_第二版_CH09

第九章 预处理命令 9.1 宏定义 9.1.1 不带参数的宏定义
用一个指定的标识符来代表一个字符串,它的一般形式 为: #define PI 3.1415926 它的作用是用指定标识符PI来代替“3.1415926”这个字 符串。
① ② ③ ④ ⑤ ⑥ ⑦ 一般习惯用大写字母来表示 可以减少某些重复输入字符串的工作量 用来替换一个字符串 宏定义不是C语句,不必在语句末加分号 用#define定义宏 用#undef取消宏定义 在进行宏定义时,可以引用已定义的宏名
第九章 预处理命令 9.3 条件编译
一般情况下,源程序中所有的代码都参加编译,但是有时希望对其 中的一部代码只有在满足一定条件才进行编译,也就是对一部分内容指 定编译的条件,这就是“条件编译”。 #ifdef Identifier program_segment_1 #else program_segment_2 #endif 例如: #ifdef PROMOTION /*如果定义了促销*/ #define DISCOUNT 0.95 /*折扣为0.95*/ #else #define DISCOUNT 1.00 /*折扣为1.00*/ #endif
第九章 预处理命令 9.3 条件编译
#ifndef Identifier program_segment_1 #else program_segment_2 #endif
#if Expression program_segment_1 #else program_segment_2 #endif
C程序设计
第九章 预处理命令
主讲人:兰强 raansan@
第九章 预处理命令
主要内容:
宏定义 文件包含处理 条ห้องสมุดไป่ตู้编译

第九章 预处理命令

第九章  预处理命令
2) 函数调用要为形参分配内存单元,而宏调用不涉及, 不进行值的传递处理,也没有“返回值”的概念;
3) 函数定义时,形参和实参类型要一致,而宏不存在类 型问题,只是简单的字符串替换;
计算机系软件教研室
预处理命令
带参数的宏定义

宏定义
带参数的宏与函数的比较: 4) 函数的 return 只能返回一个值,而宏可以设法 得到 n 个结果; [例] 见教材Page 192
计算机系软件教研室
预处理命令
带参数的宏定义

宏定义
一般形式:#define 宏名(参数表) 例如: #define S(a,b) a*b area=S(3,2);
字符串

展开过程:按#define命令中指定的字符串从左到右进行替换 ,字符串中带有形参的话,首先用相应的实参去替换,形成 新的字符串,然后去替换宏。

5) 被包含文件中若有全局静态变量,则在包含文件中也 是有效的,并且不必用extern说明。
计算机系软件教研室
预处理命令


“文件包含”处理

一个程序经过了一段时间工作后,可能积累了一批符号 常数和带参数的宏定义语句。在编写新程序时经常要使 用它们,可以将这些符号常数和宏定义汇集起来单独构 成一个文件,然后用预处理语句#include将它们包含进 新程序中。 预处理提供的文件包含能力不仅减少了重复性工作,而 且如果因宏定义出错或某种原因需要修改某些宏定义语 句时,不必对使用这些宏定义的各个程序文件分别进行 修改,这种工作方式同样减轻了程序开发的工作量,减 少了人工处理时可能造成的各种错误。
不带参数的宏定义

宏定义
宏定义就是用一个指定的标识符(名字),即“宏名”,来 代表一个字符串。

C程序课件第9章预处理

C程序课件第9章预处理
4 2021/3/20
1、无参宏定义
用一个指定的标识符(即名字)来代 表一个字符串,它的一般形式为:
#define 标识符 字符串 其中的“#”表示这是一条预处理命令。 凡是以“#”开头的均为预处理命令。 “define”为宏定义命令。“标识符”为 所定义的宏名。“字符串”可以是常数、 表达式、格式串等。
2 2021/3/20
所谓预处理是指在进行编译的第一遍扫描(词 法扫描和语法分析)之前所作的工作。预处理是 C 语言的一个重要功能,它由预处理程序负责完 成。当对一个源文件进行编译时,系统将自动引 用预处理程序对源程序中的预处理部分作处理, 处理完毕自动进入对源程序的编译。
C 语言提供了多种预处理功能,如宏定义、文 件包含、条件编译等。分别用宏定义命令、文件 包含命令和条件编译命令来实现。为了与一般C 语句相区别,这些命令以符号“#”开头。合理地 使用预处理功能编写的程序便于阅读、修改、移 植和调试,也有利于模块化程序设计。本章介绍 常用的几种预处理功能。
14 2021/3/20
9)宏定义是专门用于预处理命令的一 个专用名词,它与定义变量的含义不同, 只作字符替换,不分配内存空间。
2、带参数的宏定义
C语言允许宏带有参数。在宏定义中 的参数称为形式参数,在宏调用中的参 数称为实际参数。对带参数的宏,在调 用中,不仅要宏展开,而且要用实参去 代换形参。
f1()
{ …… }
表示PI只在main函数中有效,在f1中无效。
10 2021/3/20
6)宏名在源程序中若用双引号括起来, 则预处理程序不对其作宏代换。 #define OK 100 main() { printf("OK");
printf("\n"); } 上例中定义宏名OK表示100,但在printf语 句中OK被引号括起来,因此不作宏代换。 程序的运行结果为:OK这表示把“OK”当 字符串处理。

c_预处理(九)A

c_预处理(九)A

带参的宏与函数区别
带参宏 处理时间 参数类型 处理过程 程序长度 运行速度 编译时 无类型问题 函数 程序运行时
定义实参,形参类型 不分配内存 分配内存 简单的字符置换 先求实参值,再代入形参 不变 变长 不占运行时间 调用和返回占时间
作业
输入两个e SUPPLUS(a,b) ((a)%(b)) main() { int a,b; printf(“input 2 numbers:”); scanf(“%d,%d”,&a,&b); printf(“The supplus of a,b:%d\n ”,SUPPLUS(a,b) ); }
例:/*----exp3.c---*/ # include <stdio.h> # define PAI 3.14159 main( ) { float r, s; r=2.0; s=PAIrr; printf("s=%5.3f\n", s); #undef PAI r=3.0; s=PAIrr; prinft("s=%5.3f\n", s); } 运行结果: 运行结果 s=12.566 s=28.274 如果在程序中提前终止宏定义,则编译时会提示: undefined symbol 'PAI' in function main
文件f1.c的内容为: 的内容为: 例: 文件 的内容为 其中为f2.c 其中为 # include "f2.c "

: main ( ) { } :
: : :
预编译后: 预编译后 f1.c的内容为:
: :
为f2.c中的内容
main ( ) { : } 再进行正式编译
文件包含
<> 直接按标准目录搜索 功能:一个源文件可将另一个源文件的内容全部 “” 先在当前目录搜索,再搜索标准目录 包含进来 可指定路径 一般形式: #include “文件名” 或 #include <文件名>
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

指针
结构体与共用体
(2)主文件file1.c
#include <stdio.h>
#include "format.h"
• 带参的宏与函数区别
带参宏
函数
处理时间 编译时
程序运行时
参数类型 处理过程
程序长度
无类型问题
定义实参,形参类型
不分配内存
分配内存
简单的字符置换 先求实参值,再代入形参
变长
不变
运行速度 不占运行时间
调用和返回占时间
认识c程序
3个基本要素
数据类型
运算符 表达式 三种典型结构 顺序结构 选择结构 循环结构 预处理 宏定义 文件包含
位运算
文件
算法
认识c程序
3个基本要素
数据类型
运算符
表达式 三种典型结构
顺序结构
例9.6 将例9.5格式宏做成头文件,把它包含在用 户程序中。
选择结构 循环结构 预处理
(1)将格式宏做成头文件 format.h
宏定义 文件包含 条件编译 高级技能
数组 函数
#define PR printf #define NL "\n" #define D "%d" #define D1 D NL #define D2 D D NL #define D3 D D D NL #define D4 D D D D NL #define S "%s"
主要内容
9.1 宏定义 9.2“文件包含”处理 9.3 条件编译
认识c程序
3个基本要素 数据类型 运算符
基本概念
表达式 三种典型结构
顺序结构 选择结构 循环结构 预处理 宏定义 文件包含
• ANSI Байду номын сангаас标准规定可以在C源程序中加入一些“预处理命令” ,以 改进程序设计环境,提高编程效率。
• 这些预处理命令是由ANSI C统一规定的,但是它不是C语言本身的 组成部分,不能直接对它们进行编译(因为编译程序不能识别它 们)。必须在对程序进行通常的编译之前,先对程序中这些特殊 的命令进行“预处理”
area=3*2
结构体与共用体
位运算
文件
算法
认识c程序
3个基本要素
数据类型 例9.3 使用带参的宏
运算符 表达式 三种典型结构 顺序结构 选择结构 循环结构 预处理 宏定义
#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); }
认识c程序
3个基本要素
数据类型
运算符
表达式 三种典型结构
顺序结构 选择结构 循环结构 预处理 宏定义 文件包含 条件编译 高级技能
数组 函数 指针 结构体与共用体
#define G 9.8 void main() {
_______ ↑
G的有效范围
… } #undef G f1() {
-----↓----
1=25.1328 s=50.2655
printf("input radius:"); v=150.7966
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);
算法
认识c程序
3个基本要素 数据类型 运算符
§9.1 宏定义
表达式 三种典型结构
9.1.1 不带参数的宏定义
顺序结构 选择结构
宏定义一般形式为:
循环结构 预处理
宏定义
#define 标识符 字符串 例如:# define PI 3.1415926
文件包含
条件编译 • 宏定义的作用是在本程序文件中用指定的标识符PI来代替
选择结构
循环结构
预处理
宏定义
文件包含 C提供的预处理功能主要有以下三种:
条件编译
1.宏定义
高级技能
2.文件包含
数组
3.条件编译
函数 指针 结构体与共用体 位运算 文件
这些功能分别用宏定义命令、文件包含命令、条件编译命令 来实现。为了与一般C语句相区别,这些命令以符号“#”开头。 例如: #define #include
(2) 在宏定义时,在宏名与带参数的括弧之间不应加空格,否则将空 格以后的字符都作为替代字符串的一部分。
例如: #define S (r) PI*r*r
宏定义
文件包含
条件编译 高级技能
数组 函数 指针
空格
??
此时 S相当于字符串“(r) PI*r*r”
结构体与共用体
位运算
文件
算法
认识c程序
3个基本要素
#include <stdio.h> #define PR printf #define NL "\n" #define D "%d" #define D1 D NL #define D2 D D NL #define D3 D D D NL #define D4 D D D D NL #define S "%s"
2*3.1415926*3.0 S展开为
3.1415926*3.0*3.0
printf函数调用语句展开为:
printf(“L=%F\NS=%f\n”, 2*3.1415926*3.0,3.1415926*3.0*3.0);
认识c程序 3个基本要素 数据类型 运算符 表达式 三种典型结构 顺序结构 选择结构 循环结构 预处理 宏定义 文件包含 条件编译 高级技能 数组 函数 指针 结构体与共用体 位运算 文件 算法
高级技能
“3.1415926”这个字符串,在编译预处理时,将程序中在该命令以
数组
后出现的所有的PI都用“3.1415926”代替。这种方法使用户能以一
函数
个简单的名字代替一个长的字符串.
指针 • 这个标识符(名字)称为“宏名”
结构体与共用体 • 在预编译时将宏名替换成字符串的过程称为“宏展开”
位运算 • #define是宏定义命令。
文件
算法
认识c程序
3个基本要素
数据类型
运算符
表达式 三种典型结构
顺序结构 选择结构 循环结构 预处理 宏定义 文件包含 条件编译 高级技能
数组 函数 指针 结构体与共用体
例9.1 使用不带参数的宏定义
运行情况如下:
#include <stdio.h>
input radius: 4↙
#define PI 3.1415926 void main() {float l,s,r,v;
说明:
(8) 对程序中用双撇号括起来的字符串内的字符,即使与宏名相同, 也不进行置换。
(9) 宏定义是专门用于预处理命令的一个专用名词,它与定义变量 的含义不同,只作字符替换,不分配内存空间!
认识c程序
3个基本要素
数据类型 运算符
9.1.2 带参数的宏定义
表达式 三种典型结构
顺序结构 选择结构
作用:不是进行简单的字符串替换,还要进行参数替换, 类似“函数调用” 。
说明:
(4) 宏定义不是C语句,不必在行末加分号。如果加了分号则会 连分号一起进行置换。
(5) #define命令出现在程序中函数的外面,宏名的有效范围为 定义命令之后到本源文件结束。通常,#define命令写在文件 开头,函数之前,作为文件一部分,在此文件范围内有效。
(6) 可以用#undef命令终止宏定义的作用域。 例如: (见下页)

}
在f1函数中,G不再代表
9.8。这样可以灵活控制宏
定义的作用范围。
位运算
文件
算法
认识c程序
3个基本要素 数据类型
说明:
运算符
表达式 三种典型结构
(7) 在进行宏定义时,可以引用已定义的宏名,可以层层置换。
顺序结构
选择结构 例9.2 在宏定义中引用已定义的宏名
循环结构
预处理 宏定义
运行情况如下:
L=18.849556 S=28.274333
文件
算法
认识c程序 3个基本要素 数据类型 运算符 表达式 三种典型结构 顺序结构 选择结构 循环结构 预处理 宏定义 文件包含 条件编译 高级技能 数组 函数 指针 结构体与共用体 位运算 文件 算法
经过宏展开后,printf函数中的输出项L被 展开为:
选择结构
循环结构 预处理
宏定义 文件包含
其一般形式为:
• #include <文件名> 直接按C编译环境的标准目录搜索! • #include “文件名” 先在“ ”里面给出的路径搜索,如果没找到,再按标准
目录和系统环境文件“path”定义的路径的顺序搜索!
条件编译
高级技能
数组
函数
指针
结构体与共用体
• 经过编译预处理后,程序可由编译程序对预处理后的源程序进行 通常的编译处理,得到可供执行的目标代码。
条件编译
高级技能
数组
函数
指针
结构体与共用体
位运算
文件
算法
认识c程序
3个基本要素 数据类型 运算符
基本概念
表达式 三种典型结构
顺序结构
相关文档
最新文档