第九章 预处理命令.

Slides:



Advertisements
Similar presentations
興南國小強化體適能活動 學務處體育組 ( ) 此檔案家長可在學校首頁行政公告下載. 教育部體適能常模 坐姿體前彎 ( 公分 ) 立定跳遠 ( 公分 ) 仰臥起坐 ( 次 ) 心肺適能 ( 分秒 ) 10 歲男 / 女生 PR25 常模標準 19/24 119/110 19/19 347/353.
Advertisements

C++语言程序设计教程 第5章 构造数据类型 第6章 C++程序的结构.
首页 全国高等学校招生考试统一考试 监考员培训 广州市招生考试委员会办公室.
人口增长.
C语言程序设计 主讲教师 :张群燕 电话:
电子成绩单项目实现.
第一章 会计法律制度 补充要点.
二、个性教育.
C语言程序设计 第十二章 位运算.
高级语言程序设计 主讲人:陈玉华.
第5章 函数与预处理 《 C语言程序设计》 (Visual C++ 6.0环境) 本章导读
循环结构又称为重复结构:用来处理需要重复处理的问题,它是程序中一种很重要的结构。
C的發展史 C程式初體驗 C程式設計基本注意事項 上機實習課程
Chap 10 函数与程序结构 10.1 函数的组织 10.2 递归函数 10.3 宏定义 10.4 编译预处理.
C程序设计.
Object-Oriented Programming in C++ 第一章 C++的初步知识
程序设计专题一 结构化程序设计与递归函数 主讲教师: 刘新国.
第5章 堆疊(Stacks) 5-1 堆疊的基礎 5-2 堆疊的表示法 5-3 堆疊的應用 - 運算式的計算與轉換
第7章 编译预处理 本章要求: 本章重点: 本章难点: 掌握用#define定义无参数宏和带有参数宏定义和调用方法;
期中考试成绩分布 《程序设计》-2017年秋.
第五章 C/C++及汇编语言的混合编程 5.1 ARM C/C++编译器 5.2 在C/C++程序中内嵌汇编指令
第3章 顺序结构程序设计 为了让计算机处理各种数据,首先就应该把源数据输入到计算机中;计算机处理结束后,再将目标数据信息以人能够识别的方式输出。C语言中的输入输出操作,是由C语言编译系统提供的库函数来实现。 3.1 格式化输出——printf()函数 3.2 格式化输入——scanf()函数.
第三章 数据类型、运算符与表达式.
2.1 C语言的数据类型 2.2 常量与变量 2.3 变量赋初值 2.4 各类数值型数据间的混合运算 2.5 C语言的运算符和表达式
授课老师:龚涛 信息科学与技术学院 2016年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
第6章 预 处 理.
第1章 概述 本章要点: C语言程序结构和特点 C语言程序的基本符号与关键字 C语言程序的编辑及运行 学习方法建议:
目录 9.1 结构体类型 9.2 共用体类型 9.3 枚举类型 9.4 类型声明符typedef 1.
C语言大学实用教程 第5章 函数与程序结构 西南财经大学经济信息工程学院 刘家芬
第2章 数据类型及表达式 本章导读 本章主要知识点 《 C语言程序设计》 (Visual C++ 6.0环境)
C程序设计 谭浩强 著 清华大学出版社.
第 二 章 数据类型、运算符与表达式.
第一章 程序设计和C语言 主讲人:高晓娟 计算机学院.
C语言程序示例: 1.输入10个数,按从小到大的顺序排序。 2.汉诺塔问题。.
Main() { Dfas Asdfasf fasdfa } #include <stdio.h> void main( ) {
Introduction to the C Programming Language
C语言程序设计 教案 崔武子制作
Oop8 function函式.
C语言程序设计 第九章 预处理命令.
Chap 5 函数 5.1 计算圆柱体积 5.2 使用函数编写程序 5.3 变量与函数.
7.1 C程序的结构 7.2 作用域和作用域规则 7.3 存储属性和生存期 7.4 变量的初始化
第十四章 若干深入问题和C独有的特性 作业: 函数指针 函数作参数 函数副作用 运算 语句 位段 存储类别 编译预处理
C程序设计.
本节内容 字符与字符串 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第一章 C语言概述 教师:周芸.
C语言程序设计 李祥 QQ:
项目1 C程序设计起步 学习目标: 通过该项目你可以知道: C语言的用途。 C语言的基本符号和关键字。 C语言程序的结构及特点。
第2章 数据类型、运算符与表达式 本章要点: 基本数据类型 常量和变量 算术运算符和算术表达式 关系运算符和关系表达式
第6章 预 处 理.
第一章 C语言概述 目录 什么是语言、程序 C语言的历史与发展 C语言的书写形式与程序结构 运行C语言的步骤与方法
THE C PROGRAMMING LANGUAGE
第二章 类型、对象、运算符和表达式.
第2章 数据类型与表达式 学习目的与要求: 掌握C 语言的基本数据类型及使用方法 掌握C程序中常用的运算符和表达式 了解数据类型的转换.
Introduction to the C Programming Language
第二章 基本数据类型 ——数据的表示.
本节内容 函数嵌套调用的内存布局 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第4章 顺序结构程序设计 为了让计算机处理各种数据,首先就应该把源数据输入到计算机中;计算机处理结束后,再将目标数据信息以人能够识别的方式输出。C语言中的输入输出操作,是由C语言编译系统提供的库函数来实现。 4.1 格式化输出——printf()函数 4.2 格式化输入——scanf()函数.
第3章 最简单的C程序设计 3.1 顺序程序设计举例 3.2 数据的表现形式及其运算 3.3 C语句 3.4 数据的输入输出.
本节内容 指针类型.
第五章 逻辑运算和判断选取控制 §5.1 关系运算符和关系表达式
第1章程序设计和C语言.
第十二章 位运算.
《数据结构与算法设计》第一部分 面向对象的C++程序设计基础.
第18讲 从C到C++ 计算机与通信工程学院.
基本資料型態 變數與常數 運算子 基本的資料處理 授課:ANT 日期:2014/03/03.
Chap 10 函数与程序结构 10.1 圆形体积计算器 10.2 汉诺塔问题 10.3 长度单位转换 10.4 大程序构成.
本节内容 指针类型 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
Introduction to the C Programming Language
C++语言程序设计 C++语言程序设计 第二章 基本数据类型与表达式 第十一组 C++语言程序设计.
Presentation transcript:

第九章 预处理命令

预处理的概念 C语言处理系统的预处理功能 预处理命令的使用 本章要点 预处理的概念 C语言处理系统的预处理功能 预处理命令的使用

主要内容 9.1 宏定义 9.2“文件包含”处理 9.3 条件编译

基本概念 ANSI C标准规定可以在C源程序中加入一些“预处理命令” ,以改进程序设计环境,提高编程效率。 这些预处理命令是由ANSI C统一规定的,但是它不是C语言本身的组成部分,不能直接对它们进行编译(因为编译程序不能识别它们)。必须在对程序进行通常的编译之前,先对程序中这些特殊的命令进行“预处理” 经过预处理后程序可由编译程序对预处理后的源程序进行通常的编译处理,得到可供执行的目标代码。

基本概念 C语言与其他高级语言的一个重要区别是可以使用预处理命令和具有预处理的功能。 C提供的预处理功能主要有以下三种: 1.宏定义   1.宏定义   2.文件包含   3.条件编译 这些功能分别用宏定义命令、文件包含命令、条件编译命令来实现。为了与一般C语句相区别,这些命令以符号“#”开头。例如: #define #include

§9.1 宏定义 9.1.1 不带参数的宏定义 宏定义一般形式为: #define 标识符 字符串 例如:# define PI 3.1415926 宏定义的作用是在本程序文件中用指定的标识符PI来代替“3.1415926”这个字符串,在编译预处理时,将程序中在该命令以后出现的所有的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=25.1328 s=50.2655 v=150.7966 input radius: 4↙ (1) 宏名一般习惯用大写字母表示,以便与变量名相区别。但这并非规定,也可用小写字母。 (2) 使用宏名代替一个字符串,可以减少程序中重复书写某些字符串的工作量。 (3) 宏定义是用宏名代替一个字符串,只作简单置换,不作正确性检查。只有在编译已被宏展开后的源程序时才会发现语法错误并报错。

说明: (4) 宏定义不是C语句,不必在行末加分号。如果加了分号则会连分号一起进行置换。 (5) #define命令出现在程序中函数的外面,宏名的有效范围为定义命令之后到本源文件结束。通常,#define命令写在文件开头,函数之前,作为文件一部分,在此文件范围内有效。 (6) 可以用#undef命令终止宏定义的作用域。 例如:

在f1函数中,G不再代表9.8。这样可以灵活控制宏定义的作用范围。 #define G 9.8 _______ void main() ↑ { G的有效范围 … } -----↓---- #undef G f1() { } 在f1函数中,G不再代表9.8。这样可以灵活控制宏定义的作用范围。

说明: 例9.2 在宏定义中引用已定义的宏名 运行情况如下: (7) 在进行宏定义时,可以引用已定义的宏名,可以层层置换。 #include <stdio.h> #define R 3.0 #define PI 3.1415926 #define L 2*PI*R #define S PI*R*R void main() { printf("L=%f\nS=%f\n",L,S); } 运行情况如下: L=18.849556 S=28.274333

printf(“L=%F\NS=%f\n”, 2*3.1415926*3.0,3.1415926*3.0*3.0); S展开为 3.1415926*3.0*3.0 printf函数调用语句展开为: printf(“L=%F\NS=%f\n”, 2*3.1415926*3.0,3.1415926*3.0*3.0);

说明: (8) 对程序中用双撇号括起来的字符串内的字符,即使与宏名相同,也不进行置换。 (9) 宏定义是专门用于预处理命令的一个专用名词,它与定义变量的含义不同,只作字符替换,不分配内存空间。

 9.1.2 带参数的宏定义 作用:不是进行简单的字符串替换,还要进行参数替换。 带参数的宏定义一般形式为: 例: #define 宏名(参数表) 字符串 字符串中包含在括弧中所指定的参数 例: 程序中用3和2分别代替宏定义中的形式参数a和b,用3*2代替S(3,2) 。因此赋值语句展开为: area=3*2 #define S(a,b) a*b  area=S(3,2);

对带参的宏定义是这样展开置换的: 对带实参的宏(如S(3,2),则按#define命令行中指定的字符串从左到右进行置换。若串中包含宏中的形参(如a、b),则将程序中相应的实参(可以是常量、变量或表达式)代替形参。如果宏定义中的字符串中的字符不是参数字符(如a*b中的*号),则保留。这样就形成了置换的字符串。

赋值语句“area=S(a); ” 经宏展开后为: 例9.3 使用带参的宏 运行情况如下: #include <stdio.h> #define PI 3.1415926 #define S(r) PI*r*r void main() {float a,area; a=3.6; area=S(a); printf("r=%f\narea=%f\n",a,area); } r=3.600000 area=40.715038 赋值语句“area=S(a); ” 经宏展开后为: area=3.1415926*a*a;

说明: (1)对带参数的宏展开只是将语句中的宏名后面括号内的实参字符串代替#define 命令行中的形参。 (2) 在宏定义时,在宏名与带参数的括弧之间不应加空格,否则将空格以后的字符都作为替代字符串的一部分。

带参数的宏和函数的区别: (1) 函数调用时,先求出实参表达式的值,然后代入形参。而使用带参的宏只是进行简单的字符替换。 (2) 函数调用是在程序运行时处理的,为形参分配临时的内存单元。而宏展开则是在编译前进行的,在展开时并不分配内存单元,不进行值的传递处理,也没有“返回值”的概念。 (3) 对函数中的实参和形参类型要求一致。而宏名无类型,它的参数也无类型,只是一个符号代表,展开时代入指定的字符串即可。宏定义时,字符串可以是任何类型的数据。 (4) 调用函数只可得到一个返回值,而用宏可以设法得到几个结果。

例9.4 通过宏展开得到若干个结果 #include <stdio.h> #define PI 3.1415926 #define CIRCLE(R,L,S,V) L=2*PI*R;S=PI*R*R;V=4.0/3.0*PI*R*R*R void main() {float r,l,s,v; scanf("%f",&r); CIRCLE(r,l,s,v); printf("r=%6.2f,l=%6.2f,s=%6.2f,v=%6.2f\n",r,l,s,v); }

对宏进行预编译,展开后的main函数如下: void main() { float r,l,s,v; scanf("%f",&r);   l=2*3.1415926*r; s=3.1515926*r*r; v=4.0/3/0*3.1415926*r*r*r;   printf(”r=%6.2f,l=%6.2f,s=%6.2f,v=%6.2f\n”,r,l,s,v); }  运行情况如下: 3.5↙ r=3.50,l=21.99,s=38.48,v=179.59

带参数的宏和函数的区别: (5) 使用宏次数多时,宏展开后源程序长,因为每展开一次都使程序增长,而函数调用不会使源程序变长。 (6) 宏替换不占运行时间,只占编译时间。而函数调用则占运行时间(分配单元、保留现场、值传递、返回)。 如果善于利用宏定义,可以实现程序的简化,如事先将程序中的“输出格式”定义好,以减少在输出语句中每次都要写出具体的输出格式的麻烦。

例9.5 通过宏展开得到若干个结果 #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" 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

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

例9.6 将例9.5时格式宏做成头文件,把它包含在用户程序中。 (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)将格式宏做成头文件format.h #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"

注意: 在编译时并不是分别对两个文件分别进行编译,然后再将它们的目标程序连接的,而是在经过编译预处理后将头文件format.h包含到主文件中,得到一个新的源程序,然后对这个文件进行编译,得到一个目标(.obj)文件。被包含的文件成为新的源文件的一部分,而单独生成目标文件。

说明: (1) 一个#include命令只能指定一个被包含文件,如果要包含n个文件,要用n个#include命令。 (2) 如果文件1包含文件2,而在文件2中要用到文件3的内容,则可在文件1中用两个include命令分别包含文件2和文件3,而且文件3应出现在文件2之前,即在file1.c中定义。 (3) 在一个被包含文件中又可以包含另一个被包含文件,即文件包含是可以嵌套的。

说明: (4) 在#include命令中,文件名可以用双撇号或尖括号括起来。 (5) 被包含文件(file2.h)与其所在的文件(即用#include命令的源文件file2.c),在预编译后已成为同一个文件(而不是两个文件)。因此,如果file2.h中有全局静态变量,它也在file1.h文件中有效,不必用extern声明。

§9.3 条件编译 (3) #if 表达式 程序段1 #else 程序段2 #endif 概念:所谓“条件编译”,是对部分内容指定编译的条件,使其只在满足一定条件才进行编译。 条件编译命令的几种形式: (1)#ifdef 标识符 程序段1  #else 程序段2  #endif (2)#ifndef 标识符 程序段1  #else 程序段2  #endif

运行结果为: C LANGUAGE 例9.7 输入一行字母字符,根据需要设置条件编译,使之能将字母全改为大写输出,或全改为小写字母输出。 #include <stdio.h> #define LETTER 1 void main() {char str[20]="C Language",c; int i; i=0; while((c=str[i])!='\0') { i++; #if LETTER if(c>='a' && c<='z') c=c-32; #else if(c>='A' && c<='Z') c=c+32; #endif printf("%c",c); } 例9.7 输入一行字母字符,根据需要设置条件编译,使之能将字母全改为大写输出,或全改为小写字母输出。 运行结果为: C LANGUAGE