这是用C语言编写的代码,它应该打印给定范围1-999内的Armstrong数。但代码既没有打印任何内容,也没有使用CPU资源。很可能它在一个无休止的循环中得到了结构。这是代码-
//C program to print Armstrong numbers up to 999
#include <math.h>
#include <stdio.h>
int main()
{
int i = 1, b, sum = 0;
printf("The Armstrong Numbers Within 0-999 are --> ");
while (i <= 999)
{
while (i != 0)
{
b = i % 10;
i = i / 10;
sum = sum + pow(b, 3);
}
if (i == sum)
{
printf("%d ", i);
sum = 0;
}
else
{
sum = 0;
}
i++;
}
return 0;
}
应在不添加任何其他附加库函数的情况下回答。
代码有问题。。。
内部while
循环破坏了i
的[原始]值,因此后续的if
将失败,因为i
将始终为零。内部循环应该使用一个临时变量。
无需使用pow
,因为b * b * b
更好/更快,[可能]更准确。使用pow
似乎违反了标准:
需要在不添加任何其他附加库函数的情况下进行回答。
if
和else
中的sum = 0;
都是冗余的。它可以移到下面。但是,最好把它放在外循环的开头。
你的第一个printf
说范围是0-999
,但你在1 开始你的外循环
该算法使用每个多维数据集的总和:https://www.javatpoint.com/armstrong-number-in-c
然而,维基百科https://en.wikipedia.org/wiki/Narcissistic_number声明我们应该将数字相加为数字中数字的幂(例如pow(b,ndig)
(。
";立方体";该算法对4位数的数字不起作用。
这里有一个重构的版本,它对多维数据集进行求和:
//C programme to print Armstrong numbers up to 999
#include <stdio.h>
int
main(void)
{
int lo = 0;
int hi = 999;
printf("The Armstrong Numbers Within %d-%d are --> ",lo,hi);
for (int i = lo; i <= hi; ++i) {
int sum = 0;
for (int j = i; j != 0; j /= 10) {
int b = j % 10;
sum += b * b * b;
}
if (i == sum)
printf("%d ", i);
}
printf("n");
return 0;
}
这是程序输出:
The Armstrong Numbers Within 0-999 are --> 0 1 153 370 371 407
这里有一个使用维基百科定义的版本:
//C programme to print Armstrong numbers up to 999
#include <stdio.h>
#ifdef DEBUG
#define dbgprt(_fmt...) printf(_fmt)
#else
#define dbgprt(_fmt...) do { } while (0)
#endif
// xpow -- raise to a power
int
xpow(int base,int exp)
{
int ret = 1;
dbgprt("xpow: ENTER base=%d exp=%dn",base,exp);
while (1) {
dbgprt("xpow: LOOP base=%d exp=%8.8Xn",base,exp);
if (exp & 1)
ret *= base;
exp >>= 1;
if (exp == 0)
break;
base *= base;
}
dbgprt("xpow: EXIT ret=%dn",ret);
return ret;
}
int
armstrong(int ndig,int i)
{
if (ndig == 0) {
ndig = i ? 0 : 1;
for (int j = i; j != 0; j /= 10, ++ndig);
}
int sum = 0;
for (int j = i; j != 0; j /= 10) {
int b = j % 10;
b = xpow(b,ndig);
sum += b;
}
int match = (i == sum);
dbgprt("armstrong: MATCH match=%d i=%dn",match,i);
return match;
}
void
armndig(int ndig)
{
dbgprt("armndig: ENTER ndig=%dn",ndig);
int lo = xpow(10,ndig - 1);
if (lo == 1)
lo = 0;
int hi = xpow(10,ndig) - 1;
printf("The Armstrong Numbers Within %d-%d are -->n",lo,hi);
for (int i = lo; i <= hi; ++i) {
if (armstrong(ndig,i))
printf("ARMSTRONG %dn",i);
}
dbgprt("armndig: EXITn");
}
int
main(void)
{
armstrong(3,407);
for (int ndig = 1; ndig <= 4; ++ndig)
armndig(ndig);
return 0;
}
这是程序输出:
The Armstrong Numbers Within 0-9 are -->
ARMSTRONG 0
ARMSTRONG 1
ARMSTRONG 2
ARMSTRONG 3
ARMSTRONG 4
ARMSTRONG 5
ARMSTRONG 6
ARMSTRONG 7
ARMSTRONG 8
ARMSTRONG 9
The Armstrong Numbers Within 10-99 are -->
The Armstrong Numbers Within 100-999 are -->
ARMSTRONG 153
ARMSTRONG 370
ARMSTRONG 371
ARMSTRONG 407
The Armstrong Numbers Within 1000-9999 are -->
ARMSTRONG 1634
ARMSTRONG 8208
ARMSTRONG 9474
更新:
int xpow(int base,int exp)
未准备好用于一般用途,因为当exp < 0
时,它有一个无限循环。如果代码使用x%2
而不是x&1
,使用exp /= 2;
而不是exp >>= 1;
,就像上面使用%10和/10(或unsigned exp
(的代码一样,那么这个无限循环就不存在了chux-恢复Monica
你是对的。我从一个已经使用了unsigned
参数的函数中改编了代码。
我一直在争论是否要全程使用unsigned
和使用unsigned long long
。
这是一个进一步清理的版本:
//C programme to print Armstrong numbers up to 999
#include <stdio.h>
#if USE64
typedef unsigned long long num_t;
#define FMT "%llu"
#define FMTX "%16.16X"
#define NDIG 16
#else
typedef unsigned int num_t;
#define FMT "%u"
#define FMTX "%8.8X"
#define NDIG 8
#endif
#ifdef DEBUG
#define dbgprt(_fmt...) printf(_fmt)
#else
#define dbgprt(_fmt...) do { } while (0)
#endif
// xpow -- raise to a power
num_t
xpow(num_t base,num_t exp)
{
num_t ret = 1;
dbgprt("xpow: ENTER base=" FMT " exp=" FMT "n",base,exp);
while (1) {
dbgprt("xpow: LOOP base=" FMT " exp=" FMTX "n",base,exp);
#if CHUX
if (exp % 2)
ret *= base;
exp /= 2;
#else
if (exp & 1)
ret *= base;
exp >>= 1;
#endif
if (exp == 0)
break;
base *= base;
}
dbgprt("xpow: EXIT ret=" FMT "n",ret);
return ret;
}
num_t
armstrong(int ndig,num_t i)
{
if (ndig == 0) {
ndig = i ? 0 : 1;
for (num_t j = i; j != 0; j /= 10, ++ndig);
}
num_t sum = 0;
for (num_t j = i; j != 0; j /= 10) {
num_t b = j % 10;
b = xpow(b,ndig);
sum += b;
}
int match = (i == sum);
dbgprt("armstrong: MATCH match=%d i=" FMT "n",match,i);
return match;
}
void
armndig(int ndig)
{
dbgprt("armndig: ENTER ndig=%dn",ndig);
num_t lo = xpow(10,ndig - 1);
if (lo == 1)
lo = 0;
num_t hi = xpow(10,ndig) - 1;
printf("The Armstrong Numbers Within " FMT "-" FMT " are -->n",lo,hi);
for (num_t i = lo; i <= hi; ++i) {
if (armstrong(ndig,i))
printf("ARMSTRONG " FMT "n",i);
}
dbgprt("armndig: EXITn");
}
int
main(void)
{
setlinebuf(stdout);
armstrong(3,407);
for (int ndig = 1; ndig <= NDIG; ++ndig)
armndig(ndig);
return 0;
}
以下是-DUSE64=0
:的程序输出
The Armstrong Numbers Within 0-9 are -->
ARMSTRONG 0
ARMSTRONG 1
ARMSTRONG 2
ARMSTRONG 3
ARMSTRONG 4
ARMSTRONG 5
ARMSTRONG 6
ARMSTRONG 7
ARMSTRONG 8
ARMSTRONG 9
The Armstrong Numbers Within 10-99 are -->
The Armstrong Numbers Within 100-999 are -->
ARMSTRONG 153
ARMSTRONG 370
ARMSTRONG 371
ARMSTRONG 407
The Armstrong Numbers Within 1000-9999 are -->
ARMSTRONG 1634
ARMSTRONG 8208
ARMSTRONG 9474
The Armstrong Numbers Within 10000-99999 are -->
ARMSTRONG 54748
ARMSTRONG 92727
ARMSTRONG 93084
The Armstrong Numbers Within 100000-999999 are -->
ARMSTRONG 548834
The Armstrong Numbers Within 1000000-9999999 are -->
ARMSTRONG 1741725
ARMSTRONG 4210818
ARMSTRONG 9800817
ARMSTRONG 9926315
The Armstrong Numbers Within 10000000-99999999 are -->
ARMSTRONG 24678050
ARMSTRONG 24678051
ARMSTRONG 88593477