第七章编译预处理
《C语言程序设计》基本知识点

《C语言程序设计》基本知识点第一章C语言基本知识1.C源程序的框架尽管各个C源程序的功能千变万化,但框架是不变的,主要有:编译预处理、主函数()、函数n()等,主函数的位置不一定在最前面,可以在程序的中部或后面,主函数的名字固定为main。
2.C语言源程序的书写规则:(1)C源程序是由一个主函数和若干个其它函数组成的。
(2)函数名后必须有小括号,函数体放在大括号内。
(3)C程序必须用小写字母书写。
(4)每句的末尾加分号。
(5)可以一行多句。
(6)可以一句多行。
(7)可以在程序的任何位置加注释。
3.语句种类语句是程序的基本成分,程序的执行就是通过一条条语句的执行而得以实现的,根据表现形式及功能的不同,C语言的基本语句可以分为五大类。
(1)流程控制语句流程控制语句的功能是控制程序的走向,程序的流程有三种基本结构:顺序结构、分支结构和循环结构,任何复杂的程序都可以由这三种基本结构复合而成。
其中后两种结构要用特定的流程控制语句实现。
(2)表达式语句表达式语句的形式是:表达式;,即表达式后跟一分号“;”,分号是语句结束符,是一个语句必不可少的成分。
表达式和表达式语句的区别在于表达式代表的是一个数值,而表达式语句则代表一种动作。
最常见的表达式语句是赋值语句。
(3)函数调用语句函数调用语句实际上也是一种表达式语句,形式为:在一次函数调用的小括号后面加上一个分号。
(4)空语句空语句的形式就是一个分号,它不代表任何动作,常常作为一个意义转折点使用。
(5)复合语句复合语句从形式上看是多个语句的组合,但在语法意义上它只相当于一个语句,在任何单一语句存在的地方都可以是复合语句。
注意复合语句中最后一个语句末尾的分号不能少。
复合语句右大括号后面没有分号。
4.运算符用来表示数据各种操作的符号称为运算符。
运算符实际上代表了一种类型数据的运算规则。
不同的运算符具有不同的运算规则,其操作的数据类型必须符合该运算符的要求,运算结果的数据类型也是固定的。
程序编译的四个步骤

程序编译的四个步骤程序编译通常涉及以下四个步骤:预处理、编译、汇编和链接。
1.预处理预处理是编译过程的第一步,它主要负责对源代码进行一些预处理操作。
预处理器工具通常被称为预处理程序,它会根据源代码文件中的预处理指令来修改源代码。
预处理指令位于源代码文件的开头,以“#”字符开头。
预处理指令主要包括宏定义、条件编译和包含文件等。
在预处理阶段,预处理器会执行以下操作:-展开宏定义:将代码中的宏定义替换为相应的代码片段。
-处理条件编译:根据条件编译指令的结果,决定是否包含或排除一些代码。
-处理包含文件:将文件中的包含文件指令替换为实际的文件内容。
预处理后的源代码通常会生成一个中间文件,供下一步编译使用。
2.编译编译是程序编译过程的第二个阶段。
在编译阶段,编译器将预处理生成的中间文件翻译成汇编语言。
编译器会按照源代码的语法规则,将源代码转换为汇编语言指令,生成目标文件(也称为汇编代码文件)。
编译器在编译过程中执行以下操作:-词法分析:将源代码分割为多个词法单元,如关键字、标识符和运算符等。
-语法分析:根据语言的语法规则,分析词法单元的组合,生成语法树。
-语义分析:检查语法树的语义正确性,进行类型检查等。
-优化:对生成的中间代码进行各种优化,以提高程序执行效率。
编译器输出的目标文件通常是汇编语言形式的代码,以便下一步汇编使用。
3.汇编汇编是编译过程的第三个阶段,它将编译器生成的汇编代码翻译成目标机器码。
汇编器(或称为汇编程序)将汇编代码中的指令和操作数翻译为目标机器指令的二进制表示。
汇编器在汇编过程中执行以下操作:-识别和解析汇编指令:将汇编代码中的汇编指令和操作数分割解析。
-确定存储器地址:根据符号的引用和定义,计算并分配存储器地址。
-生成目标机器指令:将汇编指令和操作数翻译为目标机器指令的二进制表示。
汇编器的输出是一个或多个目标文件,每个目标文件都包含可在目标机器上执行的二进制指令。
4.链接链接是编译的最后一个阶段,它将多个目标文件和库文件组合在一起,生成最终的可执行文件。
编译预处理的作用

编译预处理的作用编译预处理是编译器在编译源代码之前所进行的一系列处理,它的主要作用是对源代码进行一些预处理,以便于编译器更好地进行编译。
编译预处理的主要任务包括宏定义、文件包含、条件编译等。
本文将从这些方面来介绍编译预处理的作用。
一、宏定义宏定义是编译预处理中最常用的功能之一。
它可以将一些常用的代码片段定义为宏,以便于在程序中多次使用。
例如,我们可以将一个常用的输出语句定义为宏:#define PRINTF(x) printf("%d\n", x)这样,在程序中就可以直接使用PRINTF(x)来输出x的值了。
宏定义的好处在于可以减少代码量,提高代码的可读性和可维护性。
二、文件包含文件包含是编译预处理中另一个重要的功能。
它可以将一个或多个头文件包含到源代码中,以便于使用头文件中定义的函数和变量。
例如,我们可以在程序中包含stdio.h头文件:#include <stdio.h>这样,在程序中就可以使用stdio.h中定义的函数和变量了。
文件包含的好处在于可以将一些常用的函数和变量封装到头文件中,以便于在多个程序中共享使用。
三、条件编译条件编译是编译预处理中最灵活的功能之一。
它可以根据不同的条件编译不同的代码,以便于在不同的平台上运行程序。
例如,我们可以使用#ifdef和#endif来判断是否定义了某个宏:#ifdef DEBUGprintf("debug mode\n");#endif这样,在程序中就可以根据是否定义了DEBUG宏来输出不同的信息了。
条件编译的好处在于可以根据不同的平台和需求编译不同的代码,以提高程序的灵活性和可移植性。
四、其他功能除了宏定义、文件包含和条件编译外,编译预处理还有一些其他的功能,如注释删除、行连接、字符转义等。
这些功能虽然不如前面三个功能重要,但也对编译器的编译效率和代码的可读性有一定的影响。
编译预处理是编译器在编译源代码之前所进行的一系列处理,它的主要作用是对源代码进行一些预处理,以便于编译器更好地进行编译。
(完整版)《C语言程序设计》基本知识点

《C语言程序设计》教学基本知识点第一章C语言基本知识1.C源程序的框架尽管各个C源程序的功能千变万化,但框架是不变的,主要有:编译预处理、主函数()、函数n()等,主函数的位置不一定在最前面,可以在程序的中部或后面,主函数的名字固定为main。
2.C语言源程序的书写规则:(1)C源程序是由一个主函数和若干个其它函数组成的。
(2)函数名后必须有小括号,函数体放在大括号内。
(3)C程序必须用小写字母书写。
(4)每句的末尾加分号。
(5)可以一行多句。
(6)可以一句多行。
(7)可以在程序的任何位置加注释。
3.语句种类语句是程序的基本成分,程序的执行就是通过一条条语句的执行而得以实现的,根据表现形式及功能的不同,C语言的基本语句可以分为五大类。
(1)流程控制语句流程控制语句的功能是控制程序的走向,程序的流程有三种基本结构:顺序结构、分支结构和循环结构,任何复杂的程序都可以由这三种基本结构复合而成。
其中后两种结构要用特定的流程控制语句实现。
(2)表达式语句表达式语句的形式是:表达式;,即表达式后跟一分号“;”,分号是语句结束符,是一个语句必不可少的成分。
表达式和表达式语句的区别在于表达式代表的是一个数值,而表达式语句则代表一种动作。
最常见的表达式语句是赋值语句。
(3)函数调用语句函数调用语句实际上也是一种表达式语句,形式为:在一次函数调用的小括号后面加上一个分号。
(4)空语句空语句的形式就是一个分号,它不代表任何动作,常常作为一个意义转折点使用。
(5)复合语句复合语句从形式上看是多个语句的组合,但在语法意义上它只相当于一个语句,在任何单一语句存在的地方都可以是复合语句。
注意复合语句中最后一个语句末尾的分号不能少。
复合语句右大括号后面没有分号。
4.运算符用来表示数据各种操作的符号称为运算符。
运算符实际上代表了一种类型数据的运算规则。
不同的运算符具有不同的运算规则,其操作的数据类型必须符合该运算符的要求,运算结果的数据类型也是固定的。
C语言题库第7章宏定义与预处理√

第七章宏定义与预处理一.单项选择1. 以下程序的运行结果是( D )。
#include<stdio.h>#define ADD(x) x+xint main ( ){int m=1,n=2,k=3,sum ;sum = ADD(m+n)*k ;printf(“%d\n”,sum) ;return 0;}A.18B.9C.12D.102. 以下程序的运行结果是( C )。
#include<stdio.h>#define MIN(x,y) (x)>(y) ? (x) : (y)int main ( ) {int i=10, j=15 , k;k = 10*MIN(i,j);printf(“%d\n”,k);return 0;}A.15B.100C.10D.1503. 以下程序的运行结果是( A )。
#include<stdio.h>#define X 5#define Y X+1#define Z Y*X/2int main ( ) {int a=Y;printf(“%d\n”,Z);printf(“%d\n”,--a);return 0;}A.75B.125C.76D.1264. 以下程序的运行结果是( C )。
#include<stdio.h>#define DOUBLE(r) r*rint main ( ) {int x=1,y=2,t;t = DOUBLE(x+y) ;printf (“%d\n”,t); return 0;}A.7B.6C.5D.85. 在“文件包含”预处理命令形式中,当#include后面的文件名用””(双引号)括起时,寻找被包含文件的方式是( C )。
A.仅仅搜索源程序所在目录B.直接按系统设定的标准方式搜索目录C.先在源程序所在目录中搜索,再按系统设定的标准方式搜索D.仅仅搜索当前目录6. 若有定义#define N 2#define Y(n) ((N+1)*n)则执行语句z=2*(N+Y(5));后,z的值为( C )。
预编译处理

预编译处理【学习目标】◇理解编译预处理的概念。
◇了解宏定义的概念,掌握简单宏定义和带参数的宏定义的格式和使用方法。
◇了解文件包含的概念,掌握文件包含的格式和使用方法。
能在程序中合理使用#include预处理指令◇了解条件编译的概念,掌握条件编译的三种格式及其使用方法。
能在程序中合理使用#define, #if, #ifndef, #else, #undef, #elif等指令。
【重点和难点】重点:编译预处理的概念,简单的宏定义与文件包含指令的用法。
难点:带参宏定义,条件编译指令,会用条件指令解决文件的重复包含问题。
【学习方法指导】本章的内容比较简单,严格说来,它也不算是C++语言的组成部分。
但是,一般说来,任何程序都离不开预编译指令。
特别是文件包含指令和条件编译指令,应把它们搞清楚。
虽然可以用宏定义的方法定义常数,但推荐使用const语句定义常量。
在编程中,如果我们能恰当地运用条件编译,就可以提高程序运行的效率。
【知识点】宏定义;宏替换;简单的宏定义;带参数的宏定义;文件包含;条件编译第一节宏定义我们用C++进行编程的时候,可以在源程序中包括一些编译命令,以告诉编译器对源程序如何进行编译。
这些命令包括:宏定义、文件包含和条件编译,由于这些命令是在程序编译的时候被执行的,也就是说,在源程序编译以前,先处理这些编译命令,所以,我们也把它们称之为编译预处理,本章将对这方面的内容加以介绍。
实际上,编译预处理命令不能算是C++语言的一部分,但它扩展了C++程序设计的能力,合理地使用编译预处理功能,可以使得编写的程序便于阅读、修改、移植和调试。
预处理命令共同的语法规则如下:◇所有的预处理命令在程序中都是以"#"来引导如"#include "stdio.h""。
◇每一条预处理命令必须单独占用一行,如"#include "stdio.h" #include <stdlib.h>" 是不允许的。
编译的整个过程:预编译、编译、汇编、链接

编译的整个过程:预编译、编译、汇编、链接编译分为四个步骤:每个步骤将⽂件编译成别的格式,如下:详解:1.预编译:预编译过程主要做4件事:①展开头⽂件在写有#include <filename>或#include "filename"的⽂件中,将⽂件filename展开,通俗来说就是将fiename⽂件中的代码写⼊到当前⽂件中;②宏替换③去掉注释④条件编译即对#ifndef #define #endif进⾏判断检查,也正是在这⼀步,#ifndef #define #endif的作⽤体现出来,即防⽌头⽂件被多次重复引⽤2.编译将代码转成汇编代码,并且在这个步骤中做了两件很重要的⼯作:①编译器在每个⽂件中保存⼀个函数地址符表,该表中存储着当前⽂件内包含的各个函数的地址;②因为这步要⽣成汇编代码,即⼀条⼀条的指令,⽽调⽤函数的代码会被编译成⼀条call指令,call指令后⾯跟的是jmp指令的汇编代码地址,⽽jmp指令后⾯跟的才是“被调⽤的函数编译成汇编代码后的第⼀条指令”的地址,但是给call指令后⾯补充上地址的⼯作是在链接的时候做的事情。
3.汇编将汇编代码转成机器码4.链接编译器将⽣产的多个.o⽂件链接到⼀起⽣成⼀个可执⾏.exe⽂件;但是在这个过程中,编译器做的⼀个重要的事情是将每个⽂件中call指令后⾯的地址补充上;⽅式是从当前⽂件的函数地址符表中开始找,如果没有,继续向别的⽂件的函数地址符表中找,找到后填补在call指令后⾯,如果找不到,则链接失败。
举例:说实话,很多⼈做了很久的C/C++,也⽤了很多IDE,但是对于可执⾏程序的底层⽣成⼀⽚茫然,这⽆疑是⼀种悲哀,可以想象到⼤公司⾯试正好被问到这样的问题,有多悲催不⾔⽽喻,这⾥正由于换⼯作的缘故,所以打算系统的把之前⽤到的C/C++补⼀补。
这⾥权且当做抛砖引⽟,⼤神飘过。
【总述】从⼀个源⽂件(.c)到可执⾏程序到底经历了哪⼏步,我想⼤多数的⼈都知道,到时到底每⼀步都做了什么,我估计也没多少⼈能够说得清清楚楚,明明⽩⽩。
程序编译的四个阶段

程序编译的四个阶段
四个阶段分别是: 预处理,编译,组装,链接
1. 预处理将头⽂件展开,将宏定义替换,⽣成符号⽂件.S
2. 编译则包含了词法检查,语法检查,权限检查, 代码优化
3. 组装:将编译后的代码组装成机器码,形成位置⽆关的⽬标⽂件 .o
4. 链接将多个位置⽆关的⽬标⽂件合并成可执⾏⽂件
可见组装才是平台相关的,之前的操作都与平台⽆关,换句话说是编译前端和编译后端
具体有个例⼦
⼀个类的成员变量修改了访问控制符,在另外⼀个⽂件被引⽤,是否必须编译修改的⽂件才能链接成功?答案是不需要
例如我们有 abc.hpp abc.cpp 定义了⼀个class
class a {
public:
int a = 0;
};
在main.cpp 中有引⽤
int main(){
a a;
std::cout << a.a;
}
这样是可以编译成功
# ⽣成main.o abc.o
g++ -c main.cpp abc.cpp
# 链接
g++ -o main main.o abc.o
# 成功
然后修改public为private 重新编译abc
g++ -c abc.cpp
# 重新链接
g++ -o main main.o abc.o
#成功!且可以执⾏
但是重新编译main.cpp
g++ -c main.cpp
#失败,提⽰⽆法访问private成员
可见,访问权限是在编译期检查的,编译成⽬标⽂件后,就不会去检查了
总结
编译成⽬标⽂件或者库⽂件后,不会再去检查权限位了,运⾏时照样可以访问。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
此指令的功能是取消已定义过的宏名,这样一 来,宏名的有效范围变为从该宏定义开始至 对应#undef语句止。 对应#undef语句止。
例 #define PAI 3.1415926 main ( ) { …… } #undef PAI 3.1415926 func ( ) { …… } 则PAI只在main函数中有效,而在func函 PAI只在main函数中有效,而在func函 数中无效。
例 文件包含举例
#include <stdio.h> #include d:\fengyi\bkc\powers.h" #define MAX_POWER 10 void main() { int n; printf("number\t exp2\t exp3\t exp4\n"); printf("----\t----\t-----\t------\n"); for(n=1;n<=MAX_POWER;n+d\t %5d\n",n,sqr(n),cube(n),quad(n)); }
(2)常用在文件头部的被包含文件,称为“标题文 )常用在文件头部的被包含文件,称为“ 头部文件” 常以“ ( 件”或“头部文件”,常以“h”(head)作为后缀,简 )作为后缀, 称头文件。在头文件中,除可包含宏定义外, 称头文件。在头文件中,除可包含宏定义外,还可包含 外部变量定义、结构类型定义等。 外部变量定义、结构类型定义等。 (3)一条包含命令,只能指定一个被包含文件。如 )一条包含命令,只能指定一个被包含文件。 果要包含n个文件 则要用n条包含命令 个文件, 条包含命令。 果要包含 个文件,则要用 条包含命令。 (4)文件包含可以嵌套,即被包含文件中又包含另 )文件包含可以嵌套, 一个文件。 一个文件。
7.2 文件包含
1.文件包含的概念 文件包含是指, 文件包含是指 , 一个源文件可以将另一个源文 件的全部内容包含进来。 件的全部内容包含进来。 2.文件包含处理命令的格式 包含文件名” #include “包含文件名” 或 包含文件名> #include <包含文件名> 两种格式的区别仅在于: 两种格式的区别仅在于: 使用双引号: (1)使用双引号:系统首先到当前目录下查找 被包含文件,如果没找到,再到系统指定的“ 被包含文件 , 如果没找到 , 再到系统指定的 “ 包含 文件目录” 由用户在配置环境时设置)去查找。 文件目录”(由用户在配置环境时设置)去查找。 使用尖括号:直接到系统指定的“ (2)使用尖括号:直接到系统指定的“包含文 件目录”去查找。一般地说,使用双引号比较保险。 件目录 ” 去查找 。 一般地说 , 使用双引号比较保险 。
3.说明 . (1)宏名一般用大写字母表示,以示与变量区别。但这并 )宏名一般用大写字母表示,以示与变量区别。 非是规定。 非是规定。 (2)宏定义不是C语句,所以不能在行尾加分号。否则, )宏定义不是C语句,所以不能在行尾加分号。否则, 宏展开时,会将分号作为字符串的1个字符 用于替换宏名。 个字符, 宏展开时,会将分号作为字符串的 个字符,用于替换宏名。 (3)在宏展开时,预处理程序仅以按宏定义简单替换宏名, )在宏展开时,预处理程序仅以按宏定义简单替换宏名, 而不作任何检查。如果有错误, 而不作任何检查。如果有错误,只能由编译程序在编译宏展开 后的源程序时发现。 后的源程序时发现。 出现在函数的外部, ( 4) 宏定义命令 ) 宏定义命令#define出现在函数的外部 , 宏名的有效 出现在函数的外部 范围是:从定义命令之后, 到本文件结束。通常, 范围是 : 从定义命令之后, 到本文件结束。 通常 ,宏定义命 令放在文件开头处。 令放在文件开头处。 (5)在进行宏定义时,可以引用已定义的宏名 。 )在进行宏定义时, (6)对双引号括起来的字符串内的字符,即使与宏名同名, )对双引号括起来的字符串内的字符,即使与宏名同名, 也不进行宏展开。 也不进行宏展开。
3.文件包含的优点 . 一个大程序,通常分为多个模块, 一个大程序 , 通常分为多个模块 , 并由多个程序员 分别编程。有了文件包含处理功能, 分别编程。有了文件包含处理功能,就可以将多个模块 共用的数据(如符号常量和数据结构)或函数, 共用的数据 ( 如符号常量和数据结构)或函数,集中到 一个单独的文件中。这样, 一个单独的文件中。 这样,凡是要使用其中数据或调用 其中函数的程序员,只要使用文件包含处理功能, 其中函数的程序员, 只要使用文件包含处理功能, 将所 需文件包含进来即可,不必再重复定义它们, 需文件包含进来即可, 不必再重复定义它们,从而减少 重复劳动。 重复劳动。 4.说明 . (1)编译预处理时,预处理程序将查找指定的被包 )编译预处理时, 含文件,并将其复制到#include命令出现的位置上。 命令出现的位置上。 含文件,并将其复制到 命令出现的位置上
语言中, 在 C 语言中 , “ 宏 ” 分为无参数的 简称无参宏) 和有参数的宏( 宏 ( 简称无参宏 ) 和有参数的宏 ( 简称 有参宏)两种。 有参宏)两种。
7.1.1 无参宏定义 7.1.2 符号常量 7.1.3 有参宏定义
7.1.1 无参宏定义
1.无参宏定义的一般格式 #define 标识符 语言符号字符串 其中: “ define” 为宏定义命令 ; “ 标识符 ” 其中 : define” 为宏定义命令; 标识符” 为所定义的宏名,通常用大写字母表示, 为所定义的宏名,通常用大写字母表示,以便于 与变量区别; 语言符号字符串”可以是常数、 与变量区别;“语言符号字符串”可以是常数、 表达式、格式串等。 表达式、格式串等。 2.使用宏定义的优点 (1)可提高源程序的可维护性 ( 2 ) 减少源程序中重复书写字符串的工作 量
第七章
编译预处理
编译预处理是指在编译系统对文件进行 编译——词法分析、语法分析、代码生成 编译——词法分析、语法分析、代码生成 及优化之前,对一些特殊的编译语句先进 行处理,然后将处理的结果与源程序一起 编译,生成目标文件。
7.1 宏定义 7.2 “文件包含”处理 文件包含” 文件包含
7.1 宏定义
7.1.2 符号常量
在定义无参宏时,如果“语言符号字符串” 在定义无参宏时,如果“语言符号字符串” 是一个常量,则相应的“宏名” 是一个常量,则相应的“宏名”就是一个符号 常量。 恰当命名的符号常量,除具有宏定义的上述 优点外,还能表达出它所代表常量的实际含义, 从而增强程序的可读性。 #define EOF -1 /*文件尾*/ /*文件尾* #define NULL 0 /*空指针*/ /*空指针* #define MIN 1 /*极小值*/ /*极小值* #define MAX 31 /*极大值*/ /*极大值* #define STEP 2 /*步长*/ /*步长*
7.1.3 有参宏定义
例 #define POWER(x) x*x x=4; y=6; z=POWER(x+y); 宏展开: 宏展开:z=x+y*x+y; 一般写成: 一般写成: #define POWER(x) (( x ) * ( x )) 宏展开: 宏展开: z=((x+y)*(x+y));
/* powers.h */ #define sqr(x) ((x)*(x)) #define cube(x) ((x)*(x)*(x)) #define quad(x) (x)*(x)*(x)*(x))
例:#define PI 3.14; area=PI*r*r; 经过宏展开后,该语句为: 经过宏展开后,该语句为: area=3.14;*r*r; 例: #define R 3.0 #define PI 3.1415926 #define L 2*PI*R #define S PI*R*R main() {printf(“L=%f\n s=%f\n”,L,S);}
1.带参宏定义的一般格式 #define 宏名(形参表) 语言符号字符串 宏名(形参表) 2.带参宏的调用和宏展开 (1)调用格式:宏名(实参表) 调用格式:宏名 实参表) 宏名( (2)宏展开:用宏调用提供的实参字符串,直接置 换宏定义命令行中相应形参字符串,非形参字符保持不 变。 3.说明
(1) 定义有参宏时 , 宏名与左圆括号之间不能留有空格。 定义有参宏时, 宏名与左圆括号之间不能留有空格 。 否则,C编译系统将空格以后的所有字符均作为替代字符串, 否则,C编译系统将空格以后的所有字符均作为替代字符串,而 将该宏视为无参宏。 将该宏视为无参宏。 ( 2) 有参宏的展开, 只是将实参作为字符串, 简单地置换 有参宏的展开 , 只是将实参作为字符串 , 形参字符串,而不做任何语法检查。在定义有参宏时, 形参字符串,而不做任何语法检查。在定义有参宏时,在所有形 参外和整个字符串外,均加一对圆括号。 参外和整个字符串外,均加一对圆括号。
#define f(x) x*x void main( ) { int i; i=f(4+4)/f(2+2); printf(“%d\ printf(“%d\n”,i); }
例 用宏定义和函数实现同样的功能
#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);
[案例7.1] 输入圆的半径,求圆的周长、面积和球的体积。 案例7 输入圆的半径,求圆的周长、面积和球的体积。 要求使用无参宏定义圆周率。 要求使用无参宏定义圆周率。 #define PI 3.1415926 /*PI 是 宏 名 , 3.1415926 用 来 替换宏名的常数* 替换宏名的常数*/ void main() { float radius,length,area,volume; radius,length,area,volume; printf("Input a radius: "); radius: "); scanf("%f",&radius); scanf("%f",&radius); length=2*PI*radius; length=2*PI*radius; area=PI*radius*radius; area=PI*radius*radius; volume=PI*radius*radius*radius*3 volume=PI*radius*radius*radius*3/4; printf("length=% f,area=% f,volume=% printf("length=%.2f,area=%.2f,volume=%.2f\n", length, area, volume); volume); }