C编译器无法识别无符号长
在我的计算机上,C编译器无法识别无符号长,c,long-integer,implicit-conversion,unsigned,unsigned-integer,C,Long Integer,Implicit Conversion,Unsigned,Unsigned Integer,在我的计算机上,long的最大值为9223372036854775807。但是,当我使用更大的值来解释无符号长时,编译器会抛出一条警告,说它需要被解释为无符号长,而我已经将它定义为无符号长。为什么会这样 //assigning maximum value of a long integer. (No error) long max_l = 9223372036854775807L; //assigning an unsigned long integer. unsigned long max_
long
的最大值为9223372036854775807
。但是,当我使用更大的值来解释无符号长
时,编译器会抛出一条警告,说它需要被解释为无符号长
,而我已经将它定义为无符号长。为什么会这样
//assigning maximum value of a long integer. (No error)
long max_l = 9223372036854775807L;
//assigning an unsigned long integer.
unsigned long max_ul = 9223372036854775808L; //warning: integer literal is too large to be represented in a signed
//integer type, interpreting as unsigned [-Wimplicitly-unsigned-literal]
此整数常量:
9223372036854775808L
太大,无法存储在long
中
相反,请使用:
9223372036854775808UL
通过添加后缀UL
或者只使用后缀U
:
unsigned long max_ul = 9223372036854775808U;
当整数常量的后缀为L
(或L
)时,编译器将按以下顺序确定其类型:第一种类型
signed long
signed long long
其中可以表示其值。类型signed long
似乎与编译器建立的类型signed long
具有相同的整数表示形式。因此,类型signed long
和类型signed long
都不能表示常量。对于这些类型,常量太大。但是与编译器建立的类型unsigned long
具有相同内部表示形式的类型unsigned long
可以表示常量
还要注意的是,C中没有负整数常量。
例如,如果你要写
int x = -1;
然后编译器将结构-1
拆分为两个标记:整数常量1
和一元运算符-
考虑下面的演示程序
#include <stdio.h>
int main(void)
{
int a[] = { 0, 1, 2 };
int *p = a + 1;
printf( "p[-1] = %d\n", p[-1] );
printf( "-1[p] = %d\n", -1[p] );
return 0;
}
表达式
-1[p]
与表达式-1[p]
不同。它被处理为-(1[p])
,相当于-p[1]
每个整数常量,如9223372036854775808
都有自己的类型。对于编译器在程序中为整型常量选择什么类型,有一些规则。对于纯十进制常量(不带任何U,L后缀),它如下所示:
- 如果它适合内部
,请尝试int
- 如果没有,请尝试是否适合
long
- 如果没有,请尝试是否适合
long
L
不会解决任何问题,因为这只会告诉编译器执行上述检查,而从long
开始
将存储整型常量的类型声明为无符号不会解决任何问题,因为赋值/初始化左侧的类型与整型常量的类型无关。您可以编写my_custom_type x=9223372036854775808L代码>和您将得到相同的警告
显而易见的解决方案是使用无符号后缀U
。否则,如果出于某种原因需要大于63位的有符号位,则需要找到一些128位的有符号“大整数”库,这将非常痛苦。是的。这很有效。还请注意,%lu
需要用作格式设置程序来打印正确的数字。您可以删除前缀。请注意,假设系统具有64位长
且没有更大的扩展整数类型,则此代码在C90中的行为与在更高版本中不同。在C90中,即使后缀是L
,常数的类型也将是无符号长
,而自C99以来,没有u
的十进制常数只能有符号类型(如果没有合适的类型,则会违反约束)。因此,它与调用编译器的模式有关。
#include <stdio.h>
int main(void)
{
int a[] = { 0, 1, 2 };
int *p = a + 1;
printf( "p[-1] = %d\n", p[-1] );
printf( "-1[p] = %d\n", -1[p] );
return 0;
}
p[-1] = 0
-1[p] = -2