文档库 最新最全的文档下载
当前位置:文档库 › C第7章预处理

C第7章预处理

第七章

2

本章导读:

C 语言的个重要特征,可以改进程序设计预处理是C语言的一个重要特征,可以

环境,提高编译效率。C 语言在正式编译(语法分析)

系统先对这些命令进行“预处理”,进行宏替换之前系统先对这些命令进行预处理,进行宏替换

和将包含的函数定义包含进源程序,然后整个源程序

再进行通常的编译处理。

①本章学习重点:

宏定义和宏替换②文件包含③条件编译

7.1 概述

在前面各章中,已多次使用过以“# ”号开头的预处理命令。如包含命令#include,宏定义命令#define 等。在源程序中这些命令都放在函数之外,而且一般都放在源文件的前面,它们称为预处理部分。

所谓预处理是指在进行编译的第一遍扫描(词法扫描和语法分析)之前所做的工作。预处理是C语言的一个重要功能,它由预处理程序负责完成。当对一个源文件进行编译时,系统将自动引用预处理程序对源程序中的预部分作完毕自动进对程序的编的预处理部分作处理,处理完毕自动进入对源程序的编译。

7.1 概述

C 语言提供了多种预处理功能,如宏定义、文件包含、条件编译等。合理地使用预处理功能编写的程序便于阅读、修改、移植和调试,也有利于模块化程序设计。本章将介绍常用的也有利于模块化程序设计本章将介绍常用的几种预处理功能。

7.2 宏定义

在C 语言源程序中允许用一个标识符来表示

个字符串,称为宏。被定义为宏的标一个字符串“宏”。被定义为“宏”的标识符称为“宏名”。在编译预处理时,对程序中所有出现的宏名,都用宏定义中的字符串去所有出现的“宏名”

代换,这称为“宏替换”或“宏展开”。

宏定义是由源程序中的宏定义命令完成的。

是由源程序中的宏定义命令完成的

宏替换是由预处理程序自动完成的。在C语言中,“宏”分为有参数和无参数两种。下面分别讨论宏分为有参数参数种面分别讨论这两种“宏”的定义和调用。

7.2.1 无参宏定义

无参宏的宏名后不带参数。其定义的一般形式为:

# define 标识符字符串

#define

其中的“# ”表示这是一条预处理命令。凡是以“# ”

开头的均为预处理命令。“define”为宏定义命令。“标开头的均为预处理命令“d fi”“标识符”为所定义的宏名。“字符串”可以是常数、表达式、格式串等。

式格式串等

在前面介绍过的符号常量的定义就是一种无参宏定义。此外,常对程序中反复使用的表达式进行宏定义。

7.2.1 无参宏定义

例如:

#d fi M(3)

#define M (y*y+3*y)

它的作用是指定标识符M 来代替表达式(y*y+3*y)。在编写源程序时,所有的(y y + 3 y)都可由M

在编写源程序时所有的(y*y+3*y M

代替,而对源程序作编译时,将先由预处理程序进宏替换表达式去换有

行宏替换,即用(y * y + 3 * y )表达式去置换所有

的宏名M ,然后再进行编译。

9【例7.1】不带参数宏的使用

程序员输入的源程序预处理(宏替换)后的新源程序

#include

#define PI 3.1415926#include void main()

void main()

{ float l,s,r,v;

printf("input radius:");

()

{ float l,s,r,v;

printf("input radius:");

scanf("%f"&r);

printf("input radius:"); scanf("%f",&r);

l=2.0*PI*r;scanf("%f",&r);

l=2.0*3.1415926*r; s=3.1415926*r*r;

s=PI*r*r;

v=4.0/3*PI*r*r*r; printf("l=%104f\n"l);v=4.0/3*3.1415926*r*r*r; printf("l=%10.4f\n",l); printf("s=%104f\n"s);

printf(l=%10.4f\n,l); printf("s=%10.4f\n",s); printf("v=%10.4f\n", v);

printf(s=%10.4f\n,s); printf("v=%10.4f\n", v); }

}

7.2.1 无参宏定义

对于宏定义还要说明以下几点:

对于宏定义还要说明以下几点

①通常情况下,宏名用大写字母来定义,以便与变量名相区别。每位编程者都遵循一些常用的约定可以大大增强程序的可读性。

宏定义是用宏名来表示个字符串,在宏展开时又以该字②宏名来表示一个字符串

符串取代宏名,这只是一种简单的代换,字符串中可以含任何字符,可以是常数,也可以是表达式,预处理程序对它不可以是也可以是预处理程序对它

作任何检查。如有错误,只能在编译已被宏展开后的源程序时发现。

时发现

7.2.1 无参宏定义

③宏定义不是说明或语句,在行末不分号如

不必加分号,如加

上分号则连分号也一起置换。

④宏定义必须写在函数之外,其作用域为宏定义命

令起到源程序结束。如要

终止其作用域可使用

命令

#undef命令。

7.2.1 无参宏定义

⑤宏名在源程序中若用引号括起来,则预处理程序不对其作宏代换。

宏代换

【例7.2】宏名在源程序中被引号括起来不进行宏替换。

7.2.1 无参宏定义

⑥宏定义允许嵌套,在宏定义的字符串中可以使用已经定义的宏名在宏展开时由预处理程序层层代换

。在宏展开时由预处理程序。

7.2.1 无参宏定义

⑦对“输出格式”作宏定义,可以减少书写麻烦。【例7.3】本例中就采用了上面⑦中所述那种方法。【例73】中所述那种方法

7.2.2 带参宏定义

C语言允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。

在宏中的参数称为实参数

对带参数的宏,有时也称为类函数宏。在调用中,

要用实参去代换形参。

不仅要宏展开,而且要用实参去代换形参

带参宏定义的一般形式为:

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

7.2.2 带参宏定义

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

其中:

?宏名同不带参的宏名,习惯用大写字母。

宏名同不带参的宏名习惯用

形参表由个或多个参数构成。注意形参与函数形?形参表由一个或多个参数构成。注意形参与函数形参的区别:参数只有参数名,没有数据类型。

?在替换字符串中通常含有各个形参。

含有各个参

7.2.2 带参宏定义

带参宏调用的一般形式为:

宏名(实参表)

在宏调用时,用实参5去代替形参y,经预处理宏展开后的语句为:k553 5

k=5*5+3*5

【例74】带参宏替换【例7.4】带参宏替换

程序员输入的源程序

预处理(宏替换)后的新源程序

#include

#include

#include#define MAX(a,b) (a>b)?a:b void main()#includevoid main(){ (){

int x,y,max;

{

int x,y,max;

printf("input two numbers: "); printf("input two numbers: ");scanf("%d%d",&x,&y);max=MAX(x y);scanf("%d%d",&x,&y); max=(x>y)?x:y; printf("max=%d\n"max);max=MAX(x,y);

printf("max=%d\n",max);} printf(max=%d\n ,max);}

}

7.2.2 带参宏定义

①带参宏定义中,宏名和形参表之间不能有空格出现。

例如,把

#define MAX(a,b) (a>b)?a:b

写为:

#d fi MAX(b)(>b)?b

#define MAX (a,b) (a>b)?a:b

将被认为是无参宏定义,宏名MAX代表字符串(a,b)(a>b)?a:b。

(b)(>b)?:b

宏展开时,宏调用语句:

max=MAX(x,y)

MAX()

将其变为:

(a b)(a>b)?a:b(x y)

max=(a,b) (a>b)?a:b(x,y)

这显然是错误的。

7.2.2 带参宏定义

②在带参宏定义中,形式参数不分配内存单元,因此不必作类型定义。而宏调用中的实参有具体的值。要用它们去代换类型定义而宏调用中的要用它们去代换形参,因此必须作类型说明。这是与函数中的情况不同的。

在函数中,形参和实参是两个不同的量,各有自己的作用域,调用时要把实参值赋予形参,进行“值传递”。而在带参宏中,只是符号代换,不存在值传递的问题。

参宏中只是符号代换

③在宏定义中的形参是标识符,而宏调用中的实参可以是表达式。

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

编译预处理习题 一.单项选择题 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 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=21 8.有以下程序 # 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); } 程序运行后的输出结果是

Fluent_UDF_第七章_UDF的编译与链接

第七章 UDF的编译与链接 编写好UDF件(详见第三章)后,接下来则准备编译(或链接)它。在7.2或7.3节中指导将用户编写好的UDF如何解释、编译成为共享目标库的UDF。 _ 第 7.1 节: 介绍 _ 第 7.2 节: 解释 UDF _ 第 7.3 节: 编译 UDF 7.1 介绍 解释的UDF和编译的UDF其源码产生途径及编译过程产生的结果代码是不同的。编译后的UDF由C语言系统的编译器编译成本地目标码。这一过程须在FLUENT运行前完成。在FLUENT运行时会执行存放于共享库里的目标码,这一过程称为“动态装载”。 另一方面,解释的UDF被编译成与体系结构无关的中间代码或伪码。这一代码调用时是在内部模拟器或解释器上运行。与体系结构无关的代码牺牲了程序性能,但其UDF可易于共享在不同的结构体系之间,即操作系统和FLUENT版本中。如果执行速度是所关心的,UDF文件可以不用修改直接在编译模式里运行。 为了区别这种不同,在FLUENT中解释UDF和编译UDF的控制面板其形式是不同的。解释UDF的控制面板里有个“Compile按钮”,当点击“Compile按钮”时会实时编译源码。编译UDF的控制面板里有个“Open按钮”,当点击“Open按钮” 时会“打开”或连接目标代码库运行FLUENT(此时在运行FLUENT之前需要编译好目标码)。 当FLUENT程序运行中链接一个已编译好的UDF库时,和该共享库相关的东西都被存放到case文件中。因此,只要读取case文件,这个库会自动地链接到FLUENT 处理过程。同样地,一个已经经过解释的UDF文件在运行时刻被编译,用户自定义的C函数的名称与内容将会被存放到用户的case文件中。只要读取这个case文件,这些函数会被自动编译。 注:已编译的UDF所用到的目标代码库必须适用于当前所使用的计算机体系结构、操作系统以及FLUENT软件的可执行版本。一旦用户的FLUENT升级、操作系统改变了或者运行在不同的类型的计算机,必须重新编译这些库。

C语言程序设计 位运算

一、选择题 1、读程序片段: int x=20; printf(“%d\n”, ~x); 上面程序片段的输出结果是( ). A)02 B)–20 C)-21 D)-11 2、表达式~0x13的值是( ). A)0xFFEC B)0xFF71 C)0xFF68 D)0xFF17 3、在位运算中,操作数每右移一位,其结果相当于( ). A)操作数乘以2 B)操作数除以2 C)操作数除以4 D)操作数乘以4 4、在位运算中,操作数每左移一位,其结果相当于( ). A)操作数乘以2 B)操作数除以2 C)操作数除以4 D)操作数乘以4 5、设有以下语句: char x=3,y=6,z; z=x^y<<2; 则z的二进制值是( ). A)00010100 B)00011011 C)00011100 D)00011000 6、请读程序: struct bit {unsigned a_bit:2; unsigned b_bit:2; unsigned c_bit:1; unsigned d_bit:1; unsigned e_bit:2; unsigned word:8; }; main() {struct bit *p; unsigned int modeword; printf(“Enter the mode word (HEX):”); scanf(“%x”,&modeword); p=(struct bit *)&modeword; printf(“\n”); printf(“a_bit: %d\n”,p ->a_bit); printf(“b_bit: %d\n”,p ->b_bit); printf(“c_bit: %d\n”,p ->c_bit); printf(“d_bit: %d\n”,p ->d_bit); printf(“e_bit: %d\n”,p ->e_bit);} 若运行时从键盘输入: 96<回车> 则以上程序的运行结果是( ). A)a_bit: 1 B) a_bit: 2 C)a_bit: 2 D) a_bit: 1

编译预处理

第九章编译预处理 9.1 选择题 【题9.1】以下叙述中不正确的是。 A)预处理命令行都必须以#号开始 B)在程序中凡是以#号开始的语句行都是预处理命令行 C)C程序在执行过程中对预处理命令行进行处理 D)以下是正确的宏定义 #define IBM_PC 【题9.2】以下叙述中正确的是。 A)在程序的一行上可以出现多个有效的预处理命令行 B)使用带参的宏时,参数的类型应与宏定义时的一致 C)宏替换不占用运行时间,只占编译时间 D)在以下定义中C R是称为“宏名”的标识符 #define C R 045 【题9.3】请读程序: #define ADD(x) x+x main() { int m=1,n=2,k=3; int sum=ADD(m+n)*k; printf(“sum=%d”,sum); } 上面程序的运行结果是。 A)sum=9 B)sum=10 C)sum=12 D)sum=18 【题9.4】以下程序的运行结果是。 #define MIN(x,y) (x)<(y)?(x):(y) main() { int i=10,j=15,k; k=10*MIN(i,j); printf(“%d\n”,k); } A)10 B)15 C)100 D)150 【题9.5】在宏定义#define PI 3.14159中,用宏名PI代替一个。 A)常量B)单精度数C)双精度数D)字符串

【题9.6】以下程序的运行结果是。 #include #define FUDGE(y) 2.84+y #define PR(a) printf(“%d”,(int)(a)) #define PRINT1(a) PR(a); putchar(‘\n’) main() { int x=2; PRINT1(FUDGE(5)*x); } A)11 B)12 C)13 D)15 【题9.7】以下有关宏替换的叙述不正确的是。 A)宏替换不占用运行时间B)宏名无类型 C)宏替换只是字符替换D)宏名必须用大写字母表示 【题9.8】C语言的编译系统对宏命令的处理是。 A)在程序运行时进行的 B)在程序连接时进行的 C)和C程序中的其它语句同时进行编译的 D)在对源程序中其它成份正式编译之前进行的 【题9.9】若有宏定义如下: #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 【题9.10】若有以下宏定义如下: #define N 2 #define Y(n) ((N+1)*n) 则执行语句z=2*(N+Y(5));后的结果是。 A)语句有错误B)z=34 C)z=70 D)z无定值 【题9.11】若有宏定义:#define MOD(x,y) x%y 则执行以下语句后的输出为。 int z,a=15,b=100; z=MOD(b,a); printf(“%d\n”,z++);

C语言第1章至第七章

第1章C语言概述 本章要点 了解C语言的特点,初步掌握C语言的基本结构,掌握在VC++6.0环境下C语言程序的编辑、编译、连接与运行,了解算法的概念及用传统流程图表示算法的方法。本章的重点和难点是VC++6.0集成环境下C 语言程序的运行方法。 第一节C语言的发展与特点 一、C语言的发展 C语言诞生以前,系统软件主要是用汇编语言编写的。但由于汇编语言依赖于计算机硬件,其可读性和可移植性都很差,而一般的高级语言又难以实现对计算机硬件直接进行操作。所以人们希望出现一种兼有汇编语言和高级语言优点的新语言,于是诞生了C语言。 C语言是由贝尔实验室的Dennis Ritchie在20世纪70年代初发明的,最初是作为UNIX 系统的开发语言。70年代末,随着微型计算机的发展,C语言开始移植到非UNIX环境中,并逐步成为独立的程序设计语言。1978年,Brian.W.Kernighan和Dennis.M.Ritchie出版了名著《The C Programming Language》,通常简称为《K&R》,该书中介绍的C语言成为后来广泛使用的C语言版本的基础,也有人称之为《K&R》标准。但是,在《K&R》中并没有定义一个完整的标准C语言。继C语言问世之后出现了许多版本,由于没有统一的标准,不同C语言版本之间缺乏兼容。为了改变这种情况,美国国家标准化协会ANSI(American National Standards Institute)于1983年根据C语言问世以来各种版本对C语言的发展和扩充,公布了第一个C语言标准草案(’83 ANSI C)。1989年,ANSI公布了一个完整的C语言标准,常称ANSI C或C89,该标准定义了语言和一个标准C库。1990年,C89被国际标准化组织ISO (International Standard Organization)接受作为国际标准,常称C90,C89和C90实质上是同一个标准。1999年,ISO对C语言标准进行修订,在基本保留原来的C语言特征的基础上,针对应用的需要,增加了一些功能,尤其是C++中的一些功能,命名为C99。本书基本上以C89为基础进行介绍。 二、C语言的特点 C语言是一种用途广泛、功能强大、使用灵活的结构化程序设计语言。由于以下原因而在程序员中流行: 1.C语言具有结构化的高级编程语言应有的所有高级指令,使程序员不需要知道硬件细节。同时,C也具有一些低级指令,允许程序员能够直接快速地访问硬件。这种把高级语言的基本结构和语句与低级语言的实用性结合起来的特点使得C语言在通用程序设计和系统程序设计上都能满足程序员的需要。

C语言程序设计教案 第九章 编译预处理

第九章编译预处理 课题:第九章编译预处理 教学目的:1、了解预处理的概念及特点 2、掌握有参宏与无参宏的定义及使用,领会文件包含的使用及效果 教学重点:教学难点:掌握宏的使用,文件包含有参宏与无参宏的使用 步骤一复习引导 ANSI C标准规定可以在C源程序中加入一些“预处理命令”,以改进程序设计环境,提高编程效率。 这些预处理命令是由ANSI C统一规定的,但它不是C语言本身的组成部分,不能直接对它们进行编译。必须在对程序进行通常的编译之前,先对程序中这些特殊的命令进行“预处理”,即根据预处理命令对程序作相应的处理。经过预处理后程序不再包括预处理命令了,最后再由编译程序对预处理后的源程序进行通常的编译处理,得到可供执行的目标代码。 步骤二讲授新课 C语言与其他高级语言的一个重要区别是可以使用预处理命令和具有预处理的功能。C 提供的预处理功能主要有以下三种:宏定义、文件包含、条件编译。 分别用宏定义命令、文件包含命令、条件编译命令来实现。为了与一般C语句相区别,这些命令以符号“ #” 开头。 §9.1宏定义 宏:代表一个字符串的标识符。 宏名:被定义为“宏”的标识符。 宏代换(展开):在编译预处理时,对程序中所有出现的“宏名”,用宏定义中的字符串去代换的过程。 一、不带参数的宏定义 一般形式:#define 标识符字符串 #define PI 3.1415926 main() { float l, s, r, v; printf( “input radius:” ); scanf( “%f”, &r ); l = 2.0*PI*r; s = PI*r*r; v = 3.0/4*PI*r*r*r; printf(“%10.4f,%10.4f,%10.4\n”, l, s, v); }

C语言题库第7章宏定义与预处理

第七章宏定义与预处理一.单项选择 1. 以下程序的运行结果是( D )。 #include #define ADD(x) x+x int main ( ) { int m=1,n=2,k=3,sum ; sum = ADD(m+n)*k ; printf(“%d\n”,sum) ; return 0; } A.18 B.9 C.12 D.10 2. 以下程序的运行结果是( C )。 #include #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.15 B.100 C.10 D.150 3. 以下程序的运行结果是( A )。 #include #define X 5 #define Y X+1 #define Z Y*X/2 int main ( ) { int a=Y; printf(“%d\n”,Z); printf(“%d\n”,--a); return 0; }

A.75 B.125 C.76 D.126 4. 以下程序的运行结果是( C )。 #include #define DOUBLE(r) r*r int main ( ) { int x=1,y=2,t; t = DOUBLE(x+y) ; printf (“%d\n”,t); return 0; } A.7 B.6 C.5 D.8 5. 在“文件包含”预处理命令形式中,当#include后面的文件名用””(双引号)括起时,寻找被包含文件的方式是( C )。 A.仅仅搜索源程序所在目录 B.直接按系统设定的标准方式搜索目录 C.先在源程序所在目录中搜索,再按系统设定的标准方式搜索 D.仅仅搜索当前目录 6. 若有定义 #define N 2 #define Y(n) ((N+1)*n) 则执行语句z=2*(N+Y(5));后,z的值为( C )。 A.无确定值 B.语句有错误 C.34 D.70 7. 若有定义#define MOD(x,y) x%y,则执行下面语句后的输出为( A )。 int z,a=15; float b=100; z=MOD(b,a); printf(“%d\n”,z++); A.有语法错误 B.11 C.10 D.6 8. 在任何情况下计算平方数都不会引起二义性的宏定义是( B ) A.#define POWER(x) (x)*(x) B.#define POWER(x) ((x)*(x))

第7章-编译预处理

一、判断题 1. 宏替换时先求出实参表达式的值,然后带入形参运算求值。 答案:F 2. 宏替换不存在类型问题,它的参数也是无类型的。 答案:T 3. 在C++语言标准库头文件中包含了许多系统函数的原型声明,因此只要程序中使用了这些函数,则应包含这些头文件。 答案:T 4. H头文件只能由编译系统提供。 答案:F 5. #include命令可以包含一个含有函数定义的C++语言源程序文件。 答案:T 6. 用#include包含的头文件的后缀必须是.h。 答案:F 7. #include “C:\\USER\\F1.H”是正确的包含命令,表示文件F1.H存放在C盘的USER 目录下。 答案:F 8. #include <…>命令中的文件名是不能包括路径的。 答案:F 9. 可以使用条件编译命令来选择某部分程序是否被编译。 答案:T 10.在软件开发中,常用条件编译命令来形成程序的调试或正式版本。 答案:T 二、选择题 1. 以下叙述中错误的是()。 A.预处理命令行都必须以#开始 B. 在程序中凡是以#开始的语句都是预处理命令行 C. C++程序在执行过程中对预处理命令行进行处理 D. 预处理命令行可以出现在C++程序中任意一行上 答案:C 2. 以下有关宏替换的叙述中错误的是()。 A.宏替换不占用运行时间 B. 宏名无类型 C. 宏替换只是字符替换 D. 宏名必须用大写字母表示 答案:D 3. 在编译指令中,宏定义使用()指令。 A.#include B. #define C. #if D. #else

答案:B 4. 社#define P(x) x/x,执行语句cout<

C语言位运算练习题1

C语言位运算练习题 一、选择题: (1)以下程序的功能是进行位运算 main() { unsigned char a, b; a=7^3; b= ~4 & 3; printf("%d %d ",a,b); } 程序运行后的输出结果是 A)4 3 B)7 3 C)7 0 D)4 0 (2)有以下程序 main() { int c=35; printf("%d ",c&c); } 程序运行后的输出结果是 A) 0 B) 70 C) 35 D) 1

(3) 设有定义语句:char c1=92,c2=92;,则以下表达式中值为零的是 A) c1^c2 B) c1&c2 C) ~c2 D) c1|c2 (4) 有以下程序 main( ) { unsigned char a,b; a=4|3; b=4&3; printf(“%d %d ”,a,b(; } 执行后输出结果是 A) 7 0 B) 0 7 C) 1 1 D) 43 0 (5) 有以下程序 main() { int x=3, y=2,z=1; printf("%d ",x/y&~z); } 程序运行后的输出结果是 A) 3

B) 2 C) 1 D) 0 (6) 设char型变量x中的值为10100111,则表达式(2+x)^(~3)的值是 A) 10101001 B) 10101000 C) 11111101 D) 01010101 (7) 有以下程序 main() { unsigned char a,b,c; a=0x3; b=a|0x8; c=b<<1; printf(“%d%d ”,b,c); } 程序运行后的输出结果是 A) –11 12 B) –6 –13 C) 12 24 D) 11 22 (8) 以下程序的输出结果是 main() { char x=040; printf("%0 ",x<<1);

第六讲编译预处理

第6讲编译预处理 6.1 编译预处理的根概念和特点 预处理——是指在进行编译的第一遍扫描(词法扫描和语法分析)之前所作的工作。 6.1.2 编译预处理的特点 ⑴预处理命令均以“#”号开头,在它前面不能出现空格以外的其他字符。 ⑵每一行命令独占一行。 ⑶命令不以“;”为结束符,它不是C语句。 ⑷预处理程序控制行的作用范围仅限于说明它们的那个文件。 ◇C语言提供的预处理功能有:宏定义、文件包含、条件编译等。 ◇合理地使用预处理功能编写的程序便于阅读、修改、移植和调试,也有利于模块化程序设计。 6.2 宏定义 宏——在C语言源程序中允许用一个标识符来表示一个字符串,称为“宏”。 宏名——被定义为“宏”的标识符称为“宏名”。 宏代换(宏替换或宏展开)——在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。 6.2.1 不带参的宏定义 其定义的一般形式为:

#define 标识符字符串 ◇在前面介绍过的符号常量的定义就是一种无参宏定义。 #define PI 3.14.5926 ◇常对程序中反复使用的表达式进行宏定义。 例如: #define M (y*y+3*y) 用标识符M来代替表达式(y*y+3*y)。 在编写源程序时,所有的(y*y+3*y)都可由M代替。【例】 #include #define M (y*y+3*y) void main() { int s,y; printf("input a number: "); scanf("%d",&y); s=3*M+4*M+5*M; printf("s=%d\n",s); } 上例程序中首先进行宏定义,定义M来替代表达式(y*y+3*y),在s=3*M+4*M+5* M中作了宏调用。在预处理时经宏展开后该语句变为: s=3*(y*y+3*y)+4*(y*y+3*y)+5*(y*y+3*y); 注意:在宏定义中表达式(y*y+3*y)两边的括号不能少。否则会发生错误。如当作以下定义后: #difine M y*y+3*y 在宏展开时将得到下述语句: s=3*y*y+3*y+4*y*y+3*y+5*y*y+3*y;

c语言位运算

那么会经常使用到三个符号: 1,p; 2,*p; 3,&p; 初学者经常会感到很迷茫,到底这三个符号表示什么? 我们知道,p是一个指针变量的名字,表示此指针变量指向的内存地址,如果使用%p来输出的话,它将是一个16进制数。而*p表示此指针指向的内存地址中存放的内容,一般是一个和指针类型一致的变量或者常量。 而我们知道,&是取地址运算符,&p就是取指针p的地址。等会,怎么又来了个地址,它到底和p有什么区别? 区别在于,指针p同时也是个变量,既然是变量,编译器肯定要为其分配内存地址,就像程序中定义了一个int型的变量i,编译器要为其分配一块内存空间一样。而&p就表示编译器为变量p分配的内存地址,而因为p是一个指针变量,这种特殊的身份注定了它要指向另外一个内存地址,程序员按照程序的需要让它指向一个内存地址,这个它指向的内存地址就用p表示。而且,p指向的地址中的内容就用*p表示。 我来举个例子说明这三个符号到底表示什么。 假设有一个楼盘的销售员,当然,现在时髦的叫法是“销售代表”之类的,我们用字母x表示他。他负责销售一个楼盘中的某套房子,此房子有一个地址为A,而他本身也需要有地方住,他居住的房子的地址为B。而这个幸运的销售员很快的卖掉了这套房子给C。现在公司要求对销售的房子必须包产到户,也就是说,现在必须提到x的时候能够管理到C。 如果用程序表示上述内容的话就可以使用指针。首先定义一个指针p,让他指向地址A,地址A中住的是C,而x本来居住的地方的地址是B。OK,现在能知道p,*p ,&p表示什么了吗?没错,p表示此指针指向的地址,就是A,而*p表示此地址中居住的人,就是C,而&p表示这个销售员居住的地址,就是B。 C语言位运算详解 位运算是指按二进制进行的运算。在系统软件中,常常需要处理二进制位的问题。C语言提供了6个位操作运算符。这些运算符只能用于整型操作数,即只能用于带符号或无符号的char,short,int与long类型。 C语言提供的位运算符列表: 运算符含义描述 & 按位与如果两个相应的二进制位都为1,则该位的结果值为1,否则为0 | 按位或两个相应的二进制位中只要有一个为1,该位的结果值为1 ^ 按位异或若参加运算的两个二进制位值相同则为0,否则为1 ~ 取反~是一元运算符,用来对一个二进制数按位取反,即将0变1,将1变0

第7章 编译预处理

第7章编译预处理 “编译预处理”是指在C编译程序对C源程序进行编译之前,对预处理命令进行“预先”处理的过程。编译预处理由编译预处理程序完成。 预处理命令(preprocessor directive)不是C语言组成部分,C语言的编译程序无法识别他们,如C程序中的“#inc lude”,即是一个预处理命令,其功能是在将源程序编译成目标程序之前将文件“stdio.h”的内容替换该命令,然后由编译程序将源程序翻译成目标程序。 C语言提供的编译预处理命令主要有以下三种: (1)宏定义。 (2)文件包含。 (3)条件编译。 为了与一般的C语句相区别,编译预处理命令必须以“#”为首字符、尾部不能加分号(C语句必须加分号),一行只能写一条编译预处理命令。 编译预处理命令可以出现在源程序中的任何位置,其作用范围是从它出现的位置直到所在源程序文件的末尾。 C的编译预处理功能为程序调试、移植提供了便利,正确使用编译预处理功能可以有效地提高程序的开发效率。 7.1 宏定义 7.1.1不带参数的宏定义 不带参数的宏定义命令形式为: #define 宏名字符串 其中:宏名为标识符。 功能:在编译预处理时,将程序中在该命令后所有与宏名相同的文本用字符串置换。 例如: #define PI 3.1415926 它的功能是在程序中用宏名“PI”来代替“3.1415926”这个字符串,在编译预处理时,将程序中在该命令以后出现的所有的“PI”都用“3.1415926”代替。使用宏定义(macro definition),可以用一个简单的名字(宏名)来代替一个较长的字符串,以增加程序的可读性。

第九章编译预处理

第九章 编译预处理 编译指令(编译预处理指令):C 源程序除了包含程序命令(语句)外,还可以使用各种编译指令(编译预处理指令)。编译指令(编译预处理指令)是给编译器的工作指令。这些编译指令通知编译器在编译工作开始之前对源程序进行某些处理。编译指令都是用“#”引导。 编译预处理:编译前根据编译预处理指令对源程序的一些处理工作。C 语言编译预处理主要包括宏定义、文件包含、条件编译。 编译工作实际分为两个阶段:编译预处理、编译。广义的编译工作还包括连接。 9、1 宏定义 宏定义:用标识符来代表一个字符串(给字符串取个名字)。C 语言用“#define ”进行宏定义。C 编译系统在编译前将这些标识符替换成所定义的字符串。 宏定义分为不带参数的宏定义和带参数宏定义。 9、1、1 不带参数宏定义(简单替换) 1 其中:标识符-宏名。 2、宏调用:在程序中用宏名替代字符串。 3、宏展开:编译预处理时将字符串替换宏名的过程,称为宏展开。

说明: (1)宏名遵循标识符规定,习惯用大写字母表示,以便区别普通的变量。 (2)#define 之间不留空格,宏名两侧空格(至少一个)分隔。 (3)宏定义字符串不要以分号结束,否则分号也作为字符串的一部分参加展开。从这点上 看宏展开实际上是简单的替换。 例如:#define PI 3.14; 展开为s=3.14;*r*r ;(导致编译错误) (4)宏定义用宏名代替一个字符串,并不管它的数据类型是什么,也不管宏展开后的词法 和语法的正确性,只是简单的替换。是否正确,编译时由编译器判断。 例如:#define PI 3.I4 照样进行宏展开(替换),是否正确,由编译器来判断。 (5)#define 宏定义宏名的作用范围从定义命令开始直到本源程序文件结束。可以通过 #undef 终止宏名的作用域。

第七章网站测试题

Question1 对于以下宏定义: #define M(x)x*x #define N(x,y)M(x)+M(y)宏调用N(2,2+5)执行后,值为_________。 选择一个答案 A. 53 B. 21 C. 19 D. 51 Qusetion2 如果一个函数定义后不希望别的文件使用,则在该函数首部前增加一个关键字_______ 选择一个答案 a. const b. extern c. static d. auto Question 3 在文件包含预处理语句(#include )的使用形式中,当之后的文件名用<>(尖括号)括起时,寻找被包含文件的方式是。选择一个答案 A. 仅仅搜索源程序所在目录 B. 仅仅搜索当前目录 C. 直接按系统设定的标准方式搜索目录 D. 先在源程序所在目录搜索,再按系统设定的标准方式搜索 Question 4 以下不正确的叙述是。 选择一个答案 A. C ++程序在执行过程中对预处理命令进行处理 B. #define ABCD 是正确的宏定义

C. 预处理命令行都必须以"#" 开始 D. 在程序中凡是以"#" 开始的语句行都是预处理命令行 Question 5 关于外部变量的下列说法错误的是_______ 选择一个答案 a. 外部变量只需要在一个文件中定义一次,但可以其他文件中多次声明 b. 只要在主函数外面定义的变量就一定是外部变量 c. 外部变量在其他文件中被使用时需要用extern进行事先声明 d. 函数外定义的变量,其前若用static修饰,则不能作为外部变量 Question 6 以下不正确的叙述是。 选择一个答案 A. 宏替换不占用运行时间 B. 宏替换只是字符替换 C. 宏名无类型 D. 宏名必须用大写字母表示 Question 7 下列哪一个不是模块化程序设计应具有的特点__________。 选择一个答案 A. 开发一个模块不需要知道系统其他模块的内部结构和编程细节 B. 具有可修改性。对系统的一次修改只涉及少数几个模块 C. 鼓励多使用外部变量,以减少模块之间的相互参数传递 D. 模块之间的接口尽可能简明 Question 8 关于编译预处理,下列说法正确的是_________。 选择一个答案 A. 用户自定义头文件时前后加条件编译指令可以避免重复包含。

补充习题(编译预处理)

编译预处理 一、选择题 1、以下叙述中正确的是() (A)用#include包含的头文件的后缀不可以是”.a” (B)若一些源程序中包含某个头文件,当该头文件有错时,只需对该头文件进行修改,包含此头文件的所有源程序不必重新进行编译(C)宏命令行可以看做是一行C语句 (D)C编译中的预处理是在编译之前进行的 2、下面是对宏定义的描述,不正确的是() (A)宏不存在类型问题,宏名无类型,它的参数也无类型 (B)宏替换不占用运行时间 (C)宏替换时先求出实参表达式的值,然后代入形参运算求值 (D)宏替换只不过是字符替代而已 3、以下程序的输出结果是() #include #define SQR(x) x*x main() {int a,k=3; a=SQR(k+1); printf(“%d\n”,a);} (A)6 (B)7 (C)8 (D)9 4、以下程序的输出结果是() #define MIN(x,y) (x)<(y)?(x):(y) #include main() {int i,j,k; i=10;j=15;k=10*MIN(i,j); printf(“%d\n”,k);} (A)15 (B)100 (C)10 (D)150 5、以下程序的输出结果是() #include

#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);} (A)5 (B)6 (C)8 (D)9 6、以下程序的输出结果是() #define f(x) x*x #include main() {int a=6,b=2,c; c=f(a)/f(b); printf(“%d\n”,c);} (A)9 (B)6 (C)36 (D)18 7、以下程序的输出结果是() #define PT 5.5 #define S(x) PT*x*x #include main() {int a=1,b=2; printf(“%4.1f\n”,S(a+b));} (A)49.5 (B)9.5 (C)22.0 (D)45.0 8、以下程序的输出结果是() #define MA(x) x*(x-1) #include main() {int a=1,b=2; printf(“%d\n”,MA(1+a+b));} (A)3 (B)4 (C)6 (D)8 9、有如下程序:()

第九章预处理的考试试题

(1) 下面叙述错误的是()。 A) “#define PRICE 30”命令的作用是定义一个与30等价的符号常量PRICE B) C源程序中加入一些预处理命令是为了改进程序设计环境,提高编程效率 C) “#include ”命令的作用是在预处理时将stdio.h文件中的实际内容代替该命令 D) 宏定义也是C语句,必须在行末加分号 (2) 若有定义:#define PI 3,则表达式PI*2*2的值为()。 A) 4 B) 不确定 C) 12 D) 322 (3) 以下程序的运行结果是()。 #define X a+b main( ) { int a=3,b=4,s1; s1=2*X; printf("%d\n",s1); } A) 8 B) 14 C) 10 D) 6 (4) 若有定义#define F 2+3,则表达式F*F的值为()。 A) 13 B) 17 C) 25 D) 11 (5) 下面叙述正确的是()。 A) 宏名必须用大写字母表示 B) 一个源程序只能有一个预编译处理命令行 C) 宏展开不占用运行时间,只占用编译时间 D) 预处理命令也是C语句,必须以分号结束 (6) 下列程序中定义的二维数组a的()。 # define M 3 # define N 4 void main( ) { int a[M][N]; …… }

A、第一维和第二维都为4 B、第一维和第二维都为3 C、第一维为4,第二维为3 D、第一维为3,第二维为4 (7) 下列程序的运行结果是()。 # define M 5 # define N M+1 # define NN N*N-M void main( ) { printf(“%d\n”,3*NN); } A、108 B、16 C、21 D、103 (8) 下列叙述正确的是()。 A、宏定义中的宏名必须用大写字母表示 B、为提高程序运行速度可在源程序中加入一些宏定义 C、一个C语言源程序只能有一条预处理命令 D、宏定义不占用程序运行时间,但与程序中的语句一样需要编译 (9) 下列叙述错误的是()。 A、宏定义可出现在源程序中任意合适的位置,且必须在行末加分号 B、预处理命令行都必须以#号开始 C、C语言源程序中加入一些预处理命令是为了改进程序设计环境,提高编程效率 D、# define PER 1.5的作用是用标识符PER代表1.5 (10) 下列程序的运行结果是()。 # define K 5 void main( ) { int a=3,b=4; printf(“%d\n”,K*(a+b)); } A、20 B、15 C、5 D、35 (11) 以下叙述正确的是()。 A) 一个源程序只能由一个编译预处理命令行 B) 编译预处理命令都必须以"#"开头 C) "#define PRICE=30"定义了与30等价的符号常量PRICE

第八章 编译预处理

第九章编译预处理 预处理功能主要有三种:宏定义;文件包含;条件编译。 9.1宏替换(宏定义) 9.1.1不带参数的宏定义 1. #define 指令:用一个指定的标识符来代表一个字符串。 2.定义的一般形式是: #define 宏名字符串(或数值) 由#define指令定义后, 在程序中每次遇到该宏名时就用所定义的字符串(或数值)代替它。 例1:#define PI 3.14159265 #define RADIUS 2.0 double circum() { return(2.0*PI*RADIUS); } double area() { return(PI*RADIUS*RADIUS); } main() { printf("L=%lf\n",circum()); printf("S=%lf\n",area()); } 注意: ①在宏定义的后面没有";"(因为它不是语句) ②习惯上用大写字符作为宏名, 与变量名相区别,而且常放在程序开头。 ③使用宏名代替一个字符串,可以减少程序中重复书写某些字符串的工作量: #define array_size 1000 int array[attay_size]; ④可以用#undef命令终止宏定义的作用域。 #define G 9.8 main() { } #undef G f1( )

…….. ⑤在进行宏定义时,可以引用已定义的宠名,可以层层置换。 例:#define R 3.0 #define PI 3.1415926 #define L 2*PI*R #define S PI*R*R main() { printf(“L=%f\ns=%f\n”,L,S); } ⑥在程序中用双引号括起来的字符串骨近字符,与宏名相同,不进行置换,作为字符串。 9.1.2带参数的宏定义 1.# define 宏名(参数)字符串 不是进行简单的字符串替换,还要进行参数替换。 例2: #define MAX(x, y) ((x)>(y))?(x):(y) main() { int i=10, j=15; printf("The Maxmum is %d", MAX(i, j)); } 展开相当于: printf("The Maxmum is %d", ((i)>(j))?(i):(j)); 9.2.“文件包含”处里(#include) 1.定义:#include 指令的作用是指示编译器将该指令所指出的另一个源文件嵌入#include指令所在的程序中.其一般形式为:#include <文件名> 或#include “文件名” 第一种形式:系统到系统标准目录中搜索该文件 第二种形式:首先到当前目录中搜索该文件,如找不到则到系统标准目录中去搜索该文件。 例3: 输入一个句子,统计单词个数。 首先编写一个头文件: /*hong.h*/ #include #define TRUE 1

相关文档
相关文档 最新文档