繁体   English   中英

当我在C中将long int分配给int时会发生什么?

[英]What happens when I assign long int to int in C?

在最近的家庭作业中,我被告知使用long变量来存储结果,因为它可能是一个很大的数字。

我决定检查它对我来说真的很重要,在我的系统上(intel core i5 / 64-bit windows 7 / gnu gcc编译器)并发现以下代码:

printf("sizeof(char) => %d\n", sizeof(char));
printf("sizeof(short) => %d\n", sizeof(short));
printf("sizeof(short int) => %d\n", sizeof(short int));
printf("sizeof(int) => %d\n", sizeof(int));
printf("sizeof(long) => %d\n", sizeof(long));
printf("sizeof(long int) => %d\n", sizeof(long int));
printf("sizeof(long long) => %d\n", sizeof(long long));
printf("sizeof(long long int) => %d\n", sizeof(long long int));

产生以下输出:

sizeof(char) => 1
sizeof(short) => 2
sizeof(short int) => 2
sizeof(int) => 4
sizeof(long) => 4
sizeof(long int) => 4
sizeof(long long) => 8
sizeof(long long int) => 8

换句话说,在我的系统上, intlong是相同的,并且对于int任何太大都不能保持,也不会long持有。

家庭作业本身不是问题。 我想知道在一个int < long的系统上,我应该如何为long分配一个int

我知道一个事实,即存在 许多 密切 相关的关于这个问题的问题,但我觉得在这些问题的答案没有给我提供什么将会或可能在这个过程中发生了全面的了解。

基本上我想弄清楚以下内容:

  1. 我应该在转让之前将longint ,或者 因为long不是一个不同的数据类型,而只是一个修饰符, 直接分配会被视为无害吗?
  2. long > int系统上会发生什么? 结果是不确定的(或不可预测的)还是会导致变量的额外部分被省略?
  3. longint的转换如何在C中工作?
  4. 当我不使用强制转换时,从longint的赋值如何在C中起作用?

该语言保证int至少为16位, long至少为32位, long可以至少表示int可以表示的所有值。

如果为int对象分配long值,则会隐式转换它。 没有必要进行明确的演员表演; 它只会指定将要发生的相同转换。

在你的系统上, intlong恰好具有相同的大小和范围,转换是微不足道的; 它只是复制价值。

longint宽的系统上,如果该值不适合int ,则转换的结果是实现定义的。 (或者,从C99开始,它可以引发实现定义的信号,但我不知道任何编译器实际上是这样做的。) 通常发生的是高位比特被丢弃,但你不应该依赖在那。 (对于无符号类型,规则是不同的;将有符号或无符号整数转换为无符号类型的结果已经明确定义。)

如果需要为int对象安全地分配long值,可以在执行赋值之前检查它是否合适:

#include <limits.h> /* for INT_MIN, INT_MAX */

/* ... */

int i;
long li = /* whatever */

if (li >= INT_MIN && li <= INT_MAX) {
    i = li;
}
else {
    /* do something else? */
}

“别的东西”的细节将取决于你想做什么。

一个更正: intlong 总是不同的类型,即使它们碰巧具有相同的大小和表示。 算术类型可以自由转换,因此这通常没有任何区别,但是例如int*long*是不同且不兼容的类型; 如果没有明确的(也可能是危险的)强制转换,你不能将long*赋给int* ,反之亦然。

如果您发现自己需要将long值转换为int ,那么您应该做的第一件事就是重新考虑代码的设计。 有时候这种转换是必要的,但更常见的是,它们表明你所分配的int应该首先被定义为long

long总是可以表示int所有值。 如果手头的值可以由您指定的变量的类型表示,则保留该值。

, where is the number of bits in the value representation (which is not necessarily all the bits in the destination). 如果无法表示,则对于签名目标类型,结果是正式未指定的,而对于无符号目标类型,它被指定为模2 的原始值,其中是值表示中的位数(不是必然是目的地的所有比特)。

实际上,在现代机器上,您也可以为签名类型进行包装。

这是因为现代机器使用二进制补码形式来表示有符号整数,而没有任何位用于表示“无效值”等 - 即用于表示值的所有位。

bits value representation any integer value is is mapped to +K*2 with the integer constant K chosen such that the result is in the range where half of the possible values are negative. 对于位值表示,任何整数值被映射到 + K * 2 ,其中选择的整数常数K使得结果处于可能值的一半为负的范围内。

因此,例如,使用32位int ,值-7表示为位模式编号-7 + 2 32 = 2 32 -7,因此如果您将位模式代表的数字显示为无符号整数,则会得到一个漂亮的大数字。

这被称为二进制补码的原因是因为它对二进制数字系统有意义,即基本两位数系统。 对于二进制数字系统,还有一个'(注意撇号的位置)补码。 类似地,对于十进制数字系统,有十个补码和niners补码。 使用4位十进制补码表示,您将代表-7为10000-7 = 9993.这就是全部,真的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM