第八章 预处理命令

合集下载

第八章 预处理命令

第八章  预处理命令

宏展开后的代码如下: #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语言中的预处理指令

C语言中的预处理指令

C语言中的预处理指令在C语言编程中,预处理指令是一种特殊的指令,用于在编译阶段之前对源代码进行处理。

预处理指令以井号(#)开头,并且不是被编译器执行的实际指令,而是由预处理器处理的。

本文将详细介绍C语言中的预处理指令,并探讨其在程序开发中的作用和用法。

一、什么是预处理指令预处理指令是在编译阶段之前对源代码进行处理的指令。

它的作用是在编译之前对源文件进行一些文本替换、条件编译或者简单的文本粘贴工作。

预处理指令以井号(#)开头,且位于编译单位(源文件或头文件)的最开始位置。

二、预处理指令的作用1. 宏定义宏定义是预处理指令中使用最广泛的功能之一。

通过宏定义,可以为一段代码或者一个常量起一个易于记忆和使用的名字,从而提高代码的可读性和维护性。

下面是一个宏定义的示例:```c#define MAX_NUM 100```在这个例子中,宏定义了一个名为MAX_NUM的常量,它的值为100。

在后续的代码中,可以使用MAX_NUM来代表100,避免了重复书写代码的问题。

2. 文件包含预处理指令还可以使用#include指令将其他文件的内容包含到当前文件中。

这种方式可以在不同的源文件中共享代码,提高代码的复用性。

下面是一个文件包含的示例:```c#include <stdio.h>```通过#include指令,可以将系统库文件stdio.h中的代码包含到当前文件中,以便后续代码可以使用stdio.h中定义的函数和类型。

3.条件编译条件编译是预处理指令中非常重要的概念。

通过条件编译,可以根据条件的真假选择性地编译代码。

这在不同的操作系统、不同的编译器或者不同的编译选项下具有重要的意义。

下面是一个条件编译的示例:```c#ifdef DEBUGprintf("Debug mode\n");#endif```在这个例子中,只有在编译时定义了DEBUG宏的情况下,才会编译并执行printf语句。

预处理命令详解

预处理命令详解

预处理命令详解在编写程序的时候,我们经常要用到#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这是一个比较常用的指令,只要在头文件的最开始加入这条指令就能够保证头文件只被被编译一次。

预处理指令——精选推荐

预处理指令——精选推荐

预处理指令预处理命令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。

预处理指令

预处理指令

#include 指令
#include 指令的作用是指示编译器将该指令所指出的另一个源文件嵌入#include指令所在 的程序中, 文件应使用双引号或尖括号括起来. C 库函数的头文件一般用#include指令在程序开关说明. 例如: #include <stdio.h> 程序中也允许嵌入其它文件, 例如: main() { #include <help.c> } 其中help.c为另一个文件, 内容可为 printf("Glad to meet you here!"); 处理命令的格式 #include "包含文件名" 或 #include <包含文件名 包含文件名" 包含文件名> 包含文件名 包含文件名 两种格式的区别仅在于: (1)使用双引号:系统首先到当前目录下查找被包含文件,如果没找到,再到系统指定 的"包含文件目录"(由用户在配置环境时设置)去查找. (2)使用尖括号:直接到系统指定的"包含文件目录"去查找.一般地说,使用双引号 比较保险.
可变参数的函数
我们在C语言编程中会遇到一些参数个数可变的函数, 例如printf()这个函数,它的定义是这样的: int printf( const char* format, ...); 它除了有一个参数format固定以外,后面跟的参数的个数 和类型是可变的,例如我们可以有以下不同的调用方法: printf("%d",i); printf("%s",s); printf("the number is %d ,string is:%s", i, s); 究竟如何写可变参数的C函数以及这些可变参数的函数 编译器是如何实现的呢?现在就这个问题进行一些探讨,希望 能对大家有些帮助.

预处理命令

预处理命令

3
math.h——文件包含数学程序。 reg51.h——文件中包含51单片机的特殊寄存器定义。 reg52.h——文件中包含52单片机的特殊寄存器定义。 setjmp.h——文件包含定义jmp_buf类型和setjmp和longjmp程序原型。 stdarg.h——文件包含可变长度参数列表程序。 stdlib.h——文件包含存储区分配程序。 stdio.h——文件包含标准输入和输出程序。 string.h——文件包含字符串操作程序、缓冲区操作程序。 对于51单片机而言,源程序开头必须要包含reg51.h头文件,因为该文件对51单片 机的相关位及寄存器进行了定义,这样在程序中才可以正常使用寄存器等资源。
#else 程序段2
#endif 若常量表达式成立,则编译程序1,否则编译程序2。
5
单片机原理及应用
单片机原理及应用
C51语言中提供了各种预处理命令,其作用类似于汇编程序中的伪指令。在编译环 境对源程序进行编译前,需要先对程序中的预处理命令进行处理,然后将处理结果和源 程序一起编译。C51语言中的预处理命令包括宏定义命令、文件包含命令和条件编译命 令等。通常,除条件编译命令外,预处理命令一般放在函数体之外,并且通常都放置在 源文件的开头。
句如下:
outputs=0xff;
/*输出 1111 1111 */
进行编译时,预处理器会将整个程序中的所有outputs替换为P2。
2.文件包含命令
#include命令的功能是将指定的定义或声明文件放入程序之中,该命令常用于引入 标准库函数文件。下面是一些常用的C51头文件:
absacc.h——包含允许直接访问8051不同存储区的宏定义。 assert.h——文件定义宏,用来建立程序的测试条件。 ctype.h——包含字符转换和分类程序。 intrins.h——文件包含指示编译器产生嵌入式固有代码的程序原型。

08_预处理命令

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宏定义的位置是任意的,宏名的有效范围是从定义命令处到本模块结束。

预处理命令

预处理命令

10.2预处理指令主要有三种类型:1、宏定义:#define和#undef指令2、文件包含:#include指令3、条件编译:#if、#ifdef、#ifndef、#elif、#else和#endif指令宏定义包含带参数的宏和不带参数的宏两种;带参数的宏定义格式为:#define 标识符(X1,X2,X3…)替换列表其与函数调用的结果完全不同,详见12/22程序macro with parameter通过程序实例得出,为了避免宏名参与的运算结果不混淆,一般采用如下两种形式的定义方式:1、#define AREA(X)(X)*(X)2、#define AREA(X)(X*X)替代#define AREA(X)X*X避免在宏定义中使用自增符号,如对于宏定义#define AREA(X)(X*X),AREA(++X),被展开为++X*++X,假如X初值为5,则其运算结果可能为42或者49,由于未规定运算顺序,编译器可能会出现不同的结果宏定义与函数有类似的地方,宏代替函数有以下优点:1、从效率角度考虑,程序执行起来会更快些,在调用函数时总会有些额外的开销,如保存调用点的信息以便函数调用结束后能正确返回调用点,而宏调用则没有这些运行时的开销;2、宏更加通用。

与函数不同,宏的参数是没有类型的,因此,宏可以接收任何类型的参数,因此它的使用范围更加广泛同时,也会以下缺点:1、源程序编译后代码量会增加,预处理过程中会在每一处宏调用的地方插入宏的替换列表,显然会使源程序的代码增加;2、预处理器不会检查宏参数的类型,也不会进行类型转换,这样采用宏调用可能会产生错误的结果3、自增、自减运算不能在宏中进行,可能会导致错误的结果;#运算符和##运算符只能出现在带参数宏的替换列表中,例如x为一个宏的参数,那么#x就可以将参数名转化为相应的字符串,该过程称为字符串化(stringization),程序实例详见12.23 stringization##运算符,如果##连接的两个操作数中其中一个为宏的参数,那么会先进行参数替换,然后再执行##运算符的操作。

预处理指令

预处理指令

9.1.2 有参宏定义
1.带参宏定义的一般格式 . #define 宏名 形参表 语言符号字符串 宏名(形参表 形参表) 2.带参宏的调用和宏展开 . 实参表) (1)调用格式:宏名 实参表 )调用格式:宏名(实参表 (2)宏展开:用宏调用提供的实参字符串,直接置换 )宏展开:用宏调用提供的实参字符串, 宏定义命令行中、相应形参字符串,非形参字符保持不变。 宏定义命令行中、相应形参字符串,非形参字符保持不变。 3.说明 . (1)定义有参宏时,宏名与左圆括号之间不能留有空 )定义有参宏时, 否则, 格。否则,C编译系统将空格以后的所有字符均作为替代 字符串,而将该宏视为无参宏。 字符串,而将该宏视为无参宏。 (2)有参宏的展开,只是将实参作为字符串,简单地 )有参宏的展开,只是将实参作为字符串, 置换形参字符串,而不做任何语法检查。在定义有参宏时, 置换形参字符串, 而不做任何语法检查。在定义有参宏时, 在所有形参外和整个字符串外,均加一对圆括号。 在所有形参外和整个字符串外,均加一对圆括号。
第9章
预处理命令
ห้องสมุดไป่ตู้
所谓预处理命令是指,在对源程序进行编译之前, 所谓预处理命令是指,在对源程序进行编译之前,先 对源程序中的编译预处理命令进行处理; 对源程序中的编译预处理命令进行处理;然后再将处理的 结果,和源程序一起进行编译,以得到目标代码。 结果,和源程序一起进行编译,以得到目标代码。 9.1 宏定义 9.2 文件包含 9.3 条件编译
9.3 条件编译
条件编译可有效地提高程序的可移植性, 条件编译可有效地提高程序的可移植性,并广泛地应 用在商业软件中,为一个程序提供各种不同的版本。 用在商业软件中,为一个程序提供各种不同的版本。 1.一般格式 . #if 常量表达式 程序段1; 程序段 ; [#else # 程序段2; 程序段 ;] #endif 2.功能:当表达式为非0(“逻辑真”)时,编译程序 .功能:当表达式为非 ( 逻辑真” 段1,否则编译程序段 。 ,否则编译程序段2。

第8章:预处理命令

第8章:预处理命令
ቤተ መጻሕፍቲ ባይዱ
例:判断是否为闰年 判断是否为闰年
#define IS_LEAP_YEAR(y) (y)%4==0 && (y)%100!=0 || (y)%400==0 int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool //---------------------------------------int y ; scanf("%d",&y); if(IS_LEAP_YEAR(y)) { NSLog(@"%d是闰年",y); }else { NSLog(@"%d不是闰年",y); }
文件包含
所谓“文件包含”处理是指一个源文件可以将 处理是指一个源文件可以将 另外一个源文件的全部内容包含进来,即将另外的 另外一个源文件的全部内容包含进来 文件包含到本文件之中。 。其一般形式为: #include “文件名” #include <文件名> #import “文件名” #import <文件名>
主要内容
宏定义 不带参数的宏定义 带参数的宏定义 文件包含 条件编译
不带参数宏定义
用一个指定的标识符(即名字 即名字)来代表一个字符串, 它的一般形式为 #define 标识符 字符串 例如:#define PI 3.1415926 #define 这种方法使用户能以一个简单的名字代替一个长的 字符串,因此把这个标识符 因此把这个标识符(名字)称为“宏名”,在 预编译时将宏名替换成字符串的过程称为“宏展开”。 预编译时将宏名替换成字符串的过程称为 #define是宏定义命令。

第8章补充-编译预处理命令

第8章补充-编译预处理命令
二、Tubro C库函数分为9大类:

I/O函数 包括各种控制台I/O、缓冲型文件I/O和UNIX式非缓 冲型文件I/O操作。 需要的包含文件:stdio.h 例如:getchar,putchar,printf,scanf,fopen, fclose,fgetc,fgets,fprintf,fsacnf,fputc, fputs,fseek,fread,fwrite 等。
§8-b1 工程文件
关于工程文件
例li_9_3.prj
建立工程文件.prj,将所有需要的文件 名写在工程文件中,使用project菜 单项完成建立工程工作。 /*LI_9_3.prj*/ LI_9_3_1.C LI_9_3_2.C 运行结果: x=25; y=25
共 140 页
第 6 页
§8-b2 编译预处理
第八章补充 编译预处理
第一节 第二节 第三节 工程文件 编译预处理 库函数简介
共 140 页
第 2 页
§8-b1 工程文件
一、基本概念 内部函数(静态函数): 只能在本文件中使用的函数 外部函数: 可被其它文件调用的函数 二、函数定义 内部函数: static 类型说明符 函数名(形参表) 外部函数: extern 类型说明符 函数名(形参表)
共 140 页 第 14 页
§8-b2 编译预处理—— 二、文件包含3
只包含源文件,不包含可执行文件和目标文件。
可以嵌套 例如:file1.c需包含file2.c, file2.c包含file3.c,在file1中,用两次 :#include<file3.h> #include<file2.h>,必须将file3.h放在前面 (4) 一个#include只能包含一个文件

C语言-预处理命令

C语言-预处理命令

我们可以在C源程序中插入传给编译程序的各中指令,这些指令被称为预处理器指令,它们扩充了程序设计的环境。

现把常用的预处理命令总结如下:1. 预处理程序按照ANSI标准的定义,预处理程序应该处理以下指令:#if #ifdef #ifndef #else #elif#endif#define#undef#line#error#pragma#include显然,上述所有的12个预处理指令都以符号#开始,,每条预处理指令必须独占一行。

2. #define#define指令定义一个标识符和一个串(也就是字符集),在源程序中发现该标识符时,都用该串替换之。

这种标识符称为宏名字,相应的替换称为宏代换。

一般形式如下:#define macro-name char-sequence这种语句不用分号结尾。

宏名字和串之间可以有多个空白符,但串开始后只能以新行终止。

例如:我们使用LEFT代表1,用RIGHT代表0,我们使用两个#define指令:#define LEFT 1#define RIGHT 0每当在源程序中遇到LEFT或RIGHT时,编译程序都用1或0替换。

定义一个宏名字之后,可以在其他宏定义中使用,例如:#define ONE 1#define TWO ONE+ONE#define THREE ONE+TWO宏代换就是用相关的串替代标识符。

因此,如果希望定义一条标准错误信息时,可以如下定义:#define ERROR_MS “Standard error on input \n”如果一个串长于一行,可在行尾用反斜线”\”续行,如下:#define LONG_STRING “This is a very very long \String that i s used as an example”3. #error#error指令强制编译程序停止编译,它主要用于程序调试。

#error指令的一般形式是:#error error-message注意,宏串error-message不用双引号包围。

8预处理命令

8预处理命令

8.4 文件包含 概念:在一个文件中,去包含另一个文 件的全部内容 #include “文件名” #include <文件名> 在编译时在出现#include <文件名>处把文 件名对应文件插入到源程序中 <文件名>:在系统目录上找指定的文件 (找到插入,找不到报错) “文件名”:在当前目录上找指定文件(找到 插入,找不到去系统目录找找到插入找不 到报错)
编译预处理
以“#”开头的行,都称为“编译预处理” 命令行。 比如:#include <stdio.h> #define max 100 编译(complier):将c语言的源程序(*.c)翻译 为机器指令(二进制代码)序列的过程
8.1 编译预处理概念 (1)概念 所谓“编译预处理”就是在c编译程序对c 源程序进行编译前,由编译预处理程序对这 些编译预处理命令进行处理的过程 c语言的预处理命令有:#define、 #undef、#if、#else、#elif、#endif、 #ifdef、#ifndef、#line、#pragma、 #error 位置:在一行的开头以“#”号开始,每行 末尾不得加“;”号,可以根据需要出现在 程序的任何一行的开始部位
2)替换文本中可以包含已定义过的宏名,比 如: #define PI 3.14 #define ADDPI (PI+1) #define TWO_ADDPI (2*ADDPI)
3)当宏定义在一行中写不下,需要在下 一行继续时,只需要在最后一个字符后紧接 着加一个反斜线“\” 比如: #define LEAP_YEAR year%4==0\ &&year%100!=0||year%400==0
(2)预处理功能主要有以下三种: 1)宏定义 常见 2)文件包含 3)条件编译 8.2 宏定义 (1)不带参数的宏定义 1)形式:#define 宏名 替换文本 比如: #define PI 3.14 (宏名不能与程序中其它名字相同) 在编译时,在此命令行之后,预处理程序 对程序中的所有名为PI的标识符用3.Βιβλιοθήκη 4来替 换,这个过程称为“宏替换”。

预处理命令

预处理命令

预处理命令预处理命令的作用:对源程序编译之前做一些处理,生成扩展C源程序。

可以简化程序开发过程,提高程序的可读性,也更有利于移植和调试C语言程序。

一、宏定义1.不带参数的宏定义(1)格式:#define 宏名标识符宏内容字符序列(2)说明:①“#”开头;②占单独书写行;③行的尾部不以分号作为结束标记。

(3)宏展开(即宏替换)在用“宏内容字符序列”替换“宏名标识符”时,必须原样替换。

例如,有程序:#define NUM1 10#define NUM2 20#define NUM NUM1 + NUM2 main ( ){int a=2, b=3;a*=NUM; b=b*NUM;printf("a=%d, b=%d\n",a,b); }宏替换后程序内容如下:main ( ){int a=2, b=3;a*=10+20;b=b*10+20; /*初学者容易理解成b=b*(10+20); 从而得到错误的b值90*/ printf("a=%d,b=%d\n",a,b); }程序的运行结果为:a=60,b=50若想使b得到90的结果,可以将“#define NUM NUM1 + NUM2”改为“#define NUM (NUM1 + NUM2)”,即在“NUM1 + NUM2”外加一个(),从而在宏替换时,会将此括号原样展开出来。

【注意:程序中字符串常量即双引号中的字符与宏名相同时,不作为宏进行宏替换操作。

】例如,有程序:#define PRINT "Hello!"main(){printf("PRINT:%s\n",PRINT);} 宏替换后程序内容如下:main(){printf("PRINT:%s\n","Hello!");} 程序的运行结果是:PRINT: Hello!2.带参数的宏定义(1)格式:#define宏名标识符(参数列表)宏内容字符序列(2)说明:①参数列表由一个或多个参数构成,参数只有参数名,没有数据类型符,用逗号分隔②“宏内容字符序列”中通常会引用宏的参数(3)宏展开(即宏替换)首先将“宏内容字符序列”中的宏参数用实参替换,再将这个宏的实际内容文本替换掉源程序中的“宏名标识符(参数列表)”。

第8章 编译预处理命令ju

第8章 编译预处理命令ju

}
12
第 8 章 编译处理命令
条件编译命令的格式2:
#if 表达式 程序段1
#else 程序段2
#endif
把file2.c插入file1.c的 #include命令的位置 处,使file2.c成为源 程序file1.c的一部分。
➢编译预处理时,若表达式的值为非0,则 ➢编与译格程式序1相段同1,,否程则序编段译2的程部序分段可2。以没有,
相当于程序段2为空语句。
13
第 8 章 编译处理命令
【例8-4】条件编译命令应用示例之二。
#define LETTER 0 main()
符号常量LETTER 值为0
{
char c;
printf("Please input a character\n");
scanf("%c",&c);
#if LETTER
#define的作用是把一个标识符(宏名)定义为一个字 符串。
#define预处理命令的格式: #define 标识符 字符串
➢ 在编译预处理时,编译系统把源程序中出现的该 标识符,均以定义的字符串替换, 将替换过程称 为宏替换。
➢ C程序中通常以大写字母定义宏名标识符。
5
第 8 章 编译处理命令
这部分语句被编译
if(c>='A’&&c<='Z')
c=c+32;
#else
if(c>='a'&&c<='z')
c=c-32;
#endif
printf("%c",c);

第8讲 预处理命令

第8讲 预处理命令

B
B A
计算机与通信工程学院 15
A
8.2 “文件包含”处理
使用文件包含指令时应注意几个问题: (1) 一个#include指令只能包含一个文件,要包含多个 文件就要用多个#include指令 。 (2) 文件包含可以嵌套。 例如:文件 file1.c 中含有指令 #include "f2.c" 在文件 f2.c 中有 #include <math.h> #include "f3.c" 则file1.c将把f2.c中包含的文件全部包含进来。
计算机与通信工程学院 14
8.2 “文件包含”处理
头文件不能单独编译,它只能和C源程序文件一起 进行编译。 文件包含的语义如下图所示:即 file1.c 把 file2.c 的 拷贝包含到自己的内部,成为一个大文件,然后再一起 编译。
File1.c #include<File2.c> File2.c File1.c
第8讲 预处理命令
第8讲 预处理命令
8.1 宏定义 8.2 “文件包含”处理 8.3 条件编译
计算机与通信工程学院
2
8.1 宏定义
8.1 宏定义
一、不带参数的宏定义
宏定义就是用一个指定的名字代表一长串字符序 列,这个名字称为宏名,被代替的长串序列就称为宏 值。其一般格式为: 宏名
#define 标识符 字符串
宏值
宏名可以出现在程序中,在预编译时,预处理程 序会先把宏名替换成宏值(称为宏展开) ,然后再去进 行编译。
计算机与通信工程学院 4
8.1 宏定义
不带参数的宏定义示例: #define PI 3.14159265
上述预处理命令中,指定PI为宏名,3.14159265为 宏值。 如果程序中有语句:

C语言编程中的预处理命令你会用吗?

C语言编程中的预处理命令你会用吗?

C语言编程中的预处理命令你会用吗?什么是预处理命令预处理命令在我之前看过的C语言基础教程中好像并没有详细说到,在现在的一些项目中预处理命令的出现频率却越来越多。

事物的存在必有其存在的理由,于是就花时间去琢磨了一下,以及查阅相关资料,发现使用预处理命令去优化代码可以达到很好的效果。

预处理命令在某资料中是这样描述的'C程序的源代码中可包括各种编译指令,这些指令称为预处理命令。

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

预处理命令实质上是运行在编译器编译过程的指令。

所以说在嵌入式程序设计中使用预处理命令不会占用最终目标运行系统的存储空间。

预处理命令有哪些在ANSI标准定义的C语言预处理程序中包括下列命令:#include,#define,#if,#else,#elif,#endif,#ifdef,#ifndef,#error,#undef,#line,#pragma等。

从以上可以看出预处理命令的共同特点就是以'#'开头。

下面就分别介绍几个在项目中使用比较多的预处理命令。

1.#include这个预处理命令算是使用的最多而又最重要的一个预处理命令了。

它的作用你是否还记得?include就是'包含'的意思,在程序编译的时候预处理器看到#include就会把<>尖括号或者' '中的那个文件找到,然后用该文件的内容替换掉#include <>这一行。

使用方法或者格式:#include <xxx.h>2.#define#define叫做宏定义,标识符为所定义的宏名,简称宏。

标识符的命名规则与前面讲的变量的命名规则是一样的。

#define的功能是将标识符定义为其后的常量。

一经定义,程序中就可以直接用标识符来表示这个常量。

是不是与定义变量类似?但是要区分开!变量名表示的是一个变量,但宏名表示的是一个常量。

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

第八章预处理命令
一、选择题
1.C语言中,宏定义有效范围从定义处开始,到源文件结束处结束,但可以用
来提前解除宏定义的作用。

(0级)
A)# ifdef B)endif C)# undefine D)# undef
2.以下不正确的叙述是。

(0级)
A)预处理命令都必须以“#”号开始
B)在程序中凡是以“#”号开始的语句行都是预处理命令行
C)C语言在执行过程中对预处理命令行进行处理
D)# define ABCD是正确的宏定义
3.以下正确的叙述是。

(0级)
A)在程序的一行中可以出现多个有效的预处理命令行
B)使用带参宏时,参数的类型应与宏定义时的一致
C)宏替换不占用运行时间,只占编译时间
D)宏定义不能出现在函数内部
4.以下不正确的叙述是。

(0级)
A)宏替换不占用运行时间
B)宏名无类型
C)宏替换只是字符替换
D)宏名必须用大写字母表示
5. 以下正确的叙述是。

(0级)
A)C语言的预处理功能是指完成宏替换和包含文件的调用
B)预处理命令只能位于C源程序文件的首部
C)凡是C源程序中行首以“#”标识的控制行都是预处理命令
D)C语言的编译预处理就是对源程序进行初步的语法检查
6.在文件包含预处理语句(# include)的使用形式中,当之后的文件名用“”(双引号)
括起时,寻找被包含文件的方式是。

(0级)
A)直接按系统设定的标准方式搜索目录
B)先在源程序所在目录搜索,再按系统设定的标准方式搜索
C)仅仅搜索源程序所在目录
D)仅仅搜索当前目录
7.在文件包含预处理语句(# include)的使用形式中,当之后的文件名用<>(尖引号)
括起时,寻找被包含文件的方式是。

(0级)
A)直接按系统设定的标准方式搜索目录
B)先在源程序所在目录搜索,再按系统设定的标准方式搜索
C)仅仅搜索源程序所在目录
D)仅仅搜索当前目录
8.C语言的编译系统对宏命令的处理。

(0级)
A)在程序运行时进行的
B)在程序连接时进行的
C)和C程序中的其它语句同时进行编译的
D)在对源程序中其它语句正式编译之前进行的
9.以下程序的输出结果是。

(1级)
# define MIN(x,y) (x)<(y) ? (x) : (y)
main( )
{ int i,j,k; i=10; j=15; k=10*MIN(i,j); printf(“%d”,k); }
A)15 B)100 C)10 D)150
10.以下程序的输出结果是。

(2级)
# include <stdio.h>
# define ADD(y) 3.54+y
# define PR(a) printf(“%d”, (int)(a))
# define PR1(a) PR(a); putchar (…\n‟)
main( )
{ int i=4; PR1(ADD(5)*i); }
A)20 B)23 C)10 D)0
11.以下程序的输出结果是。

(2级)
# include <stdio.h>
# define N 2
# define M N+2
# define CUBE(x) (x*x*x)
main( )
{ int i=M; i=CUBE(i); printf(“%d\n”, i); }
A)17 B)64 C)125 D)53
二、填空题
1.C提供的预处理功能主要有三种,分别是、和。

(0级)
2.设有以下宏定义:# define WIDTH 80
# define LENGTH WIDTH+40
则执行赋值语句:v= LENGTH*20;(v为int型变量)后,v的值是。

(2级)
3.设有以下宏定义:# define WIDTH 80
# define LENGTH (WIDTH+40)
则执行赋值语句:k= LENGTH*20;(k为int型变量)后,k的值是。

(2级)
三、读程序写结果题
1.以下程序的输出结果是。

(2级)
# define PR(int) printf (”int=%d\n”, int)
main( )
{ int x=1,y=1,z=1; x+=y+=z; PR(x<y?y:x);
PR(x<y?x++:y++); PR(x); PR( y );
PR(z+=x<y?x++:y++); PR( y );
}
2.以下程序的输出结果是。

(2级)
# include <stdio.h>
# define PR(a) printf (”a=%d”, (int)(a))
# define PRINT(a) PR(a); putchar(…\n‟);
main( )
{ float x=3.1415,y=1.823; PRINT(2*x); PRINT(3*y*y);
}
3.以下程序的输出结果是。

(2级)
# include <stdio.h>
# define PR(a) printf (”a=%d”, (int)(a))
# define PRINT(a) PR(a); putchar(…\n‟);
# define PRINT2(a,b) PR(a), PRINT(b)
# define PRINT3(a,b,c) PR(a), PRINT2(b,c)
main( )
{ float x=3.1415,y=1.823,z=0.923;
PRINT3(x,2*y,3*z)
}
4.以下程序的输出结果是。

(1级)
# define A 3
# define B(a) ((A+1)*a)
main( )
{ int x; x=3*(A+B(7)); printf (”x=%4d\n”, x);
}
5.以下程序的输出结果是。

(1级)
# define POWER(x) ((x)*(x))
main( )
{ int i=1; while(i<=4) printf(“%d”, POWER(i++));
}
6.以下程序的输出结果是。

(1级)
main( )
{int b=5;
#define b 2
#define f(x) b*(x)
int y=3;
printf(“%d,”, f(y+1));
#undef b
printf(“%d,”, f(y+1));
#define b 3
printf(“%d\n”, f(y+1));
}
7.以下程序的输出结果是。

(2级)
#define DEBUG
main( )
{int a=14,b=15,c; c=a/b;
# ifdef DEBUG
printf(“a=%d,b=%d,”,a,b);
#endif
printf(“c=%d\n,”,c);
}a=14,b=15,c=0
8.以下程序的输出结果是。

(2级)
main( )
{int a=20,b=10,c; c=a/b;
# ifdef DEBUG
printf(“a=%d,b=%d,”,a,b);
#endif
printf(“c=%d\n,”,c);
}
四、编程题
1.编写一个宏定义MY ALPHA(c),用以判定c是否是字母字符,若是,得1;否则得0。

(2级)
2.编写一个宏定义AREA(a,b,c),用于求一个边长为a、b和c的三角形的面积。

其公式为:
s=(a+b+c)/2 area= s(s-a)(s-b)(s-c) (1级)
3.编写一个程序求三个数中最大者,要求用带参宏实现。

(1级)
4.编写一个程序求1+2+..+n之和,要求用带参宏实现。

(1级)
5.编写一个宏定义LEAPYEAR(y),用以判定年份y是否是闰年。

判定标准是:若y是4的倍数且不是100的倍数或者y是400的倍数,则y是闰年。

(1级)。

相关文档
最新文档