前些天偶然看到了一个收集C语言迷题的网站,非常感兴趣。本人对C/C++语言自己非常感兴趣,曾经作过几年相应的开发,也算是相对比较熟悉的了,但也被其中的一些问题给难住了,毕竟这些问题都是涉及到很是细节的知识,可能在开发中,常常会无心地碰到,虽然百思不得其解,但也会无心地就被咱们本身给绕过去了。 html
出于对技术细节的了解,接下来将会摘录一些问题,进行分析。 编程
先来看看今天这个问题的代码吧。 数组
#include<stdio.h> #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定义为以下类型: spa
typedef unsigned long size_t;说明宏返回的结果应该是一个 un signed long 类型的值。
那么这两个类型的数字进行比较,会出现什么结果呢? code
对了,int型的d会被隐式转换成unsigned long类型,让咱们来试试转换吧。 htm
在的值是-1,其在机器内的补码表示为: 开发
1111111111111111,即为:0xFFFF get
而后在转换的时候,系统会根据转换的状况,因为int型的长度没有unsigned long长,所以会根据int型数字的高位进行扩展,扩展后的结果,便得d变成了以下数字: io
11111111111111111111111111111111,即:0xFFFFFFFF
好了如今你应该明白为何输出不告终果了吧。
最后让咱们来作个总结,通常状况下,在C语言中隐式转换数据类型遵循长度小的向长度大的转换,有符号向无符号转换,字符型转换为整形。只要咱们在编程中稍加留意,通常不会出现这样的问题,何况在本题中,这种循环的写法,恐怕也只是出题人故意为之吧,但仍是当心应对为妙。
以上只是我的观点,不是之处,欢迎讨论。