第8章 预处理命令

合集下载

第八章 预处理命令

第八章  预处理命令

宏展开后的代码如下: #include <stdio.h> void main( ) { int i,a[10]; for(i=0;i<10;i++) scanf("%d",&a[i]); for(i=0;i<10;i++) printf("%d ",a[i]); printf("\n"); }
说明:
宏展开后的代码如下: #include <stdio.h> void main( ) { float a,area; a=3.6; area=3.1415926*a*a; printf("r=%f\narea=%f\n",a,area); }
例8.4 举例说明带参数的宏定义的方法。(实参是表达式) 源代码如下: #include <stdio.h> #define S(a,b) a*b+2 //形参 void main( ) { int x=2,y=5,z; z=S(x+y,y-x); //宏调用,实参是表达式 printf("%d\n",z); }
例8.7 根据条件编译的表达式的值,决定是计算圆周长还是圆面积。 #include <stdio.h> #define PI 3.1415926 #define FLAG 1 void main( ) {float r,L,S; printf("半 径:"); scanf("%f",&r); #if FLAG //表达式的值为“非零” L=2*PI*r; printf("圆周长:%f\n",L); #else S=PI*r*r; printf("圆面积:%f\n",S); #endif }

C语言预处理命令总结大全.docx

C语言预处理命令总结大全.docx

C语言预处理命令总结大全(2012-02-13 17:18)标签:C语言预处理分类:C编程C程序的源代码中可包括各种编译指令,这些指令称为预处理命令。

虽然它们实际上不是C语言的一部分,但却扩展了C程序设计的环境。

本节将介绍如何应用预处理程序和注释简化程序开发过程,并提高程序的可读性。

ANSI标准定义的C 语言预处理程序包括下列命令:#defi ne ,#error ,# in elude , #if , #else , #elif , #en dif , #ifdef , #if ndef , #undef, #line , #pragma等。

非常明显,所有预处理命令均以符号#开头,下面分别加以介绍。

命令#define定义了一个标识符及一个串。

在源程序中每次遇到该标识符时,均以定义的串代换它。

ANSI标准将标识符定义为宏名,将替换过程称为宏替换。

命令的一般形式为:#define identifier string1该语句没有分号。

在标识符和串之间可以有任意个空格,串一旦开始,仅由一新行结束。

2宏名定义后,即可成为其它宏名定义中的一部分。

3宏替换仅仅是以文本串代替宏标识符,前提是宏标识符必须独立的识别出来,否则不进行替换。

例如:#defi ne XYZ this is a tes使用宏printf("XYZ") ;//该段不打印"this is a test"而打印"XYZ"。

因为预编译器识别出的是"XYZ"4如果串长于一行,可以在该行末尾用一反斜杠’\'续行。

#defi neLONG_STRING"this is a very long\stri ng that is used as an example"5 C语言程序普遍使用大写字母定义标识符。

6用宏代换代替实在的函数的一大好处是宏替换增加了代码的速度,因为不存在函数调用的开销。

c语言第8章 编译预处理及位运算习题答案

c语言第8章 编译预处理及位运算习题答案

编译预处理习题一.单项选择题1.在宏定义#define A 3.897678中,宏名A代替一个()。

A)单精度数 B)双精度数 C)常量 D)字符串2.以下叙述中正确的是A)预处理命令行必须位于源文件的开头 B)在源文件的一行上可以有多条预处理命令C)宏名必须用大写字母表示D)宏替换不占用程序的运行时间3.C语言的编译系统对宏命令的处理()。

A)在程序运行时进行的B)在程序连接时进行的C)和C程序中的其它语句同时进行的D)在对源程序中其它语句正式编译之前进行的4.在文件包含预处理语句的中,被包含文件名用“< >”括起时,寻找被包含文件的方式是()。

A)直接按系统设定的标准方式搜索目录B)先在源程序所在目录搜索,再按系统设定的标准方式搜索C)仅仅在源程序所在目录搜索D)仅仅搜索当前目录5.以下说法中正确的是A)#define和printf都是C语句 B)#define是C语句,而printf不是C)printf是C语句,但#define不是D)#define和printf都不是C语句6.#define A 3.897678#include <stdio.h>main( ){ printf(“A=%f ”,A);}程序运行结果为()。

A) 3.897678=3.897678 B) 3.897678=A C) A=3.897678 D)无结果7.有宏定义:#define LI(a,b) a*b#define LJ(a,b) (a)*(b)在后面的程序中有宏引用:x=LI(3+2,5+8);y=LJ(3+2,5+8);则x、y的值是()。

A) x=65,y=65 B) x=21,y=65 C) x=65,y=21 D)x=21,y=218.有以下程序# define f(x) (x*x)main(){ int i1, i2;i1=f(8)/f(4) ; i2=f(4+4)/f(2+2) ;printf("%d, %d\n",i1,i2);}程序运行后的输出结果是A)64, 28 B)4, 4 C)4, 3D)64, 649.以下程序的输出结果是#define M(x,y,z) x*y+zmain(){ int a=1,b=2, c=3;printf(“%d\n”, M(a+b,b+c, c+a));}A) 19 B) 17 C) 15 D) 1210.有以下程序#define N 5#define M1 N*3#define M2 N*2main(){ int i;i=M1+M2; printf(“%d\n”,i);}程序编译后运行的输出结果是:A) 10 B) 20 C) 25 D) 3011.有如下程序#define N 2#define M N+1#define NUM 2*M+1#main(){ int i;for(i=1;i<=NUM;i++)printf(“%d\n”,i);}该程序中的for循环执行的次数是A) 5 B) 6C) 7 D) 812.位运算是对运算对象按二进制位进行操作的运算,运算的对象是____数据,以___的形式参与运算。

预处理命令详解

预处理命令详解

预处理命令详解在编写程序的时候,我们经常要用到#pragma指令来设定编译器的状态或者是指示编译器完成一些特定的动作。

1. #pragma message指令message能够在编译消息输出窗口中输出相应的消息,这对于源代码信息的控制非常重要的。

格式如下:#pragma message(“消息文本”)编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。

当我们在程序中定义了许多宏来控制源代码版本的时候,我们自己有可能都会忘记有没有正确的设置这些宏,此时我们可以用这条指令在编译的候进行检查,假设我们希望判断自己有没有源代码的什么地方定义了_X86这个宏可以用下面的方法:#ifdef _x86#pragma message("_x86 macro activated!")#endif当我们定义了_X86这个宏以后,应用程序在编译时就会在编译输出窗口里显示"_x86 macro activated!"。

2. #pragma code_seg指令格式如下:#pragma code_seg([[{push |pop},][identifier,]]["segment-name",]["segment-class"])该指令用来指定函数在.obj文件中存放的节,观察.obj文件可以使用VC自带的dumpbin命令行程序,函数在.obj文件中默认的存放节为.text节。

(1)如果code_seg没有带参数的话,则函数存放在.txt节中;(2)push(可选参数):将一个记录放到内部编译器的堆栈中,可选参数(记录名)可以为一个标识符或者节名;pop(可选参数)将一个记录从堆栈顶端弹出,该记录可以为一个标识符或者节名;(3)identifier (可选参数):当使用push指令时,为压入堆栈的记录指派的一个标识符,当该标识符被删除的时候和其相关的堆栈中的记录将被弹出堆栈;(4)"segment-name" (可选参数):表示函数存放的节名;例如://默认情况下,函数被存放在.txt节中void func1() { // stored in .txt }//将函数存放在.my_data1节中#pragma code_seg(".my_data1")void func2() { // stored in my_data1 }//r1为标识符,将函数放入.my_data2节中#pragma code_seg(push, r1, ".my_data2)void func3() { // stored in my_data2 }int main() { }3. #pragma once指令格式如下:#pragma once这是一个比较常用的指令,只要在头文件的最开始加入这条指令就能够保证头文件只被被编译一次。

C语言程序设计知识点—第8章 指针结构体与预处理命令

C语言程序设计知识点—第8章 指针结构体与预处理命令
比较两个指针 #include<stdio.h> void main () { int *ptrnum1, *ptrnum2; int value = 1; ptrnum1 = &value; value += 10; ptrnum2 = &value; if (ptrnum1 == ptrnum2) printf("\n 两个指针指向同一个地址\n"); else printf("\n 两个指针指向不同的地址\n"); }
指针使用示例 2 void main() { int num1 = 50, num2 = 100; int *ptr1, *ptr2; ptr1 = &num1; printf(" num1 的值是: %d", *ptr1); printf("\n num1 的地址是: %x \n", ptr1); ptr2 = &num2; printf("\n num2 的值是: %d", *ptr2); printf("\n num2 的地址是: %x \n", ptr2); *ptr2 = *ptr1; printf("\n 重新赋值后 num2 的值是: %d", *ptr2); printf("\n 重新赋值后 num2 的地址是: %x\n", ptr2); }
C 语言程序设计知识点
主讲教师:杨剑
第 8 章:指针、结构体与预处理命令
1. 本章目标
理解指针的概念 定义指针变量 掌握对指针的操作 理解指针和数组的关系 理解结构体的概念和定义 理解预处理指令
2. 内存地址
内存是一个连续编址的空间,每一个存储单元都有一个固定的编号,称为内存地址。 内存地址通常用 16 进制数表示。

c语言第8章-编译预处理及位运算习题答案doc资料

c语言第8章-编译预处理及位运算习题答案doc资料

c语言第8章-编译预处理及位运算习题答案编译预处理习题一.单项选择题1.在宏定义#define A 3.897678中,宏名A代替一个()。

A)单精度数 B)双精度数 C)常量 D)字符串2.以下叙述中正确的是A)预处理命令行必须位于源文件的开头 B)在源文件的一行上可以有多条预处理命令C)宏名必须用大写字母表示D)宏替换不占用程序的运行时间3.C语言的编译系统对宏命令的处理()。

A)在程序运行时进行的B)在程序连接时进行的C)和C程序中的其它语句同时进行的D)在对源程序中其它语句正式编译之前进行的4.在文件包含预处理语句的中,被包含文件名用“< >”括起时,寻找被包含文件的方式是()。

A)直接按系统设定的标准方式搜索目录B)先在源程序所在目录搜索,再按系统设定的标准方式搜索C)仅仅在源程序所在目录搜索D)仅仅搜索当前目录5.以下说法中正确的是A)#define和printf都是C语句 B)#define是C语句,而printf不是C)printf是C语句,但#define不是D)#define和printf都不是C 语句6.#define A 3.897678#include <stdio.h>main( ){ printf(“A=%f ”,A);}程序运行结果为()。

A) 3.897678=3.897678 B) 3.897678=A C) A=3.897678 D)无结果7.有宏定义:#define LI(a,b) a*b#define LJ(a,b) (a)*(b)在后面的程序中有宏引用:x=LI(3+2,5+8);y=LJ(3+2,5+8);则x、y的值是()。

A) x=65,y=65 B) x=21,y=65 C) x=65,y=21 D)x=21,y=218.有以下程序# define f(x) (x*x)main(){ int i1, i2;i1=f(8)/f(4) ; i2=f(4+4)/f(2+2) ;printf("%d, %d\n",i1,i2);}程序运行后的输出结果是A)64, 28 B)4, 4 C)4, 3D)64, 649.以下程序的输出结果是#define M(x,y,z) x*y+zmain(){ int a=1,b=2, c=3;printf(“%d\n”, M(a+b,b+c, c+a));}A) 19 B) 17 C) 15 D) 1210.有以下程序#define N 5#define M1 N*3#define M2 N*2main(){ int i;i=M1+M2; printf(“%d\n”,i);}程序编译后运行的输出结果是:A) 10 B) 20 C) 25 D) 3011.有如下程序#define N 2#define M N+1#define NUM 2*M+1#main(){ int i;for(i=1;i<=NUM;i++)printf(“%d\n”,i);}该程序中的for循环执行的次数是A) 5 B) 6C) 7 D) 812.位运算是对运算对象按二进制位进行操作的运算,运算的对象是____数据,以___的形式参与运算。

kj-第8章预处理命令ppt课件(全)

这里J引用了I1和I2,K引用了J和I2。 注意K展开是:30+60*2+30+60/2+60, 不要以为是:(30+60)*2+(30+60)/2+60。 除非前面的定义是:#define J (I1+I2)。
8.1.2 带参数的宏定义
带参数的宏定义的一般形式为: #define标识符(形参表) 字符串
例8.1 # include <stdio.h> #define SIZE 5 int main()
{int i,sum=0; int data[SIZE]; for(i=0;i<SIZE;i++)
{scanf(“%d”,&data[i]); sum=sum+data[i]; } printf(“sum=%d\n”,sum); return 0; } 运行此程序可计算5个数组元素值的总和。
是作为一个源程序编译,得到一个目标(.obj)文件。
说明:
(1)如果要包含n个文件,必须用n个include命令。即一个 include命令只能指定一个被包含文件。
(2)假设“wj1.c”、“wj2.c”、“wj3.c”是三个不同的文 件,若在“wj1.c”有如下两行命令:
# include <wj3.c>
含义是用指定的宏名(即标识符)来代表其后字符串。
例如: #define SIZE 10000 #define PI 3.1415926 #define FORMAT “%d,%d,%d\n”
作用是指用标识符SIZE来代替字符串“10000”, 用标识符PI来代替字符串“3.1415926”, 用标识符FORMAT来代替字符串“ “%d,%d,%d\n” ”,

预处理指令——精选推荐

预处理指令预处理命令1 . 基本介绍使⽤库函数之前,应该⽤#include引⼊对应的头⽂件,这种以#开头的命令称为预处理命令这些在编译之前对源⽂件进⾏简单加⼯的过程,就称为预处理(即预先处理,提前处理)预处理主要是处理以#开头的命令。

例如#include<stdio.h>,预处理命令要放在所有函数之外,⽽且⼀般都放在源⽂件的前⾯预处理是C语⾔的⼀个重要功能,由预处理程序完成,当对⼀个源⽂件进⾏编译时,系统将⾃动调⽤预处理程序对源程序中的预处理部分做处理,处理完毕⾃动进⼊对源程序的编译C语⾔提供了多种预处理功能,如宏定义,⽂件包含,条件编译,合理的使⽤会使编写的程序便于阅读,修改,移植和调试,也有利于程序模块化设计2 . 快速⼊门2.1 具体要求开发⼀个C语⾔程序,让它暂停5秒以后再输出内容“hello 尚硅⾕”,并且要求跨平台,在Windows和Linux下都能运⾏2.2 提⽰Windows平台下的暂停函数的原型是void Sleep(DWORD dwMilliseconds),参数的单位是“毫秒”,位于<windows.h>头⽂件linux平台下暂停函数的原型是unsigned int sleep(unsigned int second),参数的单位是“秒”,位于<unistd.h>头⽂件if ,#endif ,就是预处理命令,他们都是在编译之前由预处理程序来执⾏的2.3 代码实现#include<stdio.h>//说明:在Windows操作系统和Linux操作系统下,⽣成源码不⼀样#incLude<windows.h>int main(){Sleep(5000);puts("hello ,尚硅⾕");getchar();rerurn 0;}#if_WIN32 //如果是windows平台,就执⾏#include<windows.h>#include<windows.h>#elif_linux_//否则判断是不是linux,如果是linux就引⼊<unistd.h>#include<unistd.h>#endifint main(){//不同的平台调⽤不同的函数#if_WIN32Sleep(5000);#elif_linux_sleep(5);#endifputs("hello,尚硅⾕");getchar();return 0;}3 . 宏定义3.1 基本介绍define叫做宏定义命令,它⼜是C语⾔预处理命令的⼀种。

预处理指令

预处理指令,宏和运算符当编译程序时,它做的第一件事是进行预处理。

这一阶段中,甚至可以人为地将编译器视为一个不同的实体——预处理器。

该阶段中,编译器读入头文件、决定编译哪些行的源代码并执行文本替换。

预编译阶段的优越性在于它的编译及运行之前执行了某些特定的操作。

这些操作并不添加额外的程序执行时间。

同时,这些命令也不与程序运行时所发出的任何指令相对应。

所以,在使用预处理指令时就需要兼顾实际的运行情况。

预处理的三个基本元素:指令:在程序编译前执行的特定命令。

预定义宏:在编译前所执行的特定命令。

预处理运算符:在#if和#define中使用。

预处理指令语法与C++的其它语法有所不同。

指令以行末结束,而不需要分号。

但你可以用续行符(\)来摆脱物理行的限制。

另外,指令必须从第一行开始。

指令:有一半预处理指令提供了对条件编译的支持,条件编译的作用是用来维护同一程序的不同版本。

这些指令包括:#if #ifdef #elif #ifndef #else #end其余的预处理指令提供了对其它功能的支持,例如包括头文件和宏定义:#define #include #pragma #error #line #undef详解:★#define [定义符号或宏]目的:一:提供了创建符号常量的有效信息途径。

二:使编写人员能写宏指令,这些宏指令看上去像函数调用,但实际上是通过文本替换来实现。

三:简单地定义某些符号作为#ifdef指令的开关。

语法格式:#define标识符替代值#define 标识符[(参数1,.....,参数n)] 替代值其中,在”替代值”中出现的形参将在使用时被实参替代. 就象写函数一样.#define 标识符◆用法一:符号常量有些程序用到了一些很重要但又非常难忘或难以输入的数字。

最好事先将它们转化成为符号常量。

在转化时,通常是以大写形式表示,以便将它们与变量名区分开来。

例:#define E 2.718281828459这条指令的意思是每当程序中出现E时,预处理器就会将E替换成2.718281828459。

08_预处理命令

本章主要内容:宏定义文件包含条件编译1.1编译预处理编译预处理是在对源程序正式编译之前的处理,以“#”开头,如文件包含“#include”、宏定义“#define”等。

预处理命令不是C语言本身的组成部分,不能直接对它进行编译。

所有的预处理指令都是在编译之前完成的,不占用程序运行时间。

C语言提供了3中预处理功能,即宏定义、文件包含、条件编译。

以“#”开头,占用一个单独的书写行,语句结尾不适用分号。

宏定义:#define文件包含:#include条件编译:#ifndef…#if…#else…#endif等1.2宏定义1.2.1不带参数的宏定义语法格式:#define 宏名[宏体](宏体可省略,如果没有则作为一个标识用于#if语句中)功能:用指定标识符(宏名)代替字符序列(宏体)说明:宏名要是一个合法的标识符,通常采用大写字母表示;宏体可以是常数、表达式和语句,甚至可以是多条语句。

举例:#define PI 3.1415926 //定义π的值为3.1415926,以后要用到π,就可以直接用PI #define OUT printf(“Hello World!\n”); //定义宏OUT替换后面的函数用#undef可以终止宏名作用域,格式为:#undef 宏名举例:void main(){#define YES 1 //定义宏YESprintf("%d\n",YES);#undef YES //结束宏YES的作用域#define YES 0 //重新定义宏YESprintf("%d\n",YES);}有关宏定义的使用,需注意以下几点:1宏名习惯采用大写,以便与普通变量区分;2宏定义不是C语句,所以不能在行尾加分号;否则,宏展开时,会将分号也算在内3在宏展开时,预处理程序仅按宏定义简单替换宏名,不做任何检查。

如果有错误,只能由编译器在编译宏展开后的源程序时发现。

4宏定义的位置是任意的,宏名的有效范围是从定义命令处到本模块结束。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

说明 :
(4) 在#include命令中,文件名可以用双撇号或尖括号括 起来。 (5) 被包含文件(file2.h)与其所在的文件(即用 #include命令的源文件file2.c),在预编译后已成为 同一个文件(而不是两个文件)。因此,如果file2.h 中有全局静态变量,它也在file1.h文件中有效,不必 用extern声明。
说明: 说明:
(1)带参的宏定义中,宏名与带参数的圆括号之间不能有空格。如: #define area (r) (3.1415926∗(r) ∗(r) ) 系统会认为这是一个不带参的宏,宏名为area,宏体为(r) ∗ ∗ (3.1415926∗(r) ∗(r))。 (2)整个宏体及其中所含形参要用括号括起(也就是说,括号不是宏体 的一部分),否则就会出错。如: #define square(x) x∗x 遇到下面语句 c=square(3+2) ; 将被替换成 c=3+2∗3+2; 这是与我们本意相背的。
输入一行字母字符, 例: 输入一行字母字符, 根据需要设置条件编译, 根据需要设置条件编译, 使之能将字母全改为大 写输出, 写输出,或全改为小写 字母输出。 字母输出。
运行结果为: C LANGUAGE
#include <stdio.h> #define LETTER 1 void main() {char str[20]="C Language",c; int i; i=0; while((c=str[i])!='\ while((c=str[i])!='\0') { i++; #if LETTER if(c>='a' && c<='z') c=cc=c-32; #else if(c>='A' && c<='Z') c=c+32; #endif printf("%c",c); } }
பைடு நூலகம்
基本概念
C语言与其他高级语言的一个重要区别是可以使用预处 理命令和具有预处理的功能。 C提供的预处理功能主要有以下三种: 1.宏定义 2.文件包含 3.条件编译 这些功能分别用宏定义命令、文件包含命令、条件 编译命令来实现。为了与一般C语句相区别,这些命令 以符号“#”开头。例如: #define #include
§8.1 宏定义
8.1.1 不带参数的宏定义 宏定义一般形式为:
#define 标识符 字符串 例如:# :#define 例如:#define PI 3.1415926
宏定义的作用是在本程序文件中用指定的标识符PI来代替“3.1415926 宏定义的作用是在本程序文件中用指定的标识符PI来代替“3.1415926” PI来代替 这个字符串,在编译预处理时,将程序中在该命令以后出现的所有的PI 这个字符串,在编译预处理时,将程序中在该命令以后出现的所有的PI 都用“3.1415926”代替 代替。 都用“3.1415926 代替。这种方法使用户能以一个简单的名字代替一个 长的字符串. 长的字符串. 这个标识符(名字)称为“宏名” 这个标识符(名字)称为“宏名” 在预编译时将宏名替换成字符串的过程称为“宏展开” define是宏 在预编译时将宏名替换成字符串的过程称为“宏展开”。#define是宏 定义命令。 定义命令。
【例8-1】求圆面积。 #define PI 3.1415926 double area_circle(double r) { return(PI ∗ r∗ r) ; } 经宏替换后为 double area_circle(double r) { return(3.1415926 ∗ r∗ r ) ; }
void main() { int a,b,c,d; char string[]="CHINA"; a=1;b=2;c=3;d=4; PR(D1,a) ; PR(D2,a,b) ; PR(D3,a,b,c) ; PR(D4,a,b,c,d) ; PR(S,string) ; }
1 12 123 1234 CHINA
运行情况如下: 运行情况如下:
§8.2 “文件包含”处理
所谓“文件包含”处理是指一个源文件可以将另外一个源文件 的全部内容包含进来。C语言提供了#include命令用来实现 “文件包含”的操作。
其一般形式为: "文件名 文件名“ #include "文件名“ 或 #include <文件名> <文件名 文件名>
【例8-3】用宏定义求解问题 #define PI 3.1415926 #define radius 2 /*符号radius表示值为2的半径*/ void main() { double l,s; l=2*PI*radius; s=PI*radius*radius; printf ("l=%f,s=%f",l,s) ; } 这里只需修改“#define radius 2”这一行中的2为3即可。
【例8-2】用宏定义求圆的周长与面积 #define PI 3.1415926 void main() { double l,s; l=2*PI*2; /*求半径为2的圆周长*/ s=PI*2*2; /*求半径为2的圆面积*/ printf("l=%f,s=%f",l,s) ; }
如果此时要求半经为3 如果此时要求半经为3的圆周长与面 就需将上例中三处2修改为3 积,就需将上例中三处2修改为3且 不能将形式相同的第一个2改为3 不能将形式相同的第一个2改为3。 用宏就可避免以上麻烦。 用宏就可避免以上麻烦。
第8章
本章主要内容: 本章主要内容: 8.1 宏 定 义 8.2 文 件 包 含 8.3 条 件 编 译
基本概念
ANSI C标准规定可以在C源程序中加入一些“预处理 命令” ,以改进程序设计环境,提高编程效率。 这些预处理命令是由ANSI C统一规定的,但是它不是 C语言本身的组成部分,不能直接对它们进行编译 (因为编译程序不能识别它们)。必须在对程序进行 必须在对程序进行 通常的编译之前,先对程序中这些特殊的命令进行 通常的编译之前, 预处理” “预处理” 经过预处理后程序可由编译程序对预处理后的源程序 进行通常的编译处理,得到可供执行的目标代码。
带参数的宏和函数的区别: 带参数的宏和函数的区别:
(1) 函数调用时,先求出实参表达式的值,然后代入形参。而使用带参 的宏只是进行简单的字符替换。 (2) 函数调用是在程序运行时处理的,为形参分配临时的内存单元。而 宏展开则是在编译前进行的,在展开时并不分配内存单元,不进行 值的传递处理,也没有“返回值”的概念。 (3) 对函数中的实参和形参类型要求一致。而宏名无类型,它的参数也 无类型,只是一个符号代表,展开时代入指定的字符串即可。宏定 义时,字符串可以是任何类型的数据。 (4) 调用函数只可得到一个返回值,而用宏可以设法得到几个结果。
作用:不是进行简单的字符串替换,还要进行参数替换。 带参数的宏定义一般形式为: 带参数的宏定义一般形式为: #define 宏名(参数表) 字符串 宏名(参数表) 其中的字符串包含有定义时的参数
例:
#define area(r) (3.1415926∗(r) ∗(r) )
【例8-5】带参的宏应用。 #define area(r) (3.1415926*(r) *(r) ) void main() { printf ("%f ",area(3) ) ; } 被替换成: void main() { printf ("%f ",3.1415926∗3∗3) ; }
§8.3 条件编译
概念:所谓“条件编译”,是对部分内容指定编译的条 件,使其只在满足一定条件才进行编译。 条件编译命令的几种形式:
(1)#ifdef 标识符 程序段1 #else 程序段2 #endif (2)#ifndef 标识 符 程序段1 #else 程序段2 #endif (3) #if 表达式 程序段1 #else 程序段2 #endif
说明: 说明:
(4)在预编译时,宏替换只是简单地用宏体(字符串)去替 代宏名而不进行语法和语义的检查。如下边的宏定义, 在预编译时也是正确的,只是在以后的编译中才报告出 错。 #define PI 3.14L5926 (5)如果在双引号中出现与宏名相同的字符,则这个字符 不被替换。
8.1.2 带参数的宏
带参数的宏和函数的区别: 带参数的宏和函数的区别:
(5) 使用宏次数多时,宏展开后源程序长,因为每展开 一次都使程序增长,而函数调用不会使源程序变长。 (6) 宏替换不占运行时间,只占编译时间。而函数调用 则占运行时间(分配单元、保留现场、值传递、返 回)。
【例8-6】通过宏展开得到若干 】 个结果。 个结果。 #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"
注意: 注意: 在编译时并不是分别对两个文件分别进行编译,然后再 将它们的目标程序连接的,而是在经过编译预处理后将 头文件包含到主文件中,得到一个新的源程序,然后对 这个文件进行编译,得到一个目标(.obj)文件。被包 含的文件成为新的源文件的一部分,而单独生成目标文 件。
说明: 说明:
(1) 一个#include命令只能指定一个被包含文件,如果要包 含n个文件,要用n个#include命令。 (2) 如果文件1包含文件2,而在文件2中要用到文件3的 内容,则可在文件1中用两个include命令分别包含文件 2和文件3,而且文件3应出现在文件2之前,即在 file1.c中定义。 (3) 在一个被包含文件中又可以包含另一个被包含文件,即 文件包含是可以嵌套的。
相关文档
最新文档