c程序设计语言复习提纲
一. 数据的定义
(一)数据类型
1. 基本类型
基本类型指整型(int)、实型(float、double)和字符型(char)。
(1)常量
①八进制整数:0123 十六进制整数:0x123 长整型常量:123l
②实数的浮点表示法:123.0 实数的科学计数法:1.23e2
③字符的转义序列:’\’(换行)、’5’(’a’)、’\\x61’(’a’)
④符号常量:#define pi 3.14 常用符号常量null(空值0)、eof(文件结束符-1)
(2)变量
①变量的定义:int a;变量名a为一个符号地址,编译连接时对应一个内存地址,该地址代表的内存单元能够存放一个整数。
②变量的初始化:a=3;通过变量名a找到相应的内存地址,将数据3保存在此内存单元中。
2. 构造类型
构造类型包括数组和结构。
(1)数组
①一维数组的定义:int a[5]; 一维数组的初始化:int a[5]={1,2,3,4,5};
②二维数组的定义和初始化:int b[2][3]={1,2,3,4,5};
③数组元素的引用:a[0]=1; b[1][2]=0;
④一维字符数组(字符串):char c[]=”abc”;(4个元素,c[3]=’{post.content}’)
⑤二维字符数组(字符串数组):char str[3][20]={“china”,”usa”,”russia”};
(2)结构
①结构类型的定义:struct rectangle{float length;float width;};
②结构变量的定义和初始化:struct rectangle rec1={20.0,10.0};
③结构变量成员的引用:rec1.length=25.0;
3. 指针
(1)指针和地址的概念
变量名 a p 指针变量
变量值(内存单元内容) 指针变量的值(地址)
内存单元地址 1000
(2)指针变量的定义和初始化
int a,*p; p=&a;
(3)通过指针引用指向实体
*p=10;
4. 构造类型和指针类型的混和定义及应用
(1)指针、数组和地址间的关系
①一维数组
int a[5]={1,2,3,4,5}; int *p=a; /* p=&a[0]; 首地址*/
a、*(p+i)、*(a+i)等价,&a、p+i、a+i等价。
②二维数组
int a[2][2]={1,2,3,4},*p;
若p=&a[0][0]; /* p=a[0]; 第0行第0列地址*/,则 a[j]、*(a[0]+ i*2+j)、*(p+i*2+j)等价。
若p=a; /*数组首地址,第0行地址*/,则a[j]、*(a+j)、*(*(a+i)+j)、*(*(p+i)+j) 等价。
(2)指针数组
int *p[4]; /*由4个指向整型变量的指针组成的指针数组*/
int (*p)[4]; /*指向由4个元素组成的一维数组的指针变量*/
(3)结构数组
struct rectangle r[3];
(4)结构指针
struct rectangle *p; p=r; r[0].length、(*p).length、p->length等价。
(5)结构中含指针或数组
struct student {char name[10]; /* char *name */……};
(6)嵌套结构
struct student {int num; float score; struct student *next;};
(7)指向指针的指针(二级)
char *str[]={“china”,”usa”,”russia”}; char **s=str;
(8)单向链表
①建立单向链表
建立头指针→建立第一个节点→头指针指向第一个节点→建立第二个节点→第一个节点的指针域指向第二个节点→……→最后一个节点指向null
②遍历单向链表
p指向头指针→p=p->next,p指向第一个节点→p=p->next,p指向第二个节点→……→p=p->next,p ==null遍历结束。
③在单向链表中插入一个节点
通过遍历确定插入位置(如在p之后)→记录p节点的下一节点q(q=p->next)→p指向新节点(p->next=new)→新节点指向q(new->next=q)。
④在单向链表中删除一个节点
通过遍历确定删除位置(如在p之后)→p->next=p->next->next
5. 空类型
为使程序减少出错,保证正确调用,凡不要求带回函数值的函数,一般应定义为空类型(void)。
(二)变量的存储类别、作用域和生存期
(1)存储类别
存储类别是指数据在内存中的存储方法,具体有以下四种:
①auto自动型:此类变量存放于内存的动态存储区。
②static静态型:此类变量存放于内存的静态存储区。
③extern外部参照型:此类变量存放于内存的静态存储区。
④register寄存器型:此类变量存放于cpu中的寄存器。
(2) 作用域(空间角度)
①局局变量:在函数内部定义,只在本函数范围有效。
②全部变量:在函数外部定义,其有效范围从定义位置开始到源文件结束。
(3)生存期(时间角度)
① 静态存储:在程序运行期间分配固定的存储空间。
② 动态存储:在程序运行期间根据需要动态分配存储空间。
自动局部变量:在函数内部定义,离开函数,值消失。
静态局部变量:在函数内部定义,离开函数,值仍保留,下次调用该函数可继续使用。
静态全局变量:只限于被本文件中的函数引用。
外部变量(extern):允许其它文件引用。
二. 运算及流程控制
1. 基本运算
(1)运算符的功能
c运算符范围很广,常用的有以下几类:
①算术运算符(+ - * / %):运算结果为数值。
②关系运算符(> < == >= <= !=):运算结果为1(真)或0(假)。
③逻辑运算符(! && ||):运算结果为1(真)或0(假)。
④赋值运算符(=):运算结果为赋值运算符右边表达式的值。
⑤条件运算符(? :):当?后表达式值非0时,运算结果为:左边表达式的值,否则为右边表达式的值。
⑥逗号运算符(,):运算结果为最右边表达式的值。
(2)运算符的优先级、结合性和目数
①优先级(由高至低):初等运算符() [] -> ·→单目运算符→算术运算符(先乘除求余,后加减)→逻辑运算符(不包括!)→条件运算符→赋值运算符→逗号运算符
②结合性:规定了运算的结合方向,除单目运算符、条件运算符和逗号运算符为自右向左外,其余均为自左向右
③目数:运算符所要求的运算对象的个数,条件运算符是唯一的三目运算符。
(3)隐式类型转换和强制类型转换
①隐式类型转换:系统会自动把不同类型的数据先先转换成同一类型,再进行运算,如10+’a’→10+97→107,3+6.5→3.0+6.5→9.5,又如float x; x=3+6.5→x值为9。
②强制类型转换:(类型名)表达式,如(int)6.5 % 3→6 % 3→0。
2. 表达式
(1)组成规则:按c语法规则,用运算符将运算对象(常量、变量、函数)连接起来。
(2)计算过程:先进行优先级高的运算,同一优先级的运算符的运算次序由结合性决定。
3.语句
(1) 表达式语句、空语句、复合语句
①表达式语句:在表达式最后加分号构成,函数调用语句就属于表达式语句。
②空语句:只有一个分号的语句,什么也不做,有时做循环体。
③复合语句:用{}括起来的一些语句。
(2) 简单控制语句
①break:提前结束整个循环或switch语句,接着执行循环或switch语句下面的语句。
②continue:提前结束本次循环,接着进行下一次是否执行循环的判断。
③return (表达式):将表达式的值作为函数值返回。若表达式值的类型与函数类型不一致,自动转换成函数类型。
(3) 选择控制语句
①if:有单分支、双分支和多分支三种形式,注意同一程序的等价转换。
②switch:根据表达式的具体值进行多分支选择。
(4) 重复控制语句
①for:既可处理循环次数已知的循环,也可处理循环次数未知而只给出循环条件的循环。
②while:当型循环,先判断循环条件,再执行循环体。
③do-while:直到型循环,先执行循环体,再判断循环条件。
三. 程序结构和函数
1.程序结构
(1)main函数与其它函数之间的关系
c程序由函数组成,一个c源程序至少包含一个main函数和若干个其它函数,每个函数实现一定的功能,从而实现程序的模块化设计。程序总是从main函数开始执行,在main函数中可以调用其它函数,其它函数间也可以相互调用。
(2)被调用函数
①标准库函数:系统将一些常用的功能模块编写成函数,放在函数库中供用户直接选用。使用时应用#include命令将相应的头文件包含到本文件中。
②自定义函数:用户为解决自己的专门需要而定义的函数。在主调函数中对被调函数进行声明,形式“函数类型 函数名(参数类型列表)”。
2.函数的定义
(1) 函数定义的ansi c格式
类型名 函数名(形式参数列表){函数体}
(2) 函数的参数及参数传递
①形式参数:调用函数前不占内存单元,调用时才分配内存单元,调用结束后释放。
②实际参数:可以是常量、变量或表达式。
③指针参数:为使在被调用函数中改变的变量的值能被主调函数得到,应该用指针变量作为函数参数。
④参数传递:是主调函数与被调用函数之间传递数据的主要途径,这种传递是“值传递”,即只能由实参传给形参,不能由形参传回给实参,因为实参与形参位于内存中不同的单元。注意实参与形参的类型应相同或赋值兼容。
(3) 函数的返回值
通过函数调用使主调函数获得一个确定的值。除了可能返回一个整型值、实型值、字符值外,也可以把指针(地址)作为函数的返回值,此时函数的定义形式为:
类型名 *函数名(参数表){函数体}
3. 函数的调用
(1)函数调用的一般格式
①通过函数名调用函数:形式“函数名(实参列表)”,位置出现在语句、表达式或实参。
②通过函数指针调用函数:定义指向函数的指针变量“类型名 (*变量名)();”,给函数指针变量赋值“函数指针变量名=函数名;”,调用“(*函数指针变量名)(实参列表)”。
(2)函数的嵌套调用和递归调用
①嵌套调用:一个函数体内不能包含另一函数的定义,即不允许嵌套定义,但允许调用另一个函数,即嵌套调用。
②递归调用:在调用一个函数的过程中直接或间接地调用该函数本身。
(3)熟练掌握标准库函数的调用
①常用数学函数:cos、sqrt、pow、exp、fabs、log、log10。
②常用字符函数:isalnum、isalpha、isdigit、islower、toupper。
③常用字符串函数:strcpy、strcmp、strcat、strlen。
四.数据的输入和输出
1.文件
所谓文件是指存放在外存上的数据集合,一个c文件是一个字节流(ascii文件、文本文件)或二进制流(二进制文件),而不是由记录组成的。在c语言中对文件的存取是以字符(字节)为单位。
2.标准文件的输入和输出
键盘和显示器被看作标准文件,通过键盘输入即从文件中读取数据,在显示器上显示即向文件中写数据。c语言不提供专门的输入输出语句,而是通过函数来实现输入输出操作,常用输入输出函数有:格式化输入输出函数(scanf、printf)、字符输入输出函数(getchar、putchar)、字符串输入输出函数(gets、puts)。
3.缓冲文件系统(文本文件)
(1) 文件的打开和关闭
file *fp; fp=fopen(文件名,使用方式);fclose(fp);
(2) 文件的基本读写操作
常用函数有:fscanf(从指定文件按格式读出数据)、fprintf(按格式向指定文件写入数据)、fgetc(从指定文件读出一个字符)、fputc(向指定文件写入一个字符)、fgets(从指定文件读出一个字符串)、fputs(向指定文件写入一个字符串)。
(3) 文件的状态检测
feof(文件指针):若文件指针指向文件末尾,函数值为真(非0)。
五.编译预处理
1.编译预处理的基本概念
预处理命令并不属于c语言本身的组成部分,这些命令在编译前处理,主要用于改进程序设计环境,提高编程效率。主要有宏定义、文件包含和条件编译三种,这些命令都以#开头。
2.宏定义
用一个指定标识符代表一个字符串,形式为:#define 标识符 字符串,常用于定义符号常量。
3.文件包含
一个源文件将另一个源文件的全部内容包含进来,形式为:#include <文件名>,常用于包含头文件。
六.面向对象程序设计初步
1. 类、对象和面向对象程序设计的基本概念
①对象:客观世界中任何一个事务都可以看作一个对象,它们之间通过一定的渠道相互联系。一个对象应该包含两个要素:数据和操作。
②类:每一个实体都是一个对象,具有相同结构和特性的对象属于同一类型,在c++中称为“类”,它代表某一批对象的共性和特征。类是对象的抽象,对象是类的具体实例。类是用来定义对象的一种抽象数据类型。
③面向对象程序设计:程序设计者的任务包括设计对象(把数据和操作代码封装在一个对象中)和协调各种对象共同完成所需任务。
2.掌握类的定义
class stud
{int num; //定义数据成员
char name[10];
char sex;
void display() //定义成员函数
{cout<<”num:”<<num<<endl;
cout<<”name:”<<name<<endl;
cout<<”sex:”<<sex<<endl;}
}
stud stud1,stud2; //定义对象
第二部分 c程序设计的常用算法
算法(algorithm):计算机解题的基本思想方法和步骤。算法的描述:是对要解决一个问题或要完成一项任务所采取的方法和步骤的描述,包括需要什么数据(输入什么数据、输出什么结果)、采用什么结构、使用什么语句以及如何安排这些语句等。通常使用自然语言、结构化流程图、伪代码等来描述算法。
一、计数、求和、求阶乘等简单算法
此类问题都要使用循环,要注意根据问题确定循环变量的初值、终值或结束条件,更要注意用来表示计数、和、阶乘的变量的初值。
例:用随机函数产生100个[0,99]范围内的随机整数,统计个位上的数字分别为1,2,3,4,5,6,7,8,9,0的数的个数并打印出来。
本题使用数组来处理,用数组a[100]存放产生的确100个随机整数,数组x[10]来存放个位上的数字分别为1,2,3,4,5,6,7,8,9,0的数的个数。即个位是1的个数存放在x[1]中,个位是2的个数存放在x[2]中,……个位是0的个数存放在x[10]。
void main()
{ int a[101],x[11],i,p;
for(i=0;i<=11;i++)
x=0;
for(i=1;i<=100;i++)
{ a=rand() % 100;
printf("%4d",a);
if(i%10==0)printf("\");
}
for(i=1;i<=100;i++)
{ p=a%10;
if(p==0) p=10;
x[p]=x[p]+1;
}
for(i=1;i<=10;i++)
{ p=i;
if(i==10) p=0;
printf("%d,%d\",p,x);
}
printf("\");
}
二、求两个整数的最大公约数、最小公倍数
分析:求最大公约数的算法思想:(最小公倍数=两个整数之积/最大公约数)
(1) 对于已知两数m,n,使得m>n;
(2) m除以n得余数r;
(3) 若r=0,则n为求得的最大公约数,算法结束;否则执行(4);
(4) m←n,n←r,再重复执行(2)。
例如: 求 m=14 ,n=6 的最大公约数. m n r
14 6 2
6 2 0
void main()
{ int nm,r,n,m,t;
printf("please input two numbers:\");
scanf("%d,%d",&m,&n);
nm=n*m;
if (m<n)
{ t=n; n=m; m=t; }
r=m%n;
while (r!=0)
{ m=n; n=r; r=m%n; }
printf("最大公约数:%d\",n);
printf("最小公倍数:%d\",nm/n);
}
三、判断素数
只能被1或本身整除的数称为素数 基本思想:把m作为被除数,将2—int( )作为除数,如果都除不尽,m就是素数,否则就不是。(可用以下程序段实现)
void main()
{ int m,i,k;
printf("please input a number:\");
scanf("%d",&m);
k=sqrt(m);
for(i=2;i<k;i++)
if(m%i==0) break;
if(i>=k)
printf("该数是素数");
else
printf("该数不是素数");
}
将其写成一函数,若为素数返回1,不是则返回0
int prime( m%)
{int i,k;
k=sqrt(m);
for(i=2;i<k;i++)
if(m%i==0) return 0;
return 1;
}
四、验证哥德巴赫猜想
(任意一个大于等于6的偶数都可以分解为两个素数之和)
基本思想:n为大于等于6的任一偶数,可分解为n1和n2两个数,分别检查n1和n2是否为素数,如都是,则为一组解。如n1不是素数,就不必再检查n2是否素数。先从n1=3开始,检验n1和n2(n2=n-n1)是否素数。然后使n1+2 再检验n1、n2是否素数,… 直到n1=n/2为止。
利用上面的prime函数,验证哥德巴赫猜想的程序代码如下:
#include "math.h"
int prime(int m)
{ int i,k;
k=sqrt(m);
for(i=2;i<k;i++)
if(m%i==0) break;
if(i>=k)
return 1;
else
return 0;
}
main()
{ int x,i;
printf("please input a even number(>=6):\");
scanf("%d",&x);
if (x<6||x%2!=0)
printf("data error!\");
else
for(i=2;i<=x/2;i++)
if (prime(i)&&prime(x-i))
{
printf("%d+%d\",i,x-i);
printf("验证成功!");
break;
}
}
五、排序问题
1.选择法排序(升序)
基本思想:
1)对有n个数的序列(存放在数组a(n)中),从中选出最小的数,与第1个数交换位置;
2)除第1 个数外,其余n-1个数中选最小的数,与第2个数交换位置;
3)依次类推,选择了n-1次后,这个数列已按升序排列。
程序代码如下:
void main()
{ int i,j,imin,s,a[10];
printf("\ input 10 numbers:\");
for(i=0;i<10;i++)
scanf("%d",&a);
for(i=0;i<9;i++)
{ imin=i;
for(j=i+1;j<10;j++)
if(a[imin]>a[j]) imin=j;
if(i!=imin)
{s=a; a=a[imin]; a[imin]=s; }
printf("%d\",a);
}
}
2.冒泡法排序(升序)
基本思想:(将相邻两个数比较,小的调到前头)
1)有n个数(存放在数组a(n)中),第一趟将每相邻两个数比较,小的调到前头,经n-1次两两相邻比较后,最大的数已“沉底”,放在最后一个位置,小数上升“浮起”;
2)第二趟对余下的n-1个数(最大的数已“沉底”)按上法比较,经n-2次两两相邻比较后得次大的数;
3)依次类推,n个数共进行n-1趟比较,在第j趟中要进行n-j次两两比较。
程序段如下
void main()
{ int a[10];
int i,j,t;
printf("input 10 numbers\");
for(i=0;i<10;i++)
scanf("%d",&a);
printf("\");
for(j=0;j<=8;j++)
for(i=0;i<9-j;i++)
if(a>a[i+1])
{t=a;a=a[i+1];a[i+1]=t;}
printf("the sorted numbers:\");
for(i=0;i<10;i++)
printf("%d\",a);
}
3.合并法排序(将两个有序数组a、b合并成另一个有序的数组c,升序)
基本思想:
1)先在a、b数组中各取第一个元素进行比较,将小的元素放入c数组;
2)取小的元素所在数组的下一个元素与另一数组中上次比较后较大的元素比较,重复上述比较过程,直到某个数组被先排完;
3)将另一个数组剩余元素抄入c数组,合并排序完成。
程序段如下:
void main()
{ int a[10],b[10],c[20],i,ia,ib,ic;
printf("please input the first array:\");
for(i=0;i<10;i++)
scanf("%d",&a);
for(i=0;i<10;i++)
scanf("%d",&b);
printf("\");
ia=0;ib=0;ic=0;
while(ia<10&&ib<10)
{ if(a[ia]<b[ib])
{ c[ic]=a[ia];ia++;}
else
{ c[ic]=b[ib];ib++;}
ic++;
}
while(ia<=9)
{ c[ic]=a[ia];
ia++;ic++;
}
while(ib<=9)
{ c[ic]=b[ib];
b++;ic++;
}
for(i=0;i<20;i++)
printf("%d\",c);
}
六、查找问题
1.①顺序查找法(在一列数中查找某数x)
基本思想:一列数放在数组a[1]---a[n]中,待查找的数放在x 中,把x与a数组中的元素从头到尾一一进行比较查找。用变量p表示a数组元素下标,p初值为1,使x与a[p]比较,如果x不等于a[p],则使p=p+1,不断重复这个过程;一旦x等于a[p]则退出循环;另外,如果p大于数组长度,循环也应该停止。(这个过程可由下语句实现)
void main()
{ int a[10],p,x,i;
printf("please input the array:\");
for(i=0;i<10;i++)
scanf("%d",&a);
printf("please input the number you want find:\");
scanf("%d",&x);
printf("\");
p=0;
while(x!=a[p]&&p<10)
p++;
if(p>=10)
printf("the number is not found!\");
else
printf("the number is found the no%d!\",p);
}
思考:将上面程序改写一查找函数find,若找到则返回下标值,找不到返回-1
②基本思想:一列数放在数组a[1]---a[n]中,待查找的关键值为key,把key与a数组中的元素从头到尾一一进行比较查找,若相同,查找成功,若找不到,则查找失败。(查找子过程如下。index:存放找到元素的下标。)
void main()
{ int a[10],index,x,i;
printf("please input the array:\");
for(i=0;i<10;i++)
scanf("%d",&a);
printf("please input the number you want find:\");
scanf("%d",&x);
printf("\");
index=-1;
for(i=0;i<10;i++)
if(x==a)
{ index=i; break;
}
if(index==-1)
printf("the number is not found!\");
else
printf("the number is found the no%d!\",index);
}
2.折半查找法(只能对有序数列进行查找)
基本思想:设n个有序数(从小到大)存放在数组a[1]----a[n]中,要查找的数为x。用变量bot、top、mid 分别表示查找数据范围的底部(数组下界)、顶部(数组的上界)和中间,mid=(top+bot)/2,折半查找的算法如下:
(1)x=a(mid),则已找到退出循环,否则进行下面的判断;
(2)x<a(mid),x必定落在bot和mid-1的范围之内,即top=mid-1;
(3)x>a(mid),x必定落在mid+1和top的范围之内,即bot=mid+1;
(4)在确定了新的查找范围后,重复进行以上比较,直到找到或者bot<=top。
将上面的算法写成如下程序:
void main()
{
int a[10],mid,bot,top,x,i,find;
printf("please input the array:\");
for(i=0;i<10;i++)
scanf("%d",&a);
printf("please input the number you want find:\");
scanf("%d",&x);
printf("\");
bot=0;top=9;find=0;
while(bot<top&&find==0)
{ mid=(top+bot)/2;
if(x==a[mid])
{find=1;break;}
else if(x<a[mid])
top=mid-1;
else
bot=mid+1;
}
if (find==1)
printf("the number is found the no%d!\",mid);
else
printf("the number is not found!\");
}
七、插入法
把一个数插到有序数列中,插入后数列仍然有序
基本思想:n个有序数(从小到大)存放在数组a(1)—a(n)中,要插入的数x。首先确定x插在数组中的位置p;(可由以下语句实现)
#define n 10
void insert(int a[],int x)
{ int p, i;
p=0;
while(x>a[p]&&p<n)
p++;
for(i=n; i>p; i--)
a=a[i-1];
a[p]=x;
}
main()
{ int a[n+1]={1,3,4,7,8,11,13,18,56,78}, x, i;
for(i=0; i<n; i++) printf("%d,", a);
printf("\input x:");
scanf("%d", &x);
insert(a, x);
for(i=0; i<=n; i++) printf("%d,", a);
printf("\");
}
八、矩阵(二维数组)运算
(1)矩阵的加、减运算
c(i,j)=a(i,j)+b(i,j) 加法
c(i,j)=a(i,j)-b(i,j) 减法
(2)矩阵相乘
(矩阵a有m*l个元素,矩阵b有l*n个元素,则矩阵c=a*b有m*n个元素)。矩阵c中任一元素 (i=1,2,…,m; j=1,2,…,n)
#define m 2
#define l 4
#define n 3
void mv(int a[m][l], int b[l][n], int c[m][n])
{ int i, j, k;
for(i=0; i<m; i++)
for(j=0; j<n; j++)
{ c[j]=0;
for(k=0; k<l; k++)
c[j]+=a[k]*b[k][j];
}
}
main()
{ int a[m][l]={{1,2,3,4},{1,1,1,1}};
int b[l][n]={{1,1,1},{1,2,1},{2,2,1},{2,3,1}}, c[m][n];
int i, j;
mv(a,b,c);
for(i=0; i<m; i++)
{ for(j=0; j<n; j++)
printf("%4d", c[j]);
printf("\");
}
}
(3)矩阵传置
例:有二维数组a(5,5),要对它实现转置,可用下面两种方式:
#define n 3
void ch1(int a[n][n])
{ int i, j, t;
for(i=0; i<n; i++)
for(j=i+1; j<n; j++)
{ t=a[j];
a[j]=a[j];
a[j]=t;
}
}
void ch2(int a[n][n])
{ int i, j, t;
for(i=1; i<n; i++)
for(j= 0; j<i; j++)
{ t=a[j];
a[j]=a[j];
a[j]=t;
}
}
main()
{ int a[n][n]={{1,2,3},{4,5,6},{7,8,9}}, i, j;
ch1(a); /*或ch2(a);*/
for(i=0; i<n; i++)
{ for(j=0; j<n; j++)
printf("%4d", a[j]);
printf("\");
}
}
(4)求二维数组中最小元素及其所在的行和列
基本思路同一维数组,可用下面程序段实现(以二维数组a[3][4]为例):
‘变量max中存放最大值,row,column存放最大值所在行列号
#define n 4
#define m 3
void min(int a[m][n])
{ int min, row, column, i, j;
min=a[0][0];
row=0;
column=0;
for(i=0; i<m; i++)
for(j=0; j<n; j++)
if(a[j]<min)
{ min=a[j];
row=i;
column=j;
}
printf("min=%d\at row%d,column%d\", min, row, column);
}
main()
{ int a[m][n]={{1,23,45,-5},{5,6,-7,6},{0,33,8,15}};
min(a);
}
九、迭代法
算法思想:对于一个问题的求解x,可由给定的一个初值x0,根据某一迭代公式得到一个新的值x1,这个新值x1比初值x0更接近要求的值x;再以新值作为初值,即:x1→x0,重新按原来的方法求x1,重复这一过和直到|x1-x0|<ε(某一给定的精度)。此时可将x1作为问题的解。
例:用迭代法求某个数的平方根。 已知求平方根的迭代公式为:
#include<math.h>
float fsqrt(float a)
{ float x0, x1;
x1=a/2;
do{
x0=x1;
x1=0.5*(x0+a/x0);
}while(fabs(x1-x0)>0.00001);
return(x1);
}
main()
{ float a;
scanf("%f", &a);
printf("genhao =%f\", fsqrt(a));
}
十、数制转换
将一个十进制整数m转换成 →r(2-16)进制字符串。
方法:将m不断除 r 取余数,直到商为零,以反序得到结果。下面写出一转换函数,参数idec为十进制数,ibase为要转换成数的基(如二进制的基是2,八进制的基是8等),函数输出结果是字符串。
char *trdec(int idec, int ibase)
{ char strdr[20], t;
int i, idr, p=0;
while(idec!=0)
{ idr=idec % ibase;
if(idr>=10)
strdr[p++]=idr-10+65;
else
strdr[p++]=idr+48;
idec/=ibase;
}
for(i=0; i<p/2; i++)
{ t=strdr;
strdr=strdr[p-i-1];
strdr[p-i-1]=t;
}
strdr[p]=’{post.content}’;
return(strdr);
}
main()
{ int x, d;
scanf("%d%d", &x, &d);
printf("%s\", trdec(x,d));
}
十一、字符串的一般处理
1.简单加密和解密
加密的思想是: 将每个字母c加(或减)一序数k,即用它后的第k个字母代替,变换式公式: c=c+k
例如序数k为5,这时 a→ f, a→f,b→?g… 当加序数后的字母超过z或z则 c=c+k -26
例如:you are good→ dtz fwj ltti
解密为加密的逆过程
将每个字母c减(或加)一序数k,即 c=c-k,
例如序数k为5,这时 z→u,z→u,y→t… 当加序数后的字母小于a或a则 c=c-k +26
下段程序是加密处理:
#include<stdio.h>
char *jiami(char stri[])
{ int i=0;
char strp[50],ia;
while(stri!=’{post.content}’)
{ if(stri>=’a’&&stri<=’z’)
{ ia=stri+5;
if (ia>’z’) ia-=26;
}
else if(stri>=’a’&&stri<=’z’)
{ ia=stri+5;
if (ia>’z’) ia-=26;
}
else ia=stri;
strp[i++]=ia;
}
strp=’{post.content}’;
return(strp);
}
main()
{ char s[50];
gets(s);
printf("%s\", jiami(s));
}
2.统计文本单词的个数
输入一行字符,统计其中有多少个单词,单词之间用格分隔开。
算法思路:
(1)从文本(字符串)的左边开始,取出一个字符;设逻辑量word表示所取字符是否是单词内的字符,初值设为0
(2)若所取字符不是“空格”,“逗号”,“分号”或“感叹号”等单词的分隔符,再判断word是否为1,若word不为1则表是新单词的开始,让单词数num = num +1,让word =1;
(3)若所取字符是“空格”,“逗号”,“分号”或“感叹号”等单词的分隔符, 则表示字符不是单词内字符,让word=0;
(4) 再依次取下一个字符,重得(2)(3)直到文本结束。
下面程序段是字符串string中包含的单词数
#include "stdio.h"
main()
{char c,string[80];
int i,num=0,word=0;
gets(string);
for(i=0;(c=string)!='{post.content}';i++)
if(c==' ') word=0;
else if(word==0)
{ word=1;
num++;}
printf("there are %d word in the line.\",num);
}
十二、穷举法
穷举法(又称“枚举法”)的基本思想是:一一列举各种可能的情况,并判断哪一种可能是符合要求的解,这是一种“在没有其它办法的情况的方法”,是一种最“笨”的方法,然而对一些无法用解析法求解的问题往往能奏效,通常采用循环来处理穷举问题。
例: 将一张面值为100元的人民币等值换成100张5元、1元和0.5元的零钞,要求每种零钞不少于1张,问有哪几种组合?
main()
{ int i, j, k;
printf(" 5元 1元 5角\");
for(i=1; i<=20; i++)
for(j=1; j<=100-i; j++)
{ k=100-i-j;
if(5*i+1*j+0.5*k==100)
printf(" %3d %3d %3d\", i, j, k);
}
}
十三、递归算法
用自身的结构来描述自身,称递归
vb允许在一个sub子过程和function过程的定义内部调用自己,即递归sub子过程和递归function函数。递归处理一般用栈来实现,每调用一次自身,把当前参数压栈,直到递归结束条件;然后从栈中弹出当前参数,直到栈空。
递归条件:(1)递归结束条件及结束时的值;(2)能用递归形式表示,且递归向终止条件发展。
例:编fac(n)=n! 的递归函数
int fac(int n)
{ if(n==1)
return(1);
else
return(n*fac(n-1));
}
main()
{ int n;
scanf("%d", &n);
printf("n!=%d\", fac(n));
}
第三部分 习题汇编
一、判断题:
1.机器语言、汇编语言、高级语言程序都是计算机语言,但只有机器语言程序才是计算机可以直接执行的程序。
2.用汇编程序处理c语言的源程序,可以生成机器语言程序。
3.若main函数无返回值,定义函数main时可以缺省标识符“void”.
4.c的编译预处理行与其他c语句一样,均应以“;”结束。
5.一条c语句如果太长,可以从任何一处插入回车符,将其分别写在若干行上。
6.c的long类型数据可以表示任何整数。
7.c的double类型数据在其数值范围内可以表示任何实数。
8.c的任何类型数据在计算机内都是以二进制形式存储的。
9.任何变量都必须要声明其类型。
10.printf函数中的格式符“%c”只能用于输出字符类型数据。
11.按格式符“%d”输出float类型变量时,截断小数位取整后输出。
12.按格式符“%6.3f”输出i (i=123.45) 时,输出结果为123.450。
13.scanf函数中的格式符“%d”不能用于输入实数数据。
14.格式符“%f”不能用于输入 double类型数据。
15.当格式符中指定宽度时,从缓冲区中读入的字符数完全取决于所指定的宽度。
16.函数的所有参数或者都采用传值调用方式,或者都采用引用调用方式。
17.函数中不可以没有return语句。
18.传值调用的形参只有在被调用示才被创建(分配存储单元)。
19.传值调用时,实参不限于变量名,而可以是表达式。
20.被定义为前向调用的函数,不必再声明其函数原型。
12.函数f可以用f(f(x))形式调用,f是递归函数。
22.程序中不能用同一个函数名定义不同的函数。
23.c语言源程序文件经过编译、连接之后生成一个后缀为.exe的文件.()
24.c语言中以%o开头的数是八进制整数.()
25.在程序的运行过程中,符号常量的值是可以改变的.()
26.在c程序中,aph和aph代表认为是一条语句.()
27.一个复合语句在语法上被认为是一条语句.()
28.只能用while语句构成循环.()
29.不能用printf函数输出字符.()
30.c程序中各函数之间既允许直接递归调用也允许间接递归调用.()
31.在函数外部定义的变量称为全局变量.()
32.宏定义的命令行可以看作是一条c语句.()
二、填空题
1.根据所给条件,写出下列各题的输出结果。
(1)int i=234, j=567; 函数printf("%d%d\", i, j)的输出结果是 。
(2)nt i=234; float x=-513.624; 函数printf("i=%5d x=%7.4f\", i, x)的输出结果是 。
(3)float alfa=60, pi=3.1415926535626; 函数printf("sin(%3.0f*%f/180)\", alfa, pi)的输出结果是 。
(4)char ch=’$’; float x=153.45; 函数printf("%c%-8.2f\", ch, x)的输出结果是 。
(5)int d=27; 函数printf("%-5d,%-5o,%-5x\", d, d, d)的输出结果是 。
(6)float x1=13.24, x2=-78.32; 函数printf("x(%d)=%.2f x(%d)=%.2f\",1,x1,2,x2)的输出结果是 。
(7)设float x=2.5, y=4.7; int a=7; 表达式x+a%3*(int)(x+y)%2/4值为 。
(8)设int x=17, y=5; 执行语句x+=--x%--y后x的值为 。
(9)设int x=17, y=5; 执行语句x%=x++/--y后x的值为 。
(10)int a=7, b=6, c=5; 表达式 (a+b)>(c*c)&&b==c||c>b值为 。
(11)设int a=3, b=5, c=7; 表达式a>c||c>b!=0&&c==b+a值为 。
(12)判断变量a、b是否绝对值相等而符号相反的逻辑表达式为 。
(13)判断变量a、b中必有且只有一个为0的逻辑表达式为 。
(14)设 int b=5;求解赋值表达式a=5+(b+=6) 后表达式值、a、b的值依次是 。
(15)求解赋值表达式a=(b=10)%(c=6) 后表达式值、a、b、c的值依次是 。
(16)求解逗号表达式x=a=3,6*a后表达式值、x、a的值依次是 。
(17)若a=13、b=25、c=-17,表达式((y=(a<b)?a:b)<c)?y:c的值为 。
(18) 若s=’d’,执行语句s=(s>=’a’&&s<=’z’)?s-32:s; 后,字符变量s的值为 。
2.根据下列数学式,写出c的算术表达式。
(1) 。
(2) 。
(3) 。
3.按照要求写出下列c的表达式。
(1)数学式 (x+1) e 2 x 所对应的c算术表达式 。
(2)将double类型变量x的整数部分与y的小数部分相加的算术表达式 。
(3)将float类型变量y四舍五入至小数点后3位的表达式 。
(4)为变量s赋值:取变量x的符号,取变量y的绝对值 。
(5)条件“-5≤x≤3”所对应的c逻辑表达式 。
(6)a、b是字符变量,已知a的值为大写字母、b的值为小写字母,写出判断a、b是否为同一字母(不区分大小写)的逻辑表达式 。
(7)int类型变量a、b均为两位正整数,写出判断a的个位数等于b的十位数、b的个位数等于a的十位数的逻辑表达式 。
(8)计算变量a、b中较小值的条件表达式 。
(9)计算变量a、b、c中较小值的条件表达式 。
(10)若字符变量ch的值为大写字母,则重新赋值为对应的小写字母 。
4.根据所给题意填空题。
(1)求1~100的和,写作for(s=0, i=1; ; ++i) s+=i;
(2)执行程序段“y=1; x=5; while(x--); y++;”后,y的值为 。
(3)顺序输出26个大写英文字母的循环结构,写作:
for( ) putchar(ch);
(4)输入若干个字符,以问号结束,同时输出这串字符(不包括问号),写作:
while( !=’?’) putchar(ch);
(5)循环程序段“k=5; for(; k<0; k--);”执行后,k的值为 。
(6)定义函数时,若缺省函数类型标识符,函数类型为 。
(7)函数之间参数传递的方式有 和 。
(8)当参数采用引用调用方式传递时,实参必须是与形参同类型的 。
(9)参数采用值传递调用方式时,若实参与形参不同类型,c的处理是:
。
(10)调用时形参值的改变对实参变量有副作用的参数传递方式是 。
(11)定义一个带参数的宏,若变量中的字符为大写字母,则转换为小写字母
(12)定义一个带参数的宏,将两个参数值交换
#define swap(a, b) {double t; }
(13)定义带参数的宏为 #define max(a, b) ((a)>(b)?(a)b))
(14)对表达式max(a, max(b, max(c, d)))作宏替换为:
(15)未初始化的int类型数据,其各元素的值是 。
(16)初始化说没有被赋值的字符类型数组元素,它们的值为 。
(17)数组声明为“int a[6];”,数组元素a[1]是否又可以写作“*(a++)”?
原因是 。
(18)引用二维数组a第i行、第j列的元素(i、j为0表示第1行、第1列),可以写作: 或 。
(19)数组声明为“int a[6][6];”,表达式“*a+i”是指 、“*(a+i)”是指 、“**a”又是指 。
(20)数组声明为“float x[7][5];”若x[6][4]是内存中从x[0][0]数起的第35个元素,则x[4][4]是第 个元素。
(21)声明“char str1[20]= "borland c++ 5.0"”后,使字符串str1为"borland"的赋值表达式,应为 。
(22)将包括空格在内的6个字符串输入到字符数组a[6][20] 中,输入语句可以写作:
。
(23)未初始化的int类型数据,其各元素的值是 。
(24)初始化说没有被赋值的字符类型数组元素,它们的值为 。
(25)数组声明为“int a[6];”,数组元素a[1]是否又可以写作“*(a++)”?
原因是 。
(26)引用二维数组a第i行、第j列的元素(i、j为0表示第1行、第1列),可以写作: 或 。
(27)数组声明为“int a[6][6];”,表达式“*a+i”是指 、“*(a+i)”是指 、“**a”又是指 。
(28)数组声明为“float x[7][5];”若x[6][4]是内存中从x[0][0]数起的第35个元素,则x[4][4]是第 个元素。
(29)声明“char str1[20]= "borland c++ 5.0"”后,使字符串str1为"borland"的赋值表达式,应为 。
(30)将包括空格在内的6个字符串输入到字符数组a[6][20] 中,输入语句可以写作:
。
(31)fopen函数的返回值是 。
(32)文件打开方式为"r+",文件打开后,文件读写位置在 。
(33)文件打开方式为"a",文件打开后,文件读写位置在 。
(34)表达式“fgetc(fpn)”的值为 或 。
(35)表达式“fgets(a, 10, fpn)”的值为 或 。
(36)函数fscanf的返回值为 或 。
(37)函数fread的返回值为所读入数据的个数或 。
(38)表达式“fscanf(fpn, "%f", &x)”的值为-1时,函数feof()的值为 。
(39)函数f定义如下,计算写出f(f(4))的值是 。
int f(int x)
{ static int k=0;
x+=k++; return x;
}
三、单项选择题
1.程序中调用了库函数exit,必须包含头文件( )。
a、math.h b、string.h c、ctype.h d、stdlib.h
2.程序中调用了库函数strcmp,必须包含头文件( )。
a、math.h b、string.h c、ctype.h d、stdlib.h
3.下列宏定义命令中,哪一个格式示正确的( )。
a、#define pi=3.14159; b、define pi=3.14159
c、#define pi "3.14159" d、#define pi(3.14159);
4.定义带参数的宏计算两个表达式的乘积,下列定义中哪个是正确的( )。
a、#define muit(u, v) u*v b、#define muit(u, v) u*v ;
c、#define muit(u, v) (u)*(v) d、#define muit(u, v)=(u)*(v)
5.宏定义为:#define div(a, b) a/b; 对语句“printf("div(a,b)=%d\", div(x+5, y-5));”作宏替换后为( )。
a、printf("div(a, b)=%d\", x+5/y-5;); b、printf("a/b=%d\", x+5/y-5);
c、printf("a/b=%d\", (x+5)/(y-5)); d、printf("a/b=%d\", x+5/y-5;);
6.下列数组声明语句中,正确的是( )。
a、int a[]={1, 2, , 4, 5}; b、char a[5]={a, b, c, d, e};
c、int a[5]={1, 2}; d、char a[5]= "hello";
7.数组声明语句为“int a[6];”,输入数组所有元素的语句应为( )。
a、scanf("%d%d%d%d%d",a[6]);
b、for(int i=0; i<6; i++) scanf("%d", a+i);
c、for(int i=0; i<6; i++) scanf("%d", *a+i);
d、for(int i=0; i<6; i++) scanf("%d", a);
8.数组声明语句为“float a[3][4];”,引用第3行第1列的元素写作( )。
a、**(a+2) b、*(*a+2) c、a[3][1] d、*(a[3]+1)
9.初始化多维数组的语句中,可以缺省的是( )。
a、最后一个下标界 b、第1个下标界
c、第2个下标界 d、以上都不是
10.数组声明为“int y[4][3];”,表达式“*(y+2)+2-*y”的值为( )。
a、10 b、20 c、16 d、8
11.数组声明为“char str1[20]= "borland", str2[]="c++5.0";”,调用函数“strcat(str1, str2);”后,字符串str1的串长是( )。
a、13 b、14 c、6 d、7
12.表达式“strcmp("windows98", "windows95")”的值为( )。
a、0 b、3 c、1 d、-3
13.下列语句定义px为指向int类型变量x的指针,其中哪一个是正确的( )。
a、int *px=x, x; b、int *px=&x, x;
c、int x, *px=x; d、int *px, x; px=&x;
14.指针变量p1和p2类型相同,要使p1、p2指向同一个变量,哪一个语句是正确的( )。
a、p2=*&p1; b、p2=**p1; c、p2=&p1; d、p2=*p1;
15.声明语句为“char a=’%’, *b=&a, **c=&b;”,下列表达式中错误的是( )。
a、a==**c b、b==*c c、**c==’%’ d、&a=*&b
16.数组定义为“int a[4][5];”,下列哪一个引用是错误的( )。
a、*a b、*(*(a+2)+3) c、&a[2][3] d、++a
17.表达式“c=*p++”的执行过程是( )。
a、复制*p的值给c后再执行p++ b、复制*p的值给c后再执行*p++
c、复制p的值给c后再执行p++ d、执行p++后将*p的值复制给c
18.声明语句为“char s[4][15], *p1, **p2; int x, *y;”下列语句中正确的是( )。
a、p2=s; b、y=*s; c、*p2=s; d、y=&x;
四、程序填空
1.填空,使修改后的下列程序在输入n后,能够求1+1/2+1/3+…+1/n的值并输出结果。
(1)
void main()
{ float (2) ;
int n,i=1;
scanf("%d",&n);
while(i<=n){
s= (3) ;
i=i+1;
}
printf("sun=%d\",s);
}
2. 程序在输入平面上3个点的坐标后,调用函数length计算并输出各点之间的距离,填空将程序补充完整并上机运行、调试。
# include<stdio.h>
(1)
float length(float x1, float y1, float x2, float y2)
{ float t;
t=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))
return t;
}
void main()
{ (2)
scanf("%f%f%f%f%f%f",&ax,&ay,&bx,&by,&cx,&cy);
len1=length(ax,ay,bx,by);
len2= (3)
len3=length(bx,by,cx,cy);
printf("%f %f %f\", (4) );
}
3. 列程序在输入m后,求n使n!≤m≤(n+1)!(例如输入726,应输出n=6),填空将程序补充完整。
void main()
{ int ;
scanf( );
for(n=2; jc<=m; n++) jc=jc*n;
printf("n=%d\", );
}
4.下列程序输出6~10000之间的亲密数对,填空将程序补充完整。
【说明】若a、b是亲密数对,则a的因子和等于b、b的因子和等于a,且a不等于b。
# include<stdio.h>
void main()
{ int a, b, c, i;
for(a=6; a<=10000; a++)
{ b=1;
for(i=2; i<=a/2; i++)
if( )b+=i;
for(i+2; i<=b/2; i++) if(b%i==0) c+=i;
if( && a!=b) printf("%d %d\", a, b);
}
}
5.输入若干个正整数,判断每个数从高位到低位各位数字是否按值从小到大排列。
# include<stdio.h>
void main()
{ int n;
while(scanf("%d", &n),n>0)
if(fun1(n))
printf("%d中各位数字按从小到大排列\", n);
}
int fun1( )
{ int k;
while(m)
if(m/10%10>k) return 0;
else { ; k=m%10; }
return 1;
}
6. 列程序显示输入数的所有因子。
# include<stdio.h>
int div( )
{ if(m%k==0)
{
printf("%d", k);
return 1
}
}
void main()
{ int n, i=2;
scanf("%d", &n);
while(n) if(div(n, i) 0) ;{n/=i;i++;}
printf("\");
}
7.输入10个数,输出其中与平均值之差的绝对值为最小的数。
# include<stdio.h>
void main()
{ float a[10], s , d, x;
int i;
for(i=0; i<10; i++) ;
for(i=0; i<10; i++) s+=a; s/=10;
d=fabs(a[0]-s); ;
for(i=1; i<10; i++)
if(fabs(a-s)<d)
{ d= ; x=a;
}
printf("%f", x);
}
8.输出如下形式的二项式系数列标。要求表的行数运行时输入,若小于1或者大于10则重新输入。
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
# include<stdio.h>
void main()
{ int a[10][10]={{0}}, i, j, n;
while( , n<1||n>10);
for(i=0; i<n; i++)
{ a[0]=1;
;
}
for(i=2; i<n; i++)
for(j=1; j<i; j++) a[j]=a[i-1][j]+ ;
for(i=0; i<n; i++)
{ for(j=0; j<=i; j++) printf("%4d", a[j]);
;
}
}
9. 入一个字符串(串长不超过60),将字符串中连续的空格符保留一个。如输入字符串为“ i am a student.”,则输出字符串为“ i am a student.”。
# include<stdio.h>
# include<string.h>
void main()
{ char b[61];
int i; gets(b);
for(i=1; ; i++)
if(b[i-1]==’ ’&&b==’ ’)
{ (b+i-1,b+i); i--; // 提示:此处填入正确的函数名
}
;
}
10.列程序求二维数组a中最大值与b中最大值之差,填空将下列程序补充完整。
# include<stdio.h>
# include<string.h>
float find_max( )
{ int i, j; float max=**x;
for(i=0; i<m; i++)
for(j=0; j<n; j++)
if(*(*(x+i)+j)>max) max=
return max;
}
void main()
{ float a[5][5], b[6][4], ; int i, j;
for(i=0; i<5; i++) pa=a;
for(i=0; i<5; i++) for(j=0; j<5; j++) scanf("%f", &a[j]);
for(i=0; i<6; i++) for(j=0; j<4; j++) scanf("%f", &b[j]);
printf("%f\", find_max(pa, 5, 5)-find_max(pb, 6, 4));
}
11.程序中,函数find_data在已从小到大排序好的数组中寻找指定数data,采用二分查找算法,找到则返回该数组元素地址,找不到,则返回 null。请填空将程序补充完整。
# include<stdio.h>
find_data(float *a, int n, float data)
{ ;
low=0;
high=n-1;
while(low<=high)
{ mid=(low+high)/2;
if(a[mid]>data)
high=mid-1;
else if(a[mid]<data) low=mid+1;
else ;
}
;
}
void main()
{ float b[10], *p , data;
for(int i=0; i<10; i++) scanf("%f", b+i); // 要求输入数据值从小到大
scanf("%f", &data); // 输入代查找的数据
p=find_data(b, 10, data);
if(p) printf("%f\", *p);
else printf("查找不到%f\", data);
}
12.填序填空,将求下列两个定积分之和的程序补充完整。
其中,求定积分的函数采用梯形公式n(main中对应的实参取50)等份积分区间。
# include<stdio.h>
float f1(float), f2(float);
float fs( )
{ float s=o, x=a, h=(b-a)/n;
int i;
for(i=1; i<=n; i++)
{ s+=((*f)(x)+(*f)(x+h))*h/2;
x+=h;
}
;
}
void main()
{ float y;
y=fs(2, 6, 50, f1)+fs(3, 7, 50, f2);
printf("%f\", y);
}
float f1(float x)
{ return x*x+x*sin(x);
}
float f2(float x)
{ ;
}
13.列函数用于在节点类型为ltab的非空链表中插入一个节点(由形参指针变量p0指向),链表按照节点数据成员no的升序排列,填空将程序补充完整。
ltab *insert(ltab *head, ltab *stud)
{ ltab *p0, *p1, *p2;
p1=head; p0=stud;
while((p0->no>p1->no)&&( ))
{ p2=p1;
p1=p1->next;
}
if(p0->no<=p1->no)
if(head==p1)
{ p0->next=head;
head=p0;
}
else { p2->next=p0;
}
else { p1->next=p0;
}
return (head);
}
14.本文件a.dat、b.dat中每行存放一个数且均按从小到大存放。下列程序将这两个文件中的数据合并到c.dat,文件c.dat中的数据也要从小到大存放。请填空,将程序补充完整、正确(若文件a.dat数据为1、6、9、18、27、35,文件b.dat数据为10、23、25、39、61,则文件c.dat中数据应为1、6、9、10、18、23、25、27、35、39、61)。
# include<stdio.h>
# include<stdlib.h>
void main()
{ file *f1, *f2, *f3; int x, y;
if((f1=fopen("a.dat", "r"))==null)
{ printf("文件a.dat不能打开!\"); exit(0);
}
if((f2=fopen("b.dat", "r"))==null)
{ printf("文件b.dat不能打开!\"); exit(0);
}
if( (1) )==null}
{ printf("文件c.dat不能打开!\"); exit(0);
}
fscanf(f1, "%d", &x); (2) ;
while(!feof(f1)&&!feof(f2))
if( (3) )
{ fprintf(f3, "%d\", x); fscanf(f1, "%d", &x);
}
else { fprintf(f3, "%d\", y); fscanf(f2, "%d", &y);
}
if(feof(f1))
{ (4) ;
while(!feof(f2))
{ fscanf(f2, "%d", &y); (5) ;
}
}
else { fprintf(f3, (6) );
while(!feof(f1))
{ (7) ; fprintf(f3, "%d\", x);
}
}
fclose(f1); fclose(f2); fclose(f3);
}
15.下列程序将键盘输入的若干姓名、成绩写入文本文件,写入过程中文件中的数据均按成绩从高到低存放。请填空将程序补充完整、正确。
# include<stdio.h>
# include<stdlib.h>
void main()
{ char name[9], na[9]; int score, sc; file *p1; int i, pt1, pt2, flag;
if((p1=fopen("d:\\file1.dat ", "w+"))==null)
{ printf("文件不能打开!\"); exit(0);
}
scanf("%s%d", name, &score); // 读入第1个人的姓名、成绩并写入文件
fprintf(p1, "%8s%3d\", name, score);
while(scanf("%s%d", name, &score)!=eof) // 读入其他人的姓名、成绩
{ rewind(p1); // 将读写位置移动到文件头
(1)
while(fscanf(p1, "%8s%3d\", na, &sc)!=eof)
if(score>sc)
{ fseek(p1, -13, 1); pt1=ftell(p1); // 确定数据的插入位置
(2) ; pt2=ftell(p1); // 确定文件尾部位置
for(i=pt2-13; i>=pt1; i=i-13)
{ fseek(p1, i, 0); fscanf(p1, "%8s%3d\", na, &sc);
(3)
}
fseek(p1, pt1, 0);
fprintf(p1, "%8s%3d\", name, score);
flag=0; // 键盘输入的数据已插入,标志位置0
break;
}
if( (4) ) // 若数据未插入,则在文件末尾插入
{ (5) // 移动文件读写位置到文件末尾
fprintf(p1, "%8s%3d\", name, score);
}
}
fclose(p1);
}
五、分析程序运行结果
阅读下列程序,写出输出结果。
程序1
# include<stdio.h>
# include<math.h>
void main()
{ float a1, a2, a3, s, d;
scanf("%f%f%f", &a1, &a2, &a3);
s=(a1+a2+a3)/2;
s=sqrt(s*(s-a1)*(s-a2)*(s-a3));
printf("%.2f%,%.2f%,%.2f,s=%10.3f\", a1, a2, a3, s);
}
运行时输入3 4 5
输出结果为:
程序2
# include<stdio.h>
void main()
{ unsigned k, n;
scanf("%u",&n);
k=n%10*10+n/10;
printf("n=%d k=%d\", n, k);
}
运行时输入数据为: 69 输出结果为:
程序3
# include<stdio.h>
void main()
{ int x=40, y=4, z=4;
x=y==z;
printf("%d %d %d\", x, y, z);
x=x==(y=z);
printf("%d %d %d\", x, y, z);
}
输出结果为:
程序4
# include<stdio.h>
void main()
{ int x, y, z;
x=y=2; z=3;
y=x++-1;
printf("%d\%d\ %d\", x, y, z);
y=--z+1;
printf("%d\%d\ %d\", x, y, z);
x=y=z=0;
++x&&++y||++z;
printf("%d\%d\ %d\", x, y, z);
--x&&++y&&++z;
printf("%d\%d\ %d\", x, y, z);
}
输出结果为:
程序5
# include<stdio.h>
void main()
{ char x; int n=0, k=0;
while((x=getchar())!=’.’)
{ switch(x)
{ case ’t’: k++; break;
case ’h’: if(k==1) k++; break;
case ’e’: if(k==2) k++; break;
default: k=0;
} 运行时输入: a the asdftheth e there .
if(k==3) n++;
} 输出结果为:
printf("%d\" ,n);
}
程序6
# include<stdio.h>
# include<ctype.h>
void main() 运行时输入: 35dffe
{ char a, b, x; int i;
while(!isupper(x=getchar())); 输出结果:
for(a=’a’; a<=x; a++)
{ for(b=’a’; b<’a’+x-a; b++) putchar(’ ’);
for(i=1; i<=2*(a-’a’)+1; i++) putchar(’ ’);
putchar(’\’);
}
}
程序7
# include<stdio.h>
void prn(int a, int b, int c, int max, int min)
{ max=(max=a>b?a:b)>c?max:c;
min=(min=a<b?a:b)<c?min:c;
printf("max=%d min=%d\", max, min);
}
void main()
{ int x, y;
x=y=0; prn(19, 23, -4, x, y);
printf("max=%d min=%d\", x, y);
}
输出结果为:
程序8
# include<stdio.h>
int f1(int, int), f11(int);
void f2(int);
void main()
{ int i, j;
for(i=0; i<5; i++)
{ f2((5-i)*3);
for(j=0; j<=i; j++) printf("%3d", f1(i, j));
putchar(’\’);
}
}
int f1(int m, int n)
{ return f11(m)/f11(n)/f11(m-n);
}
int f11(int k)
{ if(k<=1)
return 1;
return k*f11(k-1);
}
viod f2(int n)
{ for(int i=1; i<=n; i++) putchar(’ ’);
}
输出结果为:
程序9
# include<stdio.h>
int f(int m, int n)
{ if(m%n==0) return n;
else return f(n, m%n);
}
void main()
{ printf("%d\", f(840, 48));
}
输出结果为:
程序10
# include<stdio.h>
#define s x=y=z
#define p3(x, y, z) printf("x=%d\y=%d\z=%d\", x, y, z);
void main()
{ int x, y, z;
s=1; ++x||++y||++z; p3(x, y, z);
s=1; ++x&&++y||++z; p3(x, y, z);
s=1; ++x&&++y&&++z; p3(x, y, z);
s=-1; ++x||++y&&++z; p3(x, y, z);
s=-1; ++x||++y||++z; p3(x, y, z);
s=-1; ++x&&++y&&++z; p3(x, y, z);
}
程序11
# include<stdio.h>
void main()
{ int m[]={1, 2, 3, 4, 5, 6, 7, 8, 9}, i, j, k;
for(i=0; i<4; i++)
{ k=m; m=m[8-i]; m[8-i]=k;
for(j=0; j<9; j++) 输出结果为:
printf("%d", m[j]);
putchar(‘\‘);
}
}
程序12
# include<stdio.h>
void main()
{ int x[4][4]={{1, 2, 3, 4}, {3, 4, 5, 6}, {5, 6, 7, 8},{7, 8, 9, 10}}, i, j;
for(i=0; i<4; i++)
for(j=0; j<4; j++)
*(*(x+i)+j)/= *(*(x+i)+i);
for(i=0; i<4; i++)
{ for(j=0; j<4; j++) printf("%3d", *(*(x+i)+j));
putchar(‘\‘);
}
}
输出结果为:
程序13
# include<stdio.h>
# include<string.h>
void main()
{ char line[]="123456789"; 输出结果:
int i, k=strlen(line);
for(i=0; i<4; i++)
{ lint[k-i]=’{post.content}’;
puts(line+i);
}
}
程序14
# include<stdio.h>
# include<string.h>
void main()
{ char a[5][20]={"abc", "def", "123", "456", "#$%"};
int i, j;
for(i=0; i<4; i++)
{ j=0;
while(a[j]) j++;
strcat(*(a+i)+j,*(a+i+1));
}
for(i=0; i<4; i++) puts(*(a+i));
}
输出结果为:
程序15
# include<stdio.h>
# include<string.h>
void del_bk(char *p)
{ char *p1; p1=p;
while(*p1!=’{post.content}’)
if(*p1==’ ’&&*(p1+1)==’ ’) 输出结果:
strcpy(p1, p1+1);
else p++;
}
void main()
{ char *aa="aa bb cccc ddd efg h";
printf("%s\", aa); del_bk(aa); printf("%s\", aa);
}
程序16
# include<stdio.h>
void main()
{ struct t1 { char c[4], *s;} 输出结果为:
s1={"abc", "def"};
struct t2 { char *cp; struct t1 ss1;}
s2={"ghi", {"jkl", "mno"}};
printf("%c, %c\", s1.c[0], *s1.s);
printf("%s, %s\", s1.c, s1.s);
printf("%s, %s\", s2.cp, s2.ss1.s);
printf("%s, %s\", ++s2.cp, ++s2.ss1.s);
}
程序17
# include<stdio.h>
void main()
{ struct info {int data; struct info *pn;};
info base, p;
base=null;
for(int i=0; i<10; i++)
{ p=(struct info*)malloc(sizeof(struct info)); p->data=i+1;
p->pn=base; base=p;
}
p=base;
while(p!=null)
{ printf("%2d", p->data); p=p->pn;
}
printf("\");
}
输出结果为:
程序18。
# include<stdio.h>
void sub1(short *x, short *y)
{ *x=*x^*y; *y=*x^*y; *x=*x^*y;
}
void main()
{ short a,b;
while(scanf("%d%d", &a, &b)!=eof)
{ sub1(&a, &b); printf("%d, %d\", a, b);
}
}
程序19
#include <stdio.h>
struct stu
{int num;char name[10];int age;};
void py(stuct stu *p)
{printf("%s\",(*p).name);}
void main()
{struct stu student[3]={{1001,"sun",25},
{1001,"ling",23},
{1003,"shen",22}};
py(student+2);
}
输出结果为:
程序20
设head是node类型的全程量,以head为头指针的链表各节点的值如下图所示。
head→ 3 ()→4 ()→5 ()→6 ()→7 null
调用fun(head)返回值是 。
#include<stdio.h>
#define len sizeof(struct node)
struct node{
int nun;
struct node *next;
};
int fun(struct node*h)
{int k=0;
struct node*p=h;
while(p!=null){
if(p->next!=null)k+=p->num;
p=p->next;
}
return k;
}
void main()
{ struct node*head ,*p1,*p2;
int i;
head=(struct node *) malloc(len);p1=head;
for(i=3;i<=7;i++)
{p2=(struct node*)malloc(len);p1->next=p2;
p2->num=i;p2->next=null;
p1=p2;printf(“%d\”,fun(head->next));
}}
六、综合编程题
1.编程,输入x后按下式计算y值并输出。
2.编程,输入t后,按下式计算y值并输出,要求分别写作if结构和switch结构。
3.输入100个数,统计其中负数、零及正数的个数。
4.输入k,利用迭代公式 计算k1/3的近似值,要求结算结果具有14位有效位数。
5.输入n,计算
6.输入n(n≤20)个数,按绝对值从小到大排序后输出。
7.输入一个5行、6列的数组,先以5行6列的格式输出该数组,然后找出该数组中值最小的元素,输出该元素及其两个下标。
8.输入1行字符(不超过80个字符)。删除其中所有的字符’$’
9.输入1行字符(不超过80个字符)。将空格符后的第1个英文字母改为大写(原为大写字母则不变)。
10.编程序计算: 精度为0.000001。
11.编程序求解一元二次方程 ax2 +bx+c=0 ,要求考虑实根、虚根等情况。
12.输入一公元年号,判断是否是闰年。闰年的条件是:年号能被4整除但不能被100整除,或者能被400整除。
13.输入3个数据,如果这3个数据能够构成三角形,计算并在窗体上输出三角形的面积。提示:(1)构成三角形的条件是:任意两边之和大于第三边。(2)计算三角形面积的公式是:
,其中: 。
14.编一子程序验证哥德巴赫猜想:一个大于等于6的偶数可以表示为两个素数之和。
例如:6=3+3 8=3+5 10= 3+7
提示:写一自定义函数来判断任意整数n是不是素数。
15.编写一个计算表达式 值的程序(m>=n>=0),要求:用输入对话框输入m和n的值,用编写函数:int fact(int x )求x!的值。
16.编程序求表达式s=x/2!+x^3/4!+…+x^(2n-1)/(2n)!的值,并打印输出。要求如下:
(1)在主函数中输入变量x与n的值,通过调用函数过程fs实现题目要求。
(2)求表达式的值用函数过程double fs (int n, double x) 完成。
17.有1分、2分、5分硬币若干枚,从中取出20枚硬币使其总值为60分,求出取法的数量以及每一种取法的1分、2分、5分硬币个数。
18.打印如下图所示的杨辉三角形(杨辉三角形为一个下三角矩阵,每一行第一个和主对角线上元素都为1,其余每一个数正好等于它上面一行的同一列与前一列数之和)。
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
19.编写一个加密程序,输入一行字符串(小于80个字符),输出其加密后的字符串
提示:加密采用字符平移算法:即将每个字母向后顺序移动5个位置,如“a”→“f”、“b”→“g”、“a”→“f”、“b”→“g”、“z”→“e”。对于非字母字符原样输出。
20.编程统计c盘mydir文件夹中文本文件data.txt中字符'$'出现的次数。并将统计结果写入到文本文件c:\\mydir\es.txt中。
第四部分 模拟试题
模拟测试试卷(一)
一、填空(20分)
1 写出下列两个数学表达式对应的c表达式:
(1) 10 ≤ x+y ≤30 。
(2) 。
(3) 写出求空间两点(x1,y1,z1)和(x2,y2,z2)之距离的c语言表达式: 。
2 当a=5,b=4,c=2时,表达式a>b!=c的值是 。
3 语句"printf("%x,%o",16,12);"的输出结果是 。
4 设 a=12 则表达式a+=a和a*=2运行后a 的值分别为 。
5 二维数组中元素在内中的存放顺序是 。
6 设 a=10,则printf("%d",++a)语句的输出结果为 。
7 有定义: int a[][3]={1,2,3,4,5,6,8,9,10},则printf("%d",*(*(a+1)+2))语句的输出结果为 。
8 c语言中没有逻辑量,在给出逻辑运算结果时,以 代表"真",用 代表"假"。
9 若已知a=10,b=15,c=1,d=2,表达式a*b&&c的运算结果 。
10 若int类型数据占两个字节,则下列语句int k=-1;printf(″%d,%u\n″,k,k);的输出结果为 。
二、选择题(将正确的答案编号填入题后的括号内)(20分)
1 以下c语言运算符中优先级最高的是( )
(a) ++ (b) == (c) && (d) %
2 下面程序执行输出结果是( )
(a) yes (b) no (c) 什么也不输出 (d) 输出的结果由输入的a值决定
main()
{int a;
scanf("%d",&a);
if (a>3)
if (a<2) printf("yes")
else printf("no");
}
3 下段程序循环体执行的次数是( )
(a) 1 (b) 2 (c) 3 (d) 0
i=1;n=0;
while (n<=2*i)
{ n=i*i;
i=i+1;}
4 已知a的ascii代码是65,下程序的输出结果是( )
(a) 因输出格式不合法,输出错误信息 (b) 65, 66
(c)a, b (d) 66, 65
main()
{ int c1=65,c2=66;
printf("%c, %c",c1,c2);
}
5 以下程序运行结果为( )
(a) 14.0 (b) 31.5 (c) 7.5 (d) 10.5
#define pt 3.5
#define s(x) pt*x*x
main()
{ int a=1, b=2;
printf(″%4.1f \n″,s(a+b));
}
6 已的定义 int k=2;int *ptr1,*ptr2;且ptr1和ptr2均已指向k,下面不正确执行的赋值语句是( )
(a) k=*ptr1+*ptr2 (b) ptr2=k; (c) ptr2=ptr1 (d) k=*ptr1*(*ptr2)
7 以下可作为函数fopen中第一个参数的正确格式是( )
(a) c:user\ext.txt (b) c:\\user\ext.txt
(c) "c:\\user\ext.txt" (d) "c:\\user\ext.txt"
8 下面程序的运行结果是( )
(a) -1 (b) 1 (c) 8 (d) 0
main()
{ int y=10;
do {y--;} while (--y);
printf("%d\",y--);
}
9 设有如下函数定义:
int f(char * s)
{ char *p=s;
while(*p!='{post.content}')p++;
return(p-s);
}
在主函数中用语句printf("%d\",f("goodbey!"));调用上述函数,则输出结果为( )
a)3 b)6 c)8 d)0
10 两次运行下面的程序,如果从键盘上分别输入6和4,则输出结果是( )
a)7和5 b)6和3 c)7和4 d)6和4
main()
{ int x;
scanf("%d",&x);
if(x++>5)printf("d%",x);
else printf("%d\",x--);
}
三、程序填空(15分)
认真阅读下面程序,在横线处填上适当的语句,使程序完成指定的功能。
1、下程序是用公式 求π的近似值,直到最后一项的绝对值小于是10 为止。
#include "math.h"
main()
{ int s=1;
float n=1,t=1,pi=0;
while( )
{ pi=pi+ ;
n= ;
s=-s;
t=s/n;
}
pi=p*4;
printf("pi=%f\",pi);
}
2 下程序是起泡对十个数按升序排序程序
main()
{ static int a[10]={12,23,14,5,6,1,0,10,9,7};
int i,j,t;
for(j=0; ;j++)
for(i=0;i<10-j;i++)
if( )
{ t=a;a=a[i+1];a[i+1]=t;}
for(i=0;i<10; )
printf("%d ", );
}
3 下面函数f(v,x,&n)将x插入到已从大到小排序好的数组v中,插入x后数组的元素仍然有序,n表示数组v中已排序好的元素的个数。
void f(int v[],int x, )
{ int k;
for (k=*n-1; ;k--)
v[k+1]=v[k];
=x;
(*n)++;
}
四、阅读程序(20分)
1 下列程序运行后的输出结果: 。
#define fm "max=%d,row=%d,colum=%d\"
main()
{
int i,j,row,col,max;
static int a[3][4]={1,3,5,7,2,4,8,10,-10,12,5,6};
max=a[0][0];
for (i=0;i<3;i++)
for (j=0;j<4;j++)
if (a[j]>max)
{ max=a[j];
row=i;
col=j;
}
printf(fm,max,row,col);
}
2 下程序运行的输出结果是: 。
#include "stdio.h"
int x,y,z;
void ppp(int *x,int y)
{++*x;y--;
z=*x+y;
printf("%d,%d,%d ",*x,y,z)
}
void main()
{ x=2;y=3;z=4;
ppp(&x,y);
printf("%d,%d,%d ",x,y,z);
ppp(&y,x);
printf("%d,%d,%d\",x,y,z);
}
3 下列程序运行后的输出结果: 。
int max(int *p ,int n)
{ int i,t;
t=*p;
for(i=1;i<n;i++)
if (t<*(p+i)) t=*(p+i);
return t;
}
main()
{ int a[10]={10,23,1,3,4,0,-9,5,9,64};
int ma;
ma=max(a,10)
printf("max of array a=%d",ma) }
4 下列程序运行后的输出结果: 。
#define x 5
#define y x+1
#define z y*x/2
main()
{ int a;
a=y;
printf("%d\",z);
printf("%d\",--a);
}
5 以下程序的输出结果是 。
int a=6,b=5;
max(int a,int b)
{ int c;
c=a>b ? a:b;
return c;
}
main()
{ int a=8;
printf("d\",max(a,b));
}
五、 程序设计(25分)
1、用二重循环建立以下数组,并打印出来(不用scanf()函数和静态数组)
0 1 1 1 1
-1 0 1 1 1
-1 -1 0 1 1
-1 -1 -1 0 1
-1 -1 -1 -1 0
2、编一程序打印输出如下图案
a
bbb
ccccc
ddddddd
eeeeeeeee
3、编一个函数void fun( char *ss),它的功能是:把ss字符串中的字符按逆序存放。例如:若输入字符串为abcdefg,则逆置后的字符串为gfedcba。在主函数main调用该函数实现输入任意字符串,按逆置打印输出。
模拟测试试卷(二)
一、填 空(10分)
1.设x、y、z和k都是int型变量,则执行表达式:x=(y=4,z=16,k=32) 后,x的值为 。
2.设x和y均为int型变量,则以下语句:x+=y;y=x-y;x-=y;的功能是 。
3.设有定义int a=12,b=12;则语句 printf("%d %d\",--a,++b);的输出结果是:
。
4.执行语句:for(i=1;i++<4;)后;变量i的值是 。
5.有以下程序运行后,输出结果是 。
#define pt 5.5
#define s(x) pt*x*x
main( )
{ int a=1,b=2;
printf("%4.1f\",s(a+b));
}
6.设有如下定义: int a=1,b=2,c=3,d=4,m=2,n=2; 则执行表达式:(m=a>b)&&(n=c>d)后,n的值为 。
二、选择题(20分)
1.设有如下的变量定义:
int i=8,k,a,b;
unsinged long w=5;
double x=1.42,y=5.2;
则以下符合c语言语法的表达式是
a)a+=a-=b=4*(a=3) b)x%(-3) c)a=a*3=2 d)y=float(i)
2.假定有以下变量定义: int k=7,x=12; 则能使值为3 的表达式是
a)x%=k%=5 b)x%=k-k%5 c


意见与建议
沪ICP证:沪B2-20070217 版权所有:东方财富网



