在这里编程相对较新,我正在尝试通过第二版K& r的" C编程语言"。我已经有了练习的答案书,而且我在练习1-13上陷入了糟糕的态度,所以我看了一个想法。
任务是:"编写一个程序来打印输入中单词长度的直方图。很容易用钢筋水平绘制直方图;垂直方向更具挑战性。"
和答案书中给出的代码如下:
#include <stdio.h>
#define MAXHIST 15
#define MAXWORD 11
#define IN 1
#define OUT 0
main()
{
int c, i, nc, state;
int len;
int maxvalue;
int ovflow;
int wl[MAXWORD];
state = OUT;
nc = 0;
ovflow = 0;
for (i = 0; i < MAXWORD; i++)
wl[i] = 0;
while ((c = getchar()) != EOF)
{
if(c == ' ' || c == 'n' || c == 't')
{
state = OUT;
if (nc > 0)
{
if (nc < MAXWORD)
++wl[nc];
else
++ovflow;
}
nc = 0;
}
else if (state == OUT)
{
state = IN;
nc = 1;
}
else
++nc;
}
maxvalue = 0;
for (i = 1; i < MAXWORD; ++i)
{
if(wl[i] > maxvalue)
maxvalue = wl[i];
}
for(i = 1; i < MAXWORD; ++i)
{
printf("%5d - %5d : ", i, wl[i]);
if(wl[i] > 0)
{
if((len = wl[i] * MAXHIST / maxvalue) <= 0)
len = 1;
}
else
len = 0;
while(len > 0)
{
putchar('*');
--len;
}
putchar('n');
}
if (ovflow > 0)
printf("There are %d words >= %dn", ovflow, MAXWORD);
return 0;
}
我可以理解其中的绝大多数,但是这部分给我带来了麻烦:
for(i = 1; i < MAXWORD; ++i)
{
printf("%5d - %5d : ", i, wl[i]);
if(wl[i] > 0)
{
if((len = wl[i] * MAXHIST / maxvalue) <= 0)
len = 1;
}
else
len = 0;
while(len > 0)
{
putchar('*');
--len;
}
putchar('n');
}
现在,我知道IF函数if((len = wl[i] * MAXHIST / maxvalue) <= 0)
正在标准化数组中的值。我不明白的是它设置了len = 1
。如果len
始终是1
,putchar('*')
功能不应该仅在0?
事先感谢您的帮助。
条件
if((len = wl[i] * MAXHIST / maxvalue) <= 0)
len = 1;
实际上永远不会小于零,因为它仅应用于正wl[i]
。如您所说,len
已被标准化为最大数量的星号。请注意,在if
语句本身中,(len = wl[i] * MAXHIST / maxvalue)
。因此,len
刚刚归一化。只有当归一化截断为零时(因为这是整数划分对数字小于1的数字的作用),才会将len
设置为1
。这只是确保至少将为非零条打印一个星号。
这是这样说的:
如果我们的单词长度为零,但归一化值为0,我们希望通过将其凸起到0来区分它。 - 大多数现代编码标准不是一个好习惯)。
将此if
分为零件可能会更容易。
len = wl[i] * MAXHIST / maxvalue;
if (len <= 0)
len = 1;
现在应该很明显,只有当其计算值不大于0时,len
才会设置为1。