C语言 当我在 C 中将 long int 分配给 int 时会发生什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13652556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What happens when I assign long int to int in C?
提问by Khaloymes
In a recent homework assignment I've been told to use longvariable to store a result, since it may be a big number.
在最近的家庭作业中,我被告知使用long变量来存储结果,因为它可能是一个很大的数字。
I decided to check will it really matter for me, on my system (intel core i5/64-bit windows 7/gnu gcc compiler) and found out that the following code:
我决定在我的系统(英特尔核心 i5/64 位 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));
produces the following output:
产生以下输出:
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
In other words, on my system, intand longare the same, and whatever will be too big for intto hold, will be too big for longto hold as well.
换句话说,在我的系统上,int和long是相同的,无论太大而int无法容纳,也将太大而long无法容纳。
The homework assignment itself is not the issue here. I wonder how, on a system where int < long, should I assign an intto long?
家庭作业本身不是这里的问题。我想知道在一个系统上int < long,我应该如何分配一个int到 long?
I'm aware to the fact that therearenumerouscloselyrelatedquestions on this subject, but I feel that the answers within these do not provide me with the complete understanding of what will or may happen in the process.
我知道一个事实,即存在有许多密切相关的关于这个问题的问题,但我觉得在这些问题的答案没有给我提供什么将会或可能在这个过程中发生了全面的了解。
Basically I'm trying to figure out the following:
基本上我想弄清楚以下几点:
- Should I cast
longtointbefore the assignment, orsinceit will be considered unharmful to assign directly?longis not a different data type, but merely a modifier, - What happens on systems where
long > int? Will the result be undefined (or unpredictable) or it will cause the extra parts of the variable to be omitted? - How does the casting from
longtointworks in C? - How does the assignment from
longtointworks in C when I don't use casting?
- 我应该在分配之前投射
long到int,还是因为直接赋值会被认为是无害的吗?long不是不同的数据类型,而只是一个修饰符, - 在系统上会发生什么
long > int?结果是未定义的(或不可预测的)还是会导致变量的额外部分被省略? - 在 C 中从
longto的转换是如何int工作的? - 当我不使用强制转换时,从
longto的赋值如何int在 C 中工作?
采纳答案by Keith Thompson
The language guarantees that intis at least 16 bits, longis at least 32 bits, and longcan represent at leastall the values that intcan represent.
语言保证int至少是 16 位,long至少是 32 位,并且至少long可以表示所有可以表示的值。int
If you assign a longvalue to an intobject, it will be implicitly converted. There's no need for an explicit cast; it would merely specify the same conversion that's going to happen anyway.
如果您分配一个long值到一个int对象时,它会被隐式转换。不需要显式转换;它只会指定无论如何都会发生的相同转换。
On your system, where intand longhappen to have the same size and range, the conversion is trivial; it simply copies the value.
在你的系统上,当int和long恰好具有相同的大小和范围时,转换是微不足道的;它只是复制值。
On a system where longis wider than int, if the value won't fit in an int, then the result of the conversion is implementation-defined. (Or, starting in C99, it can raise an implementation-defined signal, but I don't know of any compilers that actually do that.) What typicallyhappens is that the high-order bits are discarded, but you shouldn't depend on that. (The rules are different for unsigned types; the result of converting a signed or unsigned integer to an unsigned type is well defined.)
在long比 宽的系统上int,如果值不适合int,则转换的结果是实现定义的。(或者,从 C99 开始,它可以引发实现定义的信号,但我不知道有任何编译器实际这样做。)通常发生的情况是高位被丢弃,但您不应该依赖在那。(无符号类型的规则不同;将有符号或无符号整数转换为无符号类型的结果是明确定义的。)
If you need to safelyassign a longvalue to an intobject, you can check that it will fit before doing the assignment:
如果您需要安全的一个分配long值的int对象,你可以检查它会做转让前适合:
#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? */
}
The details of "something else" are going to depend on what you want to do.
“其他事情”的细节将取决于你想做什么。
One correction: intand longare alwaysdistinct types, even if they happen to have the same size and representation. Arithmetic types are freely convertible, so this often doesn't make any difference, but for example int*and long*are distinct and incompatible types; you can't assign a long*to an int*, or vice versa, without an explicit (and potentially dangerous) cast.
一个修正:int和long是总是不同的类型,即使它们碰巧具有相同的大小和代表性。算术类型可以自由转换,因此这通常不会产生任何区别,但例如int*和long*是不同且不兼容的类型;如果没有明确的(并且有潜在危险的)强制转换,您就不能将 a 分配long*给 an int*,反之亦然。
And if you find yourself needing to convert a longvalue to int, the first thing you should do is reconsider your code's design. Sometimes such conversions are necessary, but more often they're a sign that the intto which you're assigning should have been defined as a longin the first place.
如果您发现自己需要将一个long值转换为int,您应该做的第一件事就是重新考虑您的代码设计。有时这样的转换是必要的,但更多时候,它们表明int您分配的对象应该首先被定义为 a long。
回答by Cheers and hth. - Alf
A longcan always represent all values of int.
If the value at hand can be represented by the type of the variable you assign to, then the value is preserved.
Along总是可以代表 的所有值int。如果手头的值可以由您分配给的变量的类型表示,那么该值将被保留。
If it can't be represented, then for signed destination type the result is formally unspecified, while for unsigned destination type it is specified as the original value modulo 2n, where nis the number of bits in the value representation (which is not necessarily all the bits in the destination).
如果它不能被表示,那么对于有符号的目标类型,结果是形式上未指定的,而对于无符号的目标类型,它被指定为原始值模 2 n,其中n是值表示中的位数(不是必须是目标中的所有位)。
In practice, on modern machines you get wrapping also for signed types.
实际上,在现代机器上,您也可以对签名类型进行包装。
That's because modern machines use two's complement formto represent signed integers, without any bits used to denote "invalid value" or such – i.e., all bits used for value representation.
那是因为现代机器使用二进制补码形式来表示有符号整数,没有任何用于表示“无效值”之类的位——即所有用于值表示的位。
With nbits value representation any integer value is xis mapped to x+K*2nwith the integer constant K chosen such that the result is in the range where half of the possible values are negative.
使用n位值表示,任何整数值x被映射到x+K*2 n并选择整数常数 K,使得结果处于可能值的一半为负的范围内。
Thus, for example, with 32-bit intthe value -7 is represented as bitpattern number -7+232= 232-7, so that if you display the number that the bitpattern stands for as unsigned integer, you get a pretty large number.
因此,例如,对于 32 位int,值 -7 表示为位模式编号 -7+2 32= 2 32-7,因此如果您将位模式代表的数字显示为无符号整数,则会得到一个非常大的数字数字。
The reason that this is called two's complementis because it makes sense for the binary numeral system, the base two numeral system. For the binary numeral system there's also a ones' (note the placement of the apostrophe) complement. Similarly, for the decimal numberal system there's ten's complement and niners' complement. With 4 digit ten's complement representation you would represent -7 as 10000-7 = 9993. That's all, really.
这被称为二进制补码的原因是因为它对二进制数字系统有意义,基二数字系统。对于二进制数字系统,还有一个(注意撇号的位置)补码。同样,对于十进制数系统,有十进制补码和九进制补码。使用 4 位十的补码表示法,您可以将 -7 表示为 10000-7 = 9993。仅此而已。

