2012-04-26 193 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。