[编程题]16、偶数求和

目录

前言:

1、题目展示:

2、问题分析:

3、最终代码展示:


前言:

开新专栏了,讲解100道基础语法编程题

用c语言讲解

目的是复习c语言中的基础语法,为单片机中的c语言代码分析做铺垫

专栏链接:

c语言基础语法编程题_1zero10的博客-优快云博客

1、题目展示:

2、问题分析:

先展示完整代码

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main() {
    int n, m;
    while (scanf("%d %d", &n, &m) == 2) {
        // 生成偶数序列
        int* arr = (int*)malloc(n * sizeof(int));
        for (int i = 0; i < n; ++i) {
            arr[i] = 2 + 2 * i;
        }

        int first = 1; // 控制输出格式
        for (int i = 0; i < n; i += m) { // 处理每组
            int end = i + m > n ? n : i + m; // 计算当前组结束位置
            int sum = 0;
            for (int j = i; j < end; ++j) {
                sum += arr[j];
            }
            // 计算平均值(当前组元素数为 end-i)
            int avg = sum / (end - i);

            // 输出控制
            if (first) {
                printf("%d", avg);
                first = 0;
            }
            else {
                printf(" %d", avg);
            }
        }
        printf("\n"); // 每组测试数据换行
        free(arr); // 释放内存
    }
    return 0;
}

1、本题数列是首项为2,公差为2的等差数列

因此公式为

由此得到任一项的通式 2+2n

2、第9行,和上一节一样,

int* arr = (int*)malloc(n * sizeof(int));

通过malloc函数(注意包含头文件<stdlib.h>)开辟动态内存空间

参数列表是n * sizeof(int),参数的值是n*sizeof(int),也就是n个数所需要的字节数

由于malloc返回值是double类型的指针,要转成int类型的指针,因此malloc函数要写成(int*)

总的来看等号右边(int*)malloc(n * sizeof(int));的含义就解释清楚了

整个表达式的含义就是把malloc函数的int类型的指针赋值给指针变量arr

那么arr现在就是一个大小动态变化的数组了

3、10、11行,通过for循环和公式,把从第0项到第n-1项的偶数数列全部赋值给数组的第0个元素到第n-1个元素

4、定义一个标记,赋值为1

5、15-32行,分组,每m个数取平均值,同时保证输出格式是第一个数定格,然后每一个数之间有一个空格

下面具体分析

我们通过一个具体例子来逐步演示iend的变化,假设输入 n=5(数列是 [2,4,6,8,10])且 m=3,看看分组过程如何工作。

第一次循环:

  • i = 0

  • 计算 end = i + m = 0 + 3 = 3 → 3 < 5 → end = 3=i+m

  • 18行的for循环执行3次,把第0,1,2个元素加起来 sum = 2 + 4 + 6 = 12

  • 22行计算平均值 = 12 / 3 = 4 除以的是end-i,当最后i+m>n也就是下面第二次循环的情况时,也可以保证除以正确的数

第二次循环:

  • i += m → i = 0 + 3 = 3

  • 计算 end = 3 + 3 = 6 → 6 > 5 → end = 5=n

  • 18行的for循环执行2次,把第3,4个元素加起来 sum = 8 + 10 = 18

  • 平均值 = 18 / 2 = 9 除以的是end-i,当最后i+m>n也就是第二次循环的情况时,也可以保证除以正确的数

循环结束:

  • i += m → i = 3 + 3 = 6 → 6 >= 5=n 不满足15行的for循环,也就结束了所有分组 和求平均数的操作

 

最后这几行就是利用first标记来达到第一个数定格,后面每个数之间空一格空格的目的

free(arr)释放内存 arr变成了悬空指针,所以最好在34行后面把 arr设置为空指针

arr = NULL; // 避免悬空指针

3、最终代码展示:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main() {
    int n, m;
    while (scanf("%d %d", &n, &m) == 2) {
        // 生成偶数序列
        int* arr = (int*)malloc(n * sizeof(int));
        for (int i = 0; i < n; ++i) {
            arr[i] = 2 + 2 * i;
        }

        int first = 1; // 控制输出格式
        for (int i = 0; i < n; i += m) { // 处理每组
            int end = i + m > n ? n : i + m; // 计算当前组结束位置
            int sum = 0;
            for (int j = i; j < end; ++j) {
                sum += arr[j];
            }
            // 计算平均值(当前组元素数为 end-i)
            int avg = sum / (end - i);

            // 输出控制
            if (first) {
                printf("%d", avg);
                first = 0;
            }
            else {
                printf(" %d", avg);
            }
        }
        printf("\n"); // 每组测试数据换行
        free(arr); // 释放内存
    }
    return 0;
}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值