目录
前言:
开新专栏了,讲解100道基础语法编程题
用c语言讲解
目的是复习c语言中的基础语法,为单片机中的c语言代码分析做铺垫
专栏链接:
1、题目展示:

2、问题分析:
此题是理解变量定义的位置,即明确其作用域以及循环与循环之间的逻辑的经典案例
因此主要从这两个方面进行讲解,顺带对代码的执行逻辑进行分析
采用先展示最终代码,再一步一步分析的思路
以下是完整的代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int m, n;
while (scanf("%d %d", &m, &n) == 2) {
int first = 1;
int found = 0;
for (int i = m;i <= n;++i) {
int a = i / 100;//百位
int b = (i / 10) % 10;//十位
int c = i % 10;//个位
if (i == (a * a * a) + (b * b * b) + (c * c * c)) {
if (!first)printf(" ");
printf("%d", i);
first = 0;
found = 1;
}
}
if (!found)printf("no");
printf("\n");
}
return 0;
}
接下来我们来一步一步分析
一、首先是代码框架
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
return 0;
}
1、写上头文件 #include <stdio.h> 便于下面调用标准输入输出头文件内包含的内容
比如scanf printf...
2、因为一会儿要调用c语言不安全函数scanf,因此要加上#define _CRT_SECURE_NO_WARNINGS,防止报错
3、写上主函数main的框架
int main() {
return 0;
}
二、main函数内的核心内容分析
int m, n;
while (scanf("%d %d", &m, &n) == 2) {
int first = 1;
int found = 0;
for (int i = m;i <= n;++i) {
int a = i / 100;//百位
int b = (i / 10) % 10;//十位
int c = i % 10;//个位
if (i == (a * a * a) + (b * b * b) + (c * c * c)) {
if (!first)printf(" ");
printf("%d", i);
first = 0;
found = 1;
}
}
if (!found)printf("no");
printf("\n");
}
首先从外层来看是顺序结构
1、先定义了两个整型输入变量m,n,为下面的多组输入做铺垫
2、搭好多组输入的代码框架,所有的程序的动作都会在里面,每一次两个数输入m,n,就执行while语句内的代码
while (scanf("%d %d", &m, &n) == 2) {
}
3、while语句内的代码核心就是要
3-1、在[m,n]这个区间内,遍历所有的数,判断每个数是不是水仙花数
3-2、遍历完所有数之后,如果有水仙花数,则输出所有的水仙花数,并且换行,让下一组输出是在另一行
3-3、如果没有水仙花数,则输出no,并且换行,让下一组输出是在另一行
4、所以我们的代码逻辑是这样的
我们先在while语句内第一行定义两个标签
4-1、int first = 1;
4-2、int found = 0;
(first和found在while循环内的原因是
1、first和found是在每组输入m,n之后进行相关功能而定义的数而非是无论while语句输入什么数,都恒定不变的数
2、如果定义在while语句外面,那么无论你每组输入的m,n是多少,first都恒为1,found都恒为0,显然不满足我们的要求)
先来看4-1、
因为每个水仙花数后面都跟着空格,再接着下一个水仙花数,所以要用到first
如果单纯
if (i == (a * a * a) + (b * b * b) + (c * c * c)) {
printf("%d", i);
printf(" ");
}
那么假设当i是你给出[m,n]范围内的最后一个水仙花数,后面没有水仙花数了,但是依然输出一个空格而题目要求的是如果是最后一个数了,就没有空格之间换行准备输入下一组数据了
那么first是怎么实现这一功能的

我们按第一次输入m,n并且遍历到第一个数开始举例
在第3行定义first=1
然后第5行 for语句开始遍历[m,n]区间内的所有数,并判断是否为水仙花数
如果当前数i的百位a,十位b,个位c都满足i==(a * a * a) + (b * b * b) + (c * c * c)
则执行第9行if语句内10、11、12、13行的内容
既然满足第9行if语句说明是当前数i水仙花数,因为第一次进行for循环,first的值还为初始值1,
所以 if (!first)后面的输出空格不执行 也就是题目要求的每组水仙花数的第一个数之前不能有空格
然后输出完当前第一个水仙花数i之后,在把first赋值为0,下一次如果第二个数是水仙花数的话,那么由于顺序结构,先执行10行,再执行11行,第一个水仙花数和第二个水仙花数之间就有了空格
再看4-2 found是如何实现功能的
第4行,定义int found = 0;表示找到了0个水仙花数
我们依然是按第一次输入m,n并且遍历到第一个数开始举例
第4行执行完了,开始执行第5行for循环,遍历[m,n]区间内的所有数,当前遍历的第一个数是i
然后i的如果当前数i的百位a,十位b,个位c都满足i==(a * a * a) + (b * b * b) + (c * c * c)
则执行第9行if语句内10、11、12、13、14行的内容
你会发现只要是[m,n]区间内存在水仙花数,都会从第5行走到第14行,found的值都从0变成了1
也就是说遍历完所有[m,n]区间内的数之后,如果没有水仙花数,那么found还是0
那么执行第16行,!found=1,输出no,然后执行第17行输出换行,然后再返回while循环的条件判断语句,输入m,n进行下一组的判断
遍历的过程中遇到水仙花数,执行3-14行的内容,之后found=1,再回到第5行进行下一个数是否为水仙花数的判断,直至遍历完所有数,然后行第16行,!found=0,不输出no,然后执行第17行输出换行,然后再返回while循环的条件判断语句,输入m,n进行下一组的判断
总结一下

1、变量定义写在哪儿的问题
第1行 定义m,n,开辟内存空间,是为了第二行while语句scanf输入能够把数据输入进来,并且存到内存里
第3、4行在while语句内定义first与found是为了每一次输入新的一组数据,水仙花数的判断逻辑以及空格输出逻辑不变,若first和found定义的位置不对,可能出现判断逻辑出错的情况
2、循环嵌套逻辑
while是大框架 对每组输入数据的操作都在while语句内实现
for循环+if(i == (a * a * a) + (b * b * b) + (c * c * c))是为了判断是否为水仙花数
for循环遍历每一个数,对遍历到的每个数执行if(i == (a * a * a) + (b * b * b) + (c * c * c))判断,因此
if(i == (a * a * a) + (b * b * b) + (c * c * c))写在for循环内
if (!found)printf("no");写在for循环外,表示遍历完所有数之后,再进行判断,如果遍历过程中存在水仙花数,那么found都会变成1,no无法输出,直至下一次输入m,n,found的值才进行重置成0的操作
3、最终代码展示:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
int m, n;
while (scanf("%d %d", &m, &n) == 2) {
int first = 1;
int found = 0;
for (int i = m;i <= n;++i) {
int a = i / 100;//百位
int b = (i / 10) % 10;//十位
int c = i % 10;//个位
if (i == (a * a * a) + (b * b * b) + (c * c * c)) {
if (!first)printf(" ");
printf("%d", i);
first = 0;
found = 1;
}
}
if (!found)printf("no");
printf("\n");
}
return 0;
}

959

被折叠的 条评论
为什么被折叠?



