这里的编程相对较新,我正试图通过第二版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 >= %d\n", 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以上的任何给定值打印一个星号?
提前感谢您的帮助。
答案 0 :(得分:1)
将if
分成几部分可能更容易。
len = wl[i] * MAXHIST / maxvalue;
if (len <= 0)
len = 1;
现在应该清楚的是,len
只有在其计算值不大于0时才会设置为1。
答案 1 :(得分:0)
条件
if((len = wl[i] * MAXHIST / maxvalue) <= 0)
len = 1;
实际上永远不会小于零,因为它仅适用于正wl[i]
。如您所愿,len
被标准化为最大数量的星号。请注意,在if
语句本身(len = wl[i] * MAXHIST / maxvalue)
中。所以len
只是标准化了。只有当规范化截断为零(因为这是整数除法对小于1的数字所做的那样)时,len
才会设置为1
。这只能确保为非零条形图打印至少一个星号。
答案 2 :(得分:0)
这是说:
如果我们有一个非零字长,但标准化值为0,我们希望通过将其提高到1来区分它。否则我们使用标准化值(在if语句本身中设置) - 大多数现代编码标准都不是一个好习惯。)