前言
在编程中,我们经常需要解决一些涉及数值运算和条件判断的问题。本篇博客将深入分析一个用于寻找指定范围内某个数的倍数个数和总和的程序。
我们将逐行解读代码,并解释每个变量的含义和作用。此外,我们还将讨论数列知识的应用,并展示如何通过数学计算得到倍数的数列。最后,我们还将探讨如何优化代码,提高效率和健壮性。
一、代码示例
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
int put = 0; //循环数
int start_num = 0;//开始值
int end_num = 0;//结束值
int what_num = 0;//被倍数
int how_many_num = 0;//倍数总数
int sum = 0;//数列和
int a1 = 0;//数列首项
int an = 0;//数列末项
int put_again = 0;//二次循环数
int choice = 0;//打印选择
printf("请输入开始值,结束值,以及原始值:\n");
scanf("%d %d %d", &start_num, &end_num, &what_num);
if (what_num == 0)
{
printf("0没有倍数,请重新输入\a");
}
else
{
if (what_num <= end_num)
{
for (put = start_num; put <= end_num; put++)
{
if (put % what_num == 0)
{
//printf("%d ", put);
how_many_num++;
sum += put;
}
else
{
}
}
printf("\n从%d到%d之间,%d的倍数有%d个,所有倍数和为%d\a", start_num, end_num, what_num, how_many_num, sum);
printf("\n\n是否需要打印所有倍数:(1/0)\n");
scanf("%s", choice);
if(choice)
{
a1 = (sum / how_many_num) - (0.5 * (how_many_num - 1) * what_num);
an = 2 * (sum / how_many_num) - a1;
for (put_again = a1; put_again <= an; put_again += what_num)
{
printf("%d ", put_again);
}
//通过数列知识计算出每个倍数,并打印
}
else
{
}
}
else
{
printf("输入错误,请重试\a");
}
}
return 0;
}
1.1代码分析:
代码开始处定义了多个整型变量,包括put、start_num、end_num、what_num、how_many_num、sum、a1、an
和put_again
。这些变量将用于存储不同的值和计算结果。
int put = 0;
int start_num = 0;
int end_num = 0;
int what_num = 0;
int how_many_num = 0;
int sum = 0;
int a1 = 0;
int an = 0;
int put_again = 0;
char num[4];
接下来,代码通过用户输入获取开始值、结束值和原始值。
scanf("%d %d %d", &start_num, &end_num, &what_num);
这些值的含义如下:
start_num:表示范围的开始值
end_num:表示范围的结束值
what_num:表示要寻找的倍数值
代码会检查原始值是否为零。如果是零,则输出错误提示并要求重新输入。否则,它会继续执行后续的操作。
if (what_num == 0)
{
printf("0没有倍数,请重新输入\a");
}
else
{
//代码执行...
}
接下来,代码会检查原始值是否小于等于结束值。如果是,将进入一个循环,遍历从开始值到结束值的每个整数。而在此循环中,代码使用条件判断语句检查当前整数是否为原始值的倍数。
if (what_num <= end_num)
{
for (put = start_num; put <= end_num; put++)
{
if (put % what_num == 0)
{
//printf("%d ", put);
how_many_num++;
sum += put;
}
else
{
}
}
printf("\n从%d到%d之间,%d的倍数有%d个,所有倍数和为%d\a", start_num, end_num, what_num, how_many_num, sum);
如果是,将更新两个变量的值:
how_many_num:倍数的个数
sum:所有倍数的总和
接着,代码会询问是否需要打印所有倍数。如果回答是,它将使用数列知识计算出每个倍数,并逐个打印出来。
if(num)
{
a1 = (sum / how_many_num) - (0.5 * (how_many_num - 1) * what_num);
an = 2 * (sum / how_many_num) - a1;
for (put_again = a1; put_again <= an; put_again += what_num)
{
printf("%d ", put_again);
}
//通过数列知识计算出每个倍数,并打印
}
这一过程涉及两个变量:
a1:数列的首项,通过数学计算得到
an:数列的末项,通过数学计算得到
最后,代码会输出从开始值到结束值之间原始值的倍数个数和它们的总和。
1.2扩展知识
本节我们对代码的实现进行了综合分析,明确了每个变量的含义和作用。接下来,我们将深入探讨数列知识的应用。
数列是数学中重要的概念之一,它由一系列按照特定规律排列的数字组成。在我们的程序中,我们可以利用数列的知识计算出倍数的数列,从而避免逐个判断每个数是否是倍数。
根据数列的公式,我们可以通过已知信息计算出数列的首项和公差。在本程序中,首项a1可以通过如下公式计算:
a1 = (sum / how_many_num) - (0.5 * (how_many_num - 1) * what_num)
其中,sum
为所有倍数的总和,how_many_num
为倍数的个数,what_num为原始值。
同样地,数列的末项an
可以通过如下公式计算:
an = 2 * (sum / how_many_num) - a1
利用这两个公式,我们得到除了倍数之外的数列。然后,我们可以得到完整的倍数数列。
二、代码优化
我们对代码的优化进行一些讨论。尽管目前的实现是有效的,但我们依然可以改进代码以提高效率和健壮性。其中一种改进方法是对代码书写方式的优化,另一种是数组知识的灵活使用。总结如下:
2.1书写方式的优化
- 去除无用变量:代码中的
put_again
和num
变量没有被使用,可以去除以减少不必要的内存占用和混淆。- 提前返回错误情况:在输入值为 0 的情况下,可以直接返回错误提示,而不需要进入后续的判断和循环。
- 使用更具描述性的变量名:将变量名改得更具描述性,可以提高代码的可读性。
- 避免空的 else 块:在判断中,如果没做任何操作,可以直接省略空的 else 块。
- 使用布尔类型代替 int 类型:对于只需要记录两个状态的变量,可以使用 bool 类型进行表示。例如,将
num
的类型改为bool
。- 避免重复计算:在打印倍数之前,可以在外层循环中计算好倍数数列的首项和末项,避免重复计算。
- 使用更直观的条件判断:在判断是否打印倍数时,可以使用更直观的条件判断方式,例如通过判断
num == 1
来判断是否需要打印倍数。
下面是经过优化后的代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdbool.h>
int main()
{
int start_num, end_num, what_num;
int how_many_num = 0;
int sum = 0;
int choice = 0;
printf("请输入开始值,结束值,以及原始值:\n");
scanf("%d %d %d", &start_num, &end_num, &what_num);
if (what_num == 0)
{
printf("0没有倍数,请重新输入\a");
return 0;
}
if (what_num <= end_num)
{
for (int put = start_num; put <= end_num; put++)
{
if (put % what_num == 0)
{
how_many_num++;
sum += put;
}
}
printf("\n从%d到%d之间,%d的倍数有%d个,所有倍数和为%d\a", start_num, end_num, what_num, how_many_num, sum);
printf("\n\n是否需要打印所有倍数:(1/0)\n");
int choice;
scanf("%d", &choice);
if (choice)
{
int a1 = (sum / how_many_num) - (0.5 * (how_many_num - 1) * what_num);
int an = 2 * (sum / how_many_num) - a1;
for (int put_again = a1; put_again <= an; put_again += what_num)
{
printf("%d ", put_again);
}
}
}
else
{
printf("输入错误,请重试\a");
}
return 0;
}
经过以上优化,代码更加清晰简洁,变量名更具描述性,同时避免了无用和重复的计算。
什么?你说还是太复杂?别急啊,接着看(doge)~
2.2代码的优化
然而,我们发现代码可读性还是较差,主要是其中数学公式计算部分,因此我们可以将打印结果储存为一个数组,后面直接调用即可。
代码示例:
int main()
{
int start_num, end_num, what_num;
int multiplies[1000]; // 假设最多有100个倍数
int how_many_num = 0;
int sum = 0;
printf("请输入开始值,结束值,以及原始值:\n");
scanf("%d %d %d", &start_num, &end_num, &what_num);
if (what_num == 0)
{
printf("0没有倍数,请重新输入\a");
return 0;
}
if (what_num <= end_num)
{
for (int put = start_num; put <= end_num; put++)
{
if (put % what_num == 0)
{
multiplies[how_many_num] = put;
how_many_num++;
sum += put;
}
}
printf("\n从%d到%d之间,%d的倍数有%d个,所有倍数和为%d\a", start_num, end_num, what_num, how_many_num, sum);
printf("\n\n是否需要打印所有倍数:(1/0)\n");
int choice;
scanf("%d", &choice);
if (choice)
{
for (int i = 0; i < how_many_num; i++)
{
printf("%d ", multiplies[i]);
}
}
}
else
{
printf("输入错误,请重试\a");
}
return 0;
}
看,是不是简洁很多,在这个修改后的代码中,我们使用一个名为 multiplies
的整型数组来存储倍数。在循环中,每次遇到一个倍数时,我们将其存入数组,并增加计数器 how_many_num
的值。最后,在需要打印倍数时,我们通过遍历数组输出所有的倍数。
这种使用数组的实现方式可以更好地组织和管理倍数数据,也使得代码逻辑更加清晰和可扩展。
总结
在本篇博客中,我们深入分析了一个用于寻找指定范围内某个数的倍数个数和总和的程序。我们逐行解读了代码,并解释了每个变量的含义和作用。此外,我们还探讨了数列知识的应用,并展示了如何通过数学计算得到倍数的数列。最后,我们还讨论了代码的优化方法,以提高程序的效率和健壮性。
希望本篇博客对读者理解程序设计中的问题求解思路有所帮助,同时也能够启发读者在编写类似程序时灵活运用数学知识。
如果对本篇博客内容有任何疑问或建议,请随时提出,我们将非常乐意与您进行讨论。