C语言 实验四 任务报告
📝实验四 任务报告
✨实验总结
😟遇到的问题:
这次好像每道题的思考都很有点问题阿🤨
🧐解决方法:
一个一个解决,相信自己🙆♂️
🤔反思:
自己的能力还是太肤浅了,还需要多加练习,提高自己的知识。
✨实验内容
🕐任务一
📃代码:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
char x[2][20];
char * imag(double,double,double);
char * solve(double,double,double);
int main()
{
double a,b,c;
printf("求解方程ax^2+bx+c=0;\n请输入a,b,c(以空格为间隔):");
while (scanf("%lf%lf%lf",&a,&b,&c)!=EOF)
{
if (a==0)
{
printf("二次项系数不能为0,请重新输入。\n\n");
printf("\n求解方程ax^2+bx+c=0;\n请输入a,b,c(以空格为间隔):");
continue;
}
solve(a, b, c);
printf("x1 = %s\n", x[0]);
printf("x2 = %s\n", x[1]);
printf("\n求解方程ax^2+bx+c=0;\n请输入a,b,c(以空格为间隔):");
}
system("pause");
return 0;
}
double delta(double a,double b, double c)
{ double d;
d=b*b-4*a*c;
return d;
}
char * imag(double a,double b,double c)
{
double i1,i2;
i1 = sqrt(-delta(a,b,c)) / 2. / a;
i2 = -b / 2. / a;
sprintf(x[0],"%.2f%+.2fi", i1, i2);
sprintf(x[1],"%.2f%+.2fi", i1, -i2);
return (char *) x;
}
char * real(double a,double b,double c)
{
double x1,x2;
x1 = (-b + sqrt(delta(a,b,c))) / (2 * a);
x2 = (-b - sqrt(delta(a,b,c))) / (2 * a);
sprintf(x[0],"%.2f",x1);
sprintf(x[1],"%.2f",x2);
return (char *) x;
}
char * solve(double a,double b,double c)
{
if (delta(a,b,c)>=0)
return real(a,b,c);
else
return imag(a,b,c);
}
🎨截图:
🤓反思:
如果只做必做,修改一下上次的作业就好。但是如果想把选做完全弄好就有点麻烦了。最后把结果以指针的形式传回,应该满足选做的条件吧。在没有学习指针之前我觉得这是不可能的事情,函数只能返回一个值。在查阅了大量的资料之后,才懂了指针在这里该如何使用,还有很多东西要学。
🕑任务二
代码:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
long long fac(int n);
int main()
{
long long p;
for (int i = 1; i <=10; ++i)
printf("%lld\n",fac(i));
system("pause");
return 0;
}
long long fac(int i)
{
static long long p=1;
p=p*i;
return p;
}
#include<stdio.h>
int func(int, int);
int main()
{
int k=4,m=1,p1,p2;
p1 = func(k,m);
p2 = func(k,m);
printf("%d,%d\n",p1,p2);
return 0;
}
int func(int a,int b)
{
static int m=0,i=2;
i += m+1;
m = i+a+b;
return (m);
}
截图:
反思:
当一个进程的全局变量被声明为static之后,它的中文名叫静态全局变量。静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见,每次被调用都使用上一次的值。
但是说实话我的理解还是不够深透,我只知道这个变量只初始化一次,下一次用的时候可以调用上一次的结果。目前我们所学所用的代码都只涉及一个c文件,下次我会尝试使用多个c文件。
实验执行顺序为,赋值k=4,m=1,然后在func
里面赋值两个静态全局变量m=0,i=2
,然后i=m+i+1=3
,m=3+1+4=8
.第二次调用的时候m
的值为8
,i
的值为3
,不会再重新初始化。
🕒任务三
📃代码:
#include <stdio.h>
#include <stdlib.h>
#define N 1000
int fun(int n,int m,int bb[N])
{
int i,j,k=0,flag;
for(j=n;j<=m;j++)
{
flag=1;
for(i=2;i<j;i++)
if(j%i==0)
{
flag=0;
break;
}
if(flag)
bb[k++]=j;
}
return k;
}
int main(){
for (int i = 0; i < 2; ++i)
{
int n=0,m=0,i,k,bb[N];
printf("输入起始数:");
scanf("%d",&n);
printf("输入终止数:");
scanf("%d",&m);
for(i=0;i<m-n;i++)
bb[i]=0;
k=fun(n,m,bb);
printf("%d到%d的素数有:\n",n,m);
for(i=0;i<k;i++)
printf("%-4d",bb[i]);
printf("\n\n");
}
system ("pause");
return 0;
}
🎨截图:
🤓反思:
这个是最简单的,填空题,但我觉得可以把上次的代码修改一下,作为一个函数,但这周太忙了,周末去做把。
🕓任务四
📃代码:
#include <stdio.h>
#include <stdlib.h>
int main()
{
long n,digit,temp,j,carry;
long a[98000];
printf("请输入n:");
while(scanf("%d",&n)!=EOF)
{
digit = 1;
a[0] = 1;
//求2^n
for (int i = 0; i < n; ++i) {
for (j = 0, carry = 0; j < digit; j++)
{
temp = 2 * a[j] + carry;
a[j] = temp % 10;
carry = temp / 10;
}
while (carry)
{
++digit;
a[digit - 1] = carry % 10;
carry = carry / 10;
}
}
//计算2^n-1
a[0] = a[0] - 1;
printf("2^n = ");
for (j = digit; j > 0; --j)
{
printf("%d", a[j - 1]);
}
printf("\n\n请输入n:");
}
system("pause");
return 0;
}
🎨截图:
🤓反思:
又是一个思考题极为复杂的任务。首先算法参考了一篇求高位阶乘的文章,把值一位一位的储存到一个很大的数组中。每次乘2的操作为:把之前的数组按位与2相乘,除以10取余再重新赋值给该位。如果发生进位,则把进的位加到前一位。这个算法的原型就是乘法竖式,为了方便设计,把2放在上面,把2^(n-1)放在下面。模拟乘法运算,最后把数组反向输出。这个题目难的不是代码,是算法。这个算法如果从0开始构建真的很难,不过可以参考这个思想进行高位的四则运算的算法设计。
🕔任务五
📃代码:
#include <stdlib.h>
#include <stdio.h>
void draw(int ,char *);
int main()
{
char *x;
int l;
printf("请依次输入行数和要打印的符号:");
while (scanf("%d %s",&l,x)!=EOF)
{
draw(l,x);
printf("\n请依次输入行数和要打印的符号:");
}
return 0;
}
void draw(int l,char *x)
{
printf("打印开始\n");
int n=2*l-1;
for (int i = 0; i < l; ++i)
{
for (int j = 0; j < n/2+1-i; ++j)
{
printf(" ");
}
for (int j = 0; j < 2*(i+1) - 1; ++j)
{
printf("%s",x);
}
for (int j = 0; j < n/2+1-i; ++j)
{
printf(" ");
}
printf("\n");
}
printf("打印结束\n");
}
#include <stdlib.h>
#include <stdio.h>
void draw(int ,char );
int main()
{
int x;
int l;
printf("请依次输入行数和要打印的符号:");
while (scanf("%d %c",&l,&x)!=EOF)
{
draw(l,x);
printf("\n请依次输入行数和要打印的符号:");
}
return 0;
}
void draw(int l,char x)
{
printf("打印开始\n");
int n=2*l-1;
for (int i = 0; i < l; ++i)
{
for (int j = 0; j < n/2+1-i; ++j)
{
printf(" ");
}
for (int j = 0; j < 2*(i+1) - 1; ++j)
{
printf("%c",x);
}
for (int j = 0; j < n/2+1-i; ++j)
{
printf(" ");
}
printf("\n");
}
printf("打印结束\n");
}
🎨截图:
🤓反思:
大概是实验2选做的简化版。不过要注意 输入的时候scanf("%c", &a);
这里的&不能少 而scanf("%s",s);
这里不能有&符号。这个实验我无法理解的是为甚么定义的是一个int变量,但是输入的时候可以转换成了字符。为什么不直接定义char呢?然后试了一下,完全没有问题。