《C语言基础与提高.pptx》由会员分享,可在线阅读,更多相关《C语言基础与提高.pptx(24页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、1int aint afloat bfloat ba=3;a=3;b=5;b=5;若将若将p p中地址换成中地址换成3AC0(B3AC0(B的地址的地址),),则可以通过则可以通过p p来访来访问问B B3a3AB05b3AC03AB0p变量变量的访问方式直接访问间接访问:定义一个变量p,存放a的地址,通过p来访问a2.1 指针第2页/共24页第1页/共24页2如如:p:p为指针变量为指针变量,它存放整型变量它存放整型变量a a的首地址的首地址,则称则称指针变量指针变量p p指向整型变量指向整型变量a a。3a3AB05b3AC03AB0p指针变量存放地址的变量指针变量的类型指针变量的类型u指
2、针所指向内存单元中存放的数据的类型指针所指向内存单元中存放的数据的类型2.1 指针第3页/共24页第2页/共24页3int *p,a,b;p=&a;int *p1,*p2,a;p1=&a;p2=p1;int *p1;p1=NULL;或或p1=0;指针变量指针变量的赋值用变量地址给指针变量赋值(使用到地址符&)变量的类型必须与指针变量类型相同用相同类型的指针变量赋值若不赋值,则指针变量的值是随机的赋空值NULLint *p1p1=0X12342.1 指针第4页/共24页第3页/共24页4printf():printf():从右到左计算参数从右到左计算参数(*q)+(*q)+和和*(q+)(q+)
3、两者不同两者不同 内容内容+地址地址+若有若有:int a=5,*p=&a;写出下面表达式的结果写出下面表达式的结果,并找出等价的表达式并找出等价的表达式&*p *&a (*p)+&a a *p+*(p+)a+牢记下列等价式:牢记下列等价式:int *p=&a;&*pp *&aa&ap *pa要求:*后一定是指针变量;2.1 指针指针变量指针变量的运算规则&与*优先级相同,右结合示例u说明说明.200020002004200820122apq2000void main()int a=2,*p=&a,*q=&a;printf(“%d,%dn”,*p+,*(q+);p=&a,q=&a;printf
4、(“%d,%dn”,*p,(*q)+);结果结果:2 2:2 2 3 23 2第5页/共24页第4页/共24页5#include void swap(int x,int y)int t;t=x;x=y;y=t;void main()int a=3,b=5;swap(a,b);printf(“%d%dn”,a,b);#include void swap(int *x,int*y)int t;t=*x;*x=*y;*y=t;void main()int a=3,b=5;swap(&a,&b);printf(“%d%dn”,a,b);void swap(int *x,int*y)int *t;t=x
5、;x=y;y=t;void swap(int *x,int*y)int *t;*t=*x;*x=*y;*y=*t;*t*t未赋初值,系统会随机未赋初值,系统会随机给值,可能指向一个已有数据给值,可能指向一个已有数据的存储单元,再执行交换,的存储单元,再执行交换,就会破坏已有数据。就会破坏已有数据。2.1 指针指针变量指针变量作函数参数示例:编写一个函数实现两个数的交换第6页/共24页第5页/共24页62.1 指针指针数组指针数组定义:数据类型标识符定义:数据类型标识符*数组名数组名元素个数元素个数;如:如:uint*pi10;由于由于“”比比“*”的优先级高,所以数组名先与的优先级高,所以数组
6、名先与“元素元素个数个数”结合,形成数组的定义形式,结合,形成数组的定义形式,“*”表示数组中每个表示数组中每个元素是指针类型,元素是指针类型,“数据类型标识符数据类型标识符”说明指针的目标变量的说明指针的目标变量的数据类型。数据类型。指针数组是一个数组,它的每个元素都是指针数组指针(指向一维数组的)数组指针(指向一维数组的)定义:数据类型标识符定义:数据类型标识符(*变量名变量名)元素个数元素个数;如:如:uinta4=0,1,2,3,10,11,12,13,20,21,22,23;int(*lp)4=a;“*”表示其后的变量名为指针类型,元素个数表示目标表示其后的变量名为指针类型,元素个数
7、表示目标变量是一维数组,并说明一维数组元素的个数。变量是一维数组,并说明一维数组元素的个数。“数据类型标数据类型标识符识符”定义一维数组元素的类型。定义一维数组元素的类型。数组指针是一个指针,它指向一个数组注意:注意:数组名是一个常量,是一个指数组名是一个常量,是一个指向数组首元素的指针。向数组首元素的指针。第7页/共24页第6页/共24页7整型值整型值整型变量整型变量地址整型变量地址一级指针变量一级指针变量地址一级指针变量地址二级指针变量2.1 指针二级指针二级指针定义:数据类型标识符定义:数据类型标识符*指针变量名指针变量名;如:如:uinta,*p=&a,*pp=&p;说明:说明:“*指
8、针变量名指针变量名”相当于相当于*(*指针变量名指针变量名),在括号中定,在括号中定义了一个指针变量,括号外的义了一个指针变量,括号外的“*”,说明指针变量(即二级指,说明指针变量(即二级指针)的针)的目标变量是一个指针类型数据目标变量是一个指针类型数据,“数据类型标识符数据类型标识符”是是目标变量(即一级指针)所指向的数据的类型,也就是最终目目标变量(即一级指针)所指向的数据的类型,也就是最终目标变量的类型标变量的类型a的内容的内容a&ap&ppp、*p p、*pppp、*pppp应用示例应用示例u写一个函数交换两个字符串写一个函数交换两个字符串voidswap(char*pp1,char*
9、pp2)char*p;p=pp1;pp1=pp2;pp2=p;voidmain()char*p1=please;char*p2=Doit,;swap(p1,p2);printf(%s%s,p1,p2);voidswap(char*pp1,char*pp2)char*p;*p=*pp1;*pp1=*pp2;*pp2=*p;voidmain()char*p1=please;char*p2=Doit,;swap(p1,p2);printf(%s%s,p1,p2);voidswap(char*pp1,char*pp2)char*p;p=*pp1;*pp1=*pp2;*pp2=p;voidmain()c
10、har*p1=please;char*p2=Doit,;swap(&p1,&p2);printf(%s%s,p1,p2);第8页/共24页第7页/共24页82.1 指针指针型函数指针型函数定义:定义:数据类型标识符数据类型标识符*函数名函数名(形参表形参表);如:如:uchar*max(char*p,char*q);因为因为“()”优先级比优先级比“*”高,所以高,所以“函数名函数名”与右侧的括号与右侧的括号“()”结合,表示结合,表示是一个函数是一个函数,“数据类型标识符数据类型标识符*”则定义则定义了函数的返回值类型。了函数的返回值类型。示例示例char*max(char*p,char*q
11、)charszTemp1024;if(strcmp(p,q)0)strcpy(szTemp,q);elsestrcpy(szTemp,p);returnszTemp;staticcharszTemp1024;char*max(char*p,char*q)returnstrcmp(p,q)0?q:p;第9页/共24页第8页/共24页92.1 指针函数指针函数指针定义:定义:数据类型标识符数据类型标识符(*函数指针变量名函数指针变量名)(形参表形参表);如:如:uint(*CALLBACK)(void*pPara);调用形式:调用形式:(*函数指针变量名函数指针变量名)(实参表实参表);如:如:u
12、intiRet=(*CALLBACK)(p);“*函数指针变量名函数指针变量名”必须用圆括号括起来,否则就成为声明必须用圆括号括起来,否则就成为声明一个指针型函数了。一个指针型函数了。“(*函数指针变量名函数指针变量名)”右侧的括号右侧的括号“()”表示表示指针变量所指向的目标是一个函数指针变量所指向的目标是一个函数,“数据类型标识符数据类型标识符”是定义指针变量所指向的函数的类型。是定义指针变量所指向的函数的类型。函数名代表函数的起始地址(即该函数的程序代码段在内存中所函数名代表函数的起始地址(即该函数的程序代码段在内存中所占用的存储空间的首地址,也称函数入口),是一个指针常量。占用的存储空
13、间的首地址,也称函数入口),是一个指针常量。应用示例应用示例u实现一个回调函数,并调用之实现一个回调函数,并调用之intcalcSum(inti1,inti2)returni1+i2;intcalcProduct(inti1,inti2)returni1*i2;typedefint(*CALL_BACK)(int,int);voidmain()CALL_BACKfunc;func=calcSum;printf(Thesumof3and4is:%d,(*func)(3,4);func=calcProduct;printf(Theproductof3and4is:%d,(*func)(3,4);第
14、10页/共24页第9页/共24页10作用:在对源程序编译之前做一些处理,生成扩展C源程序种类宏定义#define文件包含#include条件编译#if-#else-#endif等格式:“#”开头占单独书写行语句尾不加分号2.2 编译预处理第11页/共24页第10页/共24页11如#define YES 1#define NO 0 if(x=YES)printf(“correct!n”);else if(x=NO)printf(“error!n”);展开后:if(x=1)printf(“correct!n”);else if(x=0)printf(“error!n”);1 宏定义不带参数宏定义一
15、般形式#define 宏名(标识符)宏体(字符串)功能:用指定标识符(宏名)代替字符序列(宏体)u宏展开:预编译时宏展开:预编译时,用宏体来替换宏名用宏体来替换宏名-不作语法检查不作语法检查如#define YES 1#define NO 0#define PI 3.1415926#define OUT printf(“Hello,World”);说明说明:1.1.定义位置定义位置:任意任意(一般在函数外面一般在函数外面)2.2.作用域作用域:从定义命令到文件结束从定义命令到文件结束3.#3.#undefundef可终止宏名作用域可终止宏名作用域 格式:格式:#undef#undef 宏名宏名
16、例#define YES 1 main().#undef YES#define YES 0 max().YES原作用域YES新作用域5.5.宏定义可嵌套,不能递归宏定义可嵌套,不能递归例#define MAX MAX+10 ()4.4.引号中的内容与宏名相同也不置换引号中的内容与宏名相同也不置换例#define PI 3.14159 printf(“2*PI=%fn”,PI*2);宏展开:printf(“2*PI=%fn”,3.14159*2);6.6.宏定义中使用必要的括号宏定义中使用必要的括号()()例#define WIDTH 80#define LENGTH WIDTH+40 var=
17、LENGTH*2;宏展开:var=80+40*2;()()例#define WIDTH 80#define LENGTH WIDTH+40 var=LENGTH*2;宏展开:var=WIDTH+40*2 var=80+40*27 7.只是简单替代,标识符不占内存空间只是简单替代,标识符不占内存空间8 8.一般宏名使用大写字母形式一般宏名使用大写字母形式.第12页/共24页第11页/共24页12带参数宏定义一般形式:#define 宏名(参数表)宏体例例#defineS(r)PI*r*r相当于定义了不带参宏相当于定义了不带参宏S,代表字符串代表字符串“(r)PI*r*r”说明:说明:u1 1.宏
18、展开:不仅宏体替换宏展开:不仅宏体替换,还要进行形参替换还要进行形参替换u2 2.宏体及各形参外一般应加括号宏体及各形参外一般应加括号()()u3 3.宏名与参数之间不能有空格宏名与参数之间不能有空格例#define S(a,b)a*b .area=S(3,2);宏展开:area=3*2;不能加空格例例#definePOWER(x)x*xx=4;y=6;z=POWER(x+y);宏展开:宏展开:z=x+y*x+y;一般写成:一般写成:#definePOWER(x)(x)*(x)宏展开:宏展开:z=(x+y)*(x+y);第13页/共24页第12页/共24页13#include#defineST
19、R(s)#s#defineSCIENTIFIC_NOTATION(a,b)(int)(a#e#b)#defineVERSION(major,minor)major#.#minorintmain()printf(STR(itisastring);/输出:itisastringprintf(“%dn”,SCIENTIFIC_NOTATION(2,3);/输出:2000printf(“n%.1fn”,VERSION(5,3);/输出:5.3return0;#把宏参数变为一个字符串,#把两个宏参数粘合在一起.续行符u4.4.符号符号“#”、“#”和和“”#define DECLARE_CALLBACK
20、_EX1(id,arg1_type)static gint _onSignaledEx1#id(GtkWidget*pWidget,arg1_type arg1,gpointer pPara)return CmdTarget:invoke(pWidget,(gpointer)arg1,pPara,CmdTarget:CBK_EX);第14页/共24页第13页/共24页14#include#defineTOW(2)#defineMUL(a,b)(a*b)intmain()/printf(%d*%d=%dn,(2),(2),(2)*(2);printf(%d*%d=%dn,TOW,TOW,MUL(
21、TOW,TOW);#include#defineSTR(s)#s#defineSAMPLEitisastringintmain()printf(STR(SAMPLE);/printf(SAMPLE);return0;#include#define_STR(s)#s#defineSTR(s)_STR(s)#defineSAMPLEitisastringintmain()printf(STR(SAMPLE);/printf(“itisastring);return0;注意:当宏参数是另一个宏的时候,凡宏定义里有用#或#的地方宏参数不会再展开第15页/共24页第14页/共24页15#define M
22、AX(x,y)(x)(y)?(x):(y).main()int a,b,c,d,t;.t=MAX(a+b,c+d);宏展开:t=(a+b)(c+d)?(a+b):(c+d);int max(int x,int y)return(xy?x:y);main()int a,b,c,d,t;.t=max(a+b,c+d);u5.5.用宏定义可以实现和函数同样的功能用宏定义可以实现和函数同样的功能第16页/共24页第15页/共24页16带参的宏与函数区别带参宏函数处理过程不分配内存简单的字符置换分配内存先求实参值,再代入形参处理时间编译前程序运行时参数类型无类型问题定义实参,形参类型程序长度变长不变运行
23、速度不占运行时间调用和返回占时间第17页/共24页第16页/共24页172 文件包含功能:一个源文件可将另一个源文件的内容全部包含进来一般形式:#include “文件名”或#include#include “file2.c”file1.cfile2.cfile1.cBABA处理过程:预编译时处理过程:预编译时,用被包含文件的内容取代该预处理命令,再对用被包含文件的内容取代该预处理命令,再对“包包含含”后的文件作一个源文件编译后的文件作一个源文件编译 直接按标准目录搜索直接按标准目录搜索(存放存放C C的库函数头文件的库函数头文件)“”先在先在当前目录当前目录搜索,再搜索标准目录搜索,再搜索标
24、准目录 可指定路径可指定路径第18页/共24页第17页/共24页18被包含文件内容源文件(*.c)头文件(*.h)宏定义数据结构定义函数说明等文件包含可嵌套文件包含可嵌套#include “file2.c”file1.cAfile3.cC#include “file3.c”file2.c Bfile1.cAfile3.cfile2.c第19页/共24页第18页/共24页19例 文件包含举例/*powers.h */#define sqr(x)(x)*(x)#define cube(x)(x)*(x)*(x)#define quad(x)(x)*(x)*(x)*(x)#include#inclu
25、de“c:powers.h#define MAX_POWER 10void main()int n;printf(number exp1t exp2t exp3t exp4n);printf(-t-t-t-n);for(n=1;n=MAX_POWER;n+)printf(%2dt%3dt%4dt%5dn,n,sqr(n),cube(n),quad(n);第20页/共24页第19页/共24页203 条件编译概念:在某个条件成立的情况下才对某一部分进行编译。三种格式:格式二形式:作用:如果标识符没有被#define命令定义过,则对程序段1进行编译,否则对程序段2进行编译格式三形式:作用:如果指定的
26、常量表达式1值为真(非零),则对程序段1进行编译,否则如果指定的常量表达式2值为真(非零),则对程序段2进行编译,否则对程序段n进行编译格式一形式:作用:如果标识符已经被#define命令定义过,则对程序段1进行编译,否则对程序段2进行编译#ifdef标识符标识符程序段程序段1#else程序段程序段2#endif#ifndef标识符标识符程序段程序段1#else程序段程序段2#endif#if常量表达式常量表达式1程序段程序段1#elif常量表达式常量表达式2程序段程序段2#else程序段程序段n#endif第21页/共24页第20页/共24页21条件编译的优点1,可以提高C源程序的通用性#i
27、fDOS#defineINTEGER_SIZE16#elifWIN32#defineINTEGER_SIZE32#else#defineINTEGER_SIZE64#endif2,可以使调试程序等过程变得灵活3,可以减少目标程序的长度#defineDEGUG.#ifdefDEBUGprintf(“x=%d,y=%dn”,x,y);#endif#include#defineCIRCLE1voidmain()floatc,r,s;c=2;#ifCIRCLEr=3.1415962*c*c;printf(“areaofroundis:%fn,r);#elses=c*c;printf(areaofsquareis:%fn,s);#endif第22页/共24页第21页/共24页22习题写一个函数对参数提供的字符串数组(数组以空指针结束)进行排序。函数原型如下:void sort(char*str_list);第23页/共24页第22页/共24页23End of chap 2End of chap 2第24页/共24页第23页/共24页谢谢您的观看!第24页/共24页
限制150内