精品-清华大学C语言课件 第16章01 宏定义
合集下载
清华大学C语言教学课件(共16个PPT)第1个共26页文档
常成 于困约 ,而败 于奢靡 。——陆 游 52、 生 命 不 等 于是呼 吸,生 命是活 动。——卢 梭
53、 伟 大 的 事 业,需 要决心 ,能力 ,组织 和责任 感。 ——易 卜 生 54、 唯 书 籍 不 朽。——乔 特
55、 为 中 华 之 崛起而 读书。 ——周 恩来
清华大学C语言教学课件(共16个PPT)
第1个
21、没有人陪你走一辈子,所以你要 适应孤 独,没 有人会 帮你一 辈子, 所以你 要奋斗 一生。 22、当眼泪流尽的时候,留下的应该 是坚强 。 23、要改变命运,首先改变自己。
24、勇气很有理由被当作人类德性之 首,因 为这种 德性保 证了所 有其余 的德性 。--温 斯顿. 丘吉尔 。 25、梯子的梯阶从来不是用来搁脚的 ,它只 是让人 们的脚 放上一 段时间 ,以便 让别一 只脚能 够再往 上登。
53、 伟 大 的 事 业,需 要决心 ,能力 ,组织 和责任 感。 ——易 卜 生 54、 唯 书 籍 不 朽。——乔 特
55、 为 中 华 之 崛起而 读书。 ——周 恩来
清华大学C语言教学课件(共16个PPT)
第1个
21、没有人陪你走一辈子,所以你要 适应孤 独,没 有人会 帮你一 辈子, 所以你 要奋斗 一生。 22、当眼泪流尽的时候,留下的应该 是坚强 。 23、要改变命运,首先改变自己。
24、勇气很有理由被当作人类德性之 首,因 为这种 德性保 证了所 有其余 的德性 。--温 斯顿. 丘吉尔 。 25、梯子的梯阶从来不是用来搁脚的 ,它只 是让人 们的脚 放上一 段时间 ,以便 让别一 只脚能 够再往 上登。
C语言程序设计全套教学教程完整版电子课件最全ppt电子教案
上一页 下一页
目录
8.1 指针的概念、定义和引用 8.1.1 指针的概念 8.1.2 指针变量的定义 8.1.3 指针变量的引用 8.2 指针与函数 8.2.1 指针变量作函数参数 8.2.2 返回值为指针的函数 8.2.3 通过指针调用函数
上一页 下一页
Hale Waihona Puke 目录8.3 指针与数组 8.3.1 指针与数组的关系 8.3.2 数组名作函数参数的指针解释 8.3.3 指针数组 8.3.4 多级指针 8.4 指针与字符串 8.4.1 字符串的表示形式 8.4.2 字符串指针作函数参数
2.汇编语言
汇编语言的指令与机器语言的指令基本上保持了一一对应的关系。与 机器语言比起来,汇编语言易记、易读、易检查、易修改,但却不能 被计算机直接识别和执行,必须由翻译程序翻译成机器语言程序后才 能执行。汇编语言仍然是面向特定计算机的语言,也仍然是低级语言
下一页
返回
1.1 程序设计语言概述
3.高级语言 高级语言是接近人类自然语言和数学语言的程序设计语言,具有以下
上一页 下一页
目录
5.2 do-while语句 5.3 for语句 5.4 break和continue语句 5.5 多重循环 5.6 综合应用举例 第6章 数组 6.1 数组概述 6.2 一维数组
上一页 下一页
目录
6.2.1 一维数组的定义 6.2.2 一维数组的引用 6.2.3 一维数组的初始化 6.2.4 一维数组的程序举例 6.3 二维数组 6.3.1 二维数组的定义 6.3.2 二维数组的引用 6.2.3 二维数组的初始化
翻译成目标程序,然后执行该目标程序。解释方式是把源程序逐句翻
上一页 下一页 返回
1.1 程序设计语言概述
精品-清华大学C语言课件 第16章02 include指令
这两行代码均使用C编译程序读入并编译,用于处理磁盘文件库的子程序。
上面给出了双引号和尖括号的形式,这里说下这两者之间的区别,用尖括号时,系统到存放C库函数 头文件所在的目录中寻找要包含的文件,这种称为标准方式;用双引号时,系统先在用户当前目录中寻 找要包含的文件,若找不到,再到存放C库函数头文件所在的目录中寻找要包含的文件。通常情况下,如 果为调用库函数用#include命令来包含相关的头文件,则用尖括号,可以节省查找的时间。如果要包含 的是用户自己编写的文件,一般用双引号,用户自己编写的文件通常是在当前目录中。如果文件不在当 前目录中,双引号可给出文件路径。
#include指令
在一个源文件中使用#include指令可以将另一个源文件的全部内容包含进来,也就是将另外的文件 包含到本文件之中。#include使编译程序将另一源文件嵌入带有#include的源文件,被读入的源文件必 须用双引号或尖括号括起来。例如:
#include "stdio.h"
#include <stdio.h>
程序运行结果如图16.6所示:
图16.6 文件包含应用 常用在文件头部的被包含的文件称为“标题文件”或“头部文件”,常以“.h”为后缀,如本例中的 f1.h。 一般情况下将如下内容放到.h文件中: 宏定义 结构、联合和枚举声明 typedef声明 外部函数声明 全局变量声明 使用文件包含为实现程序修改提供了方便,当需要修改一些参数时不必修改每个程序,只需修改一个 文件(头部文件)即可。 关于“文件包含”有以下几点要注意: 一个#include命令只能指定一个被包含的文件。 文件包含是可以嵌套的,即在一个被包含文件中还可以包含另一个被包含文件。 当在file1.c中包含文件file2.h,那么在预编译后就成为一个文件而不是两个文件,这时如果 file2.h中有全局静态变量,则该全局变量在file1.c文件中也有效,这时不需要再用extern声明。
精品-清华大学C语言课件 第16章05 本章常见错误
#include "file3.c" #include "file2.c"
这里要注意命令的顺序,file3.c要写在file2.c的前面。
本章常见错误
本讲大纲
1.带参数的宏最好加括号 2.使用宏时注意事项 3.文件包含的嵌套
带参数的宏最好加括号
定义带参数的宏时,最好用括号将参数括起来。有时候传递的参数可能是表达式而不只是一个 单独的值,这时候如果没有括号就会出错。如下面的代码,使用两个宏的结果是不一样的。
#define A(a,b)(a)*(b) #define B(a,b)a*b 4; printf("%d\n",A(x+y,x-y));//20 printf("%d\n",B(x+y,x-y));//26 }
包含文件也是可以进行嵌套的,一个被包含的文件file1.c又包含了另一个文件file2.c,就是 文件的嵌套。 下面介绍文件嵌套的形式。 在文件file1.c中:
#include "file2.c"
表示一个被包含的文件file1.c又包含了另一个文件file2.c。在文件file2.c中:
#include "file3.c"
使用宏时注意事项
在使用宏时应该注意以下几点: 宏定义不是C语言的语句,不要在行末添加分号。 书写宏定义的时候,如果需要续行,有些编译器需要加续行符(\)。 在宏定义时,宏名和带参数的括号间不要加空格,否则该空格将被看作是宏体的一部分。 进行宏替换时,不应增加或者减少内容,只是简单的替换。
文件包含的嵌套
这就是说文件file1.c包含文件file2.c,在文件file2.c中包含文件file3.c,也就是说file1.c 包含了两个文件,即file2.c和file3.c。
这里要注意命令的顺序,file3.c要写在file2.c的前面。
本章常见错误
本讲大纲
1.带参数的宏最好加括号 2.使用宏时注意事项 3.文件包含的嵌套
带参数的宏最好加括号
定义带参数的宏时,最好用括号将参数括起来。有时候传递的参数可能是表达式而不只是一个 单独的值,这时候如果没有括号就会出错。如下面的代码,使用两个宏的结果是不一样的。
#define A(a,b)(a)*(b) #define B(a,b)a*b 4; printf("%d\n",A(x+y,x-y));//20 printf("%d\n",B(x+y,x-y));//26 }
包含文件也是可以进行嵌套的,一个被包含的文件file1.c又包含了另一个文件file2.c,就是 文件的嵌套。 下面介绍文件嵌套的形式。 在文件file1.c中:
#include "file2.c"
表示一个被包含的文件file1.c又包含了另一个文件file2.c。在文件file2.c中:
#include "file3.c"
使用宏时注意事项
在使用宏时应该注意以下几点: 宏定义不是C语言的语句,不要在行末添加分号。 书写宏定义的时候,如果需要续行,有些编译器需要加续行符(\)。 在宏定义时,宏名和带参数的括号间不要加空格,否则该空格将被看作是宏体的一部分。 进行宏替换时,不应增加或者减少内容,只是简单的替换。
文件包含的嵌套
这就是说文件file1.c包含文件file2.c,在文件file2.c中包含文件file3.c,也就是说file1.c 包含了两个文件,即file2.c和file3.c。
清华大学C语言教学课件(共16个PPT)第2个共33页
16、业余生活要有意义,不要越轨。——华盛顿 17、一个人即使已登上顶峰,也仍要自强不息。——罗素·贝克 18、最大的挑战和突破在于用人,而用人最大的突破在于信任人。——马云 19、自己活着,就是为了使别人过得更美好。——雷锋 20、要掌握书,莫被书掌握;要为生而读,莫为读而生。——布尔沃
清华大学C语言教学课件(共16个PPT) 第2个
16、自己选择的路、跪着也要把它走 完。 17、一般情况下)不想三年以后的事, 只想现 在的事 。现在 有成就 ,以后 才能更 辉煌。
18、敢于向黑暗宣战的人,心里必须 充满光 明。 19、学习的关键--重复。
20、懦弱的人只会裹足不前,莽撞的 人只能 引为烧 身,只 有真正 勇敢的 人才能 所向披 靡。
ENDቤተ መጻሕፍቲ ባይዱ
精品-清华大学C语言课件 第16章03 条件编译
程序运行结果如图16.12所示:
图16.12 输出行号Fra bibliotekpragma命令
1.#pragma命令 #pragma命令的作用是设定编译器的状态,或者指示编译器完成一些特定的动作。 #pragma指令的一般形式如下:
#pragma 参数
参数可为以下几种情况: message参数,该参数能够在编译信息输出窗口中输出相应的信息。 code_seg参数,设置程序中函数代码存放的代码段。 once参数,保证头文件被编译一次。 2.预定义宏名 ANSI标准说明了五个预定义宏替换名。它们是: __LINE__:其含义是是当前被编译代码的行号。 __FILE__:其含义是当前源程序的文件名称。 __DATE__:其含义是当前源程序的创建日期。 __TIME__:其含义是当前源程序的创建时间。 __STDC__:其含义是用来判断当前编译器是否是为标准C,若其值为1表示符合标准C,否则不是标准C。
}程序效果如图16.13所示。
图16.13 使用条件编译隐藏密码
#ifndef_FILE_H_ #define_FILE_H_ //要包含的内容 #endif
实例4 防止头文件重复包含
程序运行结果如图16.11所示: 图16.11 #ifdef及#ifndef应用
#undef命令
在前面讲#define命令时提到过#undef命令,使用#undef命令用来删除事先定义了的宏定义。 #undef命令的一般形式如下:
#undef 宏替换名
例如:
#define MAX_SIZE 100 char array[MAX_SIZE]; #undef MAX_SIZE
图16.10 #else应用 #elif指令用来建立一种“如果…或者如果…”这样阶梯状多重编译操作选择,这与多分支if语 句中的else if类似。 #elif一般形式如下:
图16.12 输出行号Fra bibliotekpragma命令
1.#pragma命令 #pragma命令的作用是设定编译器的状态,或者指示编译器完成一些特定的动作。 #pragma指令的一般形式如下:
#pragma 参数
参数可为以下几种情况: message参数,该参数能够在编译信息输出窗口中输出相应的信息。 code_seg参数,设置程序中函数代码存放的代码段。 once参数,保证头文件被编译一次。 2.预定义宏名 ANSI标准说明了五个预定义宏替换名。它们是: __LINE__:其含义是是当前被编译代码的行号。 __FILE__:其含义是当前源程序的文件名称。 __DATE__:其含义是当前源程序的创建日期。 __TIME__:其含义是当前源程序的创建时间。 __STDC__:其含义是用来判断当前编译器是否是为标准C,若其值为1表示符合标准C,否则不是标准C。
}程序效果如图16.13所示。
图16.13 使用条件编译隐藏密码
#ifndef_FILE_H_ #define_FILE_H_ //要包含的内容 #endif
实例4 防止头文件重复包含
程序运行结果如图16.11所示: 图16.11 #ifdef及#ifndef应用
#undef命令
在前面讲#define命令时提到过#undef命令,使用#undef命令用来删除事先定义了的宏定义。 #undef命令的一般形式如下:
#undef 宏替换名
例如:
#define MAX_SIZE 100 char array[MAX_SIZE]; #undef MAX_SIZE
图16.10 #else应用 #elif指令用来建立一种“如果…或者如果…”这样阶梯状多重编译操作选择,这与多分支if语 句中的else if类似。 #elif一般形式如下:
清华大学C语言教学课件(共16个PPT)第1个共26页
清华大学C语言教学课件(共16个PPT) 第1个
•
6、黄金时代是在我们的前面,而不在 我们的 后面。
•
7、心急吃不了热汤圆。
•
8、你可以很有个性,但某些时候请收口 (蹩脚 的工人 总是说 工具不 好)。
•
10、只要下定决心克服恐惧,便几乎 能克服 任何恐 惧。因 为,请 记住, 除了在 脑海中 ,恐惧 无处藏 身。-- 戴尔. 卡耐基 。
55、 为 中 华 之 崛起而 读书。 ——周 恩来
谢谢!
51、 天 下 之 事 常成 于困约 ,而败 于奢靡 。——陆 游 52、 生 命 不 等 于是呼 吸,生 命是活 动。——卢 梭
53、 伟 大 的 事 业,需 要决心 ,能力 ,组织 和责任 感。 ——易 卜 生 54、 唯 书 籍 不 朽。——乔 特
•
6、黄金时代是在我们的前面,而不在 我们的 后面。
•
7、心急吃不了热汤圆。
•
8、你可以很有个性,但某些时候请收口 (蹩脚 的工人 总是说 工具不 好)。
•
10、只要下定决心克服恐惧,便几乎 能克服 任何恐 惧。因 为,请 记住, 除了在 脑海中 ,恐惧 无处藏 身。-- 戴尔. 卡耐基 。
55、 为 中 华 之 崛起而 读书。 ——周 恩来
谢谢!
51、 天 下 之 事 常成 于困约 ,而败 于奢靡 。——陆 游 52、 生 命 不 等 于是呼 吸,生 命是活 动。——卢 梭
53、 伟 大 的 事 业,需 要决心 ,能力 ,组织 和责任 感。 ——易 卜 生 54、 唯 书 籍 不 朽。——乔 特
C语言完整 ppt课件
1.4.1 宏定义
用一个标识符来表示一个字符串,称为“宏”,标识符称为“宏名”。在 程序中 用宏名替代字符串称为“宏调用”。在编译预处理时,将对程序中所有出现的 “宏 名”,都用宏定义中的字符串代换,这个过程称为“宏展开”。
1.4.1.1 不带参数的宏定义
格式为:#define 标识符 字符串
1.4.1.2 带参数的宏定义
1-4
1.3 C程序上机步骤
C源程序编好后,要经过编辑、编译、连接, 生成可执行文件后,才可运行。
运行集成开发软件
编辑源程序
编译
有 有错? 无 连接
不正确
运行
结果正确? 正确
结束
1-5
1.4 编译预处理
编译预处理是指,在C编译程序对C源程序进行编译之前,由编译预处理程 序对源程序中的预处理命令进行处理的过程。
1.2.1 C语言程序举例
1.2.2 C语言程序的结构
1.2.2.1 函数是C语言程序的基本单位。
1.2.2.2 函数的一般结构
任何函数(包括main()函数)都是由函数首部和函数体两部分组成。
1. 函数首部: 函数首部即函数第一行,由函数类型、函数名和函数参数表三部分组成。
2. 函数体: 函数体为函数首部下面的花括号{……}内的部分。 函数体一般由声明部分和执行部分构成:声明部分定义所用到的变量,声明所调用的函数等; 执行部分有若干语句组成。
2.6.1 运算符及表达式简介 2.6.1.1 运算符
C语言中的运算符具有2个特点: ⑴ 运算符的优先级 C语言中,运算符的优先级共分为15级,1级最高,15级最低。 ⑵ 运算符的结合性 C语言中各运算符的结合性分为左结合性(从左到右)和右结合性(从右到左)。 2.6.1.2 表达式 表达式是由常量、变量、函数和运算符组成的式子。 表达式求值是按运算符的优先级和结合性规定的顺序进行的。
用一个标识符来表示一个字符串,称为“宏”,标识符称为“宏名”。在 程序中 用宏名替代字符串称为“宏调用”。在编译预处理时,将对程序中所有出现的 “宏 名”,都用宏定义中的字符串代换,这个过程称为“宏展开”。
1.4.1.1 不带参数的宏定义
格式为:#define 标识符 字符串
1.4.1.2 带参数的宏定义
1-4
1.3 C程序上机步骤
C源程序编好后,要经过编辑、编译、连接, 生成可执行文件后,才可运行。
运行集成开发软件
编辑源程序
编译
有 有错? 无 连接
不正确
运行
结果正确? 正确
结束
1-5
1.4 编译预处理
编译预处理是指,在C编译程序对C源程序进行编译之前,由编译预处理程 序对源程序中的预处理命令进行处理的过程。
1.2.1 C语言程序举例
1.2.2 C语言程序的结构
1.2.2.1 函数是C语言程序的基本单位。
1.2.2.2 函数的一般结构
任何函数(包括main()函数)都是由函数首部和函数体两部分组成。
1. 函数首部: 函数首部即函数第一行,由函数类型、函数名和函数参数表三部分组成。
2. 函数体: 函数体为函数首部下面的花括号{……}内的部分。 函数体一般由声明部分和执行部分构成:声明部分定义所用到的变量,声明所调用的函数等; 执行部分有若干语句组成。
2.6.1 运算符及表达式简介 2.6.1.1 运算符
C语言中的运算符具有2个特点: ⑴ 运算符的优先级 C语言中,运算符的优先级共分为15级,1级最高,15级最低。 ⑵ 运算符的结合性 C语言中各运算符的结合性分为左结合性(从左到右)和右结合性(从右到左)。 2.6.1.2 表达式 表达式是由常量、变量、函数和运算符组成的式子。 表达式求值是按运算符的优先级和结合性规定的顺序进行的。
精品-清华大学C语言课件 第16章04 综合应用
综合应用
本讲大纲
1.编写头文件包含圆面积的计算公式 2.利用宏定义求偶数的和
编写头文件包含圆面积的计算公式
【例16.8】 编写程序,将计算圆面积的宏定义存储在一个头文件中,输入半径便可得到圆的面积。 //main函数中
#include <stdio.h> #include "area.h" void main() {
float r;/*定义浮点型变量,存储圆的半径*/ printf("请输入半径:\n");/*提示用户输入圆的半径*/ scanf("%f",&r);/*接收用户的输入*/ printf("面积 =%.2f\n",Area(r));/*输出圆的面积*/ }
// area.h
#ifndef __AREA_H__ #define __AREA_H__ #define PI 3.14 double Area(float r) { return PI*r*r; } #endif
}程序运行效果如图16.15所示。
图16.15 利用宏定义求偶数和
程序效果如图16.14所示。 图16.14 编写头文件包含圆面积的计算公式
利用宏定义求偶数的和
【例16.9】 编写程序实现利用宏定义求1-100的偶数和,定义一个宏判断一个数是否为偶数。
#include<stdio.h> #define TRUE 1 #define FALSE 0 #define EVEN(x) (((x)%2==0)?TRUE:FALSE) void main() { int sum,i;/*定义整型变量,分别为存储累计和和循环计数变量*/ sum=0;/*给累加和初始化*/ for(i=1;i<=100;i++)/*1-100做循环*/ { if(EVEN(i))/*如果是偶数*/ sum+=i;/*累加*/ } printf("SUM=%d\n",sum);/*输出累加和*/
本讲大纲
1.编写头文件包含圆面积的计算公式 2.利用宏定义求偶数的和
编写头文件包含圆面积的计算公式
【例16.8】 编写程序,将计算圆面积的宏定义存储在一个头文件中,输入半径便可得到圆的面积。 //main函数中
#include <stdio.h> #include "area.h" void main() {
float r;/*定义浮点型变量,存储圆的半径*/ printf("请输入半径:\n");/*提示用户输入圆的半径*/ scanf("%f",&r);/*接收用户的输入*/ printf("面积 =%.2f\n",Area(r));/*输出圆的面积*/ }
// area.h
#ifndef __AREA_H__ #define __AREA_H__ #define PI 3.14 double Area(float r) { return PI*r*r; } #endif
}程序运行效果如图16.15所示。
图16.15 利用宏定义求偶数和
程序效果如图16.14所示。 图16.14 编写头文件包含圆面积的计算公式
利用宏定义求偶数的和
【例16.9】 编写程序实现利用宏定义求1-100的偶数和,定义一个宏判断一个数是否为偶数。
#include<stdio.h> #define TRUE 1 #define FALSE 0 #define EVEN(x) (((x)%2==0)?TRUE:FALSE) void main() { int sum,i;/*定义整型变量,分别为存储累计和和循环计数变量*/ sum=0;/*给累加和初始化*/ for(i=1;i<=100;i++)/*1-100做循环*/ { if(EVEN(i))/*如果是偶数*/ sum+=i;/*累加*/ } printf("SUM=%d\n",sum);/*输出累加和*/
C语言程序设计(上)清华大学出版社PPT课件
"\nluck"
字符串常量的长度 : – 所包含的字符个数
字符串常量的存储方式:
所占存储单元数:串长度+1
例如:
a \0
字符串 结束标记
\n l u c k \0
3. 变量
26
1) 变量的有关概念
在程序运行过程中,其值改变的数据,称
为变量,变量用标识符表示,称为变量名。
变量必须“先定义后使用”
占内存(位) 占内存(字节)
数值范围
有效位数
32
4
3.4E-38~3.4E+38
7
64
8
1.7E-308~1.7E+308
16
80
10
1.2E-493~1.2E+4932
19
35
(2)表示方式。实型常数的表示方式如下。 十进制数:例如6.2,.96,-387.29。 指数形式:例如-2.3E3,-7.5E-3。
007 008 012 010 013 009 011 092 063 039 034 000
40
③字符串常量。字符串常量是由一对双引号 括起来的字符序列。例如:"BOOK",
“$20.5”等都是合法的字符串常量。 ④字符变量。字符变量的取值是字符常量,
即单个字符。字符变量的类型说明符是char。 ⑤符号常量。在C语言中可以用一个标识符
表2.3 字符型数据所占位数
数据类型 类 型 符
有符号字 符型
无符号字 符型
char unsigne
d char
占内 存 ( 位)
8 8
占内存 (字 节)
1 1
数值范围 (ASCII码值)
-128~127(有 符号字符型)
字符串常量的长度 : – 所包含的字符个数
字符串常量的存储方式:
所占存储单元数:串长度+1
例如:
a \0
字符串 结束标记
\n l u c k \0
3. 变量
26
1) 变量的有关概念
在程序运行过程中,其值改变的数据,称
为变量,变量用标识符表示,称为变量名。
变量必须“先定义后使用”
占内存(位) 占内存(字节)
数值范围
有效位数
32
4
3.4E-38~3.4E+38
7
64
8
1.7E-308~1.7E+308
16
80
10
1.2E-493~1.2E+4932
19
35
(2)表示方式。实型常数的表示方式如下。 十进制数:例如6.2,.96,-387.29。 指数形式:例如-2.3E3,-7.5E-3。
007 008 012 010 013 009 011 092 063 039 034 000
40
③字符串常量。字符串常量是由一对双引号 括起来的字符序列。例如:"BOOK",
“$20.5”等都是合法的字符串常量。 ④字符变量。字符变量的取值是字符常量,
即单个字符。字符变量的类型说明符是char。 ⑤符号常量。在C语言中可以用一个标识符
表2.3 字符型数据所占位数
数据类型 类 型 符
有符号字 符型
无符号字 符型
char unsigne
d char
占内 存 ( 位)
8 8
占内存 (字 节)
1 1
数值范围 (ASCII码值)
-128~127(有 符号字符型)
C语言常用宏定义技巧
#define MEM_W(x) (*((uint16 *)(x)))
注:类似于这种有多个字符串组成的宏定义一定要注意加上“()”,因为我们知道宏定义只是一种简单的字符替换功能。
4. 求最大值和最小值:
#define MAX(x,y) (((x)>(y))?(x):(y))
constructor
13. 冒泡排序算法的时间复杂度是什么?
O(n^2)
14. 写出float x 与“零值”比较的if语句。
if(x>0.000001&&x<-0.000001)
16. Internet采用哪种网络协议?该协议的主要层次结构?
tcp/ip 应用层/传输层/网络层/数据链路层/物理层
{
FLOPW(ray,val)
}
else
Hale Waihona Puke { } 8. 得到一个变量的地址:
#define B_PTR(var) ((byte *)(void *)&(var))
#define W_PTR(var) ((word *)(void *)&(var))
C语言常用宏定义技巧
2
推荐 C语言常用宏定义技巧
用C语言编程,宏定义是个很重要的编程技巧。用好了宏定义,它可以增强程序的可读性、可移植性、方便性、灵活性等等。
1. 防止一个头文件被重复包含:
#ifndef COMDEF_H
#define COMDEF_H
#define FLOPW(ray,val) do{ (ray)[0]=((val)/256); (ray)[1] =((val)&0xFF);}while(0)
c语言课件PPT课件
写入文件
使用fprintf函数将数据写入文件 中,按照指定的格式写入。
格式化输入输出
fscanf和fprintf函数支持格式化 输入输出,方便数据的读写。
文件的定位操作(fseek和ftell函数)
1 2
定位文件指针
使用fseek函数将文件指针移动到指定位置。
获取当前文件指针位置
使用ftell函数获取当前文件指针的位置。
先执行一次代码块,然后当条件满足时重复执行。
goto语句
无条件跳转到程序中的指定位置。
示例
使用do-while循环和goto语句实现一个简单的菜单选择系统。
04 函数和宏定义
函数的定义和调用
总结词
函数的定义和调用是C语言中非常重要的概念,它们允许我们将代码块组织在 一起,并在需要时多次调用它。
详细描述
VS
详细描述
宏定义使用`#define`指令来定义常量、 宏函数或条件编译指令。宏定义在预处理 阶段被替换为相应的值或代码块。文件包 含指令使用`#include`来包含其他文件的 内容,通常用于引入库的头文件或共享代 码。这些预处理指令可以帮助我们减少代 码重复和提高代码的可维护性。
05 数组和字符串
结合性是指相同优先级的运算符在表 达式中的结合方向,决定了运算符的 执行顺序。
03 控制结构
if语句和条件运算符
01
02
03
if语句
用于根据条件执行不同的 代码块。
条件运算符
也称为三目运算符,用于 简化if-else语句。
示例
判断一个数是否为正数、 负数或零。
switch语句和枚举类型
switch语句
字符串函数
C语言提供了一系列字符串函数,用于 对字符串进行操作,如连接、比较、 查找等。
C语言程序设计 16-枚举、预处理等汇总
带参的宏定义在分析程序之前先进行宏展开, S(a+b,c+d)展开时用a+b代替x,用c+d代替y, 展开的结果为:a+b*c+d
24
带参的宏定义使用举例
#define S(x,y) x*y main() { int a=3,b=4,c=5,d=6;
printf("a*b=%d\n", S (aa*b, b ) ) ; printf("a+b*c+d=%d\n" , S(a((+ab+)b*()c,(+cd+)d))));; }
enum weekday day; (2) enum weekday {Sun,Mon,Tue} day; (3) enum {Sun,Mon,Tue} day;
12
三、枚举型变量的使用
1)可对枚举变量赋值,但只能把枚举元素名赋给 枚举变量,不能把枚举元素值直接赋给枚举变量。 如: enum weekday {Sun,Mon, Tue, Wed, Thu,
10
一、枚举类型的定义
• 枚举元素的值也可在定义时重指定。例如: enum weekday {Sun=7,Mon=1, Tue, Wed, Thu,
Fri, Sat} ; 对于没有指定值的元素,按顺序加1,故: Tue是2,Wed是3,…,Sat是6。
11
二、枚举型变量的定义 枚举型变量的定义也有三种方式,如: (1) enum weekday { Sun,Mon,Tue };
3)可用枚举变量进行判断或比较操作。 enum flag {true,false} my_flag; … if (my_flag == true)
24
带参的宏定义使用举例
#define S(x,y) x*y main() { int a=3,b=4,c=5,d=6;
printf("a*b=%d\n", S (aa*b, b ) ) ; printf("a+b*c+d=%d\n" , S(a((+ab+)b*()c,(+cd+)d))));; }
enum weekday day; (2) enum weekday {Sun,Mon,Tue} day; (3) enum {Sun,Mon,Tue} day;
12
三、枚举型变量的使用
1)可对枚举变量赋值,但只能把枚举元素名赋给 枚举变量,不能把枚举元素值直接赋给枚举变量。 如: enum weekday {Sun,Mon, Tue, Wed, Thu,
10
一、枚举类型的定义
• 枚举元素的值也可在定义时重指定。例如: enum weekday {Sun=7,Mon=1, Tue, Wed, Thu,
Fri, Sat} ; 对于没有指定值的元素,按顺序加1,故: Tue是2,Wed是3,…,Sat是6。
11
二、枚举型变量的定义 枚举型变量的定义也有三种方式,如: (1) enum weekday { Sun,Mon,Tue };
3)可用枚举变量进行判断或比较操作。 enum flag {true,false} my_flag; … if (my_flag == true)
C语言(清华大学出版社)ppt课件
结构。 (4)具有结构化的控制语句 ,是完全模块化
和结构化的语言。 (5)语法限制不太严格,程序设计自由度大。
C程序设计(第三版)
C语言的特点
(6)允许直接访问物理地址,能进行位操 作,能实现汇编语言的大部分功能,可直接 对硬件进行操作。兼有高级和低级语言 的特点 。
(7)目标代码质量高,程序执行效率高。 只比汇编程序成的目标代码效率低10 %-20%。
C程序设计(第三版)
算法如下 :
S1:输入n
S2:i=2
(i作为除数)
S3:n被i除,得余数r
S4:如果r=0,表示n能被i整除,则打印n“不 是素数”,算法结束。否则执行S5
S5:i+1→i
S6:如果i≤n-1,返回S3。否则打印 n “是素
实际上,n不必被2到(n-1)的整数除,只需 被2到n/2间整数除,甚至只需被2到 之n 间的 整数除即可。
C程序设计(第三版)
说明: 本程序的作用是输出一行信息:
1.3 简单的C语Th言is程i序s a介C绍program.
#include <stdio.h>
/*文件包含*/
main( )
/*主函数 */
{
/*函数体开始*/
printf ("This is a C program.\n"); /*输出语句*/
(8)程序可移植性好(与汇编语言比)。基 本上不做修改就能用于各种型号的计算 机和各种操作系统。
C程序设计(第三版)
1.2 C语言的特点
问题:既然有了面向对象的C++语言,为 什么还要学习C语言?
解释1:C++是由于开发大型应用软件的需 要而产生的,并不是所有的人都要去编 写大型软件。
和结构化的语言。 (5)语法限制不太严格,程序设计自由度大。
C程序设计(第三版)
C语言的特点
(6)允许直接访问物理地址,能进行位操 作,能实现汇编语言的大部分功能,可直接 对硬件进行操作。兼有高级和低级语言 的特点 。
(7)目标代码质量高,程序执行效率高。 只比汇编程序成的目标代码效率低10 %-20%。
C程序设计(第三版)
算法如下 :
S1:输入n
S2:i=2
(i作为除数)
S3:n被i除,得余数r
S4:如果r=0,表示n能被i整除,则打印n“不 是素数”,算法结束。否则执行S5
S5:i+1→i
S6:如果i≤n-1,返回S3。否则打印 n “是素
实际上,n不必被2到(n-1)的整数除,只需 被2到n/2间整数除,甚至只需被2到 之n 间的 整数除即可。
C程序设计(第三版)
说明: 本程序的作用是输出一行信息:
1.3 简单的C语Th言is程i序s a介C绍program.
#include <stdio.h>
/*文件包含*/
main( )
/*主函数 */
{
/*函数体开始*/
printf ("This is a C program.\n"); /*输出语句*/
(8)程序可移植性好(与汇编语言比)。基 本上不做修改就能用于各种型号的计算 机和各种操作系统。
C程序设计(第三版)
1.2 C语言的特点
问题:既然有了面向对象的C++语言,为 什么还要学习C语言?
解释1:C++是由于开发大型应用软件的需 要而产生的,并不是所有的人都要去编 写大型软件。
c语言讲义(国立清华大学)
• 宣告過結構之後可以用它來定義變數 struct t_point pt; • 所以 pt 會包含 x 以及 y 兩個成員,可以使 用 . 來存取它們 pt.x = 10; pt.y = 20;
什麼是 C 結構 (C Structure)
• 已經宣告過的結構可以再拿來宣告另一個結構 struct t_rect { struct t_point pt1; struct t_point pt2; }; • 然後用它來產生變數,以及存取成員 struct t_rect screen; screen.pt1.x = 10;
C 結構
什麼是 C 結構 (C Structure)
• 結構是多個相關的變數的集合,用一個共 同的名稱來統稱 • 要描述平面上的點座標,若使用結構則可 以自定一個叫做 t_point 的資料型態,寫成 struct t_point { int x; int y; };做運算
• 結構可以使用的運算元只有 =、&、. • 其他的運算則必須自己寫函數來達到我們 想要的功能
結構參數的傳遞方式
• 傳遞結構變數到函數,會用 call-by-value 的方式 • 結構同樣可以用指標方式來達到 call-byreference 的效果 • 可以使用 typedef 宣告新的型別名稱,這 樣接下來宣告變數會比較方便 typedef struct t_point Point; Point pt;
什麼是 C 結構 (C Structure)
• 已經宣告過的結構可以再拿來宣告另一個結構 struct t_rect { struct t_point pt1; struct t_point pt2; }; • 然後用它來產生變數,以及存取成員 struct t_rect screen; screen.pt1.x = 10;
C 結構
什麼是 C 結構 (C Structure)
• 結構是多個相關的變數的集合,用一個共 同的名稱來統稱 • 要描述平面上的點座標,若使用結構則可 以自定一個叫做 t_point 的資料型態,寫成 struct t_point { int x; int y; };做運算
• 結構可以使用的運算元只有 =、&、. • 其他的運算則必須自己寫函數來達到我們 想要的功能
結構參數的傳遞方式
• 傳遞結構變數到函數,會用 call-by-value 的方式 • 結構同樣可以用指標方式來達到 call-byreference 的效果 • 可以使用 typedef 宣告新的型別名稱,這 樣接下來宣告變數會比較方便 typedef struct t_point Point; Point pt;
C语言宏定义(高级篇)PPT课件
在软件开发过程中需要定制各种小工具在软件开发过程中需要定制各种小工具实现模块公共功能的复用和易用其中编码实现模块公共功能的复用和易用其中编码过程中的过程中的bugbug调试工具就是非常重要的一种调试工具就是非常重要的一种类型
Special Issue for HITMath-07
补充(三) 宏 编程 —— #define
& 常用调试技巧
Macro Programming Using #define &
General Debug Technology
1
内容简介
本部分将主要讲解C++中宏定义的 应用——如何利用宏来简化程序设计, 实现代码级的简化、封装、重用等。
2
简单常量的定义
#define N 1000
定义简单的常量,便于修改。 切不可在后面加上分号! 等效于 const int N = 1000; 仅是简单替换,而不是作为一个量来使用。
则,IW3DScene* pScene = MAKE_COMPONENT( Scene ); 将被理解为:
pScene = ((IW3DScene *)MakeComponent("Scene");
8
宏定义举例(二)
#define IMPLEMENT_COMPONENT( I, C )
\
static IComponent* Component_Factory_##C() \
// …
void Draw() {
// … } // Draw
private: DWORD m_dwFogColor; ///< Fog color
// … }; //class CW3DCamera
Special Issue for HITMath-07
补充(三) 宏 编程 —— #define
& 常用调试技巧
Macro Programming Using #define &
General Debug Technology
1
内容简介
本部分将主要讲解C++中宏定义的 应用——如何利用宏来简化程序设计, 实现代码级的简化、封装、重用等。
2
简单常量的定义
#define N 1000
定义简单的常量,便于修改。 切不可在后面加上分号! 等效于 const int N = 1000; 仅是简单替换,而不是作为一个量来使用。
则,IW3DScene* pScene = MAKE_COMPONENT( Scene ); 将被理解为:
pScene = ((IW3DScene *)MakeComponent("Scene");
8
宏定义举例(二)
#define IMPLEMENT_COMPONENT( I, C )
\
static IComponent* Component_Factory_##C() \
// …
void Draw() {
// … } // Draw
private: DWORD m_dwFogColor; ///< Fog color
// … }; //class CW3DCamera
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
5*(a)*(b)+(b)
而本意是希望得到:
5*((a)*(b)+(b))
解决的办法就是上面说的宏扩展时加上括号就能避免这种错误发生。
对带参数的宏的展开只是将语句中的宏名后面括号内的实参字符串代替#define命令行中的形参。 在宏定义时,在宏名与带参数的括号之间不可以加空格,否则将空格以后的字符都作为替代字符串的 一部分。
#include<stdio.h> #define TEST "this is an example" main() { printf(TEST); #undef TEST }
宏定义用于预处理命令,它不同于定义的变量,只作字符替换,不分配内存空间。
,还要进行参数替换。一般形式如下: #define 宏名(参数表)字符串 【例16.1】 对两个数实现乘法加法混合运算。
对于带参数的宏定义有以下几点需要强调:
宏定义时参数要加括号,如不加括号,有时结果是正确的,有时结果便是错误的,那么什么时候是正 确的,什么时候是错误的,下面具体说下:
如实例16.1当参数x=10,y=9时,在参数不加括号的情况下调用MIX(x,y),可以正确的输出结果;当 x=10,y=3+4时,在参数不加括号的情况下调用MIX(x,y),则输出的结果是错误的,因为此时调用的 MIX(x,y)执行情况如下:
#define 宏名 字符串
“#”表示这是一条预处理命令。 宏名是一个标识符,必须符合C语言标识符的规定。 字符串这里可以是常数、表达式、格式字符串等。 例如:
#define PI 3.14159
它的作用是在该程序中用PI替代3.14159,在编译预处理时,每当在源程序中遇到PI就自动用 3.14159代替。
#include<stdio.h> #define TEST "this is an example" void main() { char exp[30]="This TEST is not that TEST";/*定义字符数组并赋初值*/ printf("%s\n",exp); }
该段代码输入结果如图16.1所示:
编译程序遇到标识符STANDARD时,就用"You are welcome to join us."替换。 对于编译程序,printf()语句如下形式是等效的:
printf("possible use of ‘i’ before definition in function main");
关于不带参数的宏定义有以下几点要强调下: 如果在串中含有宏名,则不进行替换。 例如:
宏定义
本讲大纲
1.不带参数的宏定义 2.带参数的宏定义 实例1 不带参数的宏定义求平行四边形面积 实例2 使用宏定义实现数组值的互换
不带参数的宏定义
宏定义指令#define用来定义一个标识符和一个字符串,以这个标识符来代表这个字符串,在程序 中每次遇到该标识符时就用所定义的字符串替换它。它的作用相当于给指定的字符串起一个别名。 不带参数的宏定义一般形式如下:
使用#define进行宏定义的好处是需要改变一个常量的时候只需改变#define命令行,整个程序的常 量都会改变,大大的提高了程序的灵活性。
宏名要简单且意义明确,一般习惯用大写字母表示以便与变量名相区别。 注意: 宏定义不是C语句,不需要在行末加分号。
宏名定义后,即可成为其它宏名定义中的一部分。例如,下面代码定义了正方形的边长SIDE、周长 PERIMETER及面积AREA的值。
试定义一个带参的宏swap(a,b),以实现两个整数之间的交换,并利用它将一维数组a和b的值进行 交换。
#include <stdio.h> #define swap(a,b) {int c;c=a;a=b;b=c;}/*定义一个带参的宏swap*/ int main() { int i, j, a[10], b[10];/*定义数组及变量为基本整型*/ printf("请输入一个数组a:\n"); for (i = 0; i < 10; i++) scanf("%d", &a[i]);/*输入一组数据存到数组a中*/ printf("请输入一个数组b:\n"); for (j = 0; j < 10; j++) scanf("%d", &b[j]);/*输入一组数据存到数组b中*/ printf("\n数组a是:\n"); for (i = 0; i < 10; i++) printf("%d,", a[i]);/*输出数组a中的内容*/ printf("\n数组b是:\n"); for (j = 0; j < 10; j++) printf("%d,", b[j]);/*输出数组b中的内容*/ for (i = 0; i < 10; i++) swap(a[i], b[i]);/*实现数组a与数组b对应值互换*/ printf("\n现在数组a是:\n"); for (i = 0; i < 10; i++) printf("%d,", a[i]);/*输出互换后数组a中的内容*/ printf("\n现在数组b是:\n"); for (j = 0; j < 10; j++) printf("%d,", b[j]);/*输出互换后数组b中的内容*/ puts(""); return 0; }
程序运行结果如图16.2所示:
图16.2 混合运算
当编译该程序时,由MIX(a,b)定义的表达式被替换,x和y用作操作数,即printf()语句被替换后取如 下形式:
printf("the min number is: %d",((a)*(b)+(b)));
用宏替换实在的函数的一个好处是宏替换增加了代码的速度,因为不存在函数调用。但增加速度也有 代价:由于重复编码而增加了程序长度。
在带参宏定义中,形式参数不分配内存单元,因此不必作类型定义。
实例1 不带参数的宏定义求平行 四边形面积
利用不带参数的宏定义求平行四边形的面积,平行四边形的面积=底边×高。将平行四边形的底边 和高设置为宏的形式(一般宏名都是大写字母,以便与其他的操作符区别)。
#include <stdio.h> #define A 8/*定义宏,设置底边的长度*/ #define H 6/*定义宏,设置高的长度*/ void main() {
#define SIDE 5 #define PERIMETER 4*SIDE #define AREA SIDE*SIDE
前面强调过宏替换是以串代替标识符这点。因此,如果希望定义一个标准的邀请语,可编写如下 代码:
#define STANDARD "You are welcome to join us." printf(STANDARD);
运行程序,显示效果如图16.4所示。 图16.4 用宏定义实现值互换
Thank you
(10*3+4+3+4);
此时计算出的结果是41,而实际上希望得出的结果是77,所以为了避免出现上面这种情况,在进行宏 定义时要在参数外面要加上括号。
宏扩展必须使用括号,来保护表达式中低优先级的操作符,以便确保调用时达到想要的效果。
如果例16.1宏扩展外没有加括号,则调用:
5*MIX(x,y)
则会被扩展为:
int AREA;/*定义整形变量,存储平行四边形面积*/ AREA=A * H;/*计算平行四边形面积*/ printf("AREA = %d\n",AREA);/*输出面积值*/
}运行程序,显示效果如图16.3所示。
图16.3 不带参数的宏定义求平行四边形面积
实例2 使用宏定义实现数组值的互换
#include<stdio.h> #define MIX(a,b) ((a)*(b)+(b))/*宏定义求两个数的混合运算*/ void main() { int x=5,y=9; printf("x,y:\n"); printf("%d,%d\n",x,y); printf("the min number is:%d\n",MIX(x,y)); /*宏定义调用*/ }
注意上面程序字符串中的TEST并没有用“this is an example”来替换,所以说如果串中含有宏名, 则不进行替换。
如果串长于一行,可以在该行末尾用一反斜杠“\”续行。 #define命令出现在程序中函数的外面,宏名的有效范围为定义命令之后到此源文件结束。 注意: 在编写程序时通常将所有的#define放到文件的开始处或独立的文件中,而不是将它们分散到整个程序 中。 可以用#undef命令终止宏定义的作用域。
而本意是希望得到:
5*((a)*(b)+(b))
解决的办法就是上面说的宏扩展时加上括号就能避免这种错误发生。
对带参数的宏的展开只是将语句中的宏名后面括号内的实参字符串代替#define命令行中的形参。 在宏定义时,在宏名与带参数的括号之间不可以加空格,否则将空格以后的字符都作为替代字符串的 一部分。
#include<stdio.h> #define TEST "this is an example" main() { printf(TEST); #undef TEST }
宏定义用于预处理命令,它不同于定义的变量,只作字符替换,不分配内存空间。
,还要进行参数替换。一般形式如下: #define 宏名(参数表)字符串 【例16.1】 对两个数实现乘法加法混合运算。
对于带参数的宏定义有以下几点需要强调:
宏定义时参数要加括号,如不加括号,有时结果是正确的,有时结果便是错误的,那么什么时候是正 确的,什么时候是错误的,下面具体说下:
如实例16.1当参数x=10,y=9时,在参数不加括号的情况下调用MIX(x,y),可以正确的输出结果;当 x=10,y=3+4时,在参数不加括号的情况下调用MIX(x,y),则输出的结果是错误的,因为此时调用的 MIX(x,y)执行情况如下:
#define 宏名 字符串
“#”表示这是一条预处理命令。 宏名是一个标识符,必须符合C语言标识符的规定。 字符串这里可以是常数、表达式、格式字符串等。 例如:
#define PI 3.14159
它的作用是在该程序中用PI替代3.14159,在编译预处理时,每当在源程序中遇到PI就自动用 3.14159代替。
#include<stdio.h> #define TEST "this is an example" void main() { char exp[30]="This TEST is not that TEST";/*定义字符数组并赋初值*/ printf("%s\n",exp); }
该段代码输入结果如图16.1所示:
编译程序遇到标识符STANDARD时,就用"You are welcome to join us."替换。 对于编译程序,printf()语句如下形式是等效的:
printf("possible use of ‘i’ before definition in function main");
关于不带参数的宏定义有以下几点要强调下: 如果在串中含有宏名,则不进行替换。 例如:
宏定义
本讲大纲
1.不带参数的宏定义 2.带参数的宏定义 实例1 不带参数的宏定义求平行四边形面积 实例2 使用宏定义实现数组值的互换
不带参数的宏定义
宏定义指令#define用来定义一个标识符和一个字符串,以这个标识符来代表这个字符串,在程序 中每次遇到该标识符时就用所定义的字符串替换它。它的作用相当于给指定的字符串起一个别名。 不带参数的宏定义一般形式如下:
使用#define进行宏定义的好处是需要改变一个常量的时候只需改变#define命令行,整个程序的常 量都会改变,大大的提高了程序的灵活性。
宏名要简单且意义明确,一般习惯用大写字母表示以便与变量名相区别。 注意: 宏定义不是C语句,不需要在行末加分号。
宏名定义后,即可成为其它宏名定义中的一部分。例如,下面代码定义了正方形的边长SIDE、周长 PERIMETER及面积AREA的值。
试定义一个带参的宏swap(a,b),以实现两个整数之间的交换,并利用它将一维数组a和b的值进行 交换。
#include <stdio.h> #define swap(a,b) {int c;c=a;a=b;b=c;}/*定义一个带参的宏swap*/ int main() { int i, j, a[10], b[10];/*定义数组及变量为基本整型*/ printf("请输入一个数组a:\n"); for (i = 0; i < 10; i++) scanf("%d", &a[i]);/*输入一组数据存到数组a中*/ printf("请输入一个数组b:\n"); for (j = 0; j < 10; j++) scanf("%d", &b[j]);/*输入一组数据存到数组b中*/ printf("\n数组a是:\n"); for (i = 0; i < 10; i++) printf("%d,", a[i]);/*输出数组a中的内容*/ printf("\n数组b是:\n"); for (j = 0; j < 10; j++) printf("%d,", b[j]);/*输出数组b中的内容*/ for (i = 0; i < 10; i++) swap(a[i], b[i]);/*实现数组a与数组b对应值互换*/ printf("\n现在数组a是:\n"); for (i = 0; i < 10; i++) printf("%d,", a[i]);/*输出互换后数组a中的内容*/ printf("\n现在数组b是:\n"); for (j = 0; j < 10; j++) printf("%d,", b[j]);/*输出互换后数组b中的内容*/ puts(""); return 0; }
程序运行结果如图16.2所示:
图16.2 混合运算
当编译该程序时,由MIX(a,b)定义的表达式被替换,x和y用作操作数,即printf()语句被替换后取如 下形式:
printf("the min number is: %d",((a)*(b)+(b)));
用宏替换实在的函数的一个好处是宏替换增加了代码的速度,因为不存在函数调用。但增加速度也有 代价:由于重复编码而增加了程序长度。
在带参宏定义中,形式参数不分配内存单元,因此不必作类型定义。
实例1 不带参数的宏定义求平行 四边形面积
利用不带参数的宏定义求平行四边形的面积,平行四边形的面积=底边×高。将平行四边形的底边 和高设置为宏的形式(一般宏名都是大写字母,以便与其他的操作符区别)。
#include <stdio.h> #define A 8/*定义宏,设置底边的长度*/ #define H 6/*定义宏,设置高的长度*/ void main() {
#define SIDE 5 #define PERIMETER 4*SIDE #define AREA SIDE*SIDE
前面强调过宏替换是以串代替标识符这点。因此,如果希望定义一个标准的邀请语,可编写如下 代码:
#define STANDARD "You are welcome to join us." printf(STANDARD);
运行程序,显示效果如图16.4所示。 图16.4 用宏定义实现值互换
Thank you
(10*3+4+3+4);
此时计算出的结果是41,而实际上希望得出的结果是77,所以为了避免出现上面这种情况,在进行宏 定义时要在参数外面要加上括号。
宏扩展必须使用括号,来保护表达式中低优先级的操作符,以便确保调用时达到想要的效果。
如果例16.1宏扩展外没有加括号,则调用:
5*MIX(x,y)
则会被扩展为:
int AREA;/*定义整形变量,存储平行四边形面积*/ AREA=A * H;/*计算平行四边形面积*/ printf("AREA = %d\n",AREA);/*输出面积值*/
}运行程序,显示效果如图16.3所示。
图16.3 不带参数的宏定义求平行四边形面积
实例2 使用宏定义实现数组值的互换
#include<stdio.h> #define MIX(a,b) ((a)*(b)+(b))/*宏定义求两个数的混合运算*/ void main() { int x=5,y=9; printf("x,y:\n"); printf("%d,%d\n",x,y); printf("the min number is:%d\n",MIX(x,y)); /*宏定义调用*/ }
注意上面程序字符串中的TEST并没有用“this is an example”来替换,所以说如果串中含有宏名, 则不进行替换。
如果串长于一行,可以在该行末尾用一反斜杠“\”续行。 #define命令出现在程序中函数的外面,宏名的有效范围为定义命令之后到此源文件结束。 注意: 在编写程序时通常将所有的#define放到文件的开始处或独立的文件中,而不是将它们分散到整个程序 中。 可以用#undef命令终止宏定义的作用域。