用符号常量表示常数—《狂人C》习题解答3(习题2.6)
/* 求出整数123的各位数字相应的字符ASCII码编号并输出。 */ #include <stdio.h> #include <stdlib.h> #define ZHENGSHU_3 123 //问题中的常数一般应该用符号常量表示 #define GE 1 #define SHI 10 #define BAI 100 #define QIAN 1000 int main( void ) { printf("%c的ASCII码值为%d\n", ZHENGSHU_3 %QIAN / BAI + '0' , ZHENGSHU_3 % QIAN / BAI + '0'); printf("%c的ASCII码值为%d\n", ZHENGSHU_3 % BAI / SHI + '0' , ZHENGSHU_3 % BAI / SHI + '0'); printf("%c的ASCII码值为%d\n", ZHENGSHU_3 % SHI / GE + '0' , ZHENGSHU_3 % SHI / GE + '0'); system("PAUSE"); return 0; }
首先,问题中的常数一般都应该写成符号常量。这是编写C程序的一个常识。
理由:
为常数取一个有意义的名字,代码可读性更好。代码的可读性是代码质量的一项重要指标。
减少了出错的可能性。把常数嵌入到代码中写错的可能性很大,甚至很难发觉。譬如把某个123误写成了12,由于123和12都是合法的int类型常量,所以编译时不会报错。但是如果把符号常量的标识符写错的几率相对来说要小得多,尤其是标识符有“字面意义”的情况下,而且即使写错了也更容易被发觉,编译器会发现代码中有没有定义或说明的标识符。
程序便于修改和扩充。这种便利来自于“数据与代码的分离”, 数据与代码分离是现代程序设计的一条重要原则。桥归桥,路归路,上帝的还给上帝,魔鬼的还给魔鬼。数据与代码之间的耦合越弱越好,这样的代码质量更高。在工业设计中,人们早就懂得这个道理,但在软件业,人们付出了很多代价之后才懂得这个道理。
有助于培养抽象思维的能力。只会盯着123写代码就如同小学生只会算术而不会代数一样。抽象思维能力在编程中是必须的。所以,尽管这只是一个具体的针对整数123的问题,也应该学着用抽象的方法描述它并解决它。
其次,算法方面:
其次,算法方面:
算法主要有两个,其一是求出一个整数的各位数字,其二是求出某个数字的ASCII码。
求出一个整数的各位数字可以通过求余和除法运算完成。例如求123的十位数,可以用123%100/10得到。
显然,求123的百位数字可以直接123/100而不必123%1000/100,同样求123的个位数字可以直接123%10而不必123%10/1。然而把求各位数字的算法统一起来,对于学习写程序是一个特别重要的训练。否则在学写循环语句和函数时就会产生巨大的困难。此外,写出形式一致的求各位数字的算法,代码也更整洁、美观。
代码也可以借助变量来写,每次只求出个位数字。
#include <stdio.h> #include <stdlib.h> #define ZHENGSHU_3 123 #define SHI 10 int main( void ) { int temp = ZHENGSHU_3 ; printf("%c的ASCII码值为%d\n", temp % SHI + '0' , temp % SHI + '0'); temp /= SHI ; printf("%c的ASCII码值为%d\n", temp % SHI + '0' , temp % SHI + '0'); temp /= SHI ; printf("%c的ASCII码值为%d\n", temp % SHI + '0' , temp % SHI + '0'); system("PAUSE"); return 0; }
C语言要求运行环境中所使用的字符集(不论是否使用ASCII码)中,0、1、2、3、4、5、6、7、8、9这些字符的编码是连续的,由于字符0的编码在代码中可以写为'0',所以只要求出了各位数字的值,再加上'0'就可以得到该数字对应字符的编码,且无论运行环境是否使用ASCII码。
第三,不足:如果从更抽象的角度提出问题,比如给出一个3位N进制整数(2<=N<=10),求其各位数字相应的ASCII码编号并输出,就会发现GE、SHI、BAI、QIAN这样的名字有些尴尬——它们太具体了,只适用于十进制。从一般的角度来说,它们应该是各种进制中各个位的权值。