C语言习题解析【含基础知识讲解】_第1页
C语言习题解析【含基础知识讲解】_第2页
C语言习题解析【含基础知识讲解】_第3页
C语言习题解析【含基础知识讲解】_第4页
C语言习题解析【含基础知识讲解】_第5页
已阅读5页,还剩182页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C语言习题解析C语言习题解析第页voidmain(){charstr[200];printf("输入一个字符串:");scnaf(“%s”,str);printf(“%s\n”,str);printf(“%s\n”,flip(str));}【5】.输入一个字符串,串内有数字和非数字字符。例如:abc2345345rrf78jfkld945将其中连续的数字作为一个整数,依次存放到另一个整型数组b中。如对于上面的输入,将2345存放到b[0]、345放入b[1]..…,统计出字符串中的整数个数,并输出这些整数。要求在主函数中完成输入和输出工作。完善下面的程序。#include<stdio.h>intcton(char*p1,int*p){//转换函数,返回值是提取数字的个数intm,n=0;charc;while(①)if(c>='0'&&c<='9'){//遇到了一串数字的第一个; //将这个字符转换为一位数字while((c=*p1++)&&c>='0'&&c<='9')m=m*10+(c­48);//将这一串数字字符都转换为数字p[n]=m; //将转换好的字符放入数组; //提取出的数字增加1}returnn;}voidmain(){inti,n,a[20];charp[200];printf("请输入带有数字的字符串:");scan(“%s”,p);n=cton(p,a);printf("\n字符串:%s中包含&d个数字:",p,n);for(i=0;i<n;i++)printf(“%d\t”,a[i]);printf(“\n”);}四、链表部分【1】.有结构体类型说明如下:structnode{intdata;node*next;};Delete_Node函数是删除链表上数据值为num结点的函数,其中参数head是链表的头指针。请完善程序。node*Delete_Node(node*head,intnum){node*p1,*p2;if(head==NULL){cout<<"链表为空,无结点可删!\n";return(NULL);}if(head­>data==num){//如果要删除的是链表第一个结点p1=head;head=head­>next;deletep1;printf("删除了一个结点!\n");}else{p1=head;//p1指针在后p2=head­>next;//p2指针在前,寻找num的结点while(p2­>data!=num&&p2­>next!=NULL){p1=p2; ① ; //p2指针指向下一个结点}if(p2­>data==num){ ② ;//把p2指针指向的结点从链表中独立出来free(p2);printf("删除了一个结点!\n");}elseprintf("%d链表上没有找到要删除的结点!\n",num);}return(head);}【2】.有结构体类型说明如下:structnode{intdata;node*next;};ADD_Node函数是把孤立的、由p指针指向的结点加到链表的尾部,其中参数head是链表的头指针。请完善程序。node*Add_Node(node*head,node*p){node*p1=head;if(head==0)head=p;else{ while(p1­>next) ① ;//p1指针找到链表的最后一个结点 ② =p; //p指针指向的结点加到链表的尾部} p­>next=0; //加链表结束标志return(head);}【3】.设已建立一个单向链表,指针head指向该链表的首结点。结点的数据结构如下:structNode{intdata;Node*next;};以下sort()函数的功能是:将head所指向链表上各结点的数据按data值从小到大的顺序排序。具体实现方法:①开始时P1指向链表的首结点;②在链表后续所有结点中,找出data值最小的结点,由p2指针保存该结点地址;③把P1指针指向的结点与p2指针指向的结点的data值进行交换;P1指向下一个结点;重复②③,直至P1指向链表的最后一个结点。Node*sort(Node*head){Node*P1=head,*p2,*p3;if(P1==NULL)returnhead;while(p1­>next!=NULL){p2=p;p3=P­>next;while(p3!=NULL){ if( ① )p2=p3;p3=p3­>next;}if(p1!=p2){intt; t= ② ;p1­>data=p2­>data; ③ =t;}P1=p1­>next;}returnhead;}第8章文件8.1简介“文件”是由文件名标识的一组有序数据的集合,文件通常存储在磁盘等外部介质上。任何程序或数据信息欲长期保存,都需要以文件形式保存。文件的存取和管理由操作系统负责,文件名是进行文件存取的唯一标识。在C语言中,输入输出设备都可抽象为一个文件。如键盘是输入文件,显示器是输出文件。一般把存储在磁盘等外部介质上的文件统称磁盘文件。在程序设计过程中,磁盘文件非常重要,我们常常需要把设计好的源程序、以及在程序运行过程中,需要的原始数据和运行结果等输出到磁盘等外部介质上,以便今后需要时使用。本章只讨论存放在磁盘等外部介质上的数据文件。C语言中的数据文件可分为文本文件和二进制文件两种。文本文件又称ASCII文件,文件中存储数据信息单位是一个字节存放一个ASCII字符。二进制文件是将数据按其在内存中的存储形式直接存放到文件中。文件的处理方法分“缓冲”和“非缓冲”两种文件系统。但在标准C语言中规定,只采用缓冲文件系统。文件对数据的存取有两种方式:顺序存取和随机存取。顺序存取是依照数据的先后次序存取文件中数据。随机存取可以根据需要直接存取指定数据。和其他语言不同,在C语言中没有专门的输入/输出语句,C语言的标准库函数提供了输入函数和输出函数,完成输入/输出操作。8.2知识点文件类型指针文件的打开与关闭文件的顺序读写文件的随机读写8.3概念8.3.1文件类型指针程序中为了实现使用统一方法操作文件,引入了“文件指针”概念,“文件指针”是一个文件结构体FILE类型定义的指针,该文件结构体格式如下:typedefstruct{shortlevel;/*fill/emptylevelofbuffer*/unsignedflags;/*Filestatusflags*/charfd;/*Filedescriptor*/unsignedcharhold;/*Ungetccharifnobuffer*/shortbsize;/*Buffersize*/unsignedchar*buffer;/*Datatransferbuffer*/unsignedchar *curp;/*Currentactivepointer*/unsignedistemp;/*Temporaryfileindicator*/shorttoken;/*Usedforvaliditychecking*/}FILE;/*ThisistheFILEobject*/通过文件类型FILE可以定义文件类型的指针变量。例如:FILE*fp;其中:fp为文件指针,是FILE类型的指针变量。通过文件指针与数据文件建立关联,实现数据的存取。8.3.2文件的打开与关闭使用文件时,必须先打开文件,然后才能对文件进行读或写操作,操作完成后应关闭文件。在C语言中的标准输入输出库函数,提供了有关文件操作所需要的函数。包括文件的打开、读/写、关闭等操作函数。打开文件函数fopen()在C语言的标准输入输出库函数中,fopen()函数实现文件打开,使用fopen()函数前,首先需要定义文件指针,然后通过fopen()函数与数据文件建立关联。fopen()函数原型为:FILE*fopen(char*name,char*mode)其中:name是文件名,mode是文件读写方式,读写方式主要有字母r(只读)、w(只写)、a(尾部添加)、b(二进制文件)等及组合,见表8­1。使用格式为:fopen(“文件名”,“读写方式”)表8­1文件的读写方式读写方式含义r/rb只读方式打开一个文本文件/二进制文件w/wb只写方式打开或建立一个文本文件/二进制文件a/ab向文本文件/二进制文件尾部添加数据r+/rb+读/写方式打开一个文本文件/二进制文件w+/wb+为读/写方式建立一个新的文本文件/二进制文件a+/ab+为读/写方式打开文本文件/二进制文件,且在文件尾部添加数据。fopen()函数有返回值,当文件正常打开时,返回的为指向文件结构体的指针;当文件打开失败,则为NULL。关闭文件函数fclose()当文件使用完毕,应关闭文件。“关闭文件”是断开文件指针与文件的关联。在C语言中,fclose()函数完成文件关闭。fclose()函数原型为:intfclose(FILE*fp)在使用文件过程中,当文件操作结束,应关闭所有打开的文件,以保证数据文件中数据的完整。fclose()函数也有返回值,当文件顺利关闭时,返回值为0;否则返回EOF(或­1)。8.3.3文件的读写操作文件打开后,可以实现对文件的读/写操作。常用的文件的读/写操作函数有:1.fputc()函数和fgetc()函数在读写数据时,可以使用fputc()函数和fgetc()函数一次读写一个字符。(1).fputc()函数函数原型为:intfputc(intc,FILE*fp)其中:c是表示需要写入文件中的一个字符,fp必须是与一个具体文件建立关联的文件指针。函数的功能是把字符c写入fp所指向的文件中。fputc()函数有返回值,当写数据成功,则返回写入的字符;否则返回EOF(或­1)。(2).fgetc()函数函数原型为:charfgetc(FILE*fp)其中:fp必须是与一个具体文件建立关联的文件指针。函数的功能是把从fp所指向的文件中读取一个字符作为返回值。在读取数据过程中,利用fgetc()函数返回值读取,但当遇到文件结束符时,函数返回文件结束符EOF(或­1)。fwrite()函数和fread()函数fputc()函数和fgetc()函数每次只能读写一个字符,但在实际使用过程中,希望一次读写获取一个完整的数据(如实数、结构体类型的数据等),这就需要使用fwrite()函数和fread()函数。这两个函数原型分别为:size_tfread(void*buffer,size_tsize,size_tn,FILE*fp)size_tfwrite(void*buffer,size_tsize,size_tn,FILE*fp)其中:指针buffer是指向要读/写数据块的首地址的指针;size是每个要读/写的数据块的大小(字节数);n是要读/写的数据块的个数;fp是与一个具体文件建立关联的文件指针。Size_t是由typedefunsignedsize_t说明的。fread与fwrite一般用于二进制文件的读/写操作。函数有返回值,当读/写数据成功,则返回读/写数据的块数;否则返回0。fprintf()函数和fscanf()函数fprintf()函数和fscanf()函数与printf()函数和scanf()函数作用相似,实现格式化读写操作,其中printf()函数和scanf()函数的操作对象是键盘和显示器,而fprintf()函数和fscanf()函数的操作对象是文件。这两个函数原型分别为:intfprintf(FILE*fp,constchar*format,...)intfscanf(FILE*fp,constchar*format,...)其中:fp必须是与一个具体文件建立关联的文件指针;format为格式字符串以及后续的输入/输出表项。其他读写函数(1).fputs()函数与fgets()函数当需要对整个字符串进行整体读写操作时,可使用fputs()函数与fgets()函数。这两个函数原型分别为:intfputs(char*s,FILE*fp)char*fgets(char*s,intn,FILE*fp)这两个函数的功能是从fp所指向的文件中读/写一个字符串。其中fputs()函数把s指向的字符串写入fp指向的文件;fgets()函数从fp所指文件读n­1个字符送入s指向的内存区。正常写入字符串时,fputs()函数返回写入的最后一个字符;否则为EOF。正常读取字符串时,fgets()函数返回读取字符串的首地址;否则返回NULL。(2).putw()函数与getw()函数当需要一次读写一个整数时,可使用putw()函数与getw()函数。这两个函数原型分别为:intputw(intw,FILE*fp)intgetw(FILE*fp)这两个函数的功能是从fp所指向的文件中读/写一个整数。其中putw()函数把整数w写入fp指向的文件;getw()函数从fp所指文件读取一个整数返回。8.3.4文件的定位操作在对文件的读/写操作过程中,有时候并不希望按照顺序方式读写,而是按照需要直接读写指定位置的数据,这就需要通过指针直接指向欲读写数据的位置(定位)。常用的定位操作函数有:rewind()函数函数原型为:voidrewind(FILE*fp)该函数的功能是重置文件位置指针到文件开头的位置。fseek()函数函数原型为:intfseek(FILE*fp,longoffset,intwhence)其中:offset表示位移量;whence是起始点。该函数的功能是改变文件位置指针到以起始点为基准加上位移量的位置。当指针移动后,指向文件中的有效位置,函数返回值为0;否则返回非0值。ftell()函数函数原型为:longftell(FILE*fp)该函数的功能是返回位置指针的当前位置(用相对文件开头的位移量表示)。当位置指针在文件中的有效位置,函数返回当前位置指针的位置;否则返回­1。8.3.5出错及测试函数feof()函数函数原型为:intfeof(FILE*fp)该函数的功能是用来判断文件是否结束。在文件操作过程中,文件中数据是否已经读取结束,可以通过feof()函数测试fp所指向的文件当前状态是否为“文件结束”。如果是文件结束,函数的返回值为1(真),否则为0(假)。ferror()函数函数原型为:intferror(FILE*fp)该函数的功能是测试文件是否出现错误。在文件操作过程中,如果出现错误,操作函数本身可以通过函数返回值表示出来,也可以通过ferror()函数检查是否产生错误。当ferror()函数的返回值为“0”表示未出错,否则表示出错。clearer()函数 函数原型为: voidclearerr(FILE*fp)该函数的功能是把文件错误标志置为0。由于文件操作过程中,一旦出错后,错误标志会一直保留,因此在错误得到处理后,可以通过该函数重置文件错误标志。8.4习题解析选择题【1】.对于文件打开方式”rb+”描述正确的是__________。 A.可读写文本文件 B.只读文本文件C.可读写二进制文件 D.只读二进制文件参考答案:C。解析:“b”说明该方式用于二进制文件,而不是文本文件;“r+”用于读写,而不是只读。具体格式“r+/rb+”方式,要求该文件应该已经存在,可以从该文件中读入或写入数据。其他的打开方式:“w+/wb+”要求建立一个新文件,建立后先向该文件写入数据,然后也可以从该文件中读取数据。“a+/ab+”要求把原来的文件内容不被删去,文件打开后,将位置指针移到文件末尾,在文件末尾添加数据,也可以读数据。【2】.C语言的数据文件类型分为__________。 A.文本文件和顺序文件 B.顺序文件和随机文件C.文本文件和二进制文件 D.数据文件和文本文件参考答案:C。解析:C语言中数据文件分为两类:文本文件和二进制文件。【3】.下列语句中把p定义为一个文件指针的是__________。 A.FILE*pB.FILEp C.filep D.file*p参考答案:A。解析:文件指针是由文件类型FILE(大写字母FILE)所定义的指针变量。定义文件指针的目的,是通过文件指针与数据文件建立关联,实现数据的存取。【4】.系统提供的文件尾测试函数是__________。A.feof()B.fgetc()C.fseek()D.rewind()参考答案:A。解析:在文件操作过程中,文件中数据是否已经读取结束,可以通过feof()函数测试fp所指向的文件当前状态是否为“文件结束”。如果是文件结束,函数的返回值为1(真),否则为0(假)。fgetc()函数是读取一个字符函数;fseek()是文件指针定位函数;rewind()是把文件指针置到文件头函数。阅读程序题【1】.分析下面程序,当程序连续运行两次以后,其运行结果是 。#include<stdio.h>#include<stdlib.h>voidmain(){FILE*fp; //定义文件指针charch,st[20]="abc",*p=st;if((fp=fopen("string","a+"))==NULL)//文件名:string打开方式:尾部添加方式{printf("不能打开文件!按任何键退出");exit(1);}while(*p++); //Ap­=2; //B//A、B两行是把指针定位到字符串的最后一个字符位置while(st<=p){fputc(*p,fp);p­­;}//把指针p所指向的字符写入到文件rewind(fp);//把文件位置指针重新置于文件开头ch=fgetc(fp);//从文件中读取字符while(ch!=EOF){//当读取数据时,文件没有结束继续读取putchar(ch);//把字符ch输出到标准输出设备ch=fgetc(fp);}printf("\n"); fclose(fp); //关闭文件}参考答案:cbacba解析:该程序的功能是把字符串st中的字符,反序写入到数据文件string中,由于文件的打开方式是尾部添加方式,所以第一次写入文件的数据是cba,第二次运行时,由于是尾部添加方式,将会在原数据cba的基础上再写入cba。温馨提示:如果希望每次运行输出的结果一样,可把文件打开方式改为以读写方式新建一个文件“w+”。【2】.分析下面程序,当程序的运行结束后,数据文件data.dat保存的结果是。#include<stdio.h>#include<stdlib.h>voidmain(){FILE*fp;if((fp=fopen("data.dat","w+"))==NULL)//文件名:data.dat打开方式:读写方式新建文件{printf("不能打开文件!按任何键退出");exit(1);}inti;for(i=10;i<20;i++)if(i%3==0)continue;elseputw(i,fp);rewind(fp);i=getw(fp);while(i!=EOF){printf("%d\t",i);i=getw(fp);}fclose(fp);}参考答案:10111314161719解析:程序中循环控制变量i共循环10次,取值范围为10~19,其中能被3整除的没有输出到数据文件,其余的才通过putw函数int类型数据写入到文件。【3】.下面程序中字符串,单词间只有一个空格,分析程序,写出程序的运行结果 。#include<stdio.h>#include<stdlib.h>voidmain(){charc,*str="Youareastudent!";FILE*fp;if((fp=fopen("mydata.dat","w+"))==NULL)//文件名:data.dat打开方式:读写方式新建文件{printf("不能打开文件!按任何键退出");exit(1);}fputs(str,fp);rewind(fp);c=fgetc(fp);while(c!=EOF){if(c=='')printf("%d\t",ftell(fp));c=fgetc(fp);}fclose(fp);}参考答案:4810解析:程序中按读/写方式打开一个文件,先写入一个字符串,通过rewind(fp);语句把文件指针定位于文件开始位置,然后依次读取字符,当读取字符为空格,则通过ftell()函数得到当前字符的位置。值得注意的是,起始字符从0开始,字符串空格位置应该是3、7和9,但程序结果为4、8和10,原因是读取字符空格后,文件指针已经移到后面的一个字符上,所以程序输出的是空格后的字符位置。三、完善程序题【1】.下面程序的功能是把数组中所有偶数输出到数据文件data.dat中,其他数据输出到显示器,请完善程序。#include<stdio.h>#include<①>voidmain(){inta[10]={1,2,3,4,5,6,7,8,9,10};FILE*fp; if(( ② =fopen("data.dat","w+"))==NULL){printf("不能打开文件!按任何键退出");exit(1);}for(inti=0;i<10;i++){ if(a[i]%2==0) ③ ; else ④ ("%d\t",i);}fclose(fp);}参考答案:①stdlib.hfpfprintf(fp,"%d",i);printf解析:①程序中需要exit()函数,要求包含stdlib.h头文件。②打开文件时,文件指针需要通过fopen()函数与数据文件建立关联。③当要求把偶数(整型数据)写到数据文件,可通过fprintf()函数。④程序要求不是偶数时,输出到显示器,因此应该使用printf函数输出。【2】.把上面建立的数据文件data.dat中的数据读出并输出到显示器,请完善程序。#include<stdio.h>#include<stdlib.h>voidmain(){inta; FILE ① ;if((fp=fopen("data.dat","r+"))==NULL){printf("不能打开文件!按任何键退出");exit(1);}while(fscanf ② !=­1)printf("%d\t",a);fclose(fp);}参考答案:①*fp②(fp,"%d",&a)解析:实现文件操作时,首先需要通过FILE定义文件指针,指针名字可以通过下面打开文件时的指针名字确定。使用fscanf语句从文件中读数据是,其格式为:第一个参数是文件指针,第二参数是读数据格式,第三参数是存放数据的地址列表。8.5同步练习题一、选择题【1】.如果打开文件时,选用的文件操作方式是”wb+”则下列说法中正确的是__________。 A.要打开的文件必须存在 B.打开文件后只能读数据 C.打开文件时可以建立新文件 D.打开文件后只能写数据【2】.下列关于文件随机定位函数fseek()的描述正确的是__________。A.若定位正确返回非零值B.包含在头文件stdlib.h中C.本函数只能用于二进制文件D.本函数可以使用文件内部指针直接指向需要的某个数据【3】.C语言早期规定建立文件缓冲区采用的形式是__________。 A.缓冲文件系统 B.非缓冲文件系统 C.分页文件系统 D.A&B【4】.fgetc函数是从指定文件读人一个字符的函数,下列有关描述正确的是__________。 A.只能读二进制文件 B.只能读文本文件 C.其参数是一个指针变量 D.其参数是一个字符串【5】.包含用户类型符“FILE”的定义的头文件是__________。A.string.hB.file.hC.stdio.hD.stdlib.h二、阅读程序题【1】.分析下面程序,写出程序的运行结果。#include<stdio.h>#include<stdlib.h>voidmain(){charstr1[]="Youareastudent!";charstr2[]="Iamastudent!",str3[20];FILE*fp;if((fp=fopen("mydata21.dat","w+"))==NULL){printf("不能打开文件!按任何键退出");exit(1);}fprintf(fp,"%s\n",str1);fprintf(fp,"%s\n",str2);rewind(fp);fscanf(fp,"%s",str3);printf("%s\n",str3);fclose(fp);}【2】.分析下面程序,写出程序的运行结果。#include<stdio.h>#include<stdlib.h>voidmain(){charstr1[]="You_are_a_student!";charstr2[]="Iamastudent!",str3[20];FILE*fp;if((fp=fopen("mydata22.dat","w+"))==NULL){printf("不能打开文件!按任何键退出");exit(1);}fprintf(fp,"%s\n",str1);fprintf(fp,"%s\n",str2);rewind(fp);fgets(str3,12,fp);printf("%s\n",str3);fclose(fp);}【3】.分析下面程序,写出程序的运行结果。#include<stdio.h>#include<stdlib.h>voidmain(){FILE*fp;if((fp=fopen("mydata23.dat","w+"))==NULL){printf("不能打开文件!按任何键退出");exit(1);}inti,n;for(i=0;i<10;i++){if(i%2==0)continue;putw(i,fp);}rewind(fp);for(i=0;i<5;i++){n=getw(fp);printf("%d\t",n);}fclose(fp);}三、完善程序题【1】.下面程序是先把字符串中除a字符外的所有字符写到数据文件“mydata31.dat”中,然后将数据文件中的所有字符读出,输出到显示器上。#include<stdio.h>#include<stdlib.h>voidmain(){charstr[]="examinationmarks";FILE*fp;if((fp=fopen("mydata31.dat","w+"))==NULL){printf("不能打开文件!按任何键退出");exit(1);}charc,*p=str;while(*p){ if(*p!='a') ① ;p++;}rewind( ②c=fgetc(fp););while( ③{printf("%c",c);c=fgetc(fp);})fclose( ④printf("\n"););}【2】.下面程序是从键盘输入10个整数,并把输入的数据写到数据文件“mydata32.dat”中,而后读出数据并输出到屏幕。请完善程序。#include<stdio.h>#include<stdlib.h>voidmain(){FILE*fp;if((fp=fopen("mydata31.dat","w+"))==NULL){printf("不能打开文件!按任何键退出");exit(1);}inti,n;for(i=1;i<=10;i++){scanf("%d",&n); putw( ① );}rewind(fp);for(i=1;i<=10;i++){n= ② ;printf("%d\t",n);}fclose(fp);printf("\n");}第9章综合训练9.1习题解析一、阅读程序题【1】.下列程序的输出结果是。#include<stdio.h>voidmain(){charch[2][5]={"6934","8254"};char*p[2];inti,j,s=0;for(i=0;i<2;i++)p[i]=ch[i];for(i=0;i<2;i++)for(j=0;p[i][j]>'\0'&&p[i][j]<='9';j=2)//As=10*p[i][j]­­­'0';//Bprintf(“%d\n”,s);}参考答案:­38解析:本题的考点是指针数组和字符与其代码的转换。使用指针数组来处理二维字符数组。程序中定义了一个二维字符数组ch和一个指针数组p,让p的每一个元素指针对应指向ch的行地址(p的第0个元素指针指向ch的第0行,以此类推)。行的for循环语句中,其第3表达式为j=2,则表达式2中的字符p[i][j]位置固定,很容易造成死循环。该问题通过B行得以很巧妙的解决。行的表达式“10*p[i][j]­­­‘0’”的计算颇为精致,它的执行过程是这样的:首先将字符p[i][j]转换为对应的ASCII代码,然后将此代码乘10,再减去字符’0’的ASCII代码(为48),最后执行p[i][j]­­(字符p[i][j]的代码­­)。循环体中的“p[i][j]­—”起关键作用,因为i和j的值不变,因此在“for(j=0;…)”循环中每次“­­”的都是同一个字符(i=0时是p[0][2],i=1时是p[1][2])。不管它们原来是什么字符,经过不断的“­­”后,最终都变为’0’。而s的值随着字符p[i][j]的变化也在不停的变化,循环“for(j=0;…)”结束的条件是“p[i][j]>'\0'”,也就是字符p[i][j]的代码为0。s的最后一次取值是p[i][j]变为’\0’的前一次,也就是p[i][j]的ASCII码为1时,这时s的值为10*1­48=­38。“for(i=0;…)”循环了2次,每次所计算出的s都是­38,屏幕输出的是后一次,也就是i=1时所计算出的s。【2】.写出以下程序执行时的屏幕输出。#include<stdio.h>intsum(intp[],int*w,intn){inti,s=0,m=0;for(i=0;i<n;i++){s+=p[i];if(p[i]>m){m=p[i];*w=i;}}returns;}voidmain(){intaa[3][3]={2,4,8,7,5,3,2,6,9};introw[3],col[3]={0,0,0};for(inti=0;i<3;i++){row[i]=sum(aa[i],col+i,3);printf("row(%d)=%d\n",i,row[i]);}for(i=1;i<3;i++)printf("第%d行位置:%d\n",i,col[i]);}#include<stdio.h>intsum(intp[],int*w,intn){inti,s=0,m=0;for(i=0;i<n;i++){s+=p[i];if(p[i]>m){ m=p[i]; *w=i;}}returns;}voidmain(){intaa[3][3]={2,4,8,7,5,3,2,6,9};introw[3],col[3]={0,0,0};for(inti=0;i<3;i++){row[i]=sum(aa[i],col+i,3);printf(”row(%d)=%d\n”,i,row[i]);}for(i=1;i<3;i++)printf(”第%d行位置:%d\n”,i,col[i]);return;}参考答案:row(0)=14row(1)=15row(2)=17第1行位置:0第2行位置:2解析:本题的考点是指针作为参数的函数调用。程序中两个函数,函数sum有3个参数,第一个为一维数组,第二个为指针,第三个指出第一个参数数组的大小。函数sum的功能是求一维数组各元素的累加和(s)以及数组中最大元素(值为m)所在的下标(*w)。s的值通过return语句返回传给主函数。因为形参指针等于实参指针,就是形参指针和实参指针指向同一个变量(主函数中的col[0]、col[1]和col[3]),因此在函数sum中对形参指针内容*w的赋值就是对主函数中数组col诸元素的赋值。这样就巧妙的通过指针传递的方式把多个值传回了主函数。主函数中定义了3个数组:aa、row和col。主函数通过一个循环,将二维数组aa每行元素值的和,通过调用函数sum计算并通过函数值返回存放于一维数组row的各元素中。同时通过函数sum找出aa数组每行中最大元素所在的列下标,通过指针返回存放于一维数组col的各元素中。显然,aa各行元素值的和分别为:14、15和17,因此在屏幕上有参考答案所示的输出。主函数只输出了aa的1行和2行最大元素所在的列下标,对照aa的定义,很容易知道有如参考答案的后两行输出。【3】.运行以下程序时,如果从键盘输入ABCDE<回车>,则输出结果为_____。#include<stdio.h>func(charstr[],intnum){while(*(str+num))num++;return(num);}voidmain(){charstr[10],*p=str;scanf("%s",p);printf("%d\n",func(p,0));}参考答案:5解析:在本题的假设中,函数func收到的实参是字符串“ABCDE”和数字0。在循环语句while中,表达式*(str+num)中的num依次为0、1、2、3、4、5,共6次,*(str+num)依次为’A’、’B’、’C’、’D’、’E’、’\0’。前5次循环num都加了1,最后1次因为循环条件表达式的值为’\0’而结束,num没能加1,因而函数返回的是5。二、完善程序题【1】.下面的程序打印杨辉三角形的前10行。11112113311464115101051161520156117213535217118285670562881193684126126843691①#defineN11voidmain(){inti,j;inta[N+1][N+1];for(i=1;i<=N;i++){a[i][i]=1; //A ② ;}for(i=2;i<=N;i++)for(j=2;j<1;j++)③;for(i=1;i<N;i++){j=N­i;while(j>0){printf(““);j­­;}for(j=1;j<=i;j++)printf(“%d\t”,④);printf(“\n”);}printf(“'\n”);}参考答案:①#include<stdio.h>a[i][1]=1a[i][j]=a[i­1][j­1]+a[i­1][j]a[i][j]解析:杨辉三角形有两个特点:一是两个边上的值均为1;二是三角形内部的每个元素值均为其两个肩膀上元素值之和。A行是在对三角形的“右腰”元素赋值,②是对“左腰”元素赋值,就是a[i][1]=1.③处是对三角形内部各元素赋值的,根据“双肩”元素的表示规则,有答案③。④是输出杨辉三角形各元素的,所以有a[i][j]。【2】.下面程序中的函数substr将字符串s1中所包含的第一个子字符串s2删除。如果s2包含在s1中,则函数返回值就是从s1的字符串中删除第一个s2后的字符串。如果s1中不包含s2,则返回一个空指针。例如s1字符串为“abcdefg”,s2字符串为“def”,则返回值为“abcg”。请完善该程序。#include<stdio.h>#include<string.h>char*substr(char*s1,char*s2){char*t,*p1=s1,*p2;inti=0,len=strlen(s2); if(p2=① ){ //如果s1中包含s2t=newchar[strlen(s1)­len+1];//申请堆空间while(p1<p2)//此循环将s1中的s2之前的字符复制到新对象中;p1+=len; //移动指针到s1中s2之后的位置 while(t[i++]=*p1++); //A//将s1中s2之后的字符添加复制到新对象中}else{//如果s1中不包括s2,就将s1整个的赋值到新对象中t=newchar[strlen(s1)+1]; strcpy(t,s1); //赋值字符串};}voidmain(){charch1[20],ch2[10],*p1;printf("请输入母串:");scanf(“%s”,ch1);printf("\n请输入子串:");scanf(“%s”,ch2);p1=substr(ch1,ch2);if(p1!=NULL)printf(“%s\n”,p1);elseprintf("母串%s中没有子串%s\n",ch1,ch2);}参考答案:①strstr(s1,s2)t[i++]=*p1++returnt解析:在①处,判断s1中是否包含s2,本来使用函数strstr就可以了,因为如果包含,要将子串在母串中的位置指针赋值给p2,所以将这两个要求结合在一起就有①“p2=strstr(s1,s2)” 。赋值字符的操作应该是:源指针(p1)和目标指针指向开始的位置;复制一个字符;指针向后移动一个字符位置。如此循环一直到源指针移动到p2位置为止。这里目标采用的是字符数组形式,指针移动用下标增值来实现,这就是②的表示法。类似的的例子还有A行。函数substr的返回值是一个字符指针,该指针指向一个“差串”,t就是这样一个指针。所以有③。三、改错题【1】.下列程序用来向已有n个已排序的元素的数组x中插入一个数key,插入key后使数组x保持仍然有序。使用的方法为前插法。此程序存在一些错误,要求将错误找到并改正,只允许在原语句上进行修改,可以增加个别说明语句,但不能增加或删除整条程序语句或修改算法。含错误的源程序: #include<stdio> //Avoidsort(intx[],intn,intkey);{for(inti=0;i<n;i++)//找出key要插入的位置iif(key<=x[i])return;//Bif(i=n)x[n]=key;//C//如果key大于数组x中的每一个数,则将key插入到位置nelse{for(intj=n;j>i;j­­)x[j]=x[j­1];//空出位置ix[i]=key;}//在i位置上插入数key}voidmain(int){inti,y[20]={1,3,5,7,9,11,13,15,17,19};printf("插入12前的十个数为:");for(i=0;i<10;i++)printf(“%d”,x[i]); //Dprintf(“\n”);sort(y,10,12);printf("插入12后的十一个数为:");for(i=0,i<11;i++)printf(“%d“,y[i]);printf(“\n”);}参考答案:①A行,改“stdio”为“stdio.h”B行,改“return”为“break”C行,改“i=n”为“i==n”D行,改“x[i]”为“y[i]”解析:本题的插入算法为:将key与数组中的每一个元素从前往后依次比较,若小于或等于某一元素则将key插入到该元素的前面。如:欲在1,3,5,7,9中插入数值8,将8与1~9的每个数比较,由于8小于9,则应插到9的前面。插入步骤分为三步:第一步:找出key要插入的位置。第二步:将此位置空出来。第三步:将key插入到此位置。行是一个语法错误,容易看出。D行类似,误将数组y写成了x。行是逻辑错误,该循环是找一个适合插入的位置,找到后应该停止查找,使用了return意即找到后什么也不做,改成break符合题意。行是语法错误,判断相等应该使用运算符“==”。【2】.求二维数组的鞍点及其所在的行号和列号。二维数组的鞍点是指该元素在其所处行上最大,且在其所处列上最小。算法是:先求出第i行的最大值,(i=0,1,2,…,M­1),M是二维数组的行数,然后再判断该最大值在它所在的列中是否为最小值。其中函数intsaddle(inta[3][4],int&row,int&col),通过第二、第三个参数带回鞍点所在的行号和列号,如果有鞍点,函数返回1,否则返回0。以下是程序正确的运行结果:126432534867row=1,col=2value=5含有错误的源程序如下:#include<stdio.h>intsaddle(inta[3][4],int&row,int&col){inti,j,flag,max;for(i=0;i<3;i++){max=a[i][0];col=0;for(j=1;j<4;j++)//Aif(a[i][j]>max)max=a[i][j];col=j;//Bflag=0;for(j=0;j<3;j++)if(max<a[j][col])//C{flag=1;break;} if(flag=0) //D{row=i;return(1);}}return(0);}voidmain(){inta[3][4]={{1,2,6,4}{3,2,5,3}{4,8,6,7}};inti,j,row,col;for(i=0;i<3;i++){for(j=0;j<4;j++)printf(“%d\t”,a[i][j]);printf(“\n”);}ifsaddle(a,row,col){printf("row=%d,col=%d\n",row,col);printf("value=%d\n",a[row][col]);}elseprintf("Notfound!\n");}参考答案:①A行,改“for(j=1;j<4;j++)”为“for(j=0;j<4;j++)”B行,改“max=a[i][j];col=j;”为“{max=a[i][j];col=j;}”C行,改“max<a[j][col]”为“max>a[j][col]”D行,改“if(flag=0)”为“if(flag==0)”解析:A行的“j=1”将会漏掉第0列。B行少了大括号将不能记录行最大值所在的列号。C行使用“<”号测试的是行最大值是否也是所在列的最大值。D行是语法错误。本题使用了函数参数的引用传递。四、算法解析【1】.用迭代法编程求x=a,求平方根的迭代公式为:axn+1=xn+ Ł xnł解析:使用C语言来实现数学上诸如此类的迭代公式是有一定定式的,即下述要点。编程时有两个要点:一是设定结束条件的循环(一般使用do或while),二是“变量迭代”。在数学上计算时,可以使用x0,x1,x2,……,xn,xn+1等多个变量。但是从编程的角度看,只要两个变量x0和x1就够了,x0用来表示计算前项(相当于迭代公式中的xn),x1表示计算后项(相当于迭代公式中的xn+1)。在计算x1时,x1就是后项,计算完毕,它立刻又成为前项(可用x0=x1实现),这就是所谓的“变量迭代”。这样的迭代在编程中经常使用。本例中的循环结束条件是|xn+1­xn|<ε(ε是一任意小的正数),此条件用C语言来表示就是fabs(x1­x0)<EP,fabs是定义在头文件math.h中一个求绝对值的函数,EP是一个常数。使用迭代法时,首项x0(称为初值)不是计算出来的,需要指定。指定初值时要注意所指定的值对本迭代公式是否有意义,例如本例中就不能指定x0为0,因为有a/x0存在。本例中指定其值为0.5。根据上述解析所设计的程序代码如下:#include<stdio.h>#include<math.h>#defineEP1e­8voidmain(){floatx0,x1,a;//为了迭代方便,初值要先赋值给后项xnprintf("a=");scanf("%f",&a);x1=a/2;do{x0=x1;x1=0.5*(x0+a/x0);}while(fabs(x1­x0)>EP);printf("a开平方根=%f\n",x1);}【2】.统计数字和串中零的个数以及各位数字的最大值。解析:本程序统计一个数据中各位数字值为零的个数,以及各位数字的最大值。例如,若输入字符串“abc103de4060x”,则数字值为零的个数为3,各位上数字值最大的是6。函数fun用来统计整数中各位数字值为零的个数,通过引用类型的形参传回主函数,找出该整数中各位上最大的数字值作为函数值返回。参考代码如下,注意阅读其中的注释。#include<stdio.h>#include<math.h>intfun(char*p,int&zero){intmax=0;zero=0;while(*p){if(*p=='0')zero++;if(*p>='0'&&*p<='9')if((*p­'0')>max)max=*p­'0';p++;} returnmax; //返回最大值}voidmain(){intzero,max;charcnum[40];printf("输入一个字符串:");scanf("%s",cnum);max=fun(cnum,zero);printf("\n字符串%s的结果为:max=%dzero=%d\n",cnum,max,zero);}9.2同步练习题一、阅读程序题【1】.有下列程序:#include<stdio.h>voidmain(){inti,*i_pointer=&i;i=10;printf("Outputinti=%d\n",i);printf("Outputintpointeri=%d\n",*i_pointer);}#include<stdio.h>voidmain(){inti,*i_pointer=&i;i=10;printf("Outputinti="<<i<<endl;printf("Outputintpointeri="<<*i_pointer<<endl;} 写出程序的运行结果、 。【2】.阅读下列程序,指出运行结果。#include<stdio.h>intadd(inta,intb){returna+b;}intmax(inta,intb){return(a>b?a:b);}voidmain(){intx,(*p)(int,int);//定义了一个指向函数的指针pp=add; //将函数add的入口地址赋给px=(*p)(10,20); //调用指针p所指向的函数printf("%d\n",x);p=max; //将函数max的入口地址赋给px=(*p)(10,20);printf("%d\n",x);}二、完善程序题【1】.用递归方法求两个数的最大公约数。#include<stdio.h>intgcd(int,int);voidmain(){intx,y;printf("x,y=");scanf(“%d%d”,x,y); printf("x,y===%d\n", ① );}intgcd(intx,inty){if(x%y==0)returny; returngcd(y,② );}【2】.若正整数n是它尾部的平方数,则称n为同构数。例如,6是其平方数36的尾部,76是其平方数5776的尾部,6与76都是同构数。找出1000以内的所有同构数。#include<stdio.h>#include<math.h>constintN=1000;voidmain(){inti,j,m;floatx;for(i=10;i<N;i++){ x=① ;//同构数的平方根必然是整数if(x==int(x)){k=i;j=10;//如果其平方根是整数while(j<i){//因为不知尾部数字有几位数字,就进行逐位试探 m=② ; //取出尾部n位数字(n=1,2)if(m==x)printf("%d是同构数!\t",i); ③ ;}}}printf("\n");}三、改错题【1】.以下程序为字符串升序排序。在程序中用一组指针指向一组字符串,用交换指针而不是交换字符串的方式来排序。程序中存在错误,请改正之。#include<stdio.h>#include<string.h>voidmain(){char*str[5],p;//*str[5]为指针数组,每个元素是字符型指针inti,j,k;for(i=0;i<5;i++){//输入5行字符串printf("String%d:",i+1);str[i]=newchar[100];cin.getline(str[i],100);}for(i=0;i<4;i++){k=i;for(j=i+1;j<5;j++)if(strcmp(str[k],str[j])>0)k=j;if(k==i){p=str[k];str[k]=str[i];str[j]=p;}}printf("Output:\n");for(i=0;i<5;i++){ //输出排序后的字符串printf("%s\n",str[i]);delete[]str[i];}}【2】.这是一个删除有序数组中元素的程序,程序中的函数sub(float&p,floatx)用于把数组中的数x删除,实数x删除后,数组还应保持有序。含有错误的源程序如下:#include<stdio.h>voidsub(float*p,floatx){while(p!=x&&*p!=0)p++;//查找x,如果指针p指向的内容不是x,继续往后查找if(*p=x){ //如果找到,即p指针所指向的内容和x相同while(*p){ //后面的数往前移动一个数字*p=*(p­1);p++;}}}voidmain(){floatx,f[20]={2,4,6,8,10,12,14,16,18};intj=0; scanf("%f",&x); //输入数据为0时程序结束while(x!=0){//可以连续删除多个数字sub(f[],x);scanf(x;}for(j=0;j<20;j++)printf("%f\t",f[j]);printf("\n");}四、上机编程题【1】.数字处理(1).定义一个函数intdigit(intx),功能是分别取x的最高位数字a,和x的最低位数字b,然后交换a和b的位置(如:对3568处理得到8563)。先检查x值,若x为4位数则返回处理结果,否则返回0。(2).主函数负责测试。从键盘输入5个各不相同的4位正整数,调用函数digit对数据进行处理。若返回结果非0,则屏幕输出返回的结果信息,若返回0则提示重新输入一个数进行处理。(3).输出格式为:Swap(<x值>)=<结果值>。【2】.建立一个4行N列的二维整型数组intdata[4][N],并赋初值给第0行、第1行和第2行,其中N是宏定义的标识符,其值不小于5。调用函数max(…)求各列三个元素中的最大值,并将结果存入数组data第3行该列的变量中。按4行N列的格式输出数组data的数据,并控制每列数据对齐。121341511789561231410【提示】(1).设计一个函数intmax(inta,intb,intc)参数为三个整型变量a、b和c,功能是求出并返回这三者中的最大值。(2).结果存入数组data第3行该列的变量中r的方法可以是:data[3][j]=max(data[i][j],data[i+1][j],data[i+2][j])【3】.验证歌德巴赫猜想。 歌德巴赫猜想猜想:任何一个大偶数(大于2的偶数)都可以分解为两个素数之和。例如:4=2+2 ,12=5+7,20=3+17。编写一个程序,对于一个任意由键盘输入的大偶数(正整数)找出可以验证歌德巴赫猜想的一对素数,并输出之。输出的格式类似“6=3+3”。【提示】(1).设计一个函数intdetect(intd),用来测试一个整数是否为素数;(2).主函数中用循环来逐个测试可能为素数并小于该偶数x的数字f,每次测试调用函数detect完成。如果所测试的数字是素数,就计算s=x­f,并测试s是否为素数,如果是,程序结束,如果不是,则弃f不用,继续循环测试f的下一个数字。【4】.学生成绩排序问题。编写一个程序,使用结构数组存储数据,使用指针处理数据,实现学生按字典顺序排序。【提示】(1).定义一个如下的结构来表示一个学生:structstudent{charname[9];intscore;};(2).在主函数中定义一个具有10个元素的结构数组,初始化给出10个无序的学生数据。并定义一个指针指向该数组。(3).在排序前先输出学生列表,每行一个学生,有列标题。(4).定义一个排序函数:voidnsort(students[],introw),对所传递过来的结构数组进行排序,排序结果用参数传回主函数。(5).主函数调用排序函数对结构数组进行排序,然后输出已排序结构数组,具体要求同前。【5】.阿拉伯数字形式的人民币数字转换为汉字大写数字。在许多情况下,需要将阿拉伯数字形式的人民币数字转换为汉字大写形式。要求编写一个通用函数,能实现这种转换,假设数字在千万元以内,带有两位小数。【提示】(1).设计一通用函数char*dx(intx)完成转换。(2).在主函数内输入阿拉伯数字,调用函数dx来转换。并在主函数中输出转换结果。格式为:小写:109.05大写:壹佰零玖圆零伍分整(3).主函数可以连续多次输入阿拉伯数字,输入负数表示结束。(4).汉字大写数字使用:零壹贰叁肆伍陆柒捌玖拾万仟佰拾圆。(5).汉字大写必须以汉字“整”结尾。汉字大写读起来必须符合习惯。9.3C语言模拟试卷9.3.1C语言模拟试卷(一)一、选择题【1】.以下叙述中正确的是______。构成C程序的基本单位是函数可以在一个函数中定义另一个函数main()函数必须放在其它函数之前所有被调用的函数一定要在调用之前进行定义【2】.下面的常量表示有一个是不正确的,不正确的是 。 A.­0 B.0x203 C.’\55’ D.’103’【3】.已知大写字母A的ASCII码是65,小写字母a的ASCII码是97,则用八进制表示的字符常量’101’是______。A.字符AB.字符aC.字符eD.非法的常量【4】.若有a=13,b=5,c=3则a%b*c的值为。A.6B.9C.7.8D.8【5】.下列表达式中,错误的是 。 A.4.0%2.0 B.k+++j C.a+b>c+d?a:b D.x*=y+25【6】.若有说明char*str1=”copy”,str2[10],str3=”hijklmn”,*str4,*str5=”abcd”;则是对strcpy()函数的正确调用是 。 A.strcpy(str2,str1) B.strcpy(str3,str1) C.strcpy(str4,str1) D.strcpy(str5,str1)【7】.设有变量说明:char*p="abcded\0fg";则sizeof(p)的值是。 A.1 B.4 C.6 D.10【8】.以下非法的赋值语句是______。 A.n=(i=2,++i); B.j++; C.++(i+1); D.x=j>0;【9】.设有变量定义inta[3][3]={0};则下述描述正确的是 。A.a[0][0]=0,其他值为随机值B.a[3][3]=0,其他值为随机值 C.数组中所有的值为0 D.语法错【10】.设有变量定义chara[]="abc",b[]={'a','b','c'};以下叙述正确的是 。A.两数组内容完全相同B.数组a元素个数大于数组b元素个数C.数组b元素个数大于数组a元素个数D.上述说法都不对二、阅读程序题【1】.若有程序#include<stdio.h>voidmain(){intx=15;while(x>10&&x<50){x++;if(x/3){x++;break;}elseprintf("%d\t",x);}printf("%d\n",x);} 程序执行后,共输出 个数,最后输出的数是 。【2】.若有程序#include<stdio.h>structab{inta,*b;};intx[]={1,2},y[]={3,4};voidmain(){aba[]={20,x,30,y},*p;p=a;printf("%d\n",*(p++­>b));printf("%d\n",p­>a);} 程序执行后,第一行输出 ,第二行输出 。【3】.若有程序#include<stdio.h>voidmain(){ints[3][3]={{1,2,3},{1,2},{1}};int(*ptr)[3];ptr=s;printf("%d\n",**ptr++);printf("%d\n",*(*(ptr++)+1));printf("%d\n",*(*(ptr++)+2));} 程序执行后,第一行输出 ,第二行输出 。【4】.若有程序#include<stdio.h>voidswap(inta,intb){a=a+b;b=a­b;a=a­b;printf("%d,%d\n",a,b);}voidmain(){inta=10,b=20;swap(a,b);printf("%d,%d\n",a,b);} 程序执行后,第一行输出 ,第二行输出 。【5】.若有程序#include<stdio.h>#defineN10#defines(x)x*x#definef(x)(x*x)voidmain(){inta,b;a=3*s(N+2);b=3*f(N+2);printf("%d\n",a);printf("%d\n",b);} 程序执行后,第一行输出 ,第二行输出 。【6】.若有程序#include<stdio.h>fun(charp[][10]){intn=0,i;for(i=0;i<7;i++)if(p[i][0]=='T'){printf("%d,%s\n",i,p[i]);n++;}returnn;}voidmain(){charstr[][10]={"Mon","Tue","Wed","Thu","Fri","Sat","Sun"};printf("%d\n",fun(str));} 程序执行后,共输出 行,最后一行输出的是 。【7】.若有程序#include<stdio.h>voidfun1(char*str1,char*str2){inti=0;while(

温馨提示

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

评论

0/150

提交评论