作者fon909 (峰)
看板C_and_CPP
標題Re: [問題] 恐怖的short int
時間Wed Aug 31 22:58:38 2011
Dev-C++針對short int守規矩的只給兩個bytes,%d本來就定義是針對int,所以scanf就覆蓋了堆疊中相鄰在一起的變數。
如果把程式碼改成如下,按照原PO的輸入資料的話,會發現for回圈每次只執行一次就跳出,因為scanf("%d",&m)會把n蓋掉。
#include<stdio.h>
int main() {
short int i,n,m; /*僅變更此處 將int 改成 short int*/
while(scanf("%d",&n)!=EOF){
printf("START of LOOP HERE\n");
for(i=0;i<n;i++){
printf("i:%d\n",i);
scanf("%d",&m);
printf("n:%d\n",n);
}
}
return 0;
}
去trace assembly可以看到i,n,m分別是在[EBP-2],[EBP-4],[EBP-6]的位置上(EBP是堆疊的基底)
呼叫完scanf丟入%d會蓋掉相鄰的變數是很正常的。
如果是用Visual C++(我用2008),它分配了比較大的堆疊,i,n,m分別給6個bytes,沒有覆蓋到也是很正常的。
從這個程式碼似乎看不到VC優的點,只看到它的footprint比較大,當然VC有相當多功能和更新Dev沒有,只是說從這個例子看不出來。
※ 引述《wemee (我不為讀者改變作風)》之銘言:
: 以下使用Dev c++,編譯器為GCC 3.4.2
: 正常情況下
: #include<stdio.h>
: int main() {
: int i,n,m;
: while(scanf("%d",&n)!=EOF){
: for(i=0;i<n;i++){
: printf("i:%d\n",i);
: scanf("%d",&m);
: }
: }
: return 0;
: }
: 執行之後
: 3 (鍵盤輸入,此時n為3)
: i=0 (正常)
: 3 (鍵盤輸入,此時m為3,不重要只是Debug後留下他)
: i=1 (正常)
: 3 (鍵盤輸入,此時m為3,不重要只是Debug後留下他)
: i=2 (正常)
: --------------------------------------------------
: 以上 完全沒問題 是正常執行的程式
: 但恐怖的來了
: 我將資料型態從int 改成 short int
: 如下
: #include<stdio.h>
: int main() {
: short int i,n,m; /*僅變更此處 將int 改成 short int*/
: while(scanf("%d",&n)!=EOF){
: for(i=0;i<n;i++){
: printf("i:%d\n",i);
: scanf("%d",&m);
: }
: }
: return 0;
: }
: 執行之後
: 3 (鍵盤輸入,此時n為3)
: i=0 (正常)
: 3 (鍵盤輸入,但沒有正常輸出i=1)
: 3 (鍵盤輸入)
: i=0 (不知為何?)
: -------------------------------------------------------------
: 請問short int型態有什麼魔力
: 可以讓原本只使用int型態的程式可以正常運作
: 改用short int就變得怪里怪氣
: 如果... 你複製以上的程式碼
: 在你的電腦可以正常執行
: 那麼我得考慮換其他版本的編譯器
: 或者改用別的IDE
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 111.249.187.181
→ Favonia:其實寫錯的時候編譯器可以隨便亂做沒關係 xD 08/31 23:10
→ fon909:更正:VC不是配6 bytes,是個別12 bytes空間給i,n,m 09/01 02:10
→ fon909:而以上是針對XP SP3 Win32環境,Debug版的程式 09/01 02:11
→ fon909:Release版又不一樣,但間距都大於4 bytes,不會被覆蓋 09/01 02:13
推 wemee:讚! 現在甚至知道 錯誤的原因是什麼了 09/01 09:22