上海海事大学自动化专业C语言课程代码参考(第七周)

想不到这么快就到了新的一周,写上周的作业仿佛就在两天前

正好今天是1024程序员节,写C语言作业非常应景

这周的作业主要是循环,话不多说,直接开始吧!

目录

上机实验

4-1      求1到100的和

输入格式:

输出格式:

4-2      求100以内偶数和

输入格式:

输出格式:

4-3     N分之一序列前N项和

输入格式:

输出格式:

输入样例:

输出样例:

4-4   求奇数分之一序列前N项和

输入格式:

输出格式:

输入样例:

输出样例:

4-5       求简单交错序列前N项和

输入格式:

输出格式:

输入样例:

输出样例:

4-6      求给定精度的简单交错序列部分和

输入格式:

输出格式:

输入样例1:

输出样例1:

输入样例2:

输出样例2:

4-7     求奇数和

输入格式:

输出格式:

输入样例:

输出样例:

结语


上机实验

4-1      求1到100的和

本题要求编写程序,计算表达式 1 + 2 + 3 + ... + 100 的值。(分别用 for  while do-while 各编写一个程序)

输入格式:

本题无输入。

输出格式:

按照以下格式输出:

1 + 2 + 3 + ... + 100 = 累加和

按题目要求似乎是要写三个程序,不过这个非常简单,我们直接看代码

while:

#include 

int main()
{
    int i = 100, sum = 0;

    while (i)
    {
        sum += i--;
    }
    printf("1 + 2 + 3 + … + 100 = %d", sum);

    return 0;
}

for:

#include 

int main()
{
    int i, sum = 0;

    for (i = 100; i; i--)
        sum += i;
    printf("1 + 2 + 3 + … + 100 = %d", sum);

    return 0;
}

do…while:

#include 

int main()
{
    int i = 100, sum = 0;

    do
    {
        sum += i--;
    } while (i);

    printf("1 + 2 + 3 + … + 100 = %d", sum);

    return 0;
}

4-2      求100以内偶数和

本题要求编写程序,计算表达式2 +4 + 6 + ... + 100 的值。

输入格式:

本题无输入。

输出格式:

按照以下格式输出:

2 +4 + 6 + ... + 100 = 累加和

这题在上一题的基础上,每次循环时加入一个判断即可。代码如下:

#include 

int main()
{
    int i, sum = 0;

    for (i = 100; i; i--)
    {
        if(!(i % 2))
            sum += i;
    }
    printf("2 + 4 + 6 + … + 100 = %d", sum);

    return 0;
}

4-3     N分之一序列前N项和

本题要求编写程序,计算序列 1 + 1/2 + 1/3 + ... 的前N项之和。

输入格式:

输入在一行中给出一个正整数N。

输出格式:

在一行中按照“sum = S”的格式输出部分和的值S,精确到小数点后6位。题目保证计算结果不超过双精度范围。

输入样例:

6

输出样例:

sum = 2.450000

这题的逻辑和前面两题一样,直接看代码吧

#include 

int main()
{
    int i;
    float sum = 0;

    scanf("%d", &i);
    for (; i; i--)
        sum += 1 / (float)i;
    printf("sum = %.6f", sum);

    return 0;
}

不过需要注意一点,这里的 i 不能为浮点类型。若为浮点类型,则需要将for内的条件判断改为大小判断,而不能直接判断 i

4-4   求奇数分之一序列前N项和

本题要求编写程序,计算序列 1 + 1/3 + 1/5 + ... 的前N项之和。

输入格式:

输入在一行中给出一个正整数N。

输出格式:

在一行中按照“sum = S”的格式输出部分和的值S,精确到小数点后6位。题目保证计算结果不超过双精度范围。

输入样例:

23

输出样例:

sum = 2.549541

看代码,如下

#include 

int main()
{
    int i;
    float sum = 0;

    scanf("%d", &i);
    for (; i; i--)
    {
            sum += 1 / (float)(i * 2 - 1);
    }
    printf("sum = %.6f", sum);

    return 0;
}

4-5       求简单交错序列前N项和

本题要求编写程序,计算序列 1 - 1/4 + 1/7 - 1/10 + ... 的前N项之和。

输入格式:

输入在一行中给出一个正整数N。

输出格式:

在一行中按照“sum = S”的格式输出部分和的值S,精确到小数点后三位。题目保证计算结果不超过双精度范围。

输入样例:

10

输出样例:

sum = 0.819

呃……简单交错序列是啥……?看题目意思貌似是分母为等差数列,分子分别为+1、-1…的求和,那就按这个写吧

稍加思考便会发现,这只将上面第四题的部分代码改动即可。代码如下

#include 

int main()
{
    int i, sig = -1;
    float sum = 0;

    scanf("%d", &i);
    for (; i; i--)
    {
            if(i % 2)
                sig = 1;
            else
                sig = -1;
            sum += sig / (float)(i * 3 - 2);
    }
    printf("sum = %.3f", sum);

    return 0;
}

在给sig赋值那一段可以用 -1 的 i 次幂的形式,在此用了判断,效果相同

4-6      求给定精度的简单交错序列部分和

本题要求编写程序,计算序列部分和 1 - 1/4 + 1/7 - 1/10 + ... 直到最后一项的绝对值不大于给定精度eps。

输入格式:

输入在一行中给出一个正实数eps。

输出格式:

在一行中按照“sum = S”的格式输出部分和的值S,精确到小数点后六位。题目保证计算结果不超过双精度范围。

输入样例1:

0.04

输出样例1:

sum = 0.854457

输入样例2:

0.02

输出样例2:

sum = 0.845541

这一题的循坏条件稍微要改一下,先看代码

#include 

int main()
{
    int i, sig = -1;
    float sum = 0, eps;

    scanf("%f", &eps);
    sum += 1;// 手动加一次
    for (i = 1; eps < 1 / (float)(i * 3 - 2);)
    {
        i++;
        if (i % 2)
            sig = 1;
        else
            sig = -1;
        sum += sig / (float)(i * 3 - 2);
    }
    printf("sum = %.6f", sum);

    return 0;
}

我们发现,题目要求的是最后一位的绝对值要小于eps,用do…while会比较好实现,但是在此用for,手动加一次也可以达到效果

但当我写完代码验证输入的时候,发现这道题似乎有点问题

当输入0.04的时候比较正常,每次的数据如下

上海海事大学自动化专业C语言课程代码参考(第七周)_第1张图片

结果和例子吻合,但当输入0.02的时候,每次的数据如下

上海海事大学自动化专业C语言课程代码参考(第七周)_第2张图片

结果与例子并不吻合,但是我们仔细一看,在倒数第二个sum处结果和例子的sum相同,但最后一个+=也是需要加起来的,所以有可能是题目出了问题

4-7     求奇数和

本题要求编写程序,计算给定的一系列正整数中奇数的和。

输入格式:

输入在一行中给出一系列正整数,其间以空格分隔。当读到零或负整数时,表示输入结束,该数字不要处理。

输出格式:

在一行中输出正整数序列中奇数的和。

输入样例:

8 7 4 3 70 5 6 101 -1

输出样例:

116

这题输入的量是不固定的,所以不能简单的一次读完,这时候我们要引入一个概念,“队列”

队列是一种遵循先入先出(FIFO)的数据结构。为什么我们要介绍这种结构呢?因为scanf所读取的缓冲区正是一个队列。

你有没有想过,scanf究竟是如何读取我们输入的值的呢?

大致过程是这样的,首先,我们在黑乎乎的界面内输入了一串字符串(还没讲过),然后电脑自动帮我们存到了一块缓冲区内,存完了之后再执行scanf,这个函数会从缓冲区的队列头开始,一路向后找,直到空格或者回车才结束。如果缓冲区为空就会返回一个EOF。当我们成功读取一个值的时候,这个值就会自动从缓冲区队列删除,下一项成为了新的队列头。于是我们就可以把大量输入给先存着,一次只拿一点点。

(EOF是stdio.h内的宏定义,其值为 -1

(与先入先出对应的还有先入后出,“栈”就是常见的先入后出结构

了解了scanf的原理之后,我们就可以利用这个原理,循环内每次只读一个数,直到返回值为EOF或小于等于0的数就跳出循环。

上面的理论我或许讲得还不是很清楚,不过没关系,随着学习的深入,这些知识迟早会理解的。直接看代码吧

#include 

int main()
{
    int i, sum;

    for (;;)// for的死循环写法
    {
        if(scanf("%d", &i) == EOF)
            break;
        if(i > 0)
        {
            if(i % 2)
                sum += i;
        }
        else
            break;
    }
    printf("%d", sum);

    return 0;
}

结语

这次写作业稍微波折了些,几道题花了不少时间,前途一片黑暗啊(悲

另外写题的过程中很多次都以为是题目出了点问题,不过最后发现只有一道题确实有点问题的,先去拿这道题问老师去了,下周见(润

你可能感兴趣的:(学习作业,1024程序员节,自动化,c语言)