C语言非常道
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

3.10 参数值的有效性检查

我们编写函数cusum的目的是为了获得通用性,能够计算从1加到N的和,这里的N是正整数。问题是这道题只能在有限的范围内求解,函数cusum的返回类型和参数类型都是unsigned long long int,它可以表示多大的数呢?不知道,这取决于具体的计算机平台,但C语言可以保证它不小于18446744073709551615。

那么,这个限制是什么意思呢?是什么原因造成的呢?我们知道,变量所占用的存储空间大小取决于它在声明时的类型。举个例子来说,在C语言里,unsigned char是整数类型,这种类型的变量都统一规定为1个字节大小。

对于绝大多数计算机架构来说,字节的长度是8比特,或者说一个字节是由8个比特组成的,因此,如果深入到变量内部,从比特的层次上来看,当unsigned char类型的变量保存的内容为二进制比特序列00000000时,具有最小值0;当它的内容为二进制比特序列11111111时,具有最大值255。

假定我们声明了一个unsigned char类型的变量c,并将其初始化为最大值255。如图3-2所示,图的右侧显示了它在存储器中的位置,以及它的位模式;左侧呢,显示了表达式c = c + 1的执行过程。

图3-2 算术操作对变量内容的影响

显然,根据二进制数的加法规则,最左侧也将有一个进位,所以255加1的结果用二进制表示就是100000000。但因为变量的大小只有8个比特,最后的进位丢失,相加的结果只能是二进制的00000000。那么,多出来的比特不会拱到邻近的存储区里吗?这怎么可能,隔壁可能是其他变量的地盘,只要计算机还有点用,它就不会允许这种事情发生。

那么,unsigned long long int类型的变量会如何呢?答案是除了大小之外,其他没有任何区别。如果它可以容纳的最大值是18446744073709551615,则我们在做从1到N的加法时,有可能还没有加到N,结果就已经等于或者超过了这个最大值,再怎么加都没有什么意义了。

为此,传递给函数cusum的参数值不能太大,建议的范围是大于0且小于等于1000000000,这既是经验,也是个人偏好。从经验上来说,从1加到1000000000的结果可以用unsigned long long int类型的变量容纳,这是我做过实验的;从个人偏好上来说,尽管1000000000不是上限,参数的值可以稍微再大一些,但这个数字比较好记,不是吗?!