预处理命令行

合集下载

c语言预处理命令之条件编译(ifdefelseendifif等)

c语言预处理命令之条件编译(ifdefelseendifif等)

C语言预处理命令之条件编译(#ifdef,#else,#endif,#if等)预处理过程扫描源代码,对其进行初步的转换,产生新的源代码提供给编译器。

可见预处理过程先于编译器对源代码进行处理。

在C语言中,并没有任何内在的机制来完成如下一些功能:在编译时包含其他源文件、定义宏、根据条件决定编译时是否包含某些代码。

要完成这些工作,就需要使用预处理程序。

尽管在目前绝大多数编译器都包含了预处理程序,但通常认为它们是独立于编译器的。

预处理过程读入源代码,检查包含预处理指令的语句和宏定义,并对源代码进行响应的转换。

预处理过程还会删除程序中的注释和多余的空白字符。

预处理指令是以#号开头的代码行。

#号必须是该行除了任何空白字符外的第一个字符。

#后是指令关键字,在关键字和#号之间允许存在任意个数的空白字符。

整行语句构成了一条预处理指令,该指令将在编译器进行编译之前对源代码做某些转换。

下面是部分预处理指令:指令用途#空指令,无任何效果#include包含一个源代码文件#define定义宏#undef取消已定义的宏#if如果给定条件为真,则编译下面代码#ifdef如果宏已经定义,则编译下面代码#ifndef如果宏没有定义,则编译下面代码#elif如果前面的#if给定条件不为真,当前条件为真,则编译下面代码#endif结束一个#if……#else条件编译块#error停止编译并显示错误信息一、文件包含#include预处理指令的作用是在指令处展开被包含的文件。

包含可以是多重的,也就是说一个被包含的文件中还可以包含其他文件。

标准C编译器至少支持八重嵌套包含。

预处理过程不检查在转换单元中是否已经包含了某个文件并阻止对它的多次包含。

这样就可以在多次包含同一个头文件时,通过给定编译时的条件来达到不同的效果。

例如:#defineAAA#include"t.c"#undefAAA#include"t.c"为了避免那些只能包含一次的头文件被多次包含,可以在头文件中用编译时条件来进行控制。

C语言的预处理命令有哪些?

C语言的预处理命令有哪些?

问:关于C语言中的预处理命令?答:我们可以在C源程序中插入传给编译程序的各种指令,这些指令被称为预处理器指令(等价于汇编语言中的伪指令),它们扩充了程序设计的环境。

现把常用的预处理命令总结如下:1. 预处理程序按照ANSI标准的定义,预处理程序应该处理以下12条指令:#if、#ifdef、#ifndef、#else、#elif、#endif、#define、#undef、#line、#error、#pragma、#include。

显然,所有的12个预处理指令都以符号#开始,,每条预处理指令必须独占一行。

2. #define#define指令定义一个标识符和一个串(也就是字符集),在源程序中发现该标识符时,都用该串替换之(原样替换,不要附加任何人为理解上的符号)。

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

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

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

在C语言里宏定义只用来做的宏名替换,而不做语法检查的,因而它不是C语句,所以宏定义的语句结尾不需要加分号。

宏也在C里也叫预处理命令,因为宏是在程序编译前先进行字符替换的,所以叫预处理.例如:我们使用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 \s tring that is used as an example”3. #error#error指令强制编译程序停止编译,它主要用于程序调试(放在错误的分支中,一旦进入错误的分支就显示该信息)。

c语言的预处理指令分3种  1宏定义  2条件编译  3文件包含

c语言的预处理指令分3种  1宏定义  2条件编译  3文件包含

c语⾔的预处理指令分3种 1宏定义 2条件编译 3⽂件包含宏简介1.C语⾔在对源程序进⾏编译之前,会先对⼀些特殊的预处理指令作解释(⽐如之前使⽤的#include⽂件包含指令),产⽣⼀个新的源程序(这个过程称为编译预处理),之后再进⾏通常的编译所有的预处理指令都是以#开头,并且结尾不⽤分号2.预处理指令分3种 1> 宏定义 2> 条件编译 3> ⽂件包含3.预处理指令在代码翻译成0和1之前执⾏4.预处理的位置是随便写的5.预处理指令的作⽤域:从编写指令的那⼀⾏开始,⼀直到⽂件结尾,可以⽤#undef取消宏定义的作⽤6.宏名⼀般⽤⼤写或者以k开头,变量名⼀般⽤⼩写 宏定义可以分为2种:不带参数的宏定义和带参数的宏定义。

⼀、不带参数的宏定义1.⼀般形式#define 宏名字符串⽐如#define ABC 10右边的字符串也可以省略,⽐如#define ABC2.作⽤它的作⽤是在编译预处理时,将源程序中所有"宏名"替换成右边的"字符串",常⽤来定义常量.3.使⽤习惯与注意1> 宏名⼀般⽤⼤写字母,以便与变量名区别开来,但⽤⼩写也没有语法错误2> 对程序中⽤双引号扩起来的字符串内的字符,不进⾏宏的替换操作。

3> 在编译预处理⽤字符串替换宏名时,不作语法检查,只是简单的字符串替换。

只有在编译的时候才对已经展开宏名的源程序进⾏语法检查4> 宏名的有效范围是从定义位置到⽂件结束。

如果需要终⽌宏定义的作⽤域,可以⽤#undef命令5> 定义⼀个宏时可以引⽤已经定义的宏名#define R 3.0#define PI 3.14#define L 2*PI*R#define S PI*R*R举例1 #include <stdio.h>2#define COUNT 434int main()5 {6char *name = "COUNT";78 printf("%s\n", name);910int ages[COUNT] = {1, 2, 67, 89};1112#define kCount 41314for ( int i = 0; i<COUNT; i++) {15 printf("%d\n", ages[i]);16 }1718// 从这⾏开始,COUNT这个宏就失效19#undef COUNT2021//int a = COUNT 写这个报错2223return0;24 }⼆、带参数的宏定义1.⼀般形式#define 宏名(参数列表) 字符串2.作⽤在编译预处理时,将源程序中所有宏名替换成字符串,并且将字符串中的参数⽤宏名右边参数列表中的参数替换3.使⽤注意1> 宏名和参数列表之间不能有空格,否则空格后⾯的所有字符串都作为替换的字符串2> 带参数的宏在展开时,只作简单的字符和参数的替换,不进⾏任何计算操作。

第10章 预处理命令

第10章 预处理命令

第十章预处理命令所谓编译预处理是指,在对源程序进行编译之前,先对源程序中的编译预处理命令进行处理;然后再将处理的结果,和源程序一起进行编译,以得到目标代码。

一、宏定义与符号常量在C语言中,“宏”分为无参数的宏(简称无参宏)和有参数的宏(简称有参宏)两种。

无参宏定义1.无参宏定义的一般格式#define 标识符字符串其中:“define”为宏定义命令;“标识符”为所定义的宏名,通常用大写字母表示,以便于与变量区别;“字符串”可以是常数、表达式、格式串等。

2.使用宏定义的优点(1)可提高源程序的可维护性(2)可提高源程序的可移植性(3)减少源程序中重复书写字符串的工作量例9.1 输入圆的半径,求圆的周长、面积和球的体积。

要求使用无参宏定义圆周率。

/*程序功能:输入圆的半径,求圆的周长、面积和球的体积。

*/#define PI 3.1415926 /*PI是宏名,3.1415926用来替换宏名的常数*/void main(){float radius,length,area,volume;printf("Input a radius: ");scanf("%f",&radius);length=2*PI*radius; /*引用无参宏求周长*/area=PI*radius*radius; /*引用无参宏求面积*/volume=PI*radius*radius*radius*3/4; /*引用无参宏求体积*/printf("length=%.2f,area=%.2f,volume=%.2f\n", length, area, volume);}3.说明(1)宏名一般用大写字母表示,以示与变量区别。

但这并非是规定。

(2)宏定义不是C语句,所以不能在行尾加分号。

否则,宏展开时,会将分号作为字符串的1个字符,用于替换宏名。

(3)在宏展开时,预处理程序仅以按宏定义简单替换宏名,而不作任何检查。

预处理指令详解

预处理指令详解

#pragma#pragma 预处理指令详解在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。

#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。

依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。

其格式一般为: #Pragma Para其中Para 为参数,下面来看一些常用的参数。

(1)message 参数。

Message 参数是我最喜欢的一个参数,它能够在编译信息输出窗口中输出相应的信息,这对于源代码信息的控制是非常重要的。

其使用方法为:#Pragma message(“消息文本”)当编译器遇到这条指令时就在编译输出窗口中将消息文本打印出来。

当我们在程序中定义了许多宏来控制源代码版本的时候,我们自己有可能都会忘记有没有正确的设置这些宏,此时我们可以用这条指令在编译的时候就进行检查。

假设我们希望判断自己有没有在源代码的什么地方定义了_X86这个宏可以用下面的方法#ifdef _X86#Pragma message(“_X86 macro activated!”)#endif当我们定义了_X86这个宏以后,应用程序在编译时就会在编译输出窗口里显示“_X86 macro activated!”。

我们就不会因为不记得自己定义的一些特定的宏而抓耳挠腮了。

(2)另一个使用得比较多的pragma参数是code_seg。

格式如:#pragma code_seg( ["section-name"[,"section-class"] ] )它能够设置程序中函数代码存放的代码段,当我们开发驱动程序的时候就会使用到它。

(3)#pragma once (比较常用)只要在头文件的最开始加入这条指令就能够保证头文件被编译一次,这条指令实际上在VC6中就已经有了,但是考虑到兼容性并没有太多的使用它。

预处理命令与结构体练习题答案

预处理命令与结构体练习题答案

第11章结构体与共用体一、选择题(在下列各题的A)、B)、C)、D)四个选项中,只有一个选项是正确的,请将正确选项填涂在答题卡相应位置上。

)11.1 C语言结构体类型变量在程序运行期间A)TC环境在内存中仅仅开辟一个存放结构体变量地址的单元B)所有的成员一直驻留在内存中C)只有最开始的成员驻留在内存中D)部分成员驻留在内存中考生答案: 正确答案: B11.2 下列各数据类型不属于构造类型的是A)枚举型 B)共用型 C)结构型 D)数组型考生答案: 正确答案: A11.3 当说明一个结构体变量时系统分配给它的内存是A)各成员所需内存量的总和 B)结构中第一个成员所需内存量C)成员中占内存量最大者所需的容量 D)结构中最后一个成员所需内存量考生答案: 正确答案: A11.4 设有以下说明语句typedef struct{ int n;char ch[8];} PER;则下面叙述中正确的是A)PER 是结构体变量名 B)PER是结构体类型名C)typedef struct 是结构体类型 D)struct 是结构体类型名考生答案: 正确答案: B11.5 已知有如下定义:struct a{char x; double y;}data,*t;,若有t=&data,则对data 中的成员的正确引用是A)(*t).data.x B)(*t).x C)t->data.x D)t.data.x 考生答案: 正确答案: B11.6 以下程序的运行结果是#include "stdio.h"main(){ struct date{ int year,month,day; } today;printf("%d\n",sizeof(struct date));}A)6 B)8 C)10 D)12考生答案: 正确答案: A11.7 设有如下定义:struck sk{ int a;float b;} data;int *p;若要使P指向data中的a域,正确的赋值语句是A)p=&a; B)p=data.a; C)p=&data.a; D)*p=data.a; 考生答案: 正确答案: C11.8 以下对结构体类型变量的定义中,不正确的是A)typedef struct aa{ int n;float m;} AA;AA tdl;B)#define AA struct aaAA { int n;float m;} tdl;C)struct{ int n;float m;} aa;struct aa tdl;D)struct{ int n;float m;} tdl;考生答案: 正确答案: C11.9 若有下面的说明和定义struct test{ int ml; char m2; float m3;union uu { char ul[5]; int u2[2];} ua;} myaa;则sizeof(struct test )的值是A)12 B)16 C)14 D)9考生答案: 正确答案: A11.10 以下程序的输出是struct st{ int x; int *y;} *p;int dt[4]={ 10,20,30,40};struct st aa[4]={ 50,&dt[0],60,&dt[0],60,&dt[0],60,&dt[0]};main(){ p=aa;printf("%d\n",++(p->x));}A)10 B)11 C)51 D)60考生答案: 正确答案: C11.11 有以下程序:#include <stdio.h>union pw{ int i;char ch[2];}a;main(){ a.ch[0]=13;a.ch[1]=0;printf("%d\n",a.i);}程序的输出结果是A)13 B)14 C)208 D)209 考生答案: 正确答案: A11.12 已知学生记录描述为:struct student{ int no;char name[20],sex;struct{ int year,month,day;} birth;};struct student s;设变量s中的“生日”是“1984年11月12日”,对“birth”正确赋值的程序段是A)year=1984;month=11;day=12;B)s.year=1984;s.month=11;s.day=12;C)birth.year=1984;birth.month=11;birth.day=12;D)s.birth.year=1984;s.birth.month=11;s.birth.day=12;考生答案: 正确答案: D11.13 有如下定义struct person{char name[9];int age;};struct person class[10]={"John",17,"paul",19,"Mary",18,"Adam",16,};根据上述定义,能输出字母M的语句是A)printf("%c\n",class[3].name);B)printf("%c\n",class[3].name[1]);C)printf("%c\n",class[2].name[1]);D)printf("%c\n",class[2].name[0]);考生答案: 正确答案: B11.14 下列程序的输出结果是struct abc{ int a, b, c, s; };main(){ struct abc s[2]={{1,2,3},{4,5,6}}; int t;t=s[0].a+s[1].b;printf("%d\n",t);}A)5 B)6 C)7 D)8考生答案: 正确答案: B11.15 若有下面的说明和定义,则sizeof(struct aa)的值是struct aa{ int r1; double r2; float r3;union uu{char u1[5];long u2[2];}ua;} mya;A)30 B)29 C)24 D)22考生答案: 正确答案: D11.16 有以下结构体说明和变量的定义,且指针p指向变量a,指针q指向变量b。

C语言编译预处理命令

C语言编译预处理命令

编译预处理命令文件包含:把指定的文件插入到预处理命令行所在的位置并取代该命令行,即把指定的文件与当前的源程序文件连接成一个源文件。

#include<文件名>在文件包含目录中去查找指定的文件,并将该文件添加到源文件中。

一个被包含的文件中可以含有文件包含命令来包含另一个文件。

#include“文件名”命令中文件名的位置是当前源文件的位置,若在当前目录中未找到该文件,则再到“包含目录”中去查找。

宏用一个标识符表示一个字符串,称为宏,被定义为宏的标识符称为宏名。

在编译预处理时对程序中所有出现的宏名用宏定义中的字符串去代换,这就是宏替换。

它是由系统编译程序时自动完成的。

无参宏定义#define 标识符字符串如#define PI 3.14使用宏时要注意:(1)宏定义是用宏名来表示一个字符串,在宏展开时用字符串取代宏名。

(2)宏定义不是变量定义或语句,在行末不能加分号,如果加上分号则分号也成为字符串的一部分。

(3)宏定义可以出现在程序的任何地方,其作用域是宏定义命令所在位置开始到源程序结束。

如果要终止其作用域可使用#undef命令。

(4)宏定义允许嵌套,在宏定义的字符串中可以使用已经定义的宏名。

在宏展开时将逐层替换。

(5)#define PI 3.1415926#define AREA PI*y*y有参宏定义#define 宏名(形参表)字符串对带参数的宏,在调用中不仅要进行宏展开,而且还要用实参去替换形参。

带参宏调用的语法格式如下:宏名(实参表);#define M(x) x+1K=M(3);K=3+1定义有参宏时要注意以下几点:(1)有参宏定义中,宏名与形参表之间不能有空格出现。

(2)在函数中,调用时要把实参的值赋给形参,进行“值传递”。

而在带参宏调用中,只是符号替换,不存在值传递问题。

(3)宏定义中的形参只能是标识符,而宏调用中的实参可以是表达式。

宏替换中对实参表达式不做计算直接照原样替换,字符串内的形参通常用括号括起来以避免出错。

C语言程序设计-谭浩强-第9章预处理命令

C语言程序设计-谭浩强-第9章预处理命令
例 #define S (r) PI*r*r 例 #define POWER(x) x*x 相当于定义了不带参宏S,代表字符串“(r) PI*r*r” x=4; y=6; z=POWER(x+y); 宏展开:z=x+y*x+y; 一般写成: #define POWER(x) ((x)*(x)) 宏展开: z=((x+y)*(x+y));
17/14
§9.1 宏定义 宏体可缺省,表示宏名
不带参数宏定义
定义过或取消宏体
一般形式: 宏体] 一般形式: #define 宏名 [宏体 宏体 功能:用指定标识符 宏名)代替字符序列 宏体) 用指定标识符(宏名 代替字符序列(宏体 功能 用指定标识符 宏名 代替字符序列 宏体
如 #define 定义位置:任意YES 1 一般在函数外面) 定义位置 任意(一般在函数外面 任意 一般在函数外面 #define 例 NO 0 YES #define 1 作用域:从定义命令到文件结束 作用域 从定义命令到文件结束 main() #define PI 3.1415926 #define OUT printf(“Hello,World”); { …….. YES原作用域 #undef可终止宏名作用域 可 } 格式: 格式: #undef 宏名 #undef YES 宏展开:预编译时,用宏体替换宏名 用宏体替换宏名---不作语法检查 宏展开:预编译时 用宏体替换宏名 不作语法检查 #define YES 0 max() 引号中的内容与宏名相同也不置换 YES新作用域 {…….. if(x==YES)WIDTH 80 如 例 #define WIDTH 80 printf(“correct!\n”); 例 #define 宏定义可嵌套, 宏定义可嵌套,不能递归 } else if (x==NO)( WIDTH+40 ) printf(“error!\n”); #define #define LENGTH 3.14159 例 #define PI LENGTH WIDTH+40 宏定义中使用必要的括号() 宏定义中使用必要的括号() 展开后: if(x==1) 展开后var=LENGTH*2; : var=LENGTH*2;printf(“correct!\n”); (×) printf(“2*PI=%f\n”,PI*2); 例 #define MAX MAX+10 × else 宏展开: 宏展开: :printf(“2*PI=%f\n”,3.14159*2); 宏展开 宏展开:var= ((x==0) ) * 2;printf(“error!\n”); 宏展开: if 80+40 宏展开 :var= 80+40*2;

C语言中的预编译宏定义

C语言中的预编译宏定义

C语言中的预编译宏定义C语言中的预编译宏定义导语:C初学者可能对预处理器没什么概念,这是情有可原,下面是C中的预编译宏定义,一起来学习下吧:(一) 预处理命令简介预处理命令由#(hash字符)开头, 它独占一行, #之前只能是空白符. 以#开头的语句就是预处理命令, 不以#开头的语句为C中的代码行. 常用的预处理命令如下:#define 定义一个预处理宏#undef 取消宏的定义#include 包含文件命令#include_next 与#include相似, 但它有着特殊的用途#if 编译预处理中的条件命令, 相当于C语法中的if语句#ifdef 判断某个宏是否被定义, 若已定义, 执行随后的语句#ifndef 与#ifdef相反, 判断某个宏是否未被定义#elif 若#if, #ifdef, #ifndef或前面的#elif条件不满足, 则执行#elif 之后的语句, 相当于C语法中的else-if#else 与#if, #ifdef, #ifndef对应, 若这些条件不满足, 则执行#else 之后的语句, 相当于C语法中的else#endif #if, #ifdef, #ifndef这些条件命令的结束标志.defined 与#if, #elif配合使用, 判断某个宏是否被定义#line 标志该语句所在的行号# 将宏参数替代为以参数值为内容的字符窜常量## 将两个相邻的标记(token)连接为一个单独的标记#pragma 说明编译器信息#warning 显示编译警告信息#error 显示编译错误信息(二) 预处理的文法预处理并不分析整个源代码文件, 它只是将源代码分割成一些标记(token), 识别语句中哪些是C语句, 哪些是预处理语句. 预处理器能够识别C标记, 文件名, 空白符, 文件结尾标志.预处理语句格式: #command name(...) token(s)1, command预处理命令的名称, 它之前以#开头, #之后紧随预处理命令, 标准C允许#两边可以有空白符, 但比较老的编译器可能不允许这样. 若某行中只包含#(以及空白符), 那么在标准C中该行被理解为空白. 整个预处理语句之后只能有空白符或者注释, 不能有其它内容.2, name代表宏名称, 它可带参数. 参数可以是可变参数列表(C99).3, 语句中可以利用""来换行.e.g.# define ONE 1 /* ONE == 1 */等价于: #define ONE 1#define err(flag, msg) if(flag)printf(msg)等价于: #define err(flag, msg) if(flag) printf(msg)(三) 预处理命令详述1, #define#define命令定义一个宏:#define MACRO_NAME(args) tokens(opt)之后出现的MACRO_NAME将被替代为所定义的标记(tokens). 宏可带参数, 而后面的标记也是可选的.对象宏不带参数的宏被称为"对象宏(objectlike macro)"#define经常用来定义常量, 此时的宏名称一般为大写的字符串. 这样利于修改这些常量.e.g.#define MAX 100int a[MAX];#ifndef __FILE_H__#define __FILE_H__#include "file.h"#endif#define __FILE_H__ 中的宏就不带任何参数, 也不扩展为任何标记. 这经常用于包含头文件.要调用该宏, 只需在代码中指定宏名称, 该宏将被替代为它被定义的内容.函数宏带参数的宏也被称为"函数宏". 利用宏可以提高代码的运行效率: 子程序的调用需要压栈出栈, 这一过程如果过于频繁会耗费掉大量的CPU运算资源. 所以一些代码量小但运行频繁的代码如果采用带参数宏来实现会提高代码的运行效率.函数宏的参数是固定的情况函数宏的定义采用这样的方式: #define name( args ) tokens其中的args和tokens都是可选的. 它和对象宏定义上的区别在于宏名称之后不带括号.注意, name之后的左括号(必须紧跟name, 之间不能有空格, 否则这就定义了一个对象宏, 它将被替换为以(开始的字符串. 但在调用函数宏时, name与(之间可以有空格.e.g.#define mul(x,y) ((x)*(y))注意, 函数宏之后的参数要用括号括起来, 看看这个例子:e.g.#define mul(x,y) x*y"mul(1, 2+2);" 将被扩展为: 1*2 + 2同样, 整个标记串也应该用括号引用起来:e.g.#define mul(x,y) (x)*(y)sizeof mul(1,2.0) 将被扩展为 sizeof 1 * 2.0调用函数宏时候, 传递给它的参数可以是函数的返回值, 也可以是任何有意义的语句:e.g.mul (f(a,b), g(c,d));e.g.#define (stmt) stmt( a=1; b=2;) 相当于在代码中加入 a=1; b=2 .( a=1, b=2;) 就有问题了: 预处理器会提示出错: 函数宏的参数个数不匹配. 预处理器把","视为参数间的分隔符.((a=1, b=2;)) 可解决上述问题.在定义和调用函数宏时候, 要注意一些问题:1, 我们经常用{}来引用函数宏被定义的内容, 这就要注意调用这个函数宏时的";"问题.example_3.7:#define swap(x,y) { unsigned long _temp=x; x=y; y=_tmp}如果这样调用它: "swap(1,2);" 将被扩展为: { unsigned long _temp=1; 1=2; 2=_tmp};明显后面的;是多余的, 我们应该这样调用: swap(1,2)虽然这样的调用是正确的, 但它和C语法相悖, 可采用下面的方法来处理被{}括起来的内容:#define swap(x,y)do { unsigned long _temp=x; x=y; y=_tmp} while (0)swap(1,2); 将被替换为:do { unsigned long _temp=1; 1=2; 2=_tmp} while (0);在Linux内核源代码中对这种do-while(0)语句有这广泛的应用.2, 有的函数宏是无法用do-while(0)来实现的, 所以在调用时不能带上";", 最好在调用后添加注释说明.eg_3.8:#define incr(v, low, high)for ((v) = (low),; (v) <= (high); (v)++)只能以这样的形式被调用: incr(a, 1, 10) /* increase a form 1 to 10 */函数宏中的参数包括可变参数列表的情况C99标准中新增了可变参数列表的内容. 不光是函数, 函数宏中也可以使用可变参数列表.#define name(args, ...) tokens#define name(...) tokens"..."代表可变参数列表, 如果它不是仅有的'参数, 那么它只能出现在参数列表的最后. 调用这样的函数宏时, 传递给它的参数个数要不少于参数列表中参数的个数(多余的参数被丢弃).通过__VA_ARGS__来替换函数宏中的可变参数列表. 注意__VA_ARGS__只能用于函数宏中参数中包含有"..."的情况.e.g.#ifdef DEBUG#define my_printf(...) fprintf(stderr, __VA_ARGS__)#else#define my_printf(...) printf(__VA_ARGS__)#endiftokens中的__VA_ARGS__被替换为函数宏定义中的"..."可变参数列表.注意在使用#define时候的一些常见错误:#define MAX = 100#define MAX 100;=, ; 的使用要值得注意. 再就是调用函数宏是要注意, 不要多给出";".注意: 函数宏对参数类型是不敏感的, 你不必考虑将何种数据类型传递给宏. 那么, 如何构建对参数类型敏感的宏呢? 参考本章的第九部分, 关于"##"的介绍.关于定义宏的另外一些问题(1) 宏可以被多次定义, 前提是这些定义必须是相同的. 这里的"相同"要求先后定义中空白符出现的位置相同, 但具体的空白符类型或数量可不同, 比如原先的空格可替换为多个其他类型的空白符: 可为tab, 注释...e.g.#define NULL 0#define NULL /* null pointer */ 0上面的重定义是相同的, 但下面的重定义不同:#define fun(x) x+1#define fun(x) x + 1 或: #define fun(y) y+1如果多次定义时, 再次定义的宏内容是不同的, gcc会给出"NAME redefined"警告信息.应该避免重新定义函数宏, 不管是在预处理命令中还是C语句中, 最好对某个对象只有单一的定义. 在gcc中, 若宏出现了重定义, gcc会给出警告.(2) 在gcc中, 可在命令行中指定对象宏的定义:e.g.$ gcc -Wall -DMAX=100 -o tmp tmp.c相当于在tmp.c中添加" #define MAX 100".那么, 如果原先tmp.c中含有MAX宏的定义, 那么再在gcc调用命令中使用-DMAX, 会出现什么情况呢?---若-DMAX=1, 则正确编译.---若-DMAX的值被指定为不为1的值, 那么gcc会给出MAX宏被重定义的警告, MAX的值仍为1.注意: 若在调用gcc的命令行中不显示地给出对象宏的值, 那么gcc 赋予该宏默认值(1), 如: -DVAL == -DVAL=1(3) #define所定义的宏的作用域宏在定义之后才生效, 若宏定义被#undef取消, 则#undef之后该宏无效. 并且字符串中的宏不会被识别e.g.#define ONE 1sum = ONE + TWO /* sum = 1 + TWO */#define TWO 2sum = ONE + TWO /* sum = 1 + 2 */#undef ONEsum = ONE + TWO /* sum = ONE + 2 */char c[] = "TWO" /* c[] = "TWO", NOT "2"! */(4) 宏的替换可以是递归的, 所以可以嵌套定义宏.e.g.# define ONE NUMBER_1# define NUMBER_1 1int a = ONE /* a = 1 */2, #undef#undef用来取消宏定义, 它与#define对立:#undef name如够被取消的宏实际上没有被#define所定义, 针对它的#undef 并不会产生错误.当一个宏定义被取消后, 可以再度定义它.3, #if, #elif, #else, #endif#if, #elif, #else, #endif用于条件编译:#if 常量表达式1语句...#elif 常量表达式2语句...#elif 常量表达式3语句......#else语句...#endif#if和#else分别相当于C语句中的if, else. 它们根据常量表达式的值来判别是否执行后面的语句. #elif相当于C中的else-if. 使用这些条件编译命令可以方便地实现对源代码内容的控制.else之后不带常量表达式, 但若包含了常量表达式, gcc只是给出警告信息.使用它们可以提升代码的可移植性---针对不同的平台使用执行不同的语句. 也经常用于大段代码注释.e.g.#if 0{一大段代码;}#endif常量表达式可以是包含宏, 算术运算, 逻辑运算等等的合法C常量表达式, 如果常量表达式为一个未定义的宏, 那么它的值被视为0.#if MACRO_NON_DEFINED == #if 0在判断某个宏是否被定义时, 应当避免使用#if, 因为该宏的值可能就是被定义为0. 而应当使用下面介绍的#ifdef或#ifndef.注意: #if, #elif, #else之后的宏只能是对象宏. 如果name为名的宏未定义, 或者该宏是函数宏. 那么在gcc中使用"-Wundef"选项会显示宏未定义的警告信息.4, #ifdef, #ifndef, defined.#ifdef, #ifndef, defined用来测试某个宏是否被定义#ifdef name 或 #ifndef name它们经常用于避免头文件的重复引用:#ifndef __FILE_H__#define __FILE_H__#include "file.h"#endifdefined(name): 若宏被定义,则返回1, 否则返回0.它与#if, #elif, #else结合使用来判断宏是否被定义, 乍一看好像它显得多余, 因为已经有了#ifdef和#ifndef. defined用于在一条判断语句中声明多个判别条件:#if defined(VAX) && defined(UNIX) && !defined(DEBUG)和#if, #elif, #else不同, #indef, #ifndef, defined测试的宏可以是对象宏, 也可以是函数宏. 在gcc中使用"-Wundef"选项不会显示宏未定义的警告信息.5, #include , #include_next#include用于文件包含. 在#include 命令所在的行不能含有除注释和空白符之外的其他任何内容.#include "headfile"#include#include 预处理标记前面两种形式大家都很熟悉, "#include 预处理标记"中, 预处理标记会被预处理器进行替换, 替换的结果必须符合前两种形式中的某一种.实际上, 真正被添加的头文件并不一定就是#include中所指定的文件. #include"headfile"包含的头文件当然是同一个文件, 但#include 包包含的"系统头文件"可能是另外的文件. 但这不值得被注意. 感兴趣的话可以查看宏扩展后到底引入了哪些系统头文件.关于#include "headfile"和#include 的区别以及如何在gcc中包含头文件的详细信息, 参考本blog的GCC笔记.相对于#include, 我们对#include_next不太熟悉. #include_next 仅用于特殊的场合. 它被用于头文件中(#include既可用于头文件中, 又可用于.c文件中)来包含其他的头文件. 而且包含头文件的路径比较特殊: 从当前头文件所在目录之后的目录来搜索头文件.比如: 头文件的搜索路径一次为A,B,C,D,E. #include_next所在的当前头文件位于B目录, 那么#include_next使得预处理器从C,D,E目录来搜索#include_next所指定的头文件.可参考cpp手册进一步了解#include_next6, 预定义宏标准C中定义了一些对象宏, 这些宏的名称以"__"开头和结尾, 并且都是大写字符. 这些预定义宏可以被#undef, 也可以被重定义.下面列出一些标准C中常见的预定义对象宏(其中也包含gcc自己定义的一些预定义宏:__LINE__ 当前语句所在的行号, 以10进制整数标注.__FILE__ 当前源文件的文件名, 以字符串常量标注.__DATE__ 程序被编译的日期, 以"Mmm dd yyyy"格式的字符串标注.__TIME__ 程序被编译的时间, 以"hh:mm:ss"格式的字符串标注, 该时间由asctime返回.__STDC__ 如果当前编译器符合ISO标准, 那么该宏的值为1__STDC_VERSION__ 如果当前编译器符合C89, 那么它被定义为199409L, 如果符合C99, 那么被定义为199901L.我用gcc, 如果不指定-std=c99, 其他情况都给出__STDC_VERSION__未定义的错误信息, 咋回事呢?__STDC_HOSTED__ 如果当前系统是"本地系统(hosted)", 那么它被定义为1. 本地系统表示当前系统拥有完整的标准C库.gcc定义的预定义宏:__OPTMIZE__ 如果编译过程中使用了优化, 那么该宏被定义为1.__OPTMIZE_SIZE__ 同上, 但仅在优化是针对代码大小而非速度时才被定义为1.__VERSION__ 显示所用gcc的版本号.可参考"GCC the complete reference".要想看到gcc所定义的所有预定义宏, 可以运行: $ cpp -dM /dev/null7, #line#line用来修改__LINE__和__FILE__.e.g.printf("line: %d, file: %s ", __LINE__, __FILE__);#line 100 "haha"printf("line: %d, file: %s ", __LINE__, __FILE__);printf("line: %d, file: %s ", __LINE__, __FILE__);显示:line: 34, file: 1.cline: 100, file: hahaline: 101, file: haha8, #pragma, _Pragma#pragma用编译器用来添加新的预处理功能或者显示一些编译信息. #pragma的格式是各编译器特定的, gcc的如下:#pragma GCC name token(s)#pragma之后有两个部分: GCC和特定的pragma name. 下面分别介绍gcc中常用的.(1) #pragma GCC dependencydependency测试当前文件(既该语句所在的程序代码)与指定文件(既#pragma语句最后列出的文件)的时间戳. 如果指定文件比当前文件新, 则给出警告信息.e.g.在demo.c中给出这样一句:#pragma GCC dependency "temp-file"然后在demo.c所在的目录新建一个更新的文件: $ touch temp-file, 编译: $ gcc demo.c 会给出这样的警告信息: warning: current file is older than temp-file如果当前文件比指定的文件新, 则不给出任何警告信息.还可以在在#pragma中给添加自定义的警告信息.e.g.#pragma GCC dependency "temp-file" "demo.c needs to be updated!"1.c:27:38: warning: extra tokens at end of #pragma directive1.c:27:38: warning: current file is older than temp-file注意: 后面新增的警告信息要用""引用起来, 否则gcc将给出警告信息.(2) #pragma GCC poison token(s)若源代码中出现了#pragma中给出的token(s), 则编译时显示警告信息. 它一般用于在调用你不想使用的函数时候给出出错信息.e.g.#pragma GCC poison scanfscanf("%d", &a);warning: extra tokens at end of #pragma directiveerror: attempt to use poisoned "scanf"注意, 如果调用了poison中给出的标记, 那么编译器会给出的是出错信息. 关于第一条警告, 我还不知道怎么避免, 用""将token(s)引用起来也不行.(3) #pragma GCC system_header从#pragma GCC system_header直到文件结束之间的代码会被编译器视为系统头文件之中的代码. 系统头文件中的代码往往不能完全遵循C标准, 所以头文件之中的警告信息往往不显示. (除非用#warning显式指明).(这条#pragma语句还没发现用什么大的用处)由于#pragma不能用于宏扩展, 所以gcc还提供了_Pragma:e.g.#define PRAGMA_DEP #pragma GCC dependency "temp-file"由于预处理之进行一次宏扩展, 采用上面的方法会在编译时引发错误, 要将#pragma语句定义成一个宏扩展, 应该使用下面的_Pragma语句:#define PRAGMA_DEP _Pragma("GCC dependency "temp-file"")注意, ()中包含的""引用之前引该加上转义字符.9, #, ###和##用于对字符串的预处理操作, 所以他们也经常用于printf, puts之类的字符串显示函数中.#用于在宏扩展之后将tokens转换为以tokens为内容的字符串常量.e.g.#define TEST(a,b) printf( #a "<" #b "=%d ", (a)<(b));注意: #只针对紧随其后的token有效!##用于将它前后的两个token组合在一起转换成以这两个token 为内容的字符串常量. 注意##前后必须要有token.e.g.#define TYPE(type, n) type n之后调用:TYPE(int, a) = 1;TYPE(long, b) = 1999;将被替换为:int a = 1;long b = 1999;(10) #warning, #error#warning, #error分别用于在编译时显示警告和错误信息, 格式如下:#warning tokens#error tokense.g.#warning "some warning"注意, #error和#warning后的token要用""引用起来!(在gcc中, 如果给出了warning, 编译继续进行, 但若给出了error, 则编译停止. 若在命令行中指定了 -Werror, 即使只有警告信息, 也不编译.【C语言中的预编译宏定义】。

C语言 选择题库第9章 编译预处理和动态存储分配

C语言 选择题库第9章 编译预处理和动态存储分配

第9章编译预处理和动态存储分配1.以下叙述中正确的是()。

A) 在C语言中,预处理命令行都以"#"开头B) 预处理命令行必须位于C源程序的起始位置C) #include <stdio.h>必须放在C程序的开头D) C语言的预处理不能实现宏定义和条件编译的功能参考答案:A【解析】预处理命令是以"#"号开头的命令,它们不是C语言的可执行命令,这些命令应该在函数之外书写,一般在源文件的最前面书写,但不是必须在起始位置书写,所以B),C)错误。

C)语言的预处理能够实现宏定义和条件编译等功能,所以D)错误。

2.以下关于宏的叙述中正确的是()。

A) 宏替换没有数据类型限制B) 宏定义必须位于源程序中所有语句之前C) 宏名必须用大写字母表示D) 宏调用比函数调用耗费时间参考答案:A【解析】宏定义写在函数的花括号外边,作用域为其后的程序,通常在文件的最开头,所以B)选项中宏定义必须位于源程序中所有语句之前是错误的。

宏名一般用大写,但不是必须用大写,所以C)选项错误。

宏展开不占运行时间,只占编译时间,函数调用占运行时间(分配内存、保留现场、值传递、返回值),所以D)选项错误。

3.有以下程序:#include <stdio.h>#define PT 3.5 ;#define S(x) PT*x*x ;main(){int a=1,b=2;printf("%4.1f\n" ,S(a+b));}程序运行后的输出结果是()。

A) 7.5 B) 31.5 C) 程序有错无输出结果D) 14.0参考答案:C【解析】宏定义不是C语句,末尾不需要有分号。

所以语句printf("%4.1f\n" ,S(a+b));展开后为printf("%4.1f\n" ,3.5;*a+b*a+b;);所以程序会出现语法错误。

第10章 预处理命令(答案)范文

第10章 预处理命令(答案)范文

第10 章预处理命令一、选择题1、下列说法不正确的是(D )。

A)宏替换不占用运行时间B)宏无类型C)宏替换只是字符替换D)宏名必须用大写字母表示2、下列说法正确的是(D)。

A)#define和printf都是C语句B)#define是C语句,但printf不是C)printf是C语句,但#define不是D)#define和printf都不是C语句3、下列说法正确的是( C)。

A)C程序必须在开头用预处理命令#includeB)预处理命令必须位于C源程序的首部C)在C语言中,预处理命令都以“#”开头D)C语言的预处理命令只能实现宏定义和条件编译的功能4、设有以下定义:#define N 3#define Y(n) ((N+1)*n)则执行语句:z=2*(N+Y(5+1));后,z的值为( C)A)出错B)42 C)48 D)545、下列程序的运行结果是(B )#define SQR(x) x*xmain(){int a,k=3;a=++SQR(k+1);printf(“%d\n”,a);}A)16 B)9 C)8 D)176、以下程序的输出结果是(B)。

A) 16 B) 2 C) 9 D) 1#define SQR(X) X*Xmain(){ int a=16, k=2, m=1;a/=SQR(k+m)/SQR(k+m);printf("%d\n",a);}7、有如下程序#define N 2#define M N+1#define NUM 2*M+1#main(){ int i;for(i=1;i<=NU M;i++)printf(“%d\n”,i); }该程序中的for循环执行的次数是( B)。

A) 5 B) 6 C) 7 D) 88、若输入1、2,下列程序的运行结果是(B )#define SWAP(a,b) t=b;b=a;a=tmain(){int a,b,t=0;scanf(“%d,%d”,&a,&b);if (a>b)SWAP(a,b);printf(“a=%d,b=%d\n”,a,b);}A)a=1,b=1 B)a=0,b=1 C)a=2,b=1 D)a=1,b=29、下列程序的运行结果是( D)#define R 3.0#define PI 3.#define L 2*PI*R#define S PI*R*Rmain(){printf(“L=%f S=%f\n”,L,S);}A) L=18. S=28.B) 18.=18. 28.=28.C) L=18. 28.=28.D) 18. =18. S=28.10、下面程序的运行结果是:(B )#define N 10#define s(x) x*x#define f(x) (x*x)main(){int i1,i2;i1=1000/s(N); i2=1000/f(N);printf("%d %d\n",i1,i2);}A)10 10 B)1000 10 C)10 1000 D)1000 100011、以下程序运行后,输出结果是(B )#define PT 5.5#define S(x) PT* x * xmain(){int a=1,b=2;printf("%4.1f\n",S(a+b));}A) 49.5 B.) 9.5 C) 22.0 D) 45.012、以下程序的输出结果是(A )#define MUL(x,y) (x)*ymain( ){ int a=3,b=4,c;c=MUL(a++,b++);printf("%d \n",c);}A) 12 B)15 C)20 D) 1613、以下叙述中正确的是(B)A)预处理命令行必须位于C源程序的起始位置B)在C语言中,预处理命令行都以“#”开头C)每个C程序必须在开头包括预处理命令行:#includeD) C语言的预处理不能实现宏定义和条件编译的功能。

第九章 预处理命令

第九章 预处理命令

第九章 预处理命令一、选择题1.以下叙述不正确的是 。

A)预处理命令行都必须以#开始B)在程序中凡是以#开始的语句行都是预处理命令行C)C程序在执行过程中对预处理命令行进行处理D)预处理命令行可以出现在C程序中任意一行上2.以下叙述中正确的是 。

A)在程序的一行上可以出现多个有效的预处理命令行B)使用带参数的宏时,参数的类型应与宏定义时的一致C)宏替换不占用运行时间,只占用编译时间D)C语言的编译预处理就是对源程序进行初步的语法检查3.以下有关宏替换的叙述不正确的是 。

A)宏替换不占用运行时间B)宏名无类型C)宏替换只是字符替换D)宏名必须用大写字母表示4.在“文件包含”预处理命令形式中,当#include后面的文件名用””(双引号)括起时,寻找被包含文件的方式是 。

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

A)直接按系统设定的标准方式搜索目录B)先在源程序所在目录中搜索,再按系统设定的标准方式搜索C)仅仅搜索源程序所在目录D)仅仅搜索当前目录6.在宏定义#define PI 3.1415926中,用宏名PI代替一个 。

A)单精度数B)双精度数C)常量D)字符串7.以下程序的运行结果是 。

#include<stdio.h>#define ADD(x) x+xvoid main ( ){ int m=1,n=2,k=3,sum ;sum = ADD(m+n)*k ;printf(“%d\n”,sum) ;A)9 B)10 C)12 D)188.以下程序的运行结果是 。

#include<stdio.h>#define MIN(x,y) (x)>(y) ? (x) : (y)void main ( ){ int i=10, j=15 , k;k = 10*MIN(i,j);printf(“%d\n”,k);}A)10 B)15 C)100 D)1509.以下程序的运行结果是 。

在C语言中

在C语言中

在C语言中,凡是以“#”号开头的行,都称为“编译预处理”命令行。

预处理命令可以放在程序中的任何位置,其有效范围是从定义开始到文件结束。

预处理命令有宏定义、文件包含和条件编译三类。

#include <stdio.h>命令行表示程序中要引用C标准函数库中的标准输入输出函数。

宏替换的规则。

宏替换分为简单的字符替换和带参数的宏替换两类。

使用宏时应注意以下几点:①宏定义仅仅是符号替换,不是赋值语句,因此不做语法检查;②为了区别程序中其他的标识符,宏名的定义通常用大写字母,但不是必须用大写;③双引号中出现的宏名不替换;④使用宏定义可以嵌套,即后定义的宏中可以使用先定义的宏。

宏定义和三目运算符。

三目运算符的格式为:test ? 语句1 : 语句2其中,test可以是任何Boolean 表达式。

语句1,当test 是true 时执行该语句,可以是复合语句;语句2,当test 是false 时执行该语句,可以是复合语句。

isDIV(k ,n)要表达的是当k除n的余数是1时表达式的值为1,否则为0,预处理命令行是以“#”开始的语句,预处理命令行的最后不能以分号表示结束,预处理命令行。

其中宏定义的字符替换的定义格式为:# define 标识符字符串,预处理命令行是在系统对源程序进行编译之前进行处理的,不是在程序执行的过程中。

#include文件包含命令,使用时应注意以下5个规则:①包含文件的#include命令行通常应书写在所用源程序文件的开头,故有时也把包含文件称作“头文件”。

头文件名可以由用户指定,其后缀不一定用“.h”。

②包含文件中,一般包含有一些公用的#define命令行、外部说明或对(库)函数的原型说明。

③当包含文件修改后,对包含该文件的源程序必须重新进行编译连接。

④在一个程序中,允许有任意多个#include命令行。

⑤在包含文件中还可以包含其他文件。

ANSIC标准规定malloc函数返回值的类型为void*。

C语言初级学习——预处理命令

C语言初级学习——预处理命令

9.4 预定义宏
• 预定义宏是C编译器预先定义好的宏,不是 用户定义的,因而不能出现在#define与# undef语句中。 • 如: _ _FILE_ _ _ _DATE_ _ 等一些常见预定义宏标识符。
【例】预定义宏使用举例。
main() { printf("%s\n",__FILE__); printf("%s\n",__DATE__); printf("%s\n",__TIME__); }
结果显示: c:\data\a.c May 22 2001 21:02:54
9.5 运算符#和##
在带参数的宏替换中,若形参中含有#: • #:
“字符串” • 例如: #字符串 #define display(i) printf(#i) ……;display(This is a test);…… 则替换为:printf(“This is a test”);
若有宏定义:#define MOD(x,y) x%y
则执行以下语句后的输出为____
int z, a=15, b=100; z=MOD(b,a); printf(“%d\n”,z++); A 11 C 6 B 10 D 宏定义不合法
若有宏定义如下: #define x 5 #define Y X+1 #define Z Y*X/2 那么执行以下printf语句后,输出结果是____. int a; a=Y; printf(“%d\n”,Z); printf(“%d\n”,--a); A 7 B 12 C 12 D 7 6 6 5 5
#include “文件名称” #include <文件名称>
• 在一些版本的C语言中,还允许“文件名”中 带路径。

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

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

如果在程序中有下面的语句: R1=Radium(100); 那么,在编译预处理时,宏展开的顺序为从左到右进行置换,如果字符串 中包含宏中的形参,则将其用程序语句中相应的实参来替代,而字符串中的 其它字符原样保留。 因此,在处理上述语句时,将用 sqrt(area/PI) 替代 Radium(100),同时将 字符串sqrt(area/PI)中的形参area用实参l00来替代,并把已定义的宏PI的值代 入,经宏展开后,该语句变为“ R1=sqrt(100/3.14159); ”。
内蒙古科技大学 工程训练中心
预处理命令概述
所谓预处理,就是指源程序被正式编译之前所进行的处理工作,这 是C语言和其他高级语言之间的一个重要区别。
所有的预处理指令均以“#”开头,在它前面不能出现空格以外的字 符,而且在行结尾处没有分号。 “预处理命令” 的作用不是实现程序的功能,它们是发布给编译系 统的信息。它们告诉编译系统,在对源程序进行编译之前应该做些什么, 所以称这类语句为编译预处理命令。 C语言在执行一个C程序时,如果程序中有预处理命令,则首先进行 编译预处理(即根据预处理命令对源程序进行预先处理),然后再将经过 预处理的源程序编译成目标文件,而后进行目标文件的连接,当这些工 作都顺利通过后,才最终执行目标代码。这种执行过程大大提高了编程 效率。
PI 的有效范围
因为#undef 的作用是终止宏定义,因此PI的作用域从它定义开始到 #undef结束。在这以后,如果程序中出现 PI,则它不代表3.14159 。使 用#undef可以灵活控制宏定义的作用范围。
2019年1月8日5时29分 工程训练中心 徐国海
(二)带参数宏定义 (了解) 定义的一般格式为: #define 宏名(形式参数列表) 字符串

C##if,#else和#endif预处理指令

C##if,#else和#endif预处理指令

C##if,#else和#endif预处理指令#if 使您可以开始条件指令,测试⼀个或多个符号以查看它们是否计算为 true。

如果它们的计算结果确实为true,则编译器将计算位于 #if 与最近的指令之间的所有代码。

例如,1 #if DEBUG2 string file = root + "/conf_debug.xml";3 #else4 string file = root + "/conf.xml";5 #endif这段代码会像往常那样编译,但读取debug配置⽂件包含在#if⼦句内。

这⾏代码只有在前⾯的#define命令定义了符号DEBUG后才执⾏。

当编译器遇到#if语句后,将先检查相关的符号是否存在,如果符号存在,就只编译#if块中的代码。

否则,编译器会忽略所有的代码,直到遇到匹配的#endif指令为⽌。

⼀般是在调试时定义符号DEBUG,把不同的调试相关代码放在#if⼦句中。

在完成了调试后,就把#define语句注释掉,所有的调试代码会奇迹般地消失,可执⾏⽂件也会变⼩,最终⽤户不会被这些调试信息弄糊涂(显然,要做更多的测试,确保代码在没有定义DEBUG的情况下也能⼯作)。

这项技术在C和C++编程中⾮常普通,称为条件编译(conditional compilation)。

参考msdn实例:1 // preprocessor_if.cs2 #define DEBUG3 #define VC_V74 using System;5 public class MyClass6 {7 static void Main()8 {9 #if (DEBUG && !VC_V7)10 Console.WriteLine("DEBUG is defined");11 #elif (!DEBUG && VC_V7)12 Console.WriteLine("VC_V7 is defined");13 #elif (DEBUG && VC_V7)14 Console.WriteLine("DEBUG and VC_V7 are defined");15 #else16 Console.WriteLine("DEBUG and VC_V7 are not defined");17 #endif18 }19 }输出结果:DEBUG and VC_V7 are defined。

C语言试题及答案

C语言试题及答案

已有如定义和输入语句,若要求a1,a2,c1,c2的值分别为10,20,A 和B,当从第一列开始输入数据时,正确的数据输入方式是( )。

(注:<CR>表示回车)int a1,a2; char c1,c2;scanf(“%d%d”,&a1,&a2);scanf(“%c%c”,&c1,%c2);1.1020AB<CR>2.10?20<CR>AB<CR>3.10? ?20? ?AB<CR>4.10?20AB<CR>2:设有以下结构体类型: struct st { char name[8]; int num; float s[4]; }student[50]; 并且结构体数组student中的元素都已有值,若要将这些元素写到硬盘文件fp中,以下不正确的形式是( )。

1.fwrite( student, sizeof( struct st ), 50, fp );2.fwrite( student, 50*sizeof( struct st ), 1, fp );3.fwrite( student, 25*sizeof( struct st ), 25, fp );4.for( i=0;i<50; i++)fwrite( student+i, sizeof( struct st ), 1, fp );3:表达式~0x13的值是( ).1.0xFFEC2.0xFF713.0xFF684.0xFF174:以下正确的说法是( ).1.如果在一个函数中的复合语句中定义了一个变量,则该变量只在该复合语句中有效2.在该函数中有效3.在本程序范围内均有效4.非法变量5:在16位IBM-PC机上使用C语言,若有如下定义:union data{int i;char ch;double f;}b;则共用体变量占用内存的字节数是( ).1.12.23.84.116:设有以下说明,则下面不正确的叙述是()。

C语言三种预处理

C语言三种预处理
3.条件编译 定义:
当满足某条件时对一组语句进行编译,而条件不满足时则编译另一组语句。 形式:
#ifndef 标识符 程序段 1
#else 程序段 2
#endif 若标识符未被定义则编译程序段 1,否则编译程序段 2。 优点: 采用条件编译,可以减少被编译的语句,从而减少目标的长度。当条件编译 段比较多时,目标程序长度可以大大减少。
1.2 带参数的宏定义 格式:
#define 宏名(参数表) 字符串 举例:
#define S(a,b) ((a)*(b)) 说明:
①宏名和参数间不能有空格! ②宏替换只做替换,不做计算和表达式求解! ③宏展开不占程序运行时间只占编译时间! 掌握宏概念的关键在“替换”!
2.文件包含 由来:
文件包含处理在程序开发中会给模块化程序设计带来很大的好处,通过文件 包含的方法把程序中的各个功能模含处理是指在一个源文件中,通过文件包含命令将另一个源文件的内
容全部包含在此文件中。在源文件编译时,连同被包含进来的文件一同编译,生 成目标目标文件。 形式:
①#include "文件名"; 或
②#include <文件名>; 两种形式区别:
①系统首先在用户当前目录中寻找要包含的文件,若未找到才到包含目录中 去查找;
C 语言提供 3 种预处理功能:①宏定义②文件包含③条件编译。
0.预处理指令 预处理指令是以#号开头的代码行。#号必须是该行除了任何空白字符外的第
一个字符。#后是指令关键字,在关键字和#号之间允许存在任意个数的空白字符。 整行语句构成了一条预处理指令,该指令将在编译器进行编译之前对源代码做某 些转换。
②系统在包含文件目录中去查找(包含目录由用户在设置环境时设置)而不 在源文件目录去查找。若文件不在当前目录中,双撇号内可给出文件路径。 说明:
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

预处理命令行都必须以【1】号开始.
答案:
======(答案1)======
#
设有以下宏定义
# define WIDTH 80
# define LENGTH (WIDTH +40)
则执行赋值语句:v= LENGTH*20;(v为int型变量)后,v的值是【1】. 答案:
======(答案1)======
2400
设有以下宏定义
# define WIDTH 80
# define LENGTH WIDTH +40
则执行赋值语句:v= LENGTH*20;(v为int型变量)后,v的值是【1】.80+40*20
答案:
======(答案1)======
880
以下程序的运行结果是【1】.
#include
#define MIN(x,y) (x)
main()
{ inti=10,j=15,k ;
k=10*MIN(i,j);
printf("%d\n",k);
}
答案:
======(答案1)======
100
下列程序运行结果为:
#define P 3
#define S(a) P*a*a
main()
{intar;
ar=S(3+5);//3*3+5*3+5
printf("\n%d",ar);
}
#define宏都是直接替换的,不会计算后再替换。

s(3+5) = p*3+5*3+5 = 9+15+5 =29
若想计算后在替换,需要加上括号:
#define S(a) P*(a)*(a)
若有宏定义如下:
#define X 5
#define Y X+1
#define Z Y*X/2
则执行以下printf语句后,输出结果是(). inta;a=Y;
printf("%d ",Z);
printf("%d\n",--a);
A) 7 6
B) 12 6
C) 12 5
D) 7 5
答案:D
请读程序:
#include <stdio.h
#define MUL(x,y) (x)*y
main()
{
int a=3,b=4,c;
c=MUL(a++,b++);
printf("%d\n",c);
}
上面程序的输出结果是().
A) 12
B) 15
C) 20
D) 16
答案:A
有如下程序
#define N 2
#define M N+1
#define NUM 2*M+1
main( )
{ inti;
for(i=1;i<=NUM;i++) printf("%d\n",i); // }
该程序中的for循环执行的次数是().
A) 5
B) 6
C) 7
D) 8
答案:B
#define N 2
#define M N+1
#define NUM (M+1)*M/2
main()
{int I;
for(I=1;I<=NUM;I++)
printf(“%d\n”,I);
}
NUM (M+1)*M/2=(2+1+1)*2+1/2=8
有以下程序
#define f(x) x*x
main( )
{ inti;
i=f(4+4)/f(2+2);
printf("%d\n",i);
}
执行后输出结果是()//.i=4+4*4+4/2+2*2+2=28
A) 28
B) 22
C) 16
D) 4
答案:A
#include "stdio.h"
main()
{ chara,b;
for(a='0',b='9';a<b;a++,b--) printf("%c %c",a,b); printf("\n"); }。

相关文档
最新文档