2012-04-26 63 views
3

下面的代码是否正确?据我的理解,它不应该正常工作,但在Dev-C++编译器上,它确实。请有人详细解释一下吗?%d与Long Int

#include<limits.h> 

int main() 
{ 
long int num_case=LONG_MAX; 

scanf("%d",&num_case); 

printf("%ld",num_case); 
return 0; 
} 

感谢

+3

如果这是你所期望的,你应该'scanf'作为'%ld'。但是由于'long'比你的典型'int'大,所以没有问题。 – RageD 2012-04-26 06:13:54

+1

**不要使用Dev-C++ **附带的编译器 - 它非常过时!请参阅http://www.jasonbadams.net/20081218/why-you-shouldnt-use-dev-c/ – ThiefMaster 2012-04-26 06:14:01

回答

4

就像那个标准C库告诉你不要做最多的事,它调用未定义的行为。未定义意味着它可能在某些情况下工作,但最不经意的时候会崩溃。

在这种情况下,它的工作原理是long intint实际上是相同的数字表示形式:四个字节,二进制补码。在另一个平台(例如x86-64 Linux)中,情况可能并非如此,您可能会遇到某种问题。特别是,8字节long int的高位字节将保持未初始化状态。

编辑:问“但它会崩溃”是思维方式不对。根据语言标准,仅仅将未初始化的字节读入类型为long int的变量可以使C程序崩溃。我们不需要找到一个这样做的平台的例子,了解该程序是不明确的。这就是我想说的。 C不会立即将规则手册扔给你,它会一直等到你移植并破坏最初的假设。

+0

这是除非x86-64是长整型int保持32位的Windows。 – dbrank0 2012-04-26 06:17:22

+1

真的会有问题吗?我的意思是,这个数字并不代表我们想要的东西,但这不会导致程序以任何方式崩溃,对吧?关于64位,唯一真正的整数类型为64位是很长的,已经在C99中引入,并且是C++ 11标准的一部分。 – Geoffroy 2012-04-26 06:19:01

+1

@Geoffroy继续运行未初始化或意外值的程序很可能会导致崩溃,尽管我从未提到崩溃;我说“有些问题。”通常我们要避免*所有*不当行为,而不仅仅是崩溃。在Mac OS和Linux上,“long”和“long long”都是64位;我没有意识到Windows做了其他事情,但它没有改变任何东西。 – Potatoswatter 2012-04-26 06:23:09

1

正如RageD所说,你真的应该在scanf()调用中使用%ld。它工作的原因是因为在你的系统上(或者对我而言),intlong int是相同的大小(可能是4),所以scanf()不会覆盖它不应该覆盖的任何内存。

0

通常在32位系统中long int有32位(与int相同)和64位系统长int有64位(与long long相同)。如果你希望你的代码是可移植的,请使用带有“%ld”的scanf。