前些天偶然看到了一个收集的网站,很是感兴趣。本人对C/C++语言本身很是感兴趣,曾经做过几年相应的开发,也算是相对比较熟悉的了,但也被其中的一些问题给难住了,毕竟这些问题都是涉及到非常细节的知识,可能在开发中,经常会无意地碰到,虽然百思不得其解,但也会无意地就被我们自己给绕过去了。
出于对技术细节的了解,接下来将会摘录一些问题,进行分析。
先来看看今天这个问题的代码吧。
#include非常完美的代码,不是吗?可是无论你是否相信,你就是看不到需要的结果。#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0])) int array[] = {23,34,12,17,204,99,16}; int main() { int d; for(d=-1;d <= (TOTAL_ELEMENTS-2);d++) printf("%d\n",array[d+1]); return 0; }
问题就出在了for循环中的数字的比较中。
首先,我们看到,d是int型,是有符号数;然后再看看宏定义呢,宏里边使用了sizeof来计算数组的容量,根据C语言标准,sizeof应该返回的是size_t数据类型,而size_t定义为如下类型:
typedef unsigned long size_t;说明宏返回的结果应该是一个 un signed long 类型的值。
那么这两个类型的数字进行比较,会出现什么结果呢?
对了,int型的d会被隐式转换成unsigned long类型,让我们来试试转换吧。
在的值是-1,其在机器内的补码表示为:
1111111111111111,即为:0xFFFF
然后在转换的时候,系统会根据转换的情况,由于int型的长度没有unsigned long长,因此会根据int型数字的高位进行扩展,扩展后的结果,便得d变成了如下数字:
11111111111111111111111111111111,即:0xFFFFFFFF
好了现在你应该明白为什么输出不了结果了吧。
最后让我们来做个总结,一般情况下,在C语言中隐式转换数据类型遵循长度小的向长度大的转换,有符号向无符号转换,字符型转换为整形。只要我们在编程中稍加留意,一般不会出现这样的问题,况且在本题中,这种循环的写法,恐怕也只是出题人故意为之吧,但还是小心应对为妙。
以上只是个人观点,不是之处,欢迎讨论。