C程序设计.

Slides:



Advertisements
Similar presentations
2.5 函数的微分 一、问题的提出 二、微分的定义 三、可微的条件 四、微分的几何意义 五、微分的求法 六、小结.
Advertisements

6.4 字符串与指针 1. 用字符数组存放一个字符串.
C语言实验 第一课 标题:学号+姓名.
C++中的声音处理 在传统Turbo C环境中,如果想用C语言控制电脑发声,可以用Sound函数。在VC6.6环境中如果想控制电脑发声则采用Beep函数。原型为: Beep(频率,持续时间) , 单位毫秒 暂停程序执行使用Sleep函数 Sleep(持续时间), 单位毫秒 引用这两个函数时,必须包含头文件
在PHP和MYSQL中实现完美的中文显示
4.3函数 4.3.1函数的概念及定义 1、函数的概念: 可以被其它程序调用具有 特定功能的一段相对独立的 程序(模块),称函数。
高级语言程序设计 主讲人:陈玉华.
授课老师:龚涛 信息科学与技术学院 2018年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
Hadoop I/O By ShiChaojie.
第13章 编译预处理 宏定义 文件包含 条件编译.
C程序设计.
第10章 预处理过程 一、编译预处理指令概述 二、预处理指令 #include 三、#define指令.
管理信息结构SMI.
走进编程 程序的顺序结构(二).
辅导课程六.
第7章 编译预处理 本章要求: 本章重点: 本章难点: 掌握用#define定义无参数宏和带有参数宏定义和调用方法;
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
第二章 Java语言基础.
第五章 习题课 电子信息与计算机科学系 曾庆尚.
2.1 C语言的数据类型 2.2 常量与变量 2.3 变量赋初值 2.4 各类数值型数据间的混合运算 2.5 C语言的运算符和表达式
第12章 编译预处理 12.1 了解编译预处理 12.2 宏 定 义 12.3 文 件 包 含 12.4 条 件 编 译.
第八章 编译预处理 西安工程大学.
第6章 预 处 理.
第九章 预处理命令.
宁波市高校慕课联盟课程 与 进行交互 Linux 系统管理.
Gzip编译及调试 曹益华
宁波市高校慕课联盟课程 与 进行交互 Linux 系统管理.
第一章 函数与极限.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
第8章 编绎和预处理.
1.3 C语言的语句和关键字 一、C语言的语句 与其它高级语言一样,C语言也是利用函数体中的可执行 语句,向计算机系统发出操作命令。按照语句功能或构成的不 同,可将C语言的语句分为五类。 goto, return.
C语言程序设计 主讲教师:陆幼利.
简单介绍 用C++实现简单的模板数据结构 ArrayList(数组, 类似std::vector)
学习目标 1、什么是字符集 2、字符集四个级别 3、如何选择字符集.
$9 泛型基础.
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
C程序设计 谭浩强 著 清华大学出版社.
线 性 代 数 厦门大学线性代数教学组 2019年4月24日6时8分 / 45.
第1章 c++概述 1.1 C++语言的简史及特点 1.2 简单的C++程序 1.3 C++语言的基本组成
实验四、TinyOS执行机制实验 一、实验目的 1、了解tinyos执行机制,实现程序异步处理的方法。
Main() { Dfas Asdfasf fasdfa } #include <stdio.h> void main( ) {
姚金宇 MIT SCHEME 使用说明 姚金宇
C语言程序设计 第九章 预处理命令.
C语言程序设计 第一章 数据类型, 运算符与表达式 第二章 顺序程序设计 第三章 选择结构程序设计 第四章 循环控制 第五章 数组.
1.2 有理数 第1课时 有理数 伏家营中学 付宝华.
第4章 Excel电子表格制作软件 4.4 函数(一).
目录 8.1 宏定义 8.2 文件包含 8.3 条件编译 1.
第九节 赋值运算符和赋值表达式.
iSIGHT 基本培训 使用 Excel的栅栏问题
第6章 预 处 理.
3.16 枚举算法及其程序实现 ——数组的作用.
本节内容 结构体 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第8章 编译预处理 所谓编译预处理是指,在对源程序进行编译之前,先对源程序中的编译预处理命令进行处理;然后再将处理的结果,和源程序一起进行编译,以得到目标代码。 8.1 宏定义与符号常量 8.2 文件包含 8.3 条件编译 [Return]
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
2.6 字符型数据 一、 字符常量 1、字符常量的定义 用一对单引号括起来的单个字符,称为字符常量。 例如,‘A’、‘1’、‘+’等。
第9章 预处理命令.
第7章 模板 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
本节内容 C语言的汇编表示 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
_03宽字符与Unicode编程 本节课讲师——void* 视频提供:昆山爱达人信息技术有限公司 官网地址:
Python 环境搭建 基于Anaconda和VSCode.
复习 标签(label)、文本框(text)控件 按钮:点击事件
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
基本知识 数据类型、变量、常量、运算符.
第18讲 从C到C++ 计算机与通信工程学院.
第三节 数量积 向量积 混合积 一、向量的数量积 二、向量的向量积 三、向量的混合积 四、小结 思考题.
第二次课后作业答案 函数式编程和逻辑式编程
THE C PROGRAMMING LANGUAGE
Presentation transcript:

C程序设计

第9章 预处理命令 ANSI C标准规定可以在C源程序中加入一些“预处理命令”,以改进程序设计环境,提高编程效率。这些预处理命令是由ANSI C统一规定的,但是它不是C语言本身的组成部分,不能直接对它们进行编译(因为编译程序不能识别它们)。必须在对程序进行通常的编译(包括词法和语法分析、代码生成、优化等)之前,先对程序中这些特殊的命令进行“预处理”,即根据预处理命令对程序作相应的处理(例如,若程序中用#define命令定义了一个符号常量A,则在预处理时将程序中所有的A都置换为指定的字符串。若程序中用#include命令包含一个文件“stdio.h”,则在预处理时将stdio.h文件中的实际内容替代该命令)。

经过预处理后的程序不再包括预处理命令了,最后再由编译程序对预处理后的源程序进行通常的编译处理,得到可供执行的目标代码。现在使用的许多C编译系统都包括了预处理、编译和连接部分,在进行编译时一气呵成。因此不少用户误认为预处理命令是C语言的一部分,甚至以为它们是C语句,这是不对的。必须正确区分预处理命令和C语句,区分预处理和编译,才能正确使用预处理命令。

C提供的预处理功能主要有以下3种: 1、宏定义 2、文件包含 3、条件编译(不要求) 分别用宏定义命令、文件包含命令、条件编译命令来实现。

9.1 宏定义 9.1.1 不带参数的宏定义 用一个指定的标识符(即名字)来代表一个字符串,它的一般形式为 #define 标识符 字符串 例如:#define PI 3.1415926 这种方法使用户能以一个简单的名字代替一个长的字符串,因此把这个标识符(名字)称为“宏名”,在预编译时将宏名替换成字符串的过程称为“宏展开”。#define是宏定义命令。

[例9.1]使用不带参数的宏定义 #include <stdio.h> #define PI 3.1415926 void main() { float l, s, r, v; printf(“input radius:”); scanf(“%f”, &r); l=2.0*PI*r; s=PI*r*r; v=4.0/3*PI*r*r*r; printf(“l=%10.4f\ns=%10.4f\nv=%10.4f\n”, l, s, v); }

说明: (1)宏名一般习惯用大写字母表示,以便与变量名相区别,但这并非规定,也可用小写字母。 (2)使用宏名代替一个字符串,可以减少程序中重复书写某些字符串的工作量。 (3)宏定义是用宏名代替一个字符串,也就是作简单的置换,不作正确性检查。 (4)宏定义不是C语句,不必在行末加分号。 (5)#define命令出现在程序中函数的外面,宏名的有效范围为定义命令之后到本源文件结束。 (6)可以用#undef命令终止宏定义的作用域。 (7)在进行宏定义时,可以引用已定义的宏名,可以层层置换。 [例9.2]在宏定义中引用已定义的宏名 (8)对程序中用双撇号括起来的字符串内的字符,即使与宏名相同,也不进行置换。 (9)宏定义是专门用于预处理命令的一个专用名词,它与定义变量的含义不同,只作字符替换,不分配内存空间。

9.1.2 带参数的宏定义 带参数的宏定义不是进行简单的字符串替换,还要进行参数替换。其定义的一般形式为 #define 宏名(参数表) 字符串 字符串中包含在括号中所指定的参数。例如: #define S(a, b) a*b …… area=S(3, 2); [例9.3]使用带参数的宏 例如: #define S(a,b) a*b 其中S-宏名,a,b是形式参数。程序调用S(3,2)时,把实参3,2分别代替形参a,b。 area=S(3,2); => area=3*2; 带参数宏定义展开规则: 在程序中如果有带实参的宏定义,则按照#define命令行中指定的“字符串”从左到右进行置换(扫描置换)。如果串中包含宏定义中的形参,则将程序中相应的实参代替形参,其它字符原样保留,形成了替换后的字符串。 注意:还是一个字符串的替换过程,只是将形参部分的字符串用相应的实参字符串替换。

说明: (1)对带参数的宏的展开只是将语句中的宏名后面括号内的实参字符串代替#define命令行中的形参。 (2)在宏定义时,在宏名与带参数的括号之间不应加空格;否则,将空格以后的字符都作为替代字符串的一部分。 (1)#define S(a,b) a*b程序中 area=S(a+b,c+d);=>area=a+b*c+d;明显和我们的意图不同。 假如:宏定义的字符串中的形参用()括号括起来,即: #define S(a,b) (a)*(b) 此时程序中:area=S(a+b,c+d);=>area=(a+b)*(c+d);符合我们的意图。 为了避免出错,建议将宏定义“字符串”中的所有形参用括号()括起来。以后,替换时括号作为一般字符原样照抄,这样用实参替换时,实参就被括号括起来作为整体。不至于发生类似错误。 (2)如:#define S (r) PI*r*r area=S(3.0); => area=(r) PI*r*r(3.0); 这样显然也是错误的。

带参数的宏定义与函数是不同的,主要有: (1)函数调用时,先求出实参表达式的值,然后带入形参。而使用带参数的宏只是进行简单的字符代替。 (2)函数调用是在程序运行时处理的,为形参分配临时的内存单元。而宏展开则是在编译前进行的,在展开时并不分配内存单元,不进行值得传递处理,也没有“返回值”的概念。 (3)对函数中的实参和形参都要定义类型,二者的类型要求一致,如不一致,应进行类型转换。而宏不存在类型问题,宏名无类型,它的参数也无类型,只是一个符号代表,展开时代入指定的字符串即可。宏定义时,字符串可以是任何类型的数据。 (4)调用函数只可得到一个返回值,而用宏可以设法得到几个结果。 [例9.4]通过宏展开得到若干个结果 (5)使用宏次数多时,宏展开后源程序变长,因为每展开一次都使程序增长,而函数调用不会使源程序变长。 (6)宏替换不占运行时间,只占编译时间。而函数调用则占运行时间(分配单元、保留现场、值传递、返回)。 [例9.5]用宏代表输出格式

9.2 “文件包含”处理 所谓“文件包含”处理是指一个源文件可以将另外一个源文件的全部内容包含进来,即将另外的文件包含到本文件之中。C语言提供了#include命令用来实现“文件包含”的操作。其一般形式为: #include “文件名”或#include <文件名>

[例9.6]将例9.5的格式宏做成头文件,把它包含在用户程序中 (1)将格式宏做成头文件format.h #define PR printf #define NL “\n” #define D “%d” #define D1 D NL #define D2 D D D NL #define D3 D D D NL #define D4 D D D D NL #define S “%s” (2)主文件file1.c #include <stdio.h> #include “format.h” 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)一个#include命令只能指定一个被包含文件,如果要包含n个文件,要用n个#include命令。 (3)在一个被包含文件中又可以包含另一个被包含文件,即文件包含是可以嵌套的。 (4)在#include命令中,文件名可以用双撇号或尖括号括起来。 (5)被包含文件与其所在的文件,在预编译后已成为同一个文件。

9.3 条件编译 一般情况下,源程序中所有行都参加编译。但是有时希望程序中一部分内容只在满足一定条件时才进行编译,也就是对这一部分内容指定编译的条件,这就是“条件编译”。有时,希望在满足某条件时对某一组语句进行编译,而当条件不满足时则编译另一组语句。

条件编译命令有以下几种形式: (1) #ifdef 标识符 程序段1 #else 程序段2 #endif

(2) #ifndef 标识符 程序段1 #else 程序段2 #endif

(3) #if 表达式 程序段1 #else 程序段2 #endif [例9.7]输入一行字母字符,根据需要设置条件编译,使之能将字母全改为大写输出,或全改为小写字母输出

习题 9.1 定义一个带参数的宏,使两个参数的值互换,并写出程序,输入两个数作为使用宏时的实参。输出已交换或的两个值。 9.2 输入两个整数,求它们相除的余数。用带参数的宏来实现,编程序。 9.3 三角形的面积为area=sqrt(s(s-a)(s-b)(s-c)其中s=(a+b+c)/2。a、b、c为三角形的三边。定义两个带参数的宏,一个用来求s,另一个宏用来求area。写程序,在程序中用带实参的宏名来求面积area。

9.4 给年份year定义一个宏,以判别该年份是否闰年。提示:宏名可定为LEAP_YEAR,形参为y,即定义宏的形式为#define LEAP_YEAR(y) (读者设计的字符串) 在程序中用以下语句输出结果: if (LEAP_YEAR(year)) printf(“%d is a leap year.\n”, year); else printf(“%d is not a leap year.\n”, year); 9.6 请设计输出实数的格式,实数用“%6.2f”格式输出。要求: (1)一行输出1个实数; (2)一行内输出2个实数; (3)一行内输出3个实数。 9.7 设计所需的各种的输出格式(包括整数、实数、字符串等),用一个文件名“format.h”把这些信息都放到此文件内,另编一个程序文件,用#include “format.h”命令,以确保能使用这些格式。

9.8 分别用函数和带参数的宏,从3个数中找出最大数。 9.10 用条件编译方法实现以下功能: 输入一行电报文字,可以任选两种输出:一为原文输出;一为将字母变成其下一字母,其他非字母字符不变。用#define命令来控制是否要译成密码。例如: #define CHANGE 1 则输出密码。若 #define CHANGE 0 则不译成密码,按源码输出。