C语言 实验三 任务报告
📝实验三任务报告
✨实验总结
😟遇到的问题:
这次整体上没有遇到什么大问题,就是srand和rand函数研究了一下,详见任务2.
🧐解决方法:
详见任务2.
🤔反思:
详见任务2.
✨实验内容
🕐任务一
📃代码:
代码1(求解实数根):
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int a,b,c,delta;
do{
printf("求解方程ax^2+bx+c=0;\n请输入a,b,c(以空格为间隔):");
scanf("%d%d%d",&a,&b,&c);
delta=b*b-4*a*c;
if (delta<0)
printf("数据输入错误请重新输入\n");
}while (delta<0);
float x1,x2;
x1=(-b+sqrt(delta))/(2*a);
x2=(-b-sqrt(delta))/(2*a);
printf("求解成功,x1=%.2f,x2=%.2f",x1,x2);
system("pause");
return 0;
}
代码2(求解任意根):
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() {
float a, b, c, delta;
float x1, x2, i1, i2;
printf("求解方程ax^2+bx+c=0;\n请输入a,b,c(以空格为间隔):");
while (scanf("%f%f%f", &a, &b, &c) != EOF)
{
delta = b * b - 4 * a * c;
if (a==0)
{
printf("二次项系数不能为0,请重新输入。\n\n");
}
else if (delta < 0)
{
printf("求解虚数根...\n");
i1 = sqrt(-delta) / 2. / a;
i2 = -b / 2. / a;
printf("求解成功,");
printf("x1=%.2f%+.2fi,", i1, i2);
printf("x2=%.2f%+.2fi\n\n", i1, -i2);
}
else
{
printf("求解实数根...\n");
x1 = (-b + sqrt(delta)) / (2 * a);
x2 = (-b - sqrt(delta)) / (2 * a);
printf("求解成功,x1=%.2f,x2=%.2f\n\n", x1, x2);
}
printf("求解方程ax^2+bx+c=0;\n请输入a,b,c(以空格为间隔):");
}
system("pause");
return 0;
}
🎨截图:
🤓反思:
这个求解程序在一开时对于虚数很烦恼,后来发现只要能把i直接像字符一样输出就好了。不过和实数不一样的是虚数的结果是带加减号的,如果把+/-
号也一起输出的话,遇到虚部为负数的话就会输出x1=0.87+-0.50i,x2=0.87--0.50i
这显然不是想要的结果。想了一下,如果让数据带符号,正数前面有个加号不就好了吗。于是搜索了一下使用%+.2fi
就可以解决问题了。不过这个+/-
号在实验二中并没有涉及,现在学会也行吧。
🕑任务二
代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
int x,n;
printf("生成N个10以内的随机数\n请输入所需要的个数:");
scanf("%d",&n);
srand(time(NULL));
for (int i = 0; i < n; ++i)
{
x = rand()%10;
printf("第%d个随机数为:%d\n",i+1,x);
}
system("pause");
return 0;
}
截图:
反思:
在之前的实验二中已经初步了解到了随机数中srand()
和rand()
的用法,之前是根据时间变化随机变换颜色,并且将srand()
加入到了循环中。不过在本次实验中我也尝试着这么做,出乎预料的居然失败了,在循环之中随机数的值没有变化。在上网查阅了很多资料后都没有很直白的介绍,琢磨了一番之后才得出让自己信服的答案。
随机数生成用到的是srand()
和rand()
函数以及常用的time()
函数。srand()
用于生成随机数种子,说人话就是在计算机中有一个随机数表,就像高中教科书附录里面的那样。比如这里的随机数表是”1 2 3 4 5 6 7 8 9“
,srand(1)
则表示种子是1,rand()
函数就会根据这个种子,从第一位开始往后依次取值,假设我要根据这个种子连续输出随机数,得到的结果就是:1,2, 3 ,4....... 并且只要种子不改变,rand()
函数就会一直按照这个顺序执行,正是所谓的伪随机。
要想改变种子的值,常用的方法就是把时间作为种子,即srand((unsigned)time(NULL));
NULL在头文件里面定义是0,这句函数的含义是取从00:00:00 GMT, January 1, 1970 到现在所持续的秒数,然后将time_t型数据转化为(unsigned)型再传给srand()
函数。当srand()
的参数值固定的时候,rand()
获得的数也是固定的,因此如果把这句话写到循环里面,每次循环的时间很快,根本达不到1秒,并且每次使用srand()
之后rand()
又会从种子的第一位开始取,这也就是我之前输出的值不变的原因。正确的用法是只需在主程序开始处调srand((unsigned)time(NULL));
后面直接用rand()。
🕒任务三
📃代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
long long n,r,f,l,t;
n = 0;
l = 8;
printf("2\t3\t");
for (int x = 1; x <= 100000000; ++x)
{
t=(int)sqrt(x);
for (int i = 2; i <= t; ++i)
{
r = x % i;
if (r == 0)
{
f = 0;
break;
}
else
f = 1;
}
if (f == 1)
{
printf("%d\t",x);
++n;
}
if (n == l)
{
printf("\n");
l=l+10;
}
}
printf("\n1亿以内的素数一共有%d个\n",n+2);
system("pause");
return 0;
}
🎨截图:
🤓反思:
稍微试了一下1亿以内的质数,之前用的是%6d
来控制输出,但是如果改成1亿的话得修改数值,不同的要求就要修改一次很麻烦。于是想到\t
被称为制表符,一劳永逸。也同时熟悉了\t
的用法,\t
默认8位左对齐,超过8位就16位再者24位以此类推,最终1亿也可以轻松表示出来。不过如果只是100-200的话%6d
还是更方便一点的。
🕓任务四
📃代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
long on;
long t,r,s,n;
on=0;
printf("请输入一个数字:");
while (scanf("%ld",&on)!=EOF)
{
long i=0,u=-1,s=0;
//转化数据
on = fabs(on);
//判断位数
do {
++u;
t = on / pow(10, u);
} while (t != 0);
//反向输出
for (int j = 0; j < u; ++j)
{
t = on / pow(10, j);
r = t % 10;
n = u - j - 1;
s = s + r * pow(10, n);
}
//取奇数
on = s;
printf("新的数为:");
do {
t = on / (int) pow(10, i);
r = t % 10;
if (r % 2 != 0)
{
printf("%d", r);
}
++i;
} while (t != 0);
printf("\n请输入一个数字:");
}
system("pause");
return 0;
}
🎨截图:
🤓反思:
思路:先把整个数反序,并以数的形式输出,再把奇数给依次输出。
这个程序其实有点难度,首先如果直接输出奇数会倒序,和结果不一样。尝试着构建算法,先找奇数再反向的话,我找奇数是先找奇数再一个一个输出,反向就变得很难。索性直接先反向在找奇数,思路就很开明了。
🕔任务五
📃代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int fac(n)
{
long s=1;
for (int i = 1; i <= n; ++i)
{
s=s*i;
}
return s;
}
int main()
{
int n,x;
printf("求解1-1/2!+1/3!+...+(-1)^(n-1)/n!\n");
printf("请输入n的值:");
while(scanf("%d",&n)!=EOF)
{
double s=0;
x=0;
for (int i = 0; i < n; ++i)
{
++x;
s = s + 1 * pow(-1, i) / fac(x);
}
printf("答案为:%f\n", s);
printf("请输入n的值:");
}
system("pause");
return 0;
}
🎨截图:
🤓反思:
这个是在课上完成的,边听函数,一边用出来的。刚开始我以为预定义的函数和主函数的变量会起冲突,结果并没有。不过之后调试的时候,n=10的时候我的答案是0.632120,看了很多遍函数之后也觉得没有问题。之后尝试了一番,把s的类型从float
改成了double
就正确了,应该是精度的问题。
🕕任务六
📃代码:
#include <stdio.h>
#include <stdlib.h>
#include "time.h"
int main()
{
srand(time(NULL));
int n,f,s,m;
m=rand()%12+1;
s=rand();
if (m==1||m==3||m==5||m==7||m==8||m==10||m==12)
{
for (int i = 0; i < 3; ++i)
{
int d = s % 31 + 1;
printf("\n您还有%d次机会,请尽力尝试吧!\n",3-i);
printf("你的幸运月份为%d月,该月有31天,请输入你的幸运日期:",m);
scanf("%d", &n);
if (n == d)
{
printf("恭喜,你就是天选之人,%d月%d日是你的良辰吉日哦!\n", m, d);
f=1;
break;
}
else if (n < d)
printf("可惜,还差一点点!不妨下次试试更大的日期?\n");
else
printf("可恶,日期过了!不妨下次试试更小的日期?\n");
}
}
else if (m==4||m==6||m==9||m==11)
{
for (int i = 0; i < 3; ++i)
{
int d = s % 30 + 1;
printf("\n您还有%d次机会,请尽力尝试吧\n",3-i);
printf("你的幸运月份为%d月,该月有30天,请输入你的幸运日期:",m);
scanf("%d", &n);
if (n == d)
{
printf("恭喜,你就是天选之人,%d月%d日是你的良辰吉日哦!\n", m, d);
f=1;
break;
}
else if (n < d)
printf("可惜,还差一点点!不妨下次试试更大的日期?\n");
else
printf("可恶,日期过了!不妨下次试试更小的日期?\n");
}
}
else
{
for (int i = 0; i < 3; ++i)
{
int d = s % 28 + 1;
printf("\n您还有%d次机会,请尽力尝试吧\n",3-i);
printf("你的幸运月份为2月,该月有28天,请输入你的幸运日期:");
scanf("%d", &n);
if (n == d)
{
printf("恭喜,你就是天选之人,%d月%d日是你的良辰吉日哦!\n", m, d);
f=1;
break;
}
else if (n < d)
printf("可惜,还差一点点!不妨下次试试更大的日期?\n");
else
printf("可恶,日期过了!不妨下次试试更小的日期?\n");
}
}
if (f==1)
printf("找到了自己的好运日,可以试试现在许愿,说不定到时候会有惊喜哟!\n");
else
printf("很抱歉你已经用完了所有机会。不要灰心,世界上好运的人只占一小部分,下次再来吧!\n");
system("pause");
return 0;
}
🎨截图:
🤓反思:
其实这个感觉是实验中比较简单的一个,就是截图不好截,正如上面所说,好运的人只占一小部分。