看板 C_and_CPP 關於我們 聯絡資訊
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