Gcc C迭代到一个非常大的数字-编译器关于无符号int的警告

Gcc C迭代到一个非常大的数字-编译器关于无符号int的警告,gcc,c,compiler-warnings,gcc-warning,unsigned-integer,Gcc,C,Compiler Warnings,Gcc Warning,Unsigned Integer,我有以下代码: #include <stdio.h> #define POWER 10000000000000000000 int main() { int i; for (i = 0; i < POWER; i++) { .... } return 0; } #包括 #定义功率100000000000000000 int main() { int i; 对于(i=0;i

我有以下代码:

#include <stdio.h>
#define POWER 10000000000000000000

int main()
{
    int i;
    for (i = 0; i < POWER; i++)
    {
         ....
    }
    return 0;
}
#包括
#定义功率100000000000000000
int main()
{
int i;
对于(i=0;i
编译器会给我以下警告:

ex1.c:33:19:警告:整数常量太大,以至于它是无符号的[默认情况下启用] ex1.c:33:2:警告:此十进制常量仅在ISO C90中无符号[默认启用]


如何使用
I
迭代所有值,直到达到
POWER
?我尝试将
I
声明为
unsigned int
,但警告仍然存在。

100000000000000000
(=10^19,如果我计算正确)需要分配64位,这是8字节。您将收到警告,因为类型
int
使用4个字节,因此无法存储该数字。使用
unsigned int
可以将可存储的最大正数翻倍,但它是4294967295,这仍然不够。如果要使用
int
,可以使用迭代循环

    for(i=0;i<p;i++){
        for(j=0;j<p;j++){
            for(k=0<p;k++){
            /*loop*/
            }
        }
     }

for(i=0;i值
100000000000000000
(=10^19,如果我计算正确)需要为分配64位,这是8个字节。您将收到警告,因为类型
int
使用4个字节,因此无法存储该数字。使用
unsigned int
可以将可存储的最大正数加倍,但仍然是4294967295,这是不够的。如果要使用
int
,您可以使用迭代循环

    for(i=0;i<p;i++){
        for(j=0;j<p;j++){
            for(k=0<p;k++){
            /*loop*/
            }
        }
     }

for(i=0;i常数
100000000000000000
需要64位来表示它。在十六进制中,它是
0x8ac7230489e80000
。它可以用无符号64位类型表示,但不能用有符号64位类型表示

从C99开始,所有整数常量都是某种有符号类型:值将适合的
int
long int
long long int
中的第一个

C90(还没有
long-long-int
)有不同的规则。在C90中,无固定小数整数常量的类型为
int
long-int
无符号长int


gcc的默认模式是
-std=gnu90
,它支持C90标准加上GNU特定的扩展。如果您在64位系统上,
long
无符号long
为64位。根据C90规则,常量的类型为
无符号long
(假设
无符号long
至少为64位)。在C99和更高版本的规则下,假设没有大于64位的整数类型,则这是违反约束的。(gcc版本5将默认值更改为
-std=gnu11

显然是在C90规则下运行的编译器警告您,
100000000000000000
的含义因编译器运行的标准版本而异

您可以通过以下更改使程序“正常工作”:

#define POWER 10000000000000000000ULL // suffix to specify the type
...
for (unsigned long long = 0; i < POWER; i ++)
...
#定义POWER 100000000000000000ull//后缀以指定类型
...
for(无符号长=0;i
但是,尽管这使程序有效,但它并不实用。以每纳秒一次迭代的速度,这个循环将需要3个多世纪才能完成。我自己的相当现代化的计算机在大约1.6纳秒的时间内执行一次空
for
循环的迭代。无论你想解决什么问题,我建议用一种不同的方法来解决它,或者把它简化成一个更小的问题。执行这个循环的最快方法是等待几十年,让硬件变得更快,然后编译并执行它


(这假设循环体是非平凡的。如果循环体什么都不做,编译器可能会优化整个循环。)

常数
100000000000000000
需要64位来表示。在十六进制中,它是
0x8ac7230489e80000
。它可以用无符号64位类型表示,但不能用有符号64位类型表示

从C99开始,所有整数常量都是某种有符号类型:值将适合的
int
long int
long long int
中的第一个

C90(还没有
long-long-int
)有不同的规则。在C90中,无固定小数整数常量的类型为
int
long-int
无符号长int


gcc的默认模式是
-std=gnu90
,它支持C90标准加上GNU特定的扩展。如果您在64位系统上,
long
无符号long
为64位。根据C90规则,常量的类型为
无符号long
(假设
无符号long
至少为64位)。在C99和更高版本的规则下,假设没有大于64位的整数类型,则这是违反约束的。(gcc版本5将默认值更改为
-std=gnu11

显然是在C90规则下运行的编译器警告您,
100000000000000000
的含义因编译器运行的标准版本而异

您可以通过以下更改使程序“正常工作”:

#define POWER 10000000000000000000ULL // suffix to specify the type
...
for (unsigned long long = 0; i < POWER; i ++)
...
#定义POWER 100000000000000000ull//后缀以指定类型
...
for(无符号长=0;i
但是,尽管这使程序有效,但它并不实用。以每纳秒一次迭代的速度,这个循环将需要3个多世纪才能完成。我自己的相当现代化的计算机在大约1.6纳秒的时间内执行一次空
for
循环的迭代。无论你想解决什么问题,我建议使用不同的方法来解决这个问题,或者将它简化为一个更小的问题。执行这个循环的最快方法是等待几十年,让硬件变得更快,然后编译