我有以下代码:
#include <stdio.h>
#define POWER 10000000000000000000
int main()
{
int i;
for (i = 0; i < POWER; i++)
{
....
}
return 0;
}
并且gcc编译器给出了以下警告:
ex1.c:33:19:警告:整数常量太大,无符号[默认启用] ex1.c:33:2:警告:此十进制常量仅在ISO C90中无符号[默认启用]
如何使用i
遍历所有值进行迭代,直到达到POWER
为止?我尝试将i
声明为unsigned int
但警告仍然存在。
答案 0 :(得分:4)
你的常量10000000000000000000
需要64位来表示它。在十六进制中,它是0x8ac7230489e80000
。它可以用 unsigned 64位类型表示,但不能用 signed 64位类型表示。
从C99开始,所有整数常量都是一些有符号的类型:int
,long int
或long long int
中的第一个,其值适合。
C90(尚未long long int
)有不同的规则。在C90中,未加十进制的十进制整数常量的类型为int
,long int
或unsigned long int
。
gcc的默认模式是-std=gnu90
,它支持C90标准和GNU特定的扩展。如果您使用的是64位系统,则long
和unsigned long
为64位。在C90规则下,您的常量类型为unsigned long
(假设unsigned long
至少为64位)。在C99及更高版本的规则下,假设没有大于64位的整数类型,则违反约束。 (gcc版本5将默认值更改为-std=gnu11
。)
显然在C90规则下运行的编译器警告您10000000000000000000
的含义因编译器运行的标准版本而异。
您可以通过以下更改使您的程序“正常工作”:
#define POWER 10000000000000000000ULL // suffix to specify the type
...
for (unsigned long long = 0; i < POWER; i ++)
...
但是,虽然这使程序有效,但它并不实用。在每纳秒一次迭代中,完成该循环需要3个多世纪。我自己的合理的现代计算机在大约1.6纳秒内执行空 for
循环的一次迭代。无论你想解决什么问题,我建议找到一种不同的方法来解决它,或者将它减少到一个较小的问题。执行该循环的最快方法是等待几十年,使硬件变得更快,然后然后编译并执行它。
(这假设循环的主体是非平凡的。如果循环的主体什么也不做,编译器可能会完全优化循环。)
答案 1 :(得分:-1)
值10000000000000000000
(如果我向右计数= 10 ^ 19)需要64位来分配,这是8个字节。您收到警告,因为类型int
使用4个字节,因此无法存储该数字。使用unsigned int
,您可以存储的最大正数加倍,但仍然是4,294,967,295仍然不够。如果你想使用int
,你可以使用迭代循环。
for(i=0;i<p;i++){
for(j=0;j<p;j++){
for(k=0<p;k++){
/*loop*/
}
}
}
其中p是int
或unsigned int
,具有POWER的立方根的vaue(在这种情况下,立方根无效为19%3!= 0且p不会是一个int
,它更多的是一个想法,而不是一个实际的解决方案)