用棧是無法產(chǎn)生垃圾數(shù)據(jù)的(想一想計算機原理).但是在使用堆的過程中很有可能產(chǎn)生的(多是一些難以回收的內存碎片,編譯時又不會報錯,或是其中的死循環(huán),漏洞),程序越小,產(chǎn)生垃圾數(shù)據(jù)的可能性就越小.現(xiàn)在,有些軟件甚至故意在內存和硬盤中留下一些無用數(shù)據(jù),這是人為因素.
創(chuàng)新互聯(lián)服務項目包括愛民網(wǎng)站建設、愛民網(wǎng)站制作、愛民網(wǎng)頁制作以及愛民網(wǎng)絡營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關系等,向廣大中小型企業(yè)、政府機構等提供互聯(lián)網(wǎng)行業(yè)的解決方案,愛民網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務的客戶以成都為中心已經(jīng)輻射到愛民省份的部分城市,未來相信會繼續(xù)擴大服務區(qū)域并繼續(xù)獲得客戶的支持與信任!
由于當初這些空間是向系統(tǒng)申請得到的,最后應該由程序返還,一切都合乎規(guī)則,對于內存來說,當系統(tǒng)結束工作時,會強制回收內存,保證安全的關機;對于硬盤來說,由于申請是合法的(對系統(tǒng)來說),所以系統(tǒng)無法處理,可以用殺毒軟件.
在所有函數(shù)體之外定義的基本數(shù)據(jù)類型的變量會被默認初始化.在函數(shù)體內未初始化而直接使用一個變量(賦值,或以其他形式訪問)會導致未定義的結果,既程序正常運行,或崩潰,或產(chǎn)生垃圾數(shù)據(jù).
首先這個數(shù)組不是靜態(tài)數(shù)組,因為你沒有寫static關鍵字!
所以這個數(shù)組是局部數(shù)組,進入函數(shù)時創(chuàng)建,函數(shù)結束時撤銷。
這個程序編譯時一般會有警告——你返回了一個已撤銷的數(shù)組的起始地址。
打個比方:你在旅館里開了5間房,并把第一間房的房號作為函數(shù)值。
函數(shù)結束時,退了房,但房號(即地址)還是在的,但那房間卻不屬于你的了。
如果沒有新人入住,那么里面的內容就沒變。一旦新人入住,那么里面的內容就會改變。
直接看第二個程序:
1) pArr = staticArr();
2) printf("%d\n", *(pArr + 1));
3) printf("%d\n", *(pArr + 2));
第1行:pArr得到了已撤銷的數(shù)組的起始地址。
第2行:調用printf函數(shù)之前,首先通過*(pArr+1)獲取了這個已撤銷數(shù)組的第一個元素的值,由于房間還沒新人入住,所以可以得到原來的值。接著,就把這個值傳給printf函數(shù),注意它是復制了一份再發(fā)給printf函數(shù)的。
注意:所有函數(shù)在調用時所給出的實際參數(shù)都將被復制給被調函數(shù)的形式參數(shù)的——即函數(shù)的形式參數(shù)都是復制品。
現(xiàn)在調用printf函數(shù)——新人入住了,那個數(shù)組的房間現(xiàn)在分配給printf函數(shù)去用了,其中內容被改變,但是printf函數(shù)輸出的是復制品,不是原件,所以“看起來沒變”。
第3行:再次通過*(pArr + 2)取值的時候,就取到了被前一個printf函數(shù)改變以后留下的垃圾值,而且這個printf函數(shù)將再次改變這些房間,留下不同的垃圾值。
用任何方法輸出這個已經(jīng)不屬于你的數(shù)組的內容,都是毫無意義的,因為它都是前一個printf函數(shù)結束工作后留下的垃圾數(shù)據(jù)。
如果你在數(shù)組定義前加static關鍵字,結果就不同了。
static int a[5] = {...};
不信,你就試一試!
如果沒有這一句,ch是一個未初始化的變量,可能輸出任何數(shù)值,跟編譯器相關。例如我用vs2008,ch對應的內存中值為-52. 所以絕大多編碼規(guī)范要求定義的變量必須初始化,防止異常的情況出現(xiàn)。
加上這一句,當你輸入一個數(shù)后,會按回車鍵,getchar就撲捉到你輸入的換行字符。
你查查ASCII碼。換行對應的ascll碼就是10.