第六章 编译预处理

36
第第第 第第第第第 第第第 第第第第第 第第第第第第第第第第第第 第第第第第第第第第第第第第第第第第第第第第第第第第第第第第第第第第第第第 第第第第第第第第第第第第第第第第第第第第第第第第第第第第第第第第第第 第第第第第第第第第第第第第第第第第第第第第第第第第第第第 第第第第第第第第第第第第第第第第第第第第第第第第第第第第

Upload: iorwen

Post on 26-Jan-2016

67 views

Category:

Documents


4 download

DESCRIPTION

第六章 编译预处理. 本章学习重点: 掌握不带参数的宏定义的格式及使用方法; 掌握带参数的宏定义的格式及使用方法; 掌握文件包含的格式及使用方法; 掌握条件编译的格式及使用方法。. 第十四讲宏定义、文件包含 和条件编译. 一、不带参数的宏定义 二、带参数的宏定义 三、文件包含处理 四、条件编译 练一练 本章小结. 结束. 一、不带参数的宏定义. 【思考题 6-1 】 输入圆的半径,求圆的周长、面积(要求使用无参宏定义圆周率)。 ( 一 )程序分析 在程序中要用到无参宏定义,要注意例程开头的宏定义语句的书写格式,掌握程序在编译之前怎样替换该宏?. - PowerPoint PPT Presentation

TRANSCRIPT

第六章 编译预处理第六章 编译预处理本章学习重点:本章学习重点: 掌握不带参数的宏定义的格式及使用方法;掌握不带参数的宏定义的格式及使用方法; 掌握带参数的宏定义的格式及使用方法;掌握带参数的宏定义的格式及使用方法; 掌握文件包含的格式及使用方法;掌握文件包含的格式及使用方法; 掌握条件编译的格式及使用方法。掌握条件编译的格式及使用方法。

第十四讲宏定义、文件包含第十四讲宏定义、文件包含和条件编译和条件编译

一、不带参数的宏定义二、带参数的宏定义三、文件包含处理四、条件编译练一练本章小结

结束

一、不带参数的宏定义一、不带参数的宏定义【思考题【思考题 6-16-1 】】 输入圆的半径,求圆的周长、面积输入圆的半径,求圆的周长、面积

(要求使用无参宏定义圆周率)。(要求使用无参宏定义圆周率)。 ((一一)程序分析)程序分析在程序中要用到无参宏定义,要注意例程开头的宏在程序中要用到无参宏定义,要注意例程开头的宏

定义语句的书写格式,掌握程序在编译之前怎样定义语句的书写格式,掌握程序在编译之前怎样替换该宏?替换该宏?

返回到本章目录

((二二)编写程序代码)编写程序代码如下如下::#define PI 3.1415926 #define PI 3.1415926

/*PI/*PI 是宏名,是宏名, 3.14159263.1415926 为用来替换宏名的常数为用来替换宏名的常数 */*/

main()main()

{ float radius,length,area;{ float radius,length,area;

printf("Input a radius: "); printf("Input a radius: ");

scanf("%f",&radius);scanf("%f",&radius);

length=2*PI*radius; length=2*PI*radius; /*/* 引用无参宏求周长引用无参宏求周长 */*/

area=PI*radius*radius; area=PI*radius*radius; /*/* 引用无参宏求面积引用无参宏求面积 */*/

printf("length=%.2f,area=%.2f\n",length,area);printf("length=%.2f,area=%.2f\n",length,area);

}}

  

返回到本章目录

((三三))调试程序及运行结果调试程序及运行结果程序中输入圆的半径值程序中输入圆的半径值 2.42.4 ,程序的运行结果如,程序的运行结果如

下:下:

返回到本章目录

11 .不带参数的宏定义.不带参数的宏定义(( 11 )不带参数宏定义的一般形式如下:)不带参数宏定义的一般形式如下:

其中,其中, #define#define 是宏定义的命令,标识符和字符串是宏定义的命令,标识符和字符串之间用空格分开。标识符称为“宏名”,通常使之间用空格分开。标识符称为“宏名”,通常使用大写英文字母和有直观意义的标识符命名,以用大写英文字母和有直观意义的标识符命名,以区别于源程序中的其他标识符。字符串又称为宏区别于源程序中的其他标识符。字符串又称为宏体,一般是常数、关键字、语句、表达式,也可体,一般是常数、关键字、语句、表达式,也可以是空白。以是空白。

#define 宏名 字符串 #define 宏名 字符串

返回到本章目录

(( 22 )功能。不带参数的宏定义的功能)功能。不带参数的宏定义的功能是将宏体字符串符号化。在程序中凡是将宏体字符串符号化。在程序中凡出现该宏名的位置,经编译预处理的出现该宏名的位置,经编译预处理的加工,都被替换成对应的宏体字符串,加工,都被替换成对应的宏体字符串,称之为“宏展开”。称之为“宏展开”。

由于宏定义不是由于宏定义不是 CC 语句,不必也不能语句,不必也不能在行末加分号。 在行末加分号。

返回到本章目录

22 .关于宏的几点说明.关于宏的几点说明(( 11 )使用宏名代替一个字符串,可以减少程序中重复书写)使用宏名代替一个字符串,可以减少程序中重复书写

某些字符串的工作量,增加程序的可读性,而且不易出错。某些字符串的工作量,增加程序的可读性,而且不易出错。(( 22 )编译预处理时,将程序中)编译预处理时,将程序中 PIPI 用用 3.14159263.1415926 代替,与代替,与

宏调用的过程相反,这种将宏名替换成字符串的过程称为宏调用的过程相反,这种将宏名替换成字符串的过程称为“宏展开”。“宏展开”。

(( 33 )) CC 语言中,用宏名替换一个字符串是简单的转换过程,语言中,用宏名替换一个字符串是简单的转换过程,不作语法检查。若将宏体的字符串中符号写错了,宏展开不作语法检查。若将宏体的字符串中符号写错了,宏展开时照样代入,只有在编译宏展开后的源程序时才会提示语时照样代入,只有在编译宏展开后的源程序时才会提示语法错误。法错误。

返回到本章目录

22 .关于宏的几点说明.关于宏的几点说明(( 44 )一个宏名只能被定义一次,否则会出现重复)一个宏名只能被定义一次,否则会出现重复

定义的错误。定义的错误。(( 55 )宏定义可以嵌套。在宏体中,可以出现已定)宏定义可以嵌套。在宏体中,可以出现已定

义的宏名,例如:义的宏名,例如:#define PI 3.1415926#define PI 3.1415926

#define PIR (PI*r) /*PI#define PIR (PI*r) /*PI 为已定义的宏名为已定义的宏名 */*/

(( 66 )如果宏定义一行书写不下,可用反斜线“)如果宏定义一行书写不下,可用反斜线“ \\””和回车键来结束本行,然后在下一行继续书写。和回车键来结束本行,然后在下一行继续书写。

返回到本章目录

(( 77 )程序中出现的由双引号括起来的字符串,即)程序中出现的由双引号括起来的字符串,即使和宏名相同,也不进行宏替换。例如,在输出使和宏名相同,也不进行宏替换。例如,在输出函数函数 printf()printf() 中如果在双引号内有与宏名相同的中如果在双引号内有与宏名相同的字符串,也不认为是宏,只认为是普通字符串原字符串,也不认为是宏,只认为是普通字符串原样输出。样输出。

(( 88 )宏定义命令行放在源程序的函数外时,宏名)宏定义命令行放在源程序的函数外时,宏名的作用域从宏定义命令行开始到本源文件结束。的作用域从宏定义命令行开始到本源文件结束。

(( 99 )宏名的作用域可以使用)宏名的作用域可以使用 #undef#undef 命令终止,命令终止,形式如下:形式如下:

22 .关于宏的几点说明.关于宏的几点说明

#undef 标识符#undef 标识符返回到本章目录

【思考题【思考题 6-26-2 】】 求两个数求两个数 aa 和和 bb 中的最大值,要中的最大值,要求用带参数的宏定义来实现。求用带参数的宏定义来实现。

((一一))程序分析 程序分析 这个程序可以使用函数来实现,但这里我们要求用这个程序可以使用函数来实现,但这里我们要求用

带参数的宏定义来实现该功能。要注意带参数的带参数的宏定义来实现该功能。要注意带参数的宏定义的格式及在编译前进行替换的方式。宏定义的格式及在编译前进行替换的方式。

二、带参数的宏定义二、带参数的宏定义

返回到本章目录

((二二))编写程序代码编写程序代码#define MAX(a,b) ((a)>(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b))

/*MAX/*MAX 为带参数的宏定义,为带参数的宏定义, aa 、、 bb 为其参数为其参数 */*/

main()main()

{ int a,b,max;{ int a,b,max;

printf("\nPlease input 2 integer number:");printf("\nPlease input 2 integer number:");

scanf("%d%d",&a,&b);scanf("%d%d",&a,&b);

max=MAX(a,b); /*max=MAX(a,b); /* 求求 aa 和和 bb 中的最大数,中的最大数, MAXMAX 为带参数的宏为带参数的宏定义定义 */*/

printf("the max value is :%d",max);printf("the max value is :%d",max);

}}

  

返回到本章目录

((三三))调试程序及运行结果调试程序及运行结果程序输入两个整数程序输入两个整数 33 和和 55 ,程序运行结果如下:,程序运行结果如下:

返回到本章目录

33 .带参数的宏定义.带参数的宏定义11 )带参数宏定义的一般格式)带参数宏定义的一般格式

22 )带参数的宏的调用和展开)带参数的宏的调用和展开(( 11 )带参数的宏的调用格式如下)带参数的宏的调用格式如下

(( 22 )带参数的宏展开。带参数的宏展开是用宏调)带参数的宏展开。带参数的宏展开是用宏调用提供的实参字符串,直接置换宏定义命令行中用提供的实参字符串,直接置换宏定义命令行中相应形参字符串,非形参字符保持不变。相应形参字符串,非形参字符保持不变。

#define 宏名(形式参数表) 字符串#define 宏名(形式参数表) 字符串

宏名(实参表)宏名(实参表)

返回到本章目录

44 .关于带参数的宏定义的几点说明(.关于带参数的宏定义的几点说明( 11 )定义有参数)定义有参数的宏时,宏名应当与参数表的左括号紧紧相连。否则,的宏时,宏名应当与参数表的左括号紧紧相连。否则,C编译系统将空格以后的所有字符均作为替代字符串,C编译系统将空格以后的所有字符均作为替代字符串,而将该宏视为无参宏。而将该宏视为无参宏。

(( 22 )宏定义时,应将整个字符串以及其中的各个参数)宏定义时,应将整个字符串以及其中的各个参数均用圆括号括起来,以确保宏展开后字符串中各个参均用圆括号括起来,以确保宏展开后字符串中各个参数的计算顺序的正确性,避免出现错误。数的计算顺序的正确性,避免出现错误。

(( 33 )在宏定义中的形参是标识符,而宏展开的实参可)在宏定义中的形参是标识符,而宏展开的实参可以是表达式。 以是表达式。

(( 44 )虽然有参数的宏与有参数的函数确实有相似之处,)虽然有参数的宏与有参数的函数确实有相似之处,但不同之处更多,主要有以下几个方面。但不同之处更多,主要有以下几个方面。

返回到本章目录

① ① 调用有参函数时,是先求出实参的值,然后再复制一份给形参。而展开有参调用有参函数时,是先求出实参的值,然后再复制一份给形参。而展开有参宏时,只是将实参简单地置换形参。宏时,只是将实参简单地置换形参。

② ② 在有参函数中,形参是有类型的,所以要求实参的类型与其一致;而在有参在有参函数中,形参是有类型的,所以要求实参的类型与其一致;而在有参宏中,形参是没有类型信息的,因此用于置换的实参,什么类型都可以。有宏中,形参是没有类型信息的,因此用于置换的实参,什么类型都可以。有时,可利用有参宏的这一特性,实现通用函数的功能。时,可利用有参宏的这一特性,实现通用函数的功能。

③ ③ 函数调用是在程序运行中处理的,临时给它分配存储单元。而宏代换是在编函数调用是在程序运行中处理的,临时给它分配存储单元。而宏代换是在编译时进行的,并不给它分配存储单元,不进行数值的传递,也没有返回值。译时进行的,并不给它分配存储单元,不进行数值的传递,也没有返回值。

④ ④ 函数的形参和实参都要求定义类型,而且二者要求一致,若二者不一致时,函数的形参和实参都要求定义类型,而且二者要求一致,若二者不一致时,还要进行类型转换。而对于宏则不存在此类问题,宏没有类型,参数也没有还要进行类型转换。而对于宏则不存在此类问题,宏没有类型,参数也没有类型,它们都仅是一种符号代表,宏展开时只是进行对应符号的代换。类型,它们都仅是一种符号代表,宏展开时只是进行对应符号的代换。

⑤ ⑤ 在程序中使用宏时,宏展开后源程序会变长。而函数调用不会使源程序变长。在程序中使用宏时,宏展开后源程序会变长。而函数调用不会使源程序变长。⑥ ⑥ 宏代换不占程序运行时间,只占编译时间。而函数调用则占运行时间(分配宏代换不占程序运行时间,只占编译时间。而函数调用则占运行时间(分配

单元、保留现场、值传递、返回)。单元、保留现场、值传递、返回)。

返回到本章目录

三、文件包含处理三、文件包含处理【思考题【思考题 6-36-3 】】 修改【思考题修改【思考题 6-26-2】,要求将【思】,要求将【思

考题考题 6-26-2】中的带参数宏定义语句单独放在一个】中的带参数宏定义语句单独放在一个头文件中,主函数单独放在一个源程序文件中,头文件中,主函数单独放在一个源程序文件中,功能同【思考题功能同【思考题 6-26-2】。】。

((一一))程序分析 程序分析 将一部分内容放到一个头文件中,在编译预处理时,将一部分内容放到一个头文件中,在编译预处理时,

将头文件内容先替换到文件包含语句部分,然后将头文件内容先替换到文件包含语句部分,然后再进行编译。注意头文件和源程序的组成。再进行编译。注意头文件和源程序的组成。

返回到本章目录

((二二))编写程序代码编写程序代码(( 11 )) in6_3.hin6_3.h 的内容:的内容:#define MAX(a,b) ((a)>(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b))

/*MAX/*MAX 为带参数的宏定义,为带参数的宏定义, aa 、、 bb 为其参数为其参数 */*/

(( 22 )主程序内容:)主程序内容:#include "in6_3.h"#include "in6_3.h"

/*/* 文件包含命令,将文件包含命令,将 in6_3.hin6_3.h 头文件包含到该程序中头文件包含到该程序中 */*/

main()main()

{ int a,b,max;{ int a,b,max;

printf("\nPlease input 2 integer number:");printf("\nPlease input 2 integer number:");

scanf("%d%d",&a,&b);scanf("%d%d",&a,&b);

max=MAX(a,b); /*max=MAX(a,b); /* 求求 aa 和和 bb 中的最大数,中的最大数, MAXMAX 为带参数的宏定义为带参数的宏定义 */*/

printf("the max value is :%d",max);printf("the max value is :%d",max);

}}

((三三))调试程序及运行结果调试程序及运行结果程序运行结果同【思考题程序运行结果同【思考题 6-26-2】的例程结果。】的例程结果。

返回到本章目录

55 .文件包含处理.文件包含处理(( 11 )编译预处理的文件包含功能。)编译预处理的文件包含功能。① ① 编译预处理的文件包含功能是一个源程序通过编译预处理的文件包含功能是一个源程序通过

#include#include 命令把另外一个源文件的全部内容嵌入命令把另外一个源文件的全部内容嵌入到源程序中来。到源程序中来。② ② 编译预处理程序把编译预处理程序把 #include#include 命令行中所指定的命令行中所指定的

源文件的全部内容放到源程序的源文件的全部内容放到源程序的 #include#include 命令行命令行所在的位置。所在的位置。③ ③ 在编译时并不是作为两个文件连接,而是作为一在编译时并不是作为两个文件连接,而是作为一

个源程序编译,得到一个目标文件。个源程序编译,得到一个目标文件。

返回到本章目录

(( 22 )文件包含)文件包含 #include#include 命令格式主要有以下两种。命令格式主要有以下两种。① ① 只检索只检索 CC 语言编译系统所确定的标准目录,格式如下:语言编译系统所确定的标准目录,格式如下:

② ② 首先对使用包含文件的源文件所在的目录进行检索,首先对使用包含文件的源文件所在的目录进行检索,若没有找到指定的文件,再在标准目录中检索,格式如若没有找到指定的文件,再在标准目录中检索,格式如下:下:

(( 33 )) #include#include 命令的嵌套使用。当一个程序中使用命令的嵌套使用。当一个程序中使用#include#include 命令嵌入一个指定的包含文件时,被嵌入的文命令嵌入一个指定的包含文件时,被嵌入的文件中还可以使用件中还可以使用 #include#include 命令,又可以包含另外一个命令,又可以包含另外一个指定的包含文件。指定的包含文件。

#include < 文件名 >#include < 文件名 >

#include " 文件名 "#include " 文件名 "

返回到本章目录

四、四、条件条件编译编译【思考题【思考题 6-46-4 】】 输入一行字母字符,根据需要设置输入一行字母字符,根据需要设置

条件编译,使之能将字母全改为大写输出,或全条件编译,使之能将字母全改为大写输出,或全改为小写字母输出。改为小写字母输出。

((一一))程序分析 程序分析 定义一个常量定义一个常量 LETTERLETTER ,通过判断,通过判断 LETTERLETTER 的值的值

来对某些程序进行条件编译。当来对某些程序进行条件编译。当 LETTERLETTER 值为值为 11时将字符串时将字符串 strstr 中的全部字符转换成大写字母,中的全部字符转换成大写字母,否则将大写字母转换成小些字母。注意条件编译否则将大写字母转换成小些字母。注意条件编译的语句格式。的语句格式。

返回到本章目录

((二二)编写程序代码)编写程序代码#include "string.h"#include "string.h"

#define LETTER 1#define LETTER 1

main()main()

{ char str[100], c;{ char str[100], c;

int i;int i;

i=0;i=0;

printf("\nPlease input a string:\n");printf("\nPlease input a string:\n");

gets(str); gets(str); /*/* 注意:如果要输入带空格的字符串必注意:如果要输入带空格的字符串必须用须用 getsgets 函数函数 */*/

返回到本章目录

((三三))调试程序及运行结果调试程序及运行结果输入一个字符串输入一个字符串 "Hello,all the world people!""Hello,all the world people!" ,,

程序将这一串小写字符变成大写字程序将这一串小写字符变成大写字符符 "HELLO,ALL THE WORLD PEOPLE!""HELLO,ALL THE WORLD PEOPLE!" 。程。程序运行结果如下:序运行结果如下:

返回到本章目录

while((c=str[i])!='\0')while((c=str[i])!='\0')

{ i++;{ i++;

#ifdef LETTER#ifdef LETTER

if(c>='a' && c<='z')if(c>='a' && c<='z')

c=c-32;c=c-32;

#else#else

if(c>='A' && c<='Z')if(c>='A' && c<='Z')

c=c+32;c=c+32;

#endif #endif

printf("%c", c);printf("%c", c);

}}

}}

返回到本章目录

66 .条件编译.条件编译所谓条件编译,是指对源程序进行选择性编译。所谓条件编译,是指对源程序进行选择性编译。11 )) #ifdef#ifdef 命令(或命令(或 #ifndef#ifndef 命令)命令)(( 11 )) #ifdef#ifdef 命令的一般格式如下命令的一般格式如下

(( 22 )功能。)功能。 #ifdef#ifdef 命令的功能是如果“标识符”已经命令的功能是如果“标识符”已经被被 #define#define 命令定义过,则编译程序段命令定义过,则编译程序段 11 ,否则编译,否则编译程序段程序段 22 。。

#ifdef 标识符 程序段 1[#else 程序段 2] #endif

#ifdef 标识符 程序段 1[#else 程序段 2] #endif

返回到本章目录

在不同的系统中,一个在不同的系统中,一个 int int 型数据占用的型数据占用的内存字节数可能是不同的。 内存字节数可能是不同的。

利用条件编译,还可使同一源程序既适合利用条件编译,还可使同一源程序既适合于调试(进行程序跟踪、打印较多的状态于调试(进行程序跟踪、打印较多的状态或错误信息),又适合高效执行要求。或错误信息),又适合高效执行要求。

#ifndef#ifndef 命令格式与命令格式与 #ifdef#ifdef 命令一样,功能正命令一样,功能正好与之相反。 好与之相反。

返回到本章目录

22 )) #if#if 命令命令(( 22 )) #if#if 命令一般格式如下:命令一般格式如下:

(( 22 )功能。)功能。 #if#if 命令的功能是当表达式为非命令的功能是当表达式为非 00(“逻辑真”)时,编译程序段(“逻辑真”)时,编译程序段 11 ,否则编译程,否则编译程序段序段 22 。 。

#if 常量表达式 程序段 1[#else 程序段 2]#endif

#if 常量表达式 程序段 1[#else 程序段 2]#endif

返回到本章目录

(( 33 )条件编译和)条件编译和 ifif 语句的区别。语句的区别。①① ifif 语句控制某些语句是否被执行,语句控制某些语句是否被执行, #if#if 命令控制命令控制着某个程序段是否被编译。着某个程序段是否被编译。② ② 用用 ifif 语句调试程序成功后,其调试语句仍被编译语句调试程序成功后,其调试语句仍被编译

成目标代码,只是不再执行,成为废码。而使用成目标代码,只是不再执行,成为废码。而使用条件编译调试程序成功后,其调试语句不再被编条件编译调试程序成功后,其调试语句不再被编译,不生成目标代码,没有废码产生,空间借用译,不生成目标代码,没有废码产生,空间借用率较高。率较高。

返回到本章目录

练一练练一练

【练习【练习 6-16-1 】】 设计一个程序,从设计一个程序,从 33 个数中找最大数,个数中找最大数,用带参数的宏定义实现。用带参数的宏定义实现。解:因为条件语句可以通过一条语句实现求解:因为条件语句可以通过一条语句实现求 33 个数个数

中最大值的功能,所以可以设一个带中最大值的功能,所以可以设一个带 33 个参数的个参数的宏定义,宏的值用一个条件语句来实现。宏定义,宏的值用一个条件语句来实现。

注意注意::在宏体部分的每一个参数和整个宏体都要在宏体部分的每一个参数和整个宏体都要用圆括号括起来,以防止宏展开时出错。用圆括号括起来,以防止宏展开时出错。

返回到本章目录

源程序如下:源程序如下:#define MAX(a,b,c) ((a)>(b)?((a)>(c)?(a):(c)):((b)>(c))?#define MAX(a,b,c) ((a)>(b)?((a)>(c)?(a):(c)):((b)>(c))?

(b):(c))(b):(c))

main()main()

{ int a,b,c,max;{ int a,b,c,max;

printf("\nPlease input 3 int number:");printf("\nPlease input 3 int number:");

scanf("%d%d%d",&a,&b,&c);scanf("%d%d%d",&a,&b,&c);

max= MAX(a,b,c);max= MAX(a,b,c);

printf("\nThe max number is:%d",max);printf("\nThe max number is:%d",max);

}}

程序运行结果如下:程序运行结果如下:

返回到本章目录

【练习【练习 6-26-2 】】 用条件编译方法实现以下功能:输入一用条件编译方法实现以下功能:输入一行电报文字,任选两种输出方式,一为原文输出,二行电报文字,任选两种输出方式,一为原文输出,二为将字母变成其下一个字母(如为将字母变成其下一个字母(如 'a''a'变成变成 'b''b' ,, 'b''b'变变成成 'c''c' ,依次类推,最后,依次类推,最后 'z''z'变成变成 'a''a' ,其他字符不,其他字符不变)。用变)。用 #define#define 命令来控制是否要译成密码,例如:命令来控制是否要译成密码,例如:

#define CHANGE 1 #define CHANGE 1

则输出密码。则输出密码。 若:若: #define CHANGE 0 #define CHANGE 0

则不译成密码,按原文输出。则不译成密码,按原文输出。

返回到本章目录

解:当字母不为解:当字母不为 'z''z' 或或 'Z''Z' 时,将字母变成其下一个字母,就是将字母时,将字母变成其下一个字母,就是将字母的的 ASCIIASCII 码值加码值加 11 即可实现;当字母为即可实现;当字母为 'z''z' 或或 'Z''Z' 时,令该字母等时,令该字母等于于 'a''a' 或或 'A''A' 。条件编译可以用。条件编译可以用 #ifdef#ifdef 命令来实现。命令来实现。

源程序如下:源程序如下:#include "string.h"#include "string.h"

#define CHANGE 1 /*#define CHANGE 1 /* 可将可将 11改为改为 00 ,则进行字母替换,则进行字母替换 */*/

main()main()

{ char str[100],ch;{ char str[100],ch;

int i,len;int i,len;

printf("\nPlease input a string:");printf("\nPlease input a string:");

gets(str);gets(str);

len=strlen(str);len=strlen(str);

返回到本章目录

#if CHANGE#if CHANGE

for(i=0;i<len;i++)for(i=0;i<len;i++)

if(str[i]>= 'a'&&str[i]<'z'|| str[i]>= 'A'&&str[i]<'Z')if(str[i]>= 'a'&&str[i]<'z'|| str[i]>= 'A'&&str[i]<'Z')

str[i]=str[i]+1;str[i]=str[i]+1;

else else

{ if(str[i]== 'z') { if(str[i]== 'z')

str[i]= 'a';str[i]= 'a';

else if(str[i]== 'Z')else if(str[i]== 'Z')

str[i]= 'Z';str[i]= 'Z';

}}

#endif#endif

puts(str);puts(str);

}}

返回到本章目录

程序运行结果如下:程序运行结果如下:

返回到本章目录

本章小结本章小结 CC 程序的编译可分为编译预处理和正式编译两个步骤。程序的编译可分为编译预处理和正式编译两个步骤。

编译预处理是在将源程序生成目标文件之前,对源程编译预处理是在将源程序生成目标文件之前,对源程序的加工。正确使用编译预处理命令可以有效提高程序的加工。正确使用编译预处理命令可以有效提高程序的开发效率。序的开发效率。

CC 语言提供了多种预处理命令,常用的有宏定义、文语言提供了多种预处理命令,常用的有宏定义、文件包含和条件编译。件包含和条件编译。

宏定义命令为宏定义命令为 #define#define ,是用一个标识符来代表一个,是用一个标识符来代表一个字符串,这个字符串可以是常量、变量或表达式。在字符串,这个字符串可以是常量、变量或表达式。在宏展开中将用该字符串代替宏名。宏定义还可以带参宏展开中将用该字符串代替宏名。宏定义还可以带参数,宏展开时除用字符串代替宏名外,还应用实参代数,宏展开时除用字符串代替宏名外,还应用实参代替形参。替形参。

返回到本章目录

本章小结本章小结文件包含命令为文件包含命令为 #include#include ,它可以把一个,它可以把一个或多个文件嵌入到另一个源文件中进行编或多个文件嵌入到另一个源文件中进行编译,结果将生成一个目标文件。译,结果将生成一个目标文件。

条件编译根据条件成立与否,选择编译程条件编译根据条件成立与否,选择编译程序中满足条件的程序段,便于程序调试,序中满足条件的程序段,便于程序调试,并使生成的目标程序较短,减少内存开销,并使生成的目标程序较短,减少内存开销,提高程序运行效率。提高程序运行效率。

返回到本章目录