C语言课程设计实习报告11.docx
《C语言课程设计实习报告11.docx》由会员分享,可在线阅读,更多相关《C语言课程设计实习报告11.docx(18页珍藏版)》请在冰豆网上搜索。
C语言课程设计实习报告11
C语言课程设计实习报告
班级:
131132
姓名:
王涛
学号:
20131000513
2014-7
题目一、
题目描述:
已知银行整存整取存款不同期限的月息利率(采用复利方式,即利滚利)分别为
0.63%期限一年
0.66%期限二年
月息利率=0.69%期限三年
0.75%期限五年
0.85%期限八年
要求输入存钱的本金和期限(以整数年为单位),求到期时能从银行得到的利息与本金的合计。
设计思路:
用嵌套的if-else结构或switch结构实现,核心函数pow(1+月利率,月份)。
然后用这个函数计算每次的结果。
运行效果截图:
附源程序如下:
#include
#include
main()
{intyear;
floatrate,corpus;
doublec;
printf("请输入存入本金:
\n");
scanf("%f",&corpus);
printf("请输入存放时间(单位:
年):
\n");
scanf("%d",&year);
if(year>=8)
{rate=0.0085;
c=corpus*pow(1+rate,year*12);
}
elseif(year>=5&&year<8)
{rate=0.0075;
c=corpus*pow(1+rate,year*12);
}
elseif(year>=3&&year<5)
{rate=0.0069;
c=corpus*pow(1+rate,year*12);
}
elseif(year>=2&&year<3)
{rate=0.0066;
c=corpus*pow(1+rate,year*12);
}
else
{rate=0.0063;
c=corpus*pow(1+rate,year*12);
}
printf("总收入为=%f\n",c);
return0;
}
题目二、
题目描述:
编写程序,用二分法求方程2x3-4x2+3x-6=0在(-10,10)之间的根。
设计思路:
1用do-while语句实现。
2二分法的计算步骤:
(1)准备计算f(x)在有根区间[a,b]端点处的值f(a),f(b)
(2)二分计算f(x)在区间中点(a+b)/2处的值f[(a+b)/2]
(3)判断若f[(a+b)/2]=0,则即是根,计算过程结束。
否则,检测:
A.若f[(a+b)/2]与f(a)异号,则根位于区间[a,(a+b)/2]内,这时以(a+b)/2代替b;
B.若f[(a+b)/2]与f(a)同号,则根位于区间[(a+b)/2,b]内,这时以(a+b)/2代替a;
反复执行步骤2和3,直到区间[a,b]长度缩小到允许的误差范围之内,此时中点(a+b)/2即为所求的根。
运行效果截图:
附源程序如下:
#include
#include
main()
{
floatx1,x2,x0,fx1,fx2,fx0;
do{
printf("请输入区间范围x1和x2\n");
scanf("%f%f",&x1,&x2);
fx1=2*x1*x1*x1-4*x1*x1+3*x1-6;
fx2=2*x2*x2*x2-4*x2*x2+3*x2-6;
}while(fx1*fx2>0);/*该循环语句实现:
确保区间范围内有零点,
否则将一直重新输入区间范围*/
do{
x0=(x1+x2)/2;
fx0=2*x0*x0*x0-4*x0*x0+3*x0-6;
if((fx0*fx1)<0){x2=x0;fx2=fx0;}
else{x1=x0;fx1=fx0;}/*标准2分发算法*/
}while(fabs(fx0)>1e-5);/*精度*/
printf("%f\n",x0);
}
题目三、
题目描述:
已有一个已排好序的10元素整型数组,要求输入一个数后,按原来排序的规律将它插入数组中。
设计思路:
首先准备一个11个空间的一维数组,然后把用户输入的数放到最后一个地址,并依次和前面的数作比较直到比前面一个数大就好,此时打印这11个数。
运行效果截图:
附源程序如下:
#include
voidmain()
{
inta[30]={7,10,13,16,20,24,26,46,68,69,99};//11个数,最后一个是a[10]//
inti,n;//n为从键盘录入的一个整数//
printf("请输入一个整数\n");
scanf("%d",&n);
printf("这个原数组为:
\n");
for(i=0;i<11;i++)//将原数组a的11个元素先打印出来//
printf("%d",a[i]);
printf("\n");
for(i=10;i>=-1;i--)//从原数组a的第11个也就是最后一个元素开始和整数n比较大小//
{if(a[i]>n)//如果a数组的第i个元素比n大,则把第i个元素往后移一个位置//
a[i+1]=a[i];/*这里值得注意的是,当输入的数小于a[0],则下次循环比较是a[-1]与n比,
a[-1]是一个很小的负数,所以肯定会执行else。
即把n赋给a[0]*/
else//如果a数组的第i个元素不比n大,则将n存放在第(i+1)的空位置上//
{a[i+1]=n;
break;//当n在a数组中按从小到大的顺序存进以后,退出此循环//
}
}
printf("您输入的整数按原来的排序规律将它插入数组后为:
\n");
for(i=0;i<12;i++)
printf("%d",a[i]);
printf("\n");
}
题目四、
题目描述:
编写程序,给定一个整数i,请求出另一个整数j,使i和j在用8位二进制表示时互为逆序。
例如:
给定i=3时,应得到j=192(3的二进制为:
00000011,192的二进制为11000000)。
设计思路:
1十进制整数转换为二进制整数用“除2求余”法。
2二进制整数转换为十进制整数用“按权相加”法。
通过这两个思路可以把二进制和十进制相互转化,然后只要做一件事情,把二进制数倒着输出变成十进制数即可。
运行效果截图:
附源程序如下:
#include
#include
voidmain(void)
{
inti,s[8],m,a;
intj=0;
printf("请输入整数i:
\n");
scanf("%d",&m);
a=m;
for(i=0;i<8;i++)/*用for循环求m的2进制表示并存放到s[i]中*/
{
s[i]=m%2;/*m对2求余*/
m=m/2;
}/*该算法将m的2进制数存入s[8]*/
/*接下来直接用一种巧妙的算法算j*/
for(i=0;i<8;i++)/*同样用循环依次取出s[8]里的数*/
if(s[i]==1)
j+=pow(2,7-i);/*pow(x,y)表示x的y次方j=j+pow(2,7-i)*/
printf("%d的二进制的互逆为%d\n",a,j);/*7-i是把s[i]逆向排序,如11010000变为00001011*/
}
题目5、
题目描述:
用递推法求ex=1+x+x2/2!
+x3/3!
+…+xn/n!
的值。
设计思路:
很简单,只要按照公式进行编程就好。
不过有几个地方值得注意,一个是该公式是n趋于无穷大的,我们也可以将循环做成无限循环的。
第二个,不能一直循环,当到达某一精确度时停止循环,用break最好不过。
运行效果截图:
附源程序如下:
#include
intmain()
{
inti;
doublen,s=1,x=1,y=1;
printf("请输入指数x(x为大于等于0的正实数)\n");
scanf("%lf",&n);
for(i=1;;i++)/*无限循环*/
{
x*=n;
y*=i;/*这里有个赋值运算符*=,例:
x*=y+3等价于x=x*(y+3)。
*/
s+=x/y;
if(x/y<1e-5)
break;
}
printf("e的%lf次方的精确到百万分之一的值为%f\n",n,s);
return0;
}
题目六、
题目描述:
打印出以下的杨辉三角形(要求打印出10行)。
1
11
121
1331
14641
15101051
………………
设计思路:
这个问题的话,用二维数组实现。
首先把1都存入二维数组,用二重循环,然后利用杨辉三角的特点,每一个值都为上两个元素的和,用语句:
a[i][j]=a[i-1][j-1]+a[i-1][j]即可实现。
最后打印二维数组,注意间隔就好。
运行效果截图:
附源程序如下:
#include
intmain()
{
inta[10][10];
inti,j;
printf("杨辉三角的前十行是\n");
for(i=0;i<10;i++)
{
a[i][0]=1;/*就是把第一列的十个数都写成1,也可以说是杨辉三角的每行第一个数*/
a[i][i]=1;/*把二维数组的对角线都写成1,也可以说是杨辉三角的每行最后一个数*/
}
for(i=2;i<10;i++)/*重新给i赋初值为2*/
for(j=1;j
a[i][j]=a[i-1][j-1]+a[i-1][j];/*这个算法很奇妙,利用了杨辉三角的特性,每个元素等于
上头那两个元素相加,所以之前一定要把所有的1打出来。
这步是程序的灵魂*/
for(i=0;i<10;i++)/*接下来打印2维数组,2重循环不解释*/
{
for(j=0;j<=i;j++)
printf("%d",a[i][j]);/*注意这里显示每个数字空格的间距*/
printf("\n");
}
return0;
}
题目七、
题目描述:
找出一个二维数组的“鞍点”,即该位置上的元素在该行上最大,在该列上最小。
设计思路:
一个二维数组可能有鞍点也可能没有鞍点,若有鞍点,则只有一个。
因此最后肯定是两种情况之一。
首先我们准备一个a[10][10]的二维数组,让用户自行输入m,n,然后只写成m*n的一个矩阵。
这个都很好办。
关键是判断鞍点,就按要求来,先用循环扫行,找出该行最大的数并赋给max,在判断max在该列是否为最小,不是的话循环继续,找下一行最大再赋给max的并判断max是否为该列最小,直到找到鞍点为止。
没有找到就直接显示矩阵无鞍点。
小技巧,在找到该行最大数的时候把他的纵坐标记下来,找到鞍点时就可以把横纵坐标都记下来并放到两个变量里。
最后把变量加一就可以显示鞍点坐标了。
运行效果截图:
附源程序如下:
/*找出一个二维数组的"鞍点",即该位置上的元素在该行上最大,在该列上最小。
*/
#include
#defineN10
#defineM10
voidmain()
{
inti,j,k,m,n,flag1,flag2,a[N][M],max,maxj;/*二维10*10数组*/
printf("输入行数n,n<=10:
");/*n为行*/
scanf("%d",&n);
printf("\n输入列数m,m<=10:
");/*m为列*/
scanf("%d",&m);
printf("\n输入二维矩阵,元素之间用空格间隔,换行建议用回车\n");
for(i=0;ifor(j=0;j*/
scanf("%d",&a[i][j]);
flag2=0;
for(i=0;i{
max=a[i][0];/*max已在前面定义为整形*/
for(j=0;jif(a[i][j]>max)
{
max=a[i][j];
maxj=j;
}/*这个循环的功能把地i行的最大值给max,maxj为其纵坐标j。
*/
for(k=0,flag1=1;kif(max>a[k][maxj])/*纵坐标不变,当max为大数的时候,让下面判断条件为假*/
flag1=0;/**/
if(flag1)
{
i=i+1;
maxj=maxj+1;/*这里由于数组是以a00开头,为修正,各加一就好了*/
printf("\n第%d行第%d列的%d是鞍点\n",i,maxj,max);
flag2=1;/*因为有鞍点了,所以就让下面if不成立即可*/
}
}/*总循环后找到一个满足的,没有就进行下面的工作*/
if(!
flag2)/*逻辑表达式是有值的,当flag2为0时,表达式的值为1,if条件成立*/
printf("\n矩阵无鞍点!
\n");
}
题目八、
题目描述:
两个大数相乘问题,本问题中,要求输入两个相对较大的正整数,能够通过程序计算出其结果。
设计思路:
两个相对较大的数肯定是不能够用LONGINT类型存储的,因为LONG型数据的数据范围也并不是很大,于是就需要采用其他的存储结构。
这里推荐用数组存储一个大数,数组的初始空间可以定义到如200或300个单元,每个单元存储一位数据,形如下图:
2
5
5
9
6
2
0
7.。
。
。
。
这样理论上,比如数组定义为200,就可以存储200个数字的整数,应该是满足足够大的条件了。
而结果的存储也需要考虑空间的问题,所以需要一个更大的数组。
在解决了存储问题后,我们需要来实现乘法运送的过程,也就是说你必须要把这个数组中的每一位数字单独来进行乘法运算,比如我们可以用一个数字和另外一个数组中的每一位去相乘,从而得到乘法运算中一行的数字,再将每一行数字错位相加。
这就是乘法运算的过程。
运行效果截图:
附源程序如下:
#include
#include
voidsum(inta[200],intb[200],intm,intn)//结果在数组里顺序是反着的
{
intmm=0;//保存进位
intc[400]={0};//保存结果
inti,j,sum,tt;
for(i=0;i{
sum=0;
for(j=0;j{
if((tt=(m-1+n-1-i-j))>=n||(tt=(m-1+n-1-i-j))<0)
continue;
else
sum=sum+a[j]*b[m-1+n-1-i-j];
}
sum=sum+mm;
c[i]=sum%10;
mm=sum/10;
}
printf("\n相乘结果是\n");
for(i=399;i>=0;i--)//首位
{
if(c[i]!
=0)
{
tt=i;break;
}
elsecontinue;
}
for(i=tt;i>=0;i--)//输出
printf("%d",c[i]);
printf("\n");
}
voidmain()
{
inti,m,n,c;
inta[200]={0},b[200]={0};
printf("请输入第一个数:
\n");
for(i=0;(c=getchar())!
='\n';i++)
a[i]=c-48;
m=i;
printf("请输入第二个数:
\n");
for(i=0;(c=getchar())!
='\n';i++)
b[i]=c-48;
n=i;//m,n为数字长度
sum(a,b,m,n);
}
题目九、
题目描述:
有十个学生的信息(包括学号,姓名,成绩),要求按照成绩的高低输出个学生的信息。
设计思路:
用结构体存放十个学生信息,采用选择法对各元素进行排序(进行比较的是各元素中的成绩)。
选择排序法用起泡算法。
运行效果截图:
附源程序如下:
#include
structStudent
{intnum;
charname[20];
floatscore;
};
intmain()
{
structStudentstu[10]={{10001,"wang",98},{10002,"tang",78},{10003,"li",83},
{10004,"su",76},{10005,"jiao",87},{10006,"ma",90},{10007,"zhao",88},
{10008,"zhou",84},{10009,"feng",91},{10010,"jiang",96}};
structStudenttemp;
constintn=10;
inti,j,k;
printf("成绩由高到低的排序是:
\n");
for(i=0;i{k=i;
for(j=i+1;jif(stu[j].score>stu[k].score)
k=j;
temp=stu[k];stu[k]=stu[i];stu[i]=temp;
}
for(i=0;iprintf("%6d%8s%6.2f\n",stu[i].num,stu[i].name,stu[i].score);
printf("\n");
return0;
}
题目十、
题目描述:
下面是一个5*5阶的螺旋方阵,试编程打印出此形式的n*n(n<10)阶的方阵(顺时针旋进)。
12345
161718196
152425207
142322218
131211109
设计思路:
该题目我没有用二维数组,原因是二维数组有限制。
我通过观察螺旋方针的特点,发现螺旋方阵由“边框”和“小螺旋方阵”组成,“小螺旋方阵”同样由“小边框”和“小小螺旋方阵”组成······因此我要做以下几件事情:
1边框是4个,得写4个公式。
2边框写完得用递推写小边框
3同样用二重循环表示行和列并进行输出。
4每个螺旋方阵(一个及其里面的螺旋方阵)都有确定的顶点,我们只选取最左上角的顶点进行公式编辑(其他都可以通过这个算出来)。
我们在程序中把该顶点的名字取成lt。
4当n(几阶)确定后,螺旋方阵的每一个数也都确定,包括顶点lt。
5通过数学方法编辑get函数求出4个边框和递归公式。
6该程序理论上能运行n为任意正整数的情况,由于屏幕限制,19是最大可视化螺旋方阵。
7由于编辑19后,数最大能到上百位,由于百位和个位数字能差两个空格,十位数与个位数能差1个空格,所以在屏幕上打印出来会很难看,因此这里还需一个小技巧。
用if~else多重循环语句判断get函数值与10,100,的大小情况,分3类输出。
只需注意在输出10以内的数时加3个空格,输入10到100以内加2个空格,输入大于等于100的加一个空格,这样就很好的把间隔挑开了,看着更美观。
运行效果截图:
附源程序如下:
#include
intget(intx,inty,intlt,intn)/*定义get函数*/
{
if(x==0)
returnlt+y;
elseif(y==0)
returnlt+4*(n-1)-x;
elseif(y==n-1)
returnlt+n+x-1;
elseif(x==n-1)
returnlt+3*(n-1)-y;
else
returnget(x-1,y-1,lt+4*(n-1),n-2);/*递归函数*/
}/*这个算法很叼*/
intmain(void)
{
intn,i,j;
printf("请输入打印几阶的螺旋方阵,建议小于20:
\n");
scanf("%d",&n);
printf("\n");/*下面双重循环打印*/
for(i=0;i{
for(j=0;j{if(get(i,j,1,n)<10)
printf("%2d",get(i,j,1,n));
elseif(get(i,j,1,n)<100)
printf("%2d",get(i,j,1,n));
elseprintf("%2d",get(i,j,1,n));
};
putchar('\n');/*小层循环结束输出回车*/
}
return0;
}