程序员考试强化

上传人:wu****ei 文档编号:135281718 上传时间:2022-08-15 格式:DOC 页数:12 大小:63.51KB
收藏 版权申诉 举报 下载
程序员考试强化_第1页
第1页 / 共12页
程序员考试强化_第2页
第2页 / 共12页
程序员考试强化_第3页
第3页 / 共12页
资源描述:

《程序员考试强化》由会员分享,可在线阅读,更多相关《程序员考试强化(12页珍藏版)》请在装配图网上搜索。

1、 指 针 (一)变量的指针和指向变量的指针变量1、变量的指针就是指变量的地址。2、指针变量:用来专门存放地址的变量例如:int a=5,*p=&a;*代表取后面所表示的地址中的内容。&代表取后面内容所存放的地址。3、指针变量可作为函数的参数此时,形参与实参是共用一个内存空间的。注意是以指针变量,还是以指针变量的内容作为参数(二)数组的指针和指向数组的指针变量1、数组的指针就是数组的起始地址,数组元素的指针就是指存放数组元素的地址。2、指向数组元素的指针。这里的定义与指向变量的指针定义相同。只是这时给变量赋值是不是普通变量的地址,而是数组元素的地址。例如:int a10,b,*p=a;在C中规定

2、:数组名就代表数组的首地址,因此a与&a0在值上是等价的。故:p=a可写成p=&a0;3、通过指针引用数组元素。定义一个指向数组元素的指针p,然后将一个存在的数组的首地址给p,然后就可以通过p来引用数组中的元素。C中规定:如果指针变量p已指向数组中的一个元素,则p+1指向同一数组中的下一个元素(而不是将p的值简单加1)。例如:数组元素是实型,每个元素需要占4个字节,则p+1意味着使p的值(地址)加4个字节,以使它指向下一个元素。我们看一个例子:int a10,*p=a;(1)p+I和a+I就是aI的地址,即,p+I,a+I,&aI三者等价。其中a+I中的I跟p+I中的I的意义一样。(2)*(p

3、+I)或*(a+I)或aI是指数组的元素。而且三者是代表同一个元素。(3)指向数组的指针变量也可以跟数组名一样使用下标来引用。即pI与aI等价。4、几个注意点:(1)指针变量可以实现自身的值的改变。如:p+;而数组名则不允许,如:a10中,a代表数组a的首地址,如果可以自加运算的话,也就是数组在内存中存放的位置是随意变化的这是不可能的,因为只要分配空间后,不可能再移动的。故:a+是错误的。(2)要注意指针变量当前值。因为指针在移动后,如果不进行复位,则它不能象数组名一样每次使用时都代表首地址,故当指针移动时可能超出范围。(3)指针变量的运算p+使p指向下一个元素。*p+,由于+和*同优先级,结

4、合方向为自右向左,因此它等价于*(p+)。作用是:先得到p指向的变量的值(即*p),然后再使p+1p。*(p+)与*(+p)作用不同。前者是先取*p,后使p加1;后者是先使p加1,再取*p。(*p)+表示p所指向的元素值加15、指向多维数组的指针和指针变量(1)多维数组的地址。(以二维数组为例)这里我们可以将二维数组看成一维数组的一维数组。如:int a1010;对第一行:a0I:可以看成是数组名为a0的一维数组。其它的同理。故如果写出a0+1,当然就代表a数组中的第二行的首地址,而不是a数组中的第二个元素的地址。*(a0+1)同样代表第二行的首地址,只是此时将该表达式加1时,不是在跑到下一行

5、啦,而是在本行朝后移一个,也就是下一个元素的地址啦。下表小结:6、字符串的指针和指向字符串的指针变量(1)字符串的指针:指字符串的首地址。(2)字符串的表示形式用字符数组存放一个字符串。如:char str1=”china”,str2=“china”,str3=a,b,0用字符指针指向一个字符串。如:char*str1=”china”;char*str1;str1=”china”;这里是指将字符串的首地址赋给str1;注意:char*a;scanf(“%s”,a);这种方法C不会提示错误,但是不允许的,因为指针变量a,定义了,但没有指它指定具体的空间,故无法正确存放你输入的字符串。7、指针运算

6、小结指针变量加(减)一个整数C语言规定,一个指针变量加(减)一个整数并不是简单地将指针变量的原值加(减)一个整数,而是将该指针变量的原值(是一个地址)和它指向的变量所占用的内存单元字节数相加(减)。如p+I代表地址计算:如果p为整型,则该式代表p+I*2;指针变量赋值将一个变量地址赋给一个指针变量。Int*p,a=100;p=&a;指针变量可以有空值,即该指针变量不指向任何变量,表示成p=NULL,其中NULL是整数0.两个指针变量可以相减如果两个指针变量指向同一个数组元素,则两个指针变量值之差是两个指针之间的元素个数,但两个指针变量相加就没有实际意义啦。两个指针变量比较若两个指针指向同一个数

7、组元素,则可以进行比较。 结构体 结构体属于构造类型,前面我们已学过的数组,它中间的各元素是属于同一类型的。但这远远不足,我们大量的是需要同一个数据中能包含多个不同类的数据,这就是结构体产生的原因。结构体的定义:Struct结构体名/结构体名是用作结构体类型的标志它不等于变量名成员表列;1、结构体类型变量的定义struct dateint day;int month;int year;struct studentint num;/学号char name20;struct date birthday;/属于结构体类型的student1,student2;或者:struct student stu

8、dent1,student2其内存空间:2+1*20=22字节注:对结构体中的成员(即“域”),可以单独使用,它的作用与地位相当于普通变量。成员也可以是结构体变量。2、结构体变量的引用(1)不能将一个结构体变量作为一个整体进行输入/出。例如:上面的student1。只能具体到其中的具体变量才行。成员变量的引用方式:student1.num“.”是成员(分量)运算符,它在所有运算符中优先级最高。(2)如果成员本身又属于一个结构体类型,则要用若干个成员运算符,一级一级地找到最低的一级的成员。只能对最低级的成员进行赋值或存取运算。例如:上面的取学生生日的年份:student1.birthday.ye

9、ar(3)对结构体变量的成员可以像其它变量一样进行各种运算,可以引用结构体变量成员的地址,也可以引用结构体变量的地址。如:student1.num+;&student1.num;&student1;但不能对结构体变量整体引用。例如这条语句是不对的:scanf(“%d,%s,%d”,&student1);因此,结构体变量的初始化就可以和普通变量的初始化一样。3、结构体数组例:有10个学生的信息需要处理,我们可以定义10个结构体类型的变量,但那样变量的管理比较烦,这时我们就可以通过结构体数组来管理,struct student stu10;具体使用是数组与结构体的合并使用,比如:第一个学生的学号,

10、stu0.num4、指向结构体类型数据的指针一个结构体变量的指针就是该变量所占据的内存段的起始地址。可以设一个指针变量,用来指向一个结构体变量,此时该变量的值是结构体变量的起始地址。指向结构体变量的指针例:struct student stu1,*p;p=&stu1; stu1.num与(*p).num相同,都代表学号,注:对指针(*p)两边的括号不能省。如省略则变成*p.num因为“.”的优先级最高,所以相当于*(p.num)这是不对的。对其中成员变量的引用用以下三种形式:结构体变量.成员名(*p).成员名p-成员名三者等价。注:p-n得到p指向的结构体变量中的成员n的值。p-n+得到p指向

11、的结构体变量中的成员n的值,用完该值后使它加1+p-n得到p指向的结构体变量中的成员n的值,使它加1后再使用。指向结构体数组的指针定义一个指向结构体数组的指针变量,这与前面定义指向数组或结构体变量的方法差不多。例:struct student stru110,*p;p=stru1;注意,这时指针是指向结构体数组,其类型还是结构体,其中p可以加1,但这里加1后是指向数组的下一个元素,而不是在当前结构体中移动。例:struct studentint num;char name20;char sex;int age;struct student stu3=10101,”li”,M,18,10102,

12、”zhang”,M,19,10104,”wang”,F,20;main()struct student*p;printf(“No.name sex agen”);for(p=stu;pnum,p-.name,p-sex,p-age);打印结果:No.Name sex age10101 li M 1810102 zhang M 1910104 wang F 205、用指针处理链表(1)链表概述链表是一种常见的重要的数据结构。它是动态地进行存储分配的一种结构。链表有一个“头指针”变量,它存放一个地址。该地址指向链表第一个元素。链表中每一个元素称为“结点”,每个结点都应包括两个部分:一为用户需要用的

13、实际数据,二为下一个结点的地址。例:定义一个存放学生学号及成绩的结构体结点,并建立含有三个学生的简单链表。struct studentint num;float score;struct student*nex;main()struct student a,b,c,*head,*p;a.num=9901;a.score=89.4;b.num=9903;b.score=79;c.num=9902;c.score=80;head=&a;a.next=&b;b.next=&c;c.next=NULL;p=head;doprintf(“%d%5.1fn”,p-num,p-score);p=p-next

14、;while(p!=NULL);(2)处理动态链表所需的函数链表结构是动态地分配存储的,即在需要时才开辟一个结点的存储单元,如何开辟呢?我们可以通过C语言提供的有关函数。malloc函数其函数原型为:void*malloc(unsigned int size);作用:是在内存的动态存储区中分配一个长度为size的连续空间。此函数的返回值是一个指向分配域起始地址的指针。如果此函数未能成功地执行,则返回空指针(NULL)calloc函数其函数原型为:void*calloc(unsigned n,unsigned size);作用:是在内存的动态区存储中分配n个长度为size的连续空间。函数返回一个

15、指向分配域起始地址的指针;如果分配不成功,返回NULL。free函数其函数原型为:void free(*p);作用:是释放由p指向的内存区,使这部分内存区能被其他变量使用。(3)建立动态链表所谓建立动态链表就是指:在程序执行过程中从无到有地建立一个链表,即一个一个地开辟结点和输入各结点数据,并建立前后相链的关系。例:建立一个有n名学生数据的单向链表struct studentlong num;float socre;struct student*next;int n;struct student*creat(void)struct student*p1,*p2,*head;n=0;p1=p2=

16、(struct student*)malloc(struct student);scanf(“%ld,%f”,&p1-num,&p1-score);head=NULL;while(p1-num!=0)n=n+1;if(n=1)head=p1;else p2-next=p1;p2=p1;p1=(struct student*)malloc(struct student);scanf(“%ld,%f”,&p1-num,&p1-score);p2-next=NULL;return(head);/返回头指针的地址main()creat();注:(struct student*)它的作用是使malloc

17、返回的指针转换为指向struct student类型数据的指针。其中*不能省略,否则变成转换成struct student类型了,而不是指针类型。(4)输出链表void print(struct student*head)struct student*p;p=head;if(head!=NULL)doprintf(“%ld%5.1fn”,p-num,p-score);p=p-next;while(p!=NULL);(5)对链表的删除操作对已有的链表中的某个元素进行删除,我们只要定位到这个结点上,然后把它前面的结点的next指向它后面的结点,就完成对该结点的删除了。Struct student*

18、del(struct student*head,long num)struct student*p1,*p2;if(head=NULL)printf(“n List null!n”);elsep1=head;while(num!=p1-num&p1-next!=NULL)/如果没找到目标结点及链表还没有结束p2=p1;p1=p1-next/将当前结点标志移向向一个结点if(num=p1-num)/找到了结点if(p1=head)head=p1-next;/如果目标结点为头结点,则将头结点标志后移一个else p2-next=p1-next;/将当前结点p1删除n=n-1;free(p1);el

19、se printf(“%ld not been found!n”,num);/找不到该结点return(head);(6)插入操作对链表的插入是指将一个结点插入到一个已有的链表中。如果没有特别要求来插入的话,我们只要将新结点加在末尾或插在开头,但如果原来的链表是有序的,此时我们就需要对链表进行定位,以保证插入后的链表还是有序的。设从小到大排列的链表中插入学号为num的。Struct student*insert(struct student*head,long num)struct student*p0,*p1,*p2;P0=(struct student*)malloc(struct stu

20、dent);p0-num=num;p0-next=NULL;if(head=NULL)head=p0;elsep1=head;p2-p1-next;while(p2!=NULL)/链表没有结束if(num=p1-num&numnum)找到位置p1-next=p0;p0-next=p2;return(head);/插入到位置,并返回链表elsep1=p2;p2=p2-next;/找不到位置,说明新结点应挂在最后if(p2=NULL)p1-next=p0;/将新结点挂在最后return(head); 文 件 (一)文件指针缓冲文件系统中,关键的概念是“文件指针”。每个被使用的文件都在内存中开辟一个

21、区,用来存放文件的有关信息(相当于文件的档案)。这些信息是保存在一个结构体变量中的。该结构体类型是由系统定义的,叫做FILE。我们在程序中使用文件时只需直接使用文件指针来定义变量。如:FILE*fp(二)文件的打开与关闭、文件的打开(fopen函数)FILE*fp;fp=fopen(文件名,使用文件的方式);如:fp=fopen(“a1”,”r”)注:其中的文件名参数,如果指定的文件名不是在当前路径下则需要在该参数中指定一个完整的路径。使用文件方式的参数,指出是读、写还是其他操作。对于文件使用方式有以下几点说明:1)文件使用方式由r,w,a,t,b,+六个字符拼成,各字符的含义是:r(read

22、): 读w(write): 写a(append): 追加t(text): 文本文件,可省略不写b(banary): 二进制文件+: 读和写2) 凡用“r”打开一个文件时,该文件必须已经存在,且只能从该文件读出。3) 用“w”打开的文件只能向该文件写入。若打开的文件不存在,则以指定的文件名建立该文件,若打开的文件已经存在,则将该文件删去,重建一个新文件。4) 若要向一个已存在的文件追加新的信息,只能用“a”方式打开文件。但此时该文件必须是存在的,否则将会出错。5) 在打开一个文件时,如果出错,fopen将返回一个空指针值NULL。如果成功,则使fp指向对应的文件缓冲区起始地址。、文件的关闭(fc

23、lose函数)在使用完一个文件后应该关闭它,以防止它再被误用。“关闭”就是使文件指针变量不再指向该文件。其一般形式为:fclose(文件指针)例:fclose(fp);3、检查文件是否结束(feof函数)在使用文件过程中,为了防止文件指针移到文件末还要再向后移时出错,我们使用该函数来检查。其一般形式为:feof(文件指针)如果已经到文件末尾则为真,否则为假4、文件的读写常用函数:fputc函数fgetc函数fputc函数其调用形式fputc(ch,fp)ch是要输出的字符,它可以是一个字符常量,也可以是一个字符。Fp是文件指针变量。该函数的作用是将字符(ch的值)输出到fp所指向的文件中去。f

24、getc函数其调用形式ch=fgetc(fp);fp为文件型指针变量,ch为字符变量。Fgetc函数带回一个字符,赋给ch。例:从键盘上输入一些字符,逐个把它们送到磁盘上去,直到输入一个“”为止。includemain()FILE*fp;char ch,filename10;scanf(“%s”,filename);if(fp=fopen(filename,”w”)=NULL)printf(“cannot open filen”);exit(0);ch=getchar();while(ch!=#)fputc(ch,fp);putchar(ch);ch=getchar();fclose(fp);

25、5、fprintf函数和fscanf函数该两函数与prinf函数及scanf函数作用差不多。只是前两个的读写对象为文件,还后两个的对象是显示终端。其一般形式为:fprintf(文件指针,格式字符串,输出表列)fscanf(文件指针,格式字符串,输入表列)例:fprintf(fp,”%d,%f”,I,t);作用:将整型变量I和实型变量t的值按%d和%f的格式输出到fp指向的文件上。Fscanf(fp,”%d,%f”,&I,&t);作用:从fp指向的文件中按%d,%f格式读入到I,t变量中。6、fgets函数和fputs函数fgets函数的作用是从指定文件读入一个字符中。如:fgets(str,n

26、,fp);n为要求得到的字符个数,但只从fp指向的文件输入n-1个字符,然后在最后加一个0字符,因此得到字符串共有n个字符。Fputs函数的作用是向指定的文件输出一个字符串。如:fputs(“china”,fp);把字符串”china”输出到fp指向的文件。Fputs函数的第一个参数可以是字符串常量、字符数组名或字符型指针。7、文件定位函数(rewind函数)一般形式:rewind(文件指针)作用:使位置指针重新返回文件的开头。8、文件定位函数(fseek函数)一般形式:fseek(文件类型指针,位移量,起始点)起始点:用0(SEEK_SET)代表文件开始,1(SEEK_CUR)代表当前位置,

27、2(SEEK_END)代表文件末尾。例:fseek(fp,200L,0);将位置指针移到离文件头100个字节处fseek(fp,50L,1);将位置指针移到离当前位置50个字节fseek(fp,-10L,2);将位置指针从文件末尾向前移动10个字节9、fread函数和fwrite函数在我们需要读入或读出一组数据时,我们需要用到这两个函数,它们的一般形式如下:fread(buffer,size,count,fp)fwrite(buffer,size,count,fp);其中:buffer是一个指针。对fread函数是读入数据的存放地址。对fwrite函数是要输出数据的地址。Size:要读写的字节数Count:要进行读写多少个size字节的数据项Fp:文件类型指针

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

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

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


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