談C中scanf陷阱

來源:互聯網
上載者:User

轉自 http://westsoftware.blog.163.com/blog/static/2609410920091953456841/

         最近一直在看Andrew Koening寫的書籍,可以說學習C/C++或者從事這方面的開發的人員非常值得一看的書籍,這裡我推薦看看《C陷阱與缺陷》與《C/C++沉思錄》。

         這裡先來看看《C陷阱與缺陷》一段代碼。

#include <stdio.h>
int main()
{
 int i;
 char c;
 //printf("i address:%ld/n",&i);
 //printf("c address:%ld/n",&c);
 for(i=0 ; i<5; i++)
 {
  scanf("%d",&c);
  printf("%d ",i);
 }
 return 0;
}

==========

這麼精小的一段代碼,看看運行結果將會是什嗎?請看清楚C是字元變數。

剛開始的時候,對他講的東西不是很明白,為了更加清楚,分析相關記憶體結構。

由於scanf指向的是一個整形指標,此時C接收字元錄入,所以在給C輸入資料的資料的時候,會將i的一些記憶體位址進行覆蓋,怎麼覆蓋的呢?在 FC6下,會將i的低端地址覆蓋成C的高端地址,不知道這麼說能不能明白?就是說C實際接收了一個整形變數,但是C存不下,多出的那部分怎麼辦呢?就將C 的高端地址位覆蓋成I的低端地址位了,所以I的值一直都是0,所以在運行此程式是一個死迴圈狀態。

上面注釋掉那兩段,可以列印看看C與I的地址。我這裡列印的地址是連續的。

但是在VC6中,是可以正常啟動並執行,這就是我說的記憶體位址覆蓋方式不一樣,換句話說,怎麼覆蓋是有編譯器決定,這裡我是這麼猜想,VC覆蓋記憶體的時 候是C的左徹的那段記憶體而不覆蓋I的記憶體位址,所以在VC中能正常。

這也是一個猜想,怠於證實。而在FC中是“往右”進行覆蓋。

所以開發的時候,一定要注意,這種陷阱一旦走進去的,就很難調試,有時候也有一種“湊巧”來避開這個問題,差錯就更加不好查。希望在以後開發的時候 能給大家有一定的參考。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.