1.6 数组
现在来写个程序,计算每个数位,空格字符(空格、tab和换行)及其他字符出现的次数。
有12种输入,因此用数组来保存每个数位的出现次数,相对于10个独立的变量,会方便很多。
#include <stdio.h>
/* 计算数位、空白字符和其他 */
main()
{
int c, i, nwhite, nother;
int ndigit[10];
nwhite = nother = 0;
for (i = 0; i < 10; ++i)
ndigit[i] = 0;
while ((c = getchar()) != EOF) {
if (c >= '0' && c <= '9')
++ndigit[c - '0'];
else if (c == ' ' || c == '\t' || c == '\n')
++nwhite;
else
++nother;
}
printf("digits = ");
for (i = 0; i < 10; ++i)
printf(" %d", ndigit[i]);
printf(", white space = %d, other = %d\n",
nwhite, nother);
}
以上面的源代码作为输入,程序的输出是 digits = 9 3 0 0 0 0 0 0 0 1, white space = 123, other = 345。
声明语句 int ndigits[10]; 定义了ndigit为一个由10个整数组成的数组。在C中,数组下标总是从0开始,所以它的各个元素是ndigit[0], ndigit[1],..., ndigit[9]。这也反映在了用来初始化和打印数组的for循环中。
下标可以是任何整型表达式,包括整型变量i,以及整型常量。
这个程序依赖于各个数位字符的存储和表示方式。例如 if (c >= '0' && c <= '9') 用来确定c是否为数位字符,如果是,则该数位对应的数值就是 c - '0'。 这个仅在'0', '1', '2', ..., '9' 都是连续递增时才成立。幸运的是,所有字符集都是如此。
根据定义,char只是小整数,因此char变量和常量在算术表达式中与int是一样的。这是很自然而且很方便的;例如, c - '0'是一个整型表达式,值介于0和9之间,对应c中储存的字符在'0'到'9'之间,所以也是数组ndigit的合法下标。
判断一个字符是数字、空白或其他的语句是
if (c >= '0' && c <= '9')
++ndigit[c - '0'];
else if (c == ' ' || c == '\t' || c == '\n')
++nwhite;
else
++nother;
样式
if (条件1)
语句1
else if (条件2)
语句2
...
...
else
语句n
通常在程序中表达多分支决策。条件判断的顺序是从顶部开始直到某个条件满足为止;在那个点上,相应的语句部分被执行,然后整个结构结束。(语句也可以是大括号中的多个语句)如果没有任何一个条件满足,且最后的else存在的话,则执行它后面的语句。若没有最后的else和语句n的话,比如前面一节的单词计数程序,则什么都不做。在程序当中,可以有任意数量的
else if (条件)
语句
加入到初始的if和最后的else之间。
在程序风格方面,我们建议采用上面的形式,如果每个if都在前面else之后又增加缩进,那么如果分支多的话,很快代码就全挤到右边了。
switch语句,第三章将介绍,提供了另一种写多分支的方式,特别适合于当条件是某个整数或字符表达式,是否匹配一组常量一个的时候。作为对比,3.4会给出上面程序的switch版本。