资源预览内容
第1页 / 共23页
第2页 / 共23页
第3页 / 共23页
第4页 / 共23页
第5页 / 共23页
第6页 / 共23页
第7页 / 共23页
第8页 / 共23页
第9页 / 共23页
第10页 / 共23页
亲,该文档总共23页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第第1313章章 编译预处理和动态编译预处理和动态 存储分配存储分配 高级语言高级语言的源程序的源程序 编译、编译、连接连接 目标代码。目标代码。 编译预处理编译预处理 上机过程:上机过程:13.1 编译预处理编译预处理 在在C编译程序对源程序进行编译前,由编译预处理编译程序对源程序进行编译前,由编译预处理程序对预处理命令行程序对预处理命令行( 以以#号开始的预处理命令行号开始的预处理命令行 )进行进行处理处理, 然后对预处理后的源程序进行编译、连接,产生然后对预处理后的源程序进行编译、连接,产生可执行的目标代码。可执行的目标代码。 C主要提供三种预处理命令主要提供三种预处理命令: 宏定义、文件包含宏定义、文件包含和和条件编译。本章重点介绍前两种。条件编译。本章重点介绍前两种。1. 宏定义宏定义(宏替换宏替换) 有两种:不带参数宏定义和带参数宏定义。有两种:不带参数宏定义和带参数宏定义。 (1) 不带参数宏定义形式不带参数宏定义形式 define 宏名宏名 替换文本替换文本其中:其中:宏名宏名 是用户定义的标识符。是用户定义的标识符。 替换文本替换文本 是字符串。是字符串。作用:编译预处理程序对源程序中所有表示宏名的标作用:编译预处理程序对源程序中所有表示宏名的标 识符用字符串来替换。识符用字符串来替换。例如:例如:#define N 100编译预处理程序对源程序中所有编译预处理程序对源程序中所有N用用100替换。替换。例:例:使用不带参数的宏定义。使用不带参数的宏定义。 #define N 10 void main() int aN,i; for(i=0;iN;i+)ai=i* *i; for(i=0;iy?x:yvoid main ( ) int i ,j ,k; i=5; j=10; k=10* *M(i, j); /* 展开:展开:k=10*510?5:10; */ printf (“%dn”,k) 说明:说明:1)调用带参数的宏时,实参与形参的个数应相同。调用带参数的宏时,实参与形参的个数应相同。 2)实参可以是常量、变量或表达式形式。实参可以是常量、变量或表达式形式。3)带参数宏替换与函数调用有类似之处,但前者对参带参数宏替换与函数调用有类似之处,但前者对参 数没有类型的要求。数没有类型的要求。4)宏替换中,实参不能替换双引号中的形参。宏替换中,实参不能替换双引号中的形参。5)与不带参数的宏定义一样,同一个宏名不能重复定与不带参数的宏定义一样,同一个宏名不能重复定 义。义。(3) 终止宏定义形式终止宏定义形式 #undef 已定义宏名已定义宏名例如:例如: #define PI 3.14159 main( ) #undef PI从终止宏定义从终止宏定义(#undef PI)后后PI无定义,不代表无定义,不代表3.14159了。了。使用宏定义的优势:使用宏定义的优势: 1) 宏替换不占程序运行时间,只占编译时间。宏替换不占程序运行时间,只占编译时间。 2) 便于阅读便于阅读 3) 修改方便修改方便注意:注意: 宏定义最后没有宏定义最后没有“ ;” 。2. 文件包含文件包含 就就是是在在一一个个文文件件中中,将将已已有有的的另另外外一一个个文文件件的的全全部部内容包含进来。内容包含进来。 由于由于C的库函数很多,将这些函数根据类型不同分的库函数很多,将这些函数根据类型不同分类类, 分别放在不同的文件中分别放在不同的文件中(例如例如, 数学函数:数学函数:math.h 、输入、输入/出:出: stdio.h 、 字符函数:字符函数: ctype.h 、字符串:、字符串:string.h 、动态分配:、动态分配:malloc.h 其它:其它:tdlib.h 。),编程时,使用哪个文件中的函数编程时,使用哪个文件中的函数, 将该文件用文件包含将该文件用文件包含的形式,写在程序的前面的形式,写在程序的前面。 C语言提供了语言提供了#include 命令行,命令行, 实现实现“文件包含文件包含”功功能,其一般形式为能,其一般形式为: #include “文件名文件名” 或或 #include 编译预程序将用指定的文件中的内容替换此命令行。编译预程序将用指定的文件中的内容替换此命令行。 如果文件名用双引号括起来时,系统先在用户当前如果文件名用双引号括起来时,系统先在用户当前目录查找要包含的文件,若找不到,再按标准方式(系目录查找要包含的文件,若找不到,再按标准方式(系统指定的目录)查找;如果文件名用尖括号括起来时,统指定的目录)查找;如果文件名用尖括号括起来时,按标准方式查找。按标准方式查找。说明:说明:1) #include 命令行的位置一般写在源程序的开头,文命令行的位置一般写在源程序的开头,文 件名后缀不一定是件名后缀不一定是“.h”。2) 包含文件包含文件(头文件头文件)中,可包含一些中,可包含一些 #define 命令行、命令行、 外部说明或对库函数的原形说明。外部说明或对库函数的原形说明。例例: 将格式宏做成头文件将格式宏做成头文件format.h 。 头文件头文件format.h内容如下:内容如下:#define PR printf#define NL “n”#define D “%dn”#define S “%s”主文件主文件 file1.c 内容如下:内容如下:#include #include void main ( ) int a=2 ,b=4; char st =“CHINA”; PR(D,a); /* 展开:展开:printf(“%dn”,a) */ PR(D,b); /* 展开:展开:printf(“%dn”,b) */ PR(S,st); /* 展开:展开:printf(“%s”,st) */ PR(NL); /* 展开:展开:printf(“n”) */ 3)3)当当包含文件包含文件(头文件头文件)修改后,对包含头文件的源程序修改后,对包含头文件的源程序 必须重进行编译连接。必须重进行编译连接。4)4)在在一个程序中允许有多个一个程序中允许有多个#include 命令行。命令行。5)5)在在包含文件包含文件(头文件头文件)中还可以其他文件。中还可以其他文件。 例:例:在在包含文件包含文件(头文件头文件) file2.h中包含文件中包含文件file3.h 。 见下面图示:见下面图示: file1.c file2.h file3.h #include “file2.h ” #include “file3.h ” 不含不含#include命命令行令行 例:例:文件包含的程序。文件包含的程序。#include #include#include void main() float x,y; char s1 =”book”,s220; x=1.5; y=sqrt(12*a)+sin(a*3.1416/180); strcpy(s2,s1); printf(“%fn”,y); printf(“%sn”,s2); 说明:说明:包含文件也可以是包含文件也可以是自己自己编的一些函数,放在一编的一些函数,放在一个文件中个文件中,使用时只要,使用时只要在程序前部包含进去,在程序前部包含进去,文件中的函数可以在程文件中的函数可以在程序中调用,节省程序开序中调用,节省程序开发时间。发时间。3. 条件编译条件编译 有有条条件件的的对对源源程程序序的的某某部部分分进进行行编编译译,减减少少目目标标代代码的存储空间。有三种形式:码的存储空间。有三种形式:形式形式1: #ifdef 标识符标识符 程序段程序段1 #else 程序段程序段2 #endif 标识符标识符 #define 定义过,则程序段定义过,则程序段1被编译,否则被编译,否则,程序段,程序段2被编译。被编译。可选可选形式形式2: #ifndf 标识符标识符 程序段程序段1 #else 程序段程序段2 #endif 标识符没用标识符没用#define 定义过,则程序段定义过,则程序段1被编译,被编译,否则,程序段否则,程序段2被编译。被编译。 形式形式3: #if 表达式表达式 程序段程序段1 #else 程序段程序段2 #endif 表达式为非表达式为非0,则程序段,则程序段1被编译,否则,程序段被编译,否则,程序段2被编译。被编译。13.2 动态存储分配动态存储分配 在程序执行期间根据需要可动态分配存储空间在程序执行期间根据需要可动态分配存储空间,不不用时可释放。用时可释放。C语言提供的四个标准函数:语言提供的四个标准函数:malloc 、calloc 、free 和和 realloc 可实现前述功能。可实现前述功能。1. malloc函数和函数和free函数函数(1) malloc函数调用形式函数调用形式 malloc(size);其中其中: size 它的类型为它的类型为unsinged int 。功能:分配功能:分配size个字节存储间。返回指向存储空间首地个字节存储间。返回指向存储空间首地 址的基类型为址的基类型为void的地址。若分配的存储空间不的地址。若分配的存储空间不 足,函数返回空足,函数返回空(NULL)。(2) free函数调用形式函数调用形式 free(P);其中其中: P 类型为指针变量,指向动态分配的地址。类型为指针变量,指向动态分配的地址。功能:将指针功能:将指针P所指的存储空间释放。所指的存储空间释放。(无函数返回值无函数返回值)例例: 函数函数malloc和和free的使用。的使用。 short int *pi; float *pf; pi=(short *)malloc(2); /*pi指向指向short int 2个字节地址个字节地址*/ pf=(float *)malloc(4); /*pf指向指向float 4个字节地址个字节地址*/ free(Pi); /* 释放指针释放指针Pi所指的存储空间所指的存储空间 */ free(Pf); /* 释放指针释放指针Pf所指的存储空间所指的存储空间 */ 在申请动态存储空间时,若不能确定数据类型所在申请动态存储空间时,若不能确定数据类型所占字节数,可以使用占字节数,可以使用sizeof运算符来求得。运算符来求得。例如:例如: short int *pi; float *pf; pi=(int *)malloc( sizeof(int) ); pf=(float *)malloc( sizeof(float) );这是一种常用的形式。这是一种常用的形式。2. calloc函数函数 调用形式调用形式: calloc(n,size);其中其中: n,size 类型均为类型均为unsinged int 。功能:给功能:给n个同一类型长度为个同一类型长度为size个字节的数据项分配个字节的数据项分配 连续存储空间。连续存储空间。若分配成功,返回存储空间的首地址,否则返回空。若分配成功,返回存储空间的首地址,否则返回空。例例: 函数函数calloc的使用。的使用。 char *ps; ps=(char *)calloc(10,sizeof(char) ); free(ps); /* 释放指针释放指针Ps所指的存储空间所指的存储空间 */分配分配10个连续的个连续的char类型的存储单元,类型的存储单元, ps指向存储单指向存储单元的首地址。元的首地址。
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号