9-预处理和动态存储

上传人:dja****22 文档编号:243021095 上传时间:2024-09-14 格式:PPT 页数:39 大小:135KB
返回 下载 相关 举报
9-预处理和动态存储_第1页
第1页 / 共39页
9-预处理和动态存储_第2页
第2页 / 共39页
9-预处理和动态存储_第3页
第3页 / 共39页
点击查看更多>>
资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,C Programming Language,39,专题之九,编译预处理和动态存储管理,1,考纲分析,编译预处理,1、 宏定义:不带参数的宏定义;带参数的宏定义。,2、 文件包含处理。,分析:这部分主要讨论了预编译,一般会出,1-2,个选择题和,1-2,个填空题。,这部分好掌握,明确两条:,1,、宏定义,#define,后面的就直接带入,再计算。,2,、头文件中的,ifndef/define/endif,的作用是,防止该头文件,被重复引用。,C,语言的预处理程序负责分析和处理以,“#”,为首字符的预处理控制行。预处理是在编译前进行的,。,C,提供的预处理功能主要有以下三种:,1.,宏定义,2.,文件包含,3.,条件编译,分别用宏定义命令、文件包含命令、条件编译命令来实现。,为了与一般,C,语句相区别,这些命令以符号,“,#”,开头。,历年真题必学,真题1:下列程序的功能是:给r输入数据后计算半径为r的圆面积s。程序在编译时出错。【2005.9】,main(), int r; float s;,scanf(%d,s=*r*r;,printf(s=%fn,s);,出错的原因是( )。,A)注释语句书写位置错误,B)存放圆半径的变量r不应该定义为整型,C)输出语句中格式描述符非法,D)计算因面积的赋值语句中使用了非法变量,真题2:下列4个程序中,完全正确的是( )。【2006.4】,A)#include B)#include ,main( ); main( ),/*programming*/ /*/programming/*/,printf(programming! n); printf(programming! n);,C)#include D)include ,main( ) main( ),/* / programming*/ */ /* programming*/,printf(programming! n); printf(programming! n);,真题3:以下叙述中错误的是( )。【2008.4】,A)在程序中凡是以“#”开始的语句行都是预处理命令行,B)预处理命令行的最后不能以分号表示结束,C)#define MAX是合法的宏定义命令行,D)C程序对预处理命令行的处理是在程序执行的过程中进行的,1 宏定义(,宏替换,),1.1 不带参数的宏定义,简单的字符串替换,一般形式,#define,宏名,字符串,通常,“,宏名,(宏标识符)”,用大写字母表示,用空格分开,,末尾不带“;”,以换行符结束。,define预处理命令不仅可以定义,符号常量,及,字符串,,而且也可以定义,带参数的宏,。,例,#define,PI,3.1415926,main(),float i,s,r,v;,printf(input raDiuS);,scanf(%f,,i=2.0*,PI,*r;,s=,PI,*r*r;,v=3.0/4*,PI,*r*r*r;,printf(l=%10.4fnS=%10.4fnv=%10.4fn,i,s,v);,(1) 宏名一般习惯用,大写字母,表示,以便与变量名相区别。但这并非规定,也可用小写字母。,(2) 使用宏名代替一个字符串,可以减少程序中重复书写某些字符串的工作量。简单不易出错,一改全改。,使用宏定义,可以提高程序的通用性.,(3) 宏定义是用宏名代替一个字符串,也就是作,简单的置换,不作正确性检查。,(4) 宏定义不是C语句,,不必在行末加分号。,(5),#define命令出现在程序中函数的外面,宏名的有效范围为定义命令之后到本源文件结束。,通常,#define命令写在文件开头,函数之前,作为文件一部分,在此文件范围内有效。,(6) 可以用,#undef命令,终止宏定义的作用域,#define,ge 8.8,main(), |, GE的有效范围,#undef,ge,f1(), ,由于#undef的作用,使GE的作用范围在#undef行处终止,因此在f1函数中,ge不再代表8.8。这样可以灵活控制宏定义的作用范围。,(7) 在进行宏定义时,可以引用已定义的宏名,可以层层置换。,例,#define,R,3.0,#define,PI,3.1415926,#define,L,2*,PI*R,#define,S,PI*R*R,main(),printf(L=%fns=%fn,,L,S,);,(8),对程序中,用双括号括起来的字符串内的字符,,即使与宏名相同,也不进行置换。,(9) 宏定义是专门用于预处理命令的一个专用名词,它与定义变量的含义不同,,只作字符替换,不分配内存空间,。,例如:,#define N 10,#define TRUE -1,#define FALSE 0,#define ON 1,#define OFF 0,#define YES 1,#define NO 0,#define PI 3.14159,#define E 2.7183,#define BLACK 0,#define BLUE 1,#define BEGIN ,#define END ,1.2带参数的宏定义,与函数可带形式参数一样,宏标识符也可带有参数。,在程序中可用实参数替带形式参数,实现宏调用。,不是进行简单的字符串替换,还要进行参数替换。,其定义的一般形式为,#define宏名(参数表)字符串,字符串中包含在括弧中所指定的参数。如:,#defines(a,b)a*b,area=s(3,2);,定义矩形面积S,a和B是边长。在程序中用了s(3,2),把3、2分别代替宏定义中的形式,历年真题必学,真题1:下列程序的输出结果是( )。【2005.4】,#define P 3,void F(int x)return(P*x*x); ,main( ), printf(%dn,F(3+5); ,A)192 B)29,C)25 D)编译出错,真题2:下列叙述中正确拘是( )。【2005.4】,A)预处理命令行必须位于源文件的开头,B)在源文件的一行上可以有多条预处理命令,C)宏名必须用大写字母表示,D)宏替换不占用程序的运行时间,真题3:有下列程序:【2005.9】,#define f(x)(x*x),main( ), int i1,i2;,i1=f(8)/f(4); i2=f(4+4)/f(2+2);,printf(%d, %dn,i1,i2);,程序运行后的输出结果是( )。,A,),64,28 B,),4,4,C)4,3 D)64,64,真题4:下列,函数rotate的功能是:将a所指N行N列的二维数组中的最后一行放到b所指二维数组的第0列中,把a所指二维数组中的第0行放到b所指二维数组的最后一列中,b所指二维数组中其他数据不变。【,2005.9】,#define N 4,void rotate(int a N,int b N), int i,j;,for(i=0;i99,printf(”Compiled for array greater than 99n”);,#else,printf(“”Compiled for small arrayn”);,#endif,运行结果:,Compiled for small array,3.2 #ifdef 条件编译,一般形式:,#ifdef 标识符,程序段1,#else,程序段2,#endif,作用是:判断标识符是否被定义过,如果是,则对程序,段1进行编译,否则编译程序段2。,例如:,#ifdef EGA,#define colar_size 16,#else,#define colar_size 256,#endif,3.3 #ifndef 条件编译,一般形式:,#ifndef 标识符,程序段1,#else,程序段2,#endif,作用是,如果标识符未被定义,则编译程序段1,否则编译程序段2。,例如:,#define USA 1,main( ),#ifdef USA,printf(”currency is dollarn”);,#else,printf(”currency is poundn”);,#ifndef FRANCE,printf(”franc cant be usedn”);,#endif,运行结果:,currency is dollar,franc cant be used,编译预处理的几点说明,1,不要混淆预处理行和C语句的概念,。在本质上预处理行不是C语言本身的组成部分,必须经编译预处理程序处理后,才能进行编译。在表现形式上,C语句必须以分号结束,预处理行的末尾不加分号,2 在定义不带参数的宏时,其作用仅仅利用宏名代替一个字符串,系统不做任何语法检查。,3 在程序定义带参数的宏时,一定要考虑宏展开后的结果,以避免产生与原设计目的不一致的情况。,历年真题,真题:下列叙述中正确的是( )。【2006.4】,A)预处理命令行必须位于C源程序的起始位置,B)在C语言中,预处理命令行都以#开头,C)每个C程序必须在开头包含预处理命令行:#include,D)C语言的预处理不能实现宏定义和条件编译的功能,二、动态内存分配函数,动态内存分配是指在程序运行过程中,根据需要而分配内存空间的方式。在数组应用中,如定义的静态数组太小,则不能满足应用需要,如定义太大,则浪费存储空间,这种情况下,采用动态内存分配的方式可满足这类实际需要多少存储空间就分配多少的应用需要。,1malloc函数,函数原型:void *malloc(unsigned int size);,功能:在内存动态存储区分配一段长度为size个字节的连续空间,如果分配成功,函数返回一个指向该区域起始地址的指针。否则如因内存空间不够等原因,则返回空指针(NULL)。,动态内存分配函数,2calloc函数,函数原型:,void *calloc(unsigned int n,unsigned int size);,功能:,在内存动态存储区分配n个长度为size个字节的连续空间,如果分配成功,函数返回一个指向该区域起始地址的指针,否则返回空指针(NULL)。,说明,:calloc函数用于为具有n个元素的一维数组动态分配存储空间,每个元素的长度为size个字节,动态内存分配函数,3free函数,函数原型:void free(void *p);,功能:释放指针p指向的存储空间,free函数无返回值。,说明:p为最近一次调用malloc函数或calloc函数返回的指针。,4realloc函数,函数原型:void *realloc(void *p,unsigned int size);,功能:将指针p所指向的存储空间,重新分配改变为size个字节,并将原存储空间存放的数据拷贝到新分配的存储空间。如果分配成功,函数返回一个指向新存储空间起始地址的指针,否则返回空指针。,动态内存分配函数,注意:,(1)最好在同一个函数内动态分配和释放存储空间。,(2)最好在定义指针时将指针初始化为NULL,在释放指针后也将指针赋值为NULL,这样便于在需判断指针有效性时,用p=NULL判断指针是否为空指针。,(3)ANSI C标准要求动态分配存储空间需将“stdlib.h”文件用#include命令包含在程序中。,例:一维动态数组,#,include,main,(),int,*p = NULL, n, i, sum;,printf(Please enter array size:);,scanf(%d, ,p,= (,int *,),malloc,(n *,sizeof,(int);,if,(p = NULL),printf(No enough memory!n);,exit(0);,printf(Please enter the score:);,for,(i=0; in; i+),scanf(%d, p + i);,sum = 0;,for,(i=0; in; i+),sum = sum + *(p + i);,printf(aver = %dn, sum/n);,free(p);,例:二维动态数组,#,include,main,(),int,*pScore = NULL, i, j, m, n, maxScore, row, col;,printf(Please enter array size m,n:);,scanf(%d,%d, ,pScore,= (int *),calloc,(m*n,sizeof,(int);,if,(p = NULL),printf(No enough memory!n);,exit(0);,printf(Please enter the score:);,for,(i=0; im; i+),for,(j = 0; jn; j+),scanf(%d, ,maxScore = FindMax(pScore, 3, 4, ,printf(maxScore = %d, class = %d, number = %dn,maxScore, row+1, col+1);,free(pScore );,历年真题,真题:已有定义:double*p;,请写出完整的语句,利用malloc函数使p指向一个双精度型的动态存储单元。【2005.9】,答案:,p=(double*)malloc(sizeof(double),
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 大学资料


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!