《C高级程序设计.ppt》由会员分享,可在线阅读,更多相关《C高级程序设计.ppt(70页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、C高级程序设计高级程序设计 陈礼民陈礼民 2005-2课程的目的:是提高c语言的基本功能的熟悉程度适应后续课程学习的要求使c语言成为他们的基本计算机语言,能为后续课程服务。课时不多,只上课18学时,(6次),18时的实验。另外还要引入vc界面。本课程不打算分散学生的注意力和精力,不讲述在别的课程中会讲述的内容和比较过时的内容。如:os的内存管理,进程调度,微机的接口,中断,数据库,绘制图形,还有许多游戏算法等等,本教材是以总结和练习题为主,有些讲课内容需要参考其它教材.本课程要求课程外面的努力,本课程在课程内只讲解基本内容,和分析一些典型的例题,学生课后要根据自己的情况积极学习.养成主动学习的
2、方法和习惯.上机前必须准备好:要调试的内容.本课程准备了较多的练习题,有些是基本的,有些有一定难度,因为时间匆忙,有些内容来不及检查,其中会有一些错误,正好可以练习你的编程和调试能力.同学们可以根据自己的情况选择去做.本课程要求,提高程序调试的能力,为独立地完成作业和研究准备条件.最后部分的”学生成绩管理系统”,有说明,有程序,程序中前面几个功能已经调通,后面排序,保存,读取等8,9功能要自己调通完成.让大家可以容易进去,又有许多事情可以做.希望大家有所改变,有所发挥.建立一个自己的系统.这一部分上课不讲,自己去做,在课程结束时交.其它作业,将采取多做者,分数高的政策.相信只要能够跟上课程进度
3、,经过积极努力,将会获得较大的提高,.至于希望在c或编程方面有进一步提高要求的同学,可以把程序员的题多做一些,也可以做些课外的,这样可以为参加各种考试和比赛创造条件.目录目录:1、函数一,vc界面等 二、数组是一种重要的数据类型:三、函数:四,递归:2、存储类型和予处理 一,存储类型二,予处理3、指针:二,1-D指针的定义和性质练习三,1-D指针的应用 四,2-D:指针的定义和性质练习 a.指向n个元素的指针 b:指针数组:c:多级指针:五,函数和指针:1,1-D指针和函数 2,2-D指针和函数 3.常见错误:4,结构:结构,指针和函数 联合:链表:5,文件6.程序员考试编程7.学生成绩管理系
4、统 1、函数、函数一、函数部分的要点有:函数的定义、调用形式函数参数的形式和传递方式函数的嵌套调用和递归调用全局变量和局部变量的区分和作用,变量的作用域和生命期,注意static的不同作用本课程主要复习:函数的通信(数据的传递)和递归调用数据的传递:通过参数传递:实参传给形参;return通过外部变量参数传递:传值调用和传参考调用:传值调用把是实参传给形参.单向传递,函数内运行的结果是传不出来的.要用return.把结果返回给调用者.因为形参是局部变量.传参考调用:即传地址,可以是传变量或数组的地址,也可以传指针二、数组是一种重要的数据类型:对于数组来讲有1-D的和2-D的.1-D数组:int
5、 a101,2,3,4,5,6,7,8,9,10;a是数组的首地址 在内存中是依次存放的它的一般表达式是 ai c编译把它化为*(a+i)来处理的。如 *(a+5)是a后面第5个2-D数组数组int a33=1,2,3,4,5,6,7,8,9;a.在内存中是依次(行的次序)存放的b 数组名是它的首地址c.ai 是行地址所以它的一般表达式:aij:*(a+i*3+j)*(ai+j)*(a+i)+j)int*p=a;*p+=?*(*(p+i)+j)=?例:判下面语句的对错和结果 *int a10,b33;scanf(“%d”,a10);scanf(“%d”,&a10);scanf(“%s”,a);
6、scnaf(scnaf(“%d%d”,&ai,&ai););scanf(“%d”,b33);scanf(scanf(“%d%d”,&bij,&bij););scanf(“%s”,b);scnaf(“%d”,&bi);scanf(scanf(“%d%d”,&bij,&bij););int a11=a,b,c,d,e,f,g,k,k;char b19;scanf(%d,&ai);scanf(“%s”,&ai);scanf(“%s”,&b);scanf(scanf(“%s%s”,b,b););scanf(scanf(“%c%c”,&bi,&bi););.类型 接受者 *%s%dint a10,b33
7、;scanf(“%d”,a10);scanf(“%d”,&a10);scanf(“%s”,a);scnaf(“%d”,&ai);char b19;scanf(“%d”,&bi);/类型?!scanf(“%s”,&bi);/输入一串?!scanf(“%s”,&b);/?!scanf(“%s”,b);scanf(“%c”,&bi);3)、数组定义为“int a45;”,引用“*(*a+1)+2”表示 。A、a10+2 B、a数组第1行第2列元素的地址 C、a01+2 D、a数组第1行第2列元素的值答案:c5)、若有定义int a23;则 对 a数 组 第 i行 第 j列 元 素 的 正 确 引 用
8、 为 。A、*(ai+j)B、(a+i)C、*ai+jD、ai+j答案:a3 字符数组:如 char a20;它有和一般数组有一样的使用方法,但可以构成字符串,字符串的特点:a.0结尾b,可以用语句进行整体输入输出.scanf(“%s”,a);printf(“%s”,a);gets(a);puts(a);c,可以作为地址对指针变量赋值.char*p;p=”abcdef”;7)、不能把字符串:Hello!赋给数组b的语句是 。A,char b10=H,e,l,l,o,!;B,char b10;b=Hello!;C,char b10;strcpy(b,Hello!);D,char b10=Hell
9、o!;答案:a,b10)、请读程序:#include#include main()char sl=”abcdefghi”;char s2=”opqrst”;strcpy(s1+5,s2+2);printf(“%s”,s1);上面程序的输出结果 。答案:abcdeqrst下面程序有错误 *11).char a19,b20;int i;scanf(%s,&ai);xfor(i=0,i!=0,i+)xif(i=)bi+=ai,xbi=0;xprintf(%s,bi);xmain()char a20=abcd efg kk;int i,j=0;for(i=0;i20;i+)if(ai=!)x aj+=
10、ai;printf(%sn,a);13).*char a11=abcd efg kk;for(i=0;i11;i+)?if(ai=)break;xfor(j=0;j11;j+)?printf(%c,aj);三、函数:1.可以独立出来的程序段 它可以重复用.函数使用有3个要点:1.定义 2.调用 3.说明其中”说明”往往被忽略,其实非常重要.提醒一下,如使用库函数power()sqrt()等又不把它们的原型包含进去,不会有正确的结果.一定要用#include“math.h”予处理语句.如.#include“math.h”printf(“%f%f“,sqrt(4),pow(2,2);在vc平台上连
11、 printf(),scanf(),等都不能够省,必须:#include“stdio.h”函数在使用时关心的是:1.是数据的传入:书写的格式 接受什么?2.使用情况:变量,数组3.结果传出:2 数据传递例 float sum(int x,int n)/定义,/被调用时接受实参x,n送来的数据 float s=1,t=1;int i;for(i=1;i=n;i+)t=t*i;s=s+x/t;x=x*x;return(s s);/结果返回main()float s;int x=2,n=20;s=sum(x,n);s=sum(x,n);/调用,把实参x,n送给函数printf(%fn,s);下面有错
12、误:sum()x /求s=2/1+3/2+5/3+8/5+.int a,b;xfloat s=0;for(i=1;i=20;i+)s=s+a/b;t=a;a=a+b;b=t;return(s);main()int i,s,x,sum;xfor(i=1;i=20;i+)int sum();xprintf(%fn,s)3.数组作为函数参数时,使用格式如下:3.数组作为函数参数时,使用方式如下:void input1(int aa,int n);void input2(int b3b3,int m,int n);void print1(int a,a,int n);void print2(int b
13、3b3,int m,int n);main()int a10,b33;input1(a a,10);/一般表达式一般表达式?input2(b b,3,3);printf1(a a,10);print2(b b,3,3);void input1(int a,int n)int i;for(i=0;in;i+)scanf(“%d”,&aiai););void input2(int b3,int m,int n)int i,j;for(i=0;im;i+)for(j=0;jn;j+)scanf(“%d”,&bijbij););/传数组和传变量的不同:/变量把值copy到函数中/数组只把地址copy到
14、函数中,数组的值根本没有传入函数/但在函数内恰恰通过传入的地址到函数外面,访问数组void print(int a,int n)int i;for(i=0;in;i+)printf(“%3d”,&ai);void print2(int b3,int m,int n)int i,j;for(i=0;im;i+)for(j=0;jn;j+)printf(“%d”,&bij);printf(“n”);17)、C语 言 中,函 数 返 回 值 的 类 型 是 由 。A、return语句中的表达式类型所决定B、调用该函数时的主调函数类型所决定C、调用该函数时系统临时决定D、在定义该函数时所指的函数类型所
15、决定答案:d18).*double fun()int x=123;return x;main()printf(%d,fun();答案:0/函数的类型是其返回值的类型/其实:原型是样本,其它地方都要以他为参考/函数定义在前,可以省去原型的说明,但这时函数的头部,起原型作用,编译以此为根据/所以fun()的返回值要根据函数的类型,转换:int-double在主函数中用%d打印double型的数据,当然是错误的Man()char y20;y=“nice”;?fun(y);fun(char a)/形参是什么?,性质?a=“book”;?!/可以吗/形参是一个局部变量/用数组形式接受地址时,(fun(c
16、har a)/地址只送给a,形参是变量,接受地址的变量=指针/所以fun(char a)和fun(char*a)是完全等价的/221页:实参和形参的对应关系:(1)f(int x,int n)main()/都是数组 .int a10;.f(a,10);(2)f(int*x,int n)main()./形参指针 int a10;/实参数组 .f(a,10);(3)f(int*x,int n)main()/实参指针 ./形参指针 int a10,*p=a;.f(p,10);(4)f(int x,int n)main()/实参指针 ./形参数组 int a10,*p=a;.f(p,10);由上可见,
17、数组名和指针都可以作为函数参数。并且它们是互通的.对于1-D数组形参可以用数组名和指向数组的指针实参也可以四,递归:函数自己调自己,引起翻复调用,如果不是无穷尽,而能收敛的-递归-调用的最后终要回来的main()int x=0;sub(&x,8,1);printf(x=%dn,x);sub(int*a,int n,int k)if(k=n)sub(a,n/2,2*k);*a+=k;解:sub(int*a,int n,int k)if(k=n)sub(a,n/2,2*k);*a+=k;main()sub(a,n,k)sub(a,n,k)sub(a,n,k)x=0;if(1=8)if(2=4)if
18、(4=2)Sub(&x,8,1)sub(a,4,2)sub(a,2,4)*a+=k;*a+=k;*a+=k;*a=x打印x=7 *a=6+1=7 *a=4+2=6 0+4=4第 1次的sub(&x,8,1):18,再调用 sub()第 2次的sub(a,4,2):24,再调用 sub()第 3次的sub(a,2,4):40,m0时 设 n=3,m=3时的结果以及画出递归过程(调用路线?)最大公约数:*if(ab)t=a;a=b;b=t;while(r=b%a)b=a;a=r;return a;*24,18 :b%a=618,6 b%a=0 j结果=6 ghs(int b,int a):if(b
19、%a)=0)结束否则?ghs(a,r);课后自学作业1.函数部分和以前的题都要看完 其中递归部分看上几题即可2.2 存储类型和予处理:自学3.下一次上课讨论 存储类型与预处理autoexternstaticregister主要难点:fun()static int x=3;x+=4;main()int i;for(i=0;i ai=*(a+i)=*(p+i)=pi char*p=book;b.2-D化为1-D问题:(a)int a33;int*p;for(i=0;i*(p+j)=aij for(j=0;j3;j+)sacnf(%d,p+j);/p+j?!2D数:a=&a00 ai行地址 a+1!
20、=&a01 a+1是数行的 但 a=a0=*a a+1=a1=*(a+1)(b)用存储方式 int*p=a;for(i=0;i3;i+)for(j=0;j3;j+)sacnf(%d,p+i*3+j);/p+i*3+j=?指针的指向及其应用指针和数组:下面是使用的基本方式:1.int a8,*p=a;2.p+;&a1 3.*(p+i)=pi=ai 4.p=a+3;&a3=&(*(a+3)=a+3Char a8=”abcdef”,b=”book”,*p,*q;p=a+3;q=b+1;strcat(p,q);strcpy(p,q);printf(%s%s”,p,q);指针作为函数的参数(1).指向变
21、量的指针作为函数的参数(2)用指向数组的指针作为函数的参数指向变量的指针作为函数的参数void fun(int*x);/原型main()int a=123,*p=&a;fun(p);/调用 printf(a=%dn,a);/what s the result?void fun(int*q)int t;printf(输入一个整数n);scanf(%d,&t);/100 *q=t;/q=t;/t t对对q q的目标赋值的目标赋值 /这这赋值改变了谁赋值改变了谁p34.#include void sub(int x,int y,int*sum)*sum=x+y;main()int x=9,y=10,
22、s=1;sub(x,y,&s);printf(%d n,s);答案:19p40、#include int x,y,z;void p(int*x,int y)+*x;y-;z=*x+y;printf(%d,%d,%d-,*x,y,z);void main()x=2;y=3;z=4;p(&x,y);printf(%d,%d,%d-,x,y,z);p(&y,x);printf(%d,%d,%dn,x,y,z);答案:3,2,5 3,3,5 4,2,6 3,4,6p36.请读程序:#include char a10;void fun(char*s)strcpy(a,ABCDEF);printf(%sn
23、,a);s=a+2;printf(%sn,s);main()char*p=a;fun(p);printf(%sn,p);主函数中输出结果是:_ fun()执行完毕后s消失了.p还是指向数组a,主函数中输出结果是:ABCDEF.(2)用指向数组的指针作为函数的参数int a8;fun(int*b).fun(a);void fun(int*,int);/原型main()int a5,i;fun(a,5);/调用 for(i=0;i5;i+)printf(%4d,ai);/定义Void fun(int*p,int n)/p=a;int i;for(i=0;in;i+)scanf(%d,p+);/1-
24、D指针和1-D数组使用很相似?!/?!/函数类型问题函数类型问题char char*strcpy(char*s1,const char*s2)char*start=s1;while(*s1+=*s2+);/作用作用,到什么时候停止到什么时候停止?!?!return start;2-D指针用2-D指针表示数据,有以下几种方式:(0)以存储方式指向。无2-D特性(1)指向n个元素的指针(一次指一行)(2)指针数组(3)多级指针用用2-D指针表示数据的几种方法指针表示数据的几种方法:(1)将以存储方式指向。int a33,a33,*p=a;aij=*(p+3*(p+3*i+ji+j)无2-D特性(2
25、)指向n个元素的指针(一次指一行)(3)指针数组 int*p3=a0,a1,a2;aij=*(*(pi+jpi+j)(4)多级指针:int*pp=p;/p是指针数组的数组名 aij=*(*(*(*(pp+ipp+i)=j)=j)p28.int a33=2,1,3,5,9,6,7,0,4;int*p=a0,a1,a2;int*pp=p,i,j,*q=a;欲求极大,下列语句哪一个是不正确的_ for(i=0;i3;i+)for(j=0;j3;j+)if(*q _(1)_)*q=_(2)_;选择答案:a.1).*(*(p+i)+j)2).*(*(p+i)+j)b.1).*(*(pp+i)+j)2).
26、*(*(pp+i)+j)c.1)*(pi+j)2).*(*(a+i)+j)d.1)*(p+3*i+j)2).*(p+3*i+j)答案:d/*q=(2);改为 q=&(2);可以吗?p33、以下正确的定义语句和赋值语句是 。A、int b35,(*q)5,(*p)3;p=b;q=b;B、float b35,*p3;p0=b0;p2=*b+4;C、double b35,s35,*q;q=b;s=q;D、int b10,*q;char*s;q=b;s=b;解:a.int b35,(*q)5,(*p)3;p=b;/列数不同c.double b35,s35,*q;q=b;s=q;/Lvalued.int
27、 b10,*q;char*s;q=b;s=b;/int 10 to char*?!?!B、float b35,*p3;p0=b0;p2=*b+4;*b=b0,b0+4=&b04 ,p0=b0,p0指向第一行若 p2=b2,则p2指向第三行现在p2=*b+4;是、p2指向第一行第5个元素。也可以.将一个3*3的矩阵转置 int*p=&a00;move(p)*move(int*pointer)/*矩阵转置函数*/int i,j,t;for(i=0;i3;i+)for(j=i;j3;j+)t=*(pointer+3*i+j);*(pointer+3*j+i)=*(pointer+3*j+i);*(p
28、ointer+3*j+i)=t;上一题用指针数组int*p=a0,a1,a2;move(p);*move(int*q)int i,j,t;for(i=0;i3;i+)for(j=i;j3;j+)t=*(qi+j);*(qi+j)=*(qj+i);*(qj+i)=t;int(*p)3;p=a;move(p);*move(int(*q)3)int i,j,t;for(i=0;i3;i+)for(j=i;j3;j+)t=(*(q+i)j;(*(q+i)j=(*(q+j)i;(*(q+j)i=t;3.常见错误 p50.;sum(int*x,int*y)int*s;s=*x+*y;main()int x
29、,y,z,s=0;x=3;y=4;sum(*x,*y);printf(%d,*s);选择:a.7 b.不定 c.0 d.语法错答案:dp49.Static int a33=1,2,3,4,5,6,7,8,9;static int*pp=a;fun(pp);void fun(int*p)这时的aIj的指针表示:选择:a.*(*(p+i)+j)b.(p+i*3+j)c.*(pi+j)答案:bp52.在 有x的地方请改正#define NL printf(n)char*strcat1(char*ps,char*pd)int t,i,n=strlen(ps);while(*ps+);while(*ps=*pd+)ps+;*ps=0;return ps;xmain()char s20,d20,*ps=s,*pd=d;scanf(%s%s,s,d);printf(%sn,strcat1(s,d);
限制150内