当我给你长整型在C诠释,会发生什么?(What happens when I assign long

2019-07-04 08:17发布

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

我决定检查会真的重要,对我来说,我的系统上(英特尔酷睿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));

产生以下输出:

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 ,我应该在指定int长?

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

基本上我试图找出以下几点:

  1. 我应该投longint转让之前,或 因为long不是一个不同的数据类型,而仅仅是改性剂, 它会被认为是无害的,直接分配?
  2. 其中,在系统上会发生什么事long > int ? 将结果是不确定的(或不可预测的),否则会导致变量的多余部分可以省略?
  3. 如何从铸造longint在C工作?
  4. 如何从分配long ,以int在C工作的时候,我不使用铸造?

Answer 1:

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

如果您分配一个long值的int对象,它将被隐式转换。 有没有必要明确地投; 它只会指定不管怎样都是发生相同的转换。

在你的系统,其中intlong碰巧有相同的大小和范围,转换是微不足道的; 它只是复制的价值。

上的系统,其中long比宽int ,如果该值将不以适合int ,则转换的结果是实现定义。 (或者,在C99开始,它可以引发实现定义的信号,但我不知道,其实做任何编译器。)什么通常的情况是,高序位被丢弃,但你不应该依赖上。 (这些规则对无符号类型不同;一个符号或无符号整数转换为一个无符号的类型被很好地定义的结果。)

如果您需要安全地分配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? */
}

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

一个修正: intlong 始终是不同的类型,即使它们碰巧具有相同的大小和代表性。 算术类型是可自由兑换,所以这往往没有任何区别,但例如int*long*是不同的和不兼容的类型; 你可以不分配long*int* ,反之亦然,没有一个明确的(和潜在的危险)铸。

如果你发现自己需要转换为long的价值int ,你应该做的第一件事是重新考虑你的代码的设计。 有时候,这种转换是必要的,但更多的时候他们的一个标志int到你应该已经定义为分配其long摆在首位。



Answer 2:

一个long能始终代表的所有值int 。 如果在手的值可以通过分配给该变量的类型来表示,则该值被保留。

如果它不能被表示,则有符号目的地键入结果是未指定的正式,而对于无符号目标类型它被指定为原始值模2 其中是(数值表示的比特数是不不一定是目标的所有位)。

在实践中,现代计算机上的你的包装也有符号类型。

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

用位值表示的任何整数值为映射到 + K * 2 其中选择为使得结果是在可能的值的一半为负的范围中的整数常数K.

因此,例如,具有32位int的值-7被表示为位模式数目-7 + 2 32 = 2 32 -7,以便如果显示的是,位模式代表作为无符号整数数,则得到相当大数字。

这被称为的原因是因为它是有道理的二进制数字系统,基本两个数值系统。 对于二进制数字系统还有一个一(注意撇号的位置)的补充。 同样,对于十进制numberal系统有超过十的补充和niners拍摄的补数。 随着4位Ten公司的补码表示你将代表-7为10000-7 = 9993.这一切,真的。



文章来源: What happens when I assign long int to int in C?