目录

  • 1 计算机概述
    • 1.1 计算机简介
    • 1.2 计算机系统
    • 1.3 数值在计算机中的表示
  • 2 C语言概述
    • 2.1 C语言发展及特点
    • 2.2 C语言程序的运行步骤和开发环境
    • 2.3 简单的C语言程序
  • 3 C语言基础
    • 3.1 变量、常量及数据类型
    • 3.2 运算符和表达式
    • 3.3 输入、输出
  • 4 选择结构
    • 4.1 计算机编程和算法
    • 4.2 if语句
    • 4.3 if嵌套和if多分支
    • 4.4 switch语句
  • 5 循环结构
    • 5.1 while语句和do...while语句
    • 5.2 for语句
    • 5.3 break语句和continue语句
    • 5.4 goto语句构成的循环
    • 5.5 嵌套循环结构
    • 5.6 程序设计举例
  • 6 函数
    • 6.1 函数的定义与调用
    • 6.2 函数的嵌套调用和递归调用
    • 6.3 作用域和生命周期
    • 6.4 章节小结与测试
  • 7 数组
    • 7.1 一维数组及应用
    • 7.2 二维数组及应用
    • 7.3 字符数组
    • 7.4 数组作为函数参数
    • 7.5 章节小结与测试
  • 8 指针
    • 8.1 指针变量
    • 8.2 指针与数组
    • 8.3 指针的多种形态
  • 9 字符串
    • 9.1 字符串概念及输入输出
    • 9.2 字符串函数
    • 9.3 指针与字符串
    • 9.4 章节小结与测试
  • 10 编译预处理
    • 10.1 宏定义
    • 10.2 文件包含
    • 10.3 条件编译
  • 11 结构体、共用体和用户定义类型
    • 11.1 结构体类型变量
    • 11.2 结构体类型数组与指针
    • 11.3 结构体与函数
    • 11.4 用指针处理链表
    • 11.5 共用体
  • 12 位运算
    • 12.1 位运算的概念和运算规则
  • 13 文件
    • 13.1 C文件概述
    • 13.2 文件的打开与关闭
    • 13.3 文件读写
    • 13.4 位置指针的定位
宏定义

学习目标:

掌握宏定义

重点:

宏定义编译预处理命令的正确使用

难点:

宏定义

 

引言:

掌握宏定义、文件包含和条件编译,分别用宏定义命令、文件包含命令和条件编译命令来实现。

为了和一般C语句相区别,这些命令以符号“#”开头。

 

一、无参宏

1无参宏的定义格式

#define 标识符 字符串

“define”为宏定义命令。

标识符为所定义的宏名,通常用大写字母表示,以便于与变量区别。

字符串可以是常数、表达式等。

: 用一个标识符来表示一个字符串。

宏名:被定义为的标识符。

宏替换:在编译预处理时,预处理程序将程序中所有出现的宏名,都用宏定义中的字符串去替换。完成后,才将程序交给编译程序去处理。

2、使用宏定义的优点

(1) 可提高源程序的可维护性;

(2) 可提高源程序的可移植性;

(3) 减少源程序中重复书写字符串的工作量。

3、关于宏定义几点说明

(1) 宏名一般用大写字母表示,以示与变量区别。但这并非是语法规定。

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

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

(4) 宏定义命令#define出现在函数的外部,宏名的有效范围是:从定义命令之后,到本文件结束。

(5) 在进行宏定义时,可以引用已定义的宏名。

(6) 对双引号括起来的字符串内的字符,即使与宏名同名,也不进行宏展开。

4、符号常量

在定义无参宏时,如果宏定义中的“字符串”是一个常量,则相应的“宏名”称为符号常量。

 

二、有参宏

1、有参宏的定义格式

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

# define ADD(X,Y) (X+Y)

2、有参宏的调用和宏展开

(1) 调用格式:宏名(实参表)

(2) 宏展开:用宏调用提供的实参字符串,直接替换宏定义命令行中相应形参字符串,非形参字符保持不变。

# define ADD(X,Y) (X+Y)

        …

sum = ADD(3,5) ;

宏替换时,用实参35 去代替形参X Y,经预处理宏展开后的语句为:

sum = (3+5) ;

3、关于有参宏的几点说明

(1) 定义有参宏时,宏名与左圆括号之间不能留有空格。

(2) 有参宏定义中,形参不分配内存单元,因此形参不必做类型定义;而宏替换中的实参有具体的值,要用它们去代换形参,因此实参必须做类型说明。在有参宏中,只是符号替换。

(3) 调用有参宏名时,一对圆括号必不可少,圆括号中实参的个数应该与形参个数相同,如果有多个参数,参数之间用逗号隔开。

(4) 在宏定义中的形参是标识符,而宏调用中的实参可以是表达式。宏替换时对实参表达式不做计算直接照原样替换。

(5) 在宏定义中,字符串内的形参和整个表达式通常要用括号括起来以避免出错。

  

、应用举例

1.10.1阅读以下程序,观察程序结果。


2.10.2阅读以下程序,观察程序结果。


3.10.3阅读以下程序,观察程序结果。


4.10.4阅读以下程序,观察程序结果。


5.10.5阅读以下程序,观察程序结果。


6.10.6阅读以下程序,观察程序结果。


7.10.7阅读以下程序,观察程序结果。


 

讨论题:

1)10.1中的“#define PI 3.14159”就是宏定义,它的作用是什么呢?


2)10.710.6稍有不同,在宏定义中将整体字符串及形参加了括号,调用就发生了什么变化?