作者:辽宁何氏医学院视光张丽杰 | 来源:互联网 | 2023-01-23 13:24
该程序应该打印出来的元素array
,但是当它运行时,没有显示输出.
#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;
}
为什么这个程序没有显示任何输出?
1> cs95..:
sizeof
返回无符号整数,因此TOTAL_ELEMENTS
也是无符号整数.
d
签了.最初d
是-1
.但是,在进行比较时,d
隐式地对无符号进行类型转换,因此不再-1
进行比较时TOTAL_ELEMENTS
,它实际上是UINT_MAX
(它4294967295
在我的机器上,但可能与其他机器不同).
也,
如果你想解决这个问题,TOTAL_ELEMENTS
可以使用int
:
for(d = -1; d <= (int)(TOTAL_ELEMENTS - 2); d++)
这将打印:
23
34
12
17
204
99
16
正如你所料.您可能还希望查看无符号和有符号整数的比较操作,以获取有关无符号比较主题的更多信息.
值得注意的是,启用编译器警告可以帮助您弄清楚发生了什么(正如hyde在他的评论中所观察到的):
$ gcc -Wall -Wextra test.c
test.c:7:17: warning: comparison of integers of different signs: 'int' and 'unsigned long' [-Wsign-compare]
for(d = 0; d
或者,为什么不开始d
在0
和运行TOTAL_ELEMENTS - 1
呢?你甚至可以放弃类型转换,这只是角落的必要条件d = -1
.
for(d = 0; d
作为脚注,以下是相关的C99标准摘录:
6.3.1.8p2定义了从有符号到无符号类型的转换.
如果具有无符号整数类型的操作数的秩大于或等于另一个操作数的类型的等级,则具有有符号整数类型的操作数将转换为具有无符号整数类型的操作数的类型.
6.3.1.3p2定义了转换的完成方式:通过添加UINT_MAX + 1
到已签名的表示.
如果新类型是无符号的,则通过重复地添加或减去一个可以在新类型中表示的最大值来转换该值,直到该值在新类型的范围内.
对于这种情况,所以-1
=> -1 + (UINT_MAX + 1)
= UINT_MAX
.
2> CIsForCOOKIE..:
我的gcc输出此警告:
warning: comparison of integers of different signs: 'int' and 'unsigned long' [-Wsign-compare]
for(d = 0; d
这意味着,(TOTAL_ELEMENTS-2)
是unsigned int
同时d
是signed int
.这使表达式始终false
为初始值d
,因为(unsigned int)(-1) > (TOTAL_ELEMENTS-2)
.
是的.课程:始终启用所有警告并阅读它们
3> Patt..:
不同整数类型之间的二进制运算是在所谓的“普通”算术转换定义的“公共”类型内执行的。因此,int d是使用值-1初始化的单一类型。转换为unsigned int时,它将返回unsigned int的最大值,该最大值远大于TOTAL_ELEMENTS返回的值。