看板 Soft_Job 關於我們 聯絡資訊
※ 引述《xsion (Xsion)》之銘言: : 標題: [心得] 程式設計師應該懂多少? : Q: 下面這段程式有沒有什麼問題? : void fun(int* ptr) : { : ptr = new int[2]; : } : int main() : { : int *ptr = NULL; : fun(ptr); : ptr[1] = 1; : ptr[2] = 2; : printf("%d %d", ptr[1], ptr[2]); : return 0; : } : : 我期待中的出淺的Programmer起碼會看出「有使用new配置記憶體,卻沒delete釋放」 : 「C語言是base-0陣列宣告大小為2的不能索引到[2]」,我想有點程度的應該還能回答 : C語言都是傳值呼叫,所以配置好的指標空間無法回傳。 : 我還想看得出錯誤的人還可以討論怎麼修改會比較好... : : 好吧,或許你們都用C++ Builder或.Net,有好用的data structure class可以用, : 所以我改問... : Q:當有不定資料長度的資料要儲存時,你會使用什麼方法。 : A:不定長度? : Q 補充道:就是一開始不知道需要多大空間,要動態配置的啊。 : A:不是寫程式時就知道大小了嗎? : Q又補充道:很多狀況要等執行時期,資料讀入或使用者輸入後才知道會有幾筆資料啊。 : 這些是編譯時期不會知道的啊。 : A:不會啊,都可以知道啊。 : : 同上題,另一位回答道。 : A:方法? Q補充道:對,就是你會用哪一種資料結構或者是哪些現成的Class? : A:用陣列啊。 Q可是陣列不能動態大小耶。 : A:是喔?......(沉默) Q:你都宣告一個很大的陣列來存放嗎? : A:這也是個方法啦......(已經恍神中) : ========================================================================= : void fun(int* ptr) : { : ptr = new int[2]; : } 基本上出現這種用法, 或者說這個需求是所謂 variable size array 的問題. 我猜, 學校教的通常會強調使用已知固定大小的 n-dimension array 來事先 聲明, 這是因為不同語言對 n-維陣列 排法不同, 最安全辦法就是在 main program 與 sub-program 間均宣告相同大小與型態的 n-維陣列, 使得下標 (index)的位址換算可以一致. 但做練習這樣是簡單可以的, 但要寫一個通用 讓別的 main program 都可以隨 varible size variable dimension 調用的 function sub-program 就有麻煩了. 老式的 FORTRAN 是在主程式預留最大的 array space , 讓 sub-program 用 call by address/reference 根據傳入的 dimension 自行換算成 one-dim 去取用. 在網路 message passing 時代, 使用 pointer 就比較麻煩一點, 但 c 語言 的低階功能就是能用 pointer 操控 address of mnemonic name , 所以多數 的花樣跟此有關. 如果照以前的 FORTRAN function 定義, function 帶入的參數, 依照數學習 慣是不可以在 function 處理時受到更動的, FORTRAN 因之也沒有調用自己的 recursive function 功能. function sub-program 如果用 stack space 暫 存 local variable 與傳遞參數, 上述問題就能一併提供, 但離開 function sub-program 那些 function 內部的 local variable 就隨 return 可能就讓 stack 的再用增長而消失了, 因此一個臨時的 heap space 隨 malloc 動態配 置而來. 但要個空間並非就照那個大小剛好的給, 通常是有個基本最小單位, 常常是超用了, 或用了不收回也沒怎樣, 這就會養成壞習慣, 對分工發展各自 的 sub-program 帶來危害. 這種問題應該是給個範例, 每個要點都提到, 學習的人一次也就全通了. 不過, 讓 sub-program 來要求一個主程式也要使用到的 memory space , 在 可讀性與維護上是不好的示範. : 面試到此已經快要升天了,針對一位強調自己會C++和物件導向的人再問道。 : Q:Class宣告中,你是如何決定成員的存取等級? : A:存取等級? : Q:就是 public, protected和private那三個啊,你宣告的變數或函式要放在哪一段裡面? : A:喔,那個喔。那些比較理論的東西,我比較沒在注意(心虛中) : Q:小姐,這些不是理論,這是物件導向最基本的精神,封裝。 : A:喔~那個喔,我都是改人家程式的,都是放在public。 : Q:所以你都不知道為甚麼要放在public嗎? : A:恩......(無言) : : 另一位面試者,強調用MFC寫過Windows Application,所以問道。 : Q:你知道Windows Message的架構嗎? : A:不知道(這個倒爽快) : Q:你知道Procress和Thread的差異嗎? : A:...(沉默是金) : Q:在Windows裡面,不同Procress間要如何溝通?(我承認我蠢,連上一題都無法 : 回答的人,我還找死問這題!) : A:阿!我有寫過,用CreatThread...... : Q:那是Thread,Thread和Process共用資料段,不需要啥特別的方法溝通。 : A:喔~(沉默) ====================== 這一題的題例要扯 local/public 宣告還可, 但扯 multi-thread 就遠了一點 ! #include <stdio.h> int * fun(int * ptr, int dim) { ptr = new int[dim + 1]; /* C array count from zero */ ptr[0] = ptr[0] + 100; /* 每次叫用 是否歸零或累加 */ ptr[3] = 3; ptr[dim] = dim; printf("%d %d %d %d %d\n",ptr[0],ptr[1],ptr[2],ptr[3],ptr[dim]); return ptr ; } int void main() /* 新規範 結束時帶回shell是否正常結束指示,DOS 是 register A */ { int * ptr, * temp1; int asize, i ,j ; asize = 12; ptr = fun(ptr, asize); ptr[1] = 1; ptr[2] = 2; for (i=0; i < asize - 5 ; i=i+5) printf("%d %d %d %d %d\n", ptr[i],ptr[i+1],ptr[i+2],ptr[i+3],ptr[i+4]); for (j=i; j <= asize; j++) printf("%d ",ptr[j]); printf("\n"); temp1 = ptr; /* 老式的 gcc 2.X delete 又再 new 使用 data array 時,不會全 init to 0 */ // delete []ptr; /* delete ptr ; delete pointer with full array */ ptr = fun(ptr, 18); delete []temp1; /*先要下一個 new array , 再清除舊的, 就不會用到舊的 */ printf("What happen ? ptr[0]= %d \n", ptr[0]); return 0; /* depend on program exit for cli */ } 動態使用記憶體, 如果反覆 new delete 一個 array , delete 的反應 因效率的考慮, 隨下一個需求空間的大小會對宣稱該回收的資料有不同 的處理, delete 資料空間的回收反應, 在實作上跟語意有點差距. ◆ From: 140.115.4.12
avhacker:這篇最後的 code 是要比誰錯比較多嗎? 06/05 10:47
judo1127:一眼看到void main.....return 0 06/05 10:56
GregHowe:嗯...都宣告void ....還要return 0 ? 06/05 11:03
GregHowe:原po說multithread並不是以這題,而是另外提出,會錯意嗎? 06/05 11:05
GregHowe:這討論串的重點倒不是討論這題目的本身....而是一種現象 06/05 11:09
GregHowe:暫且不論這題是有多少錯誤..原po希望看到的是回答的內容 06/05 11:10
GregHowe:是否能看出一些比較像是程式設計師能看出的錯誤 06/05 11:12
clubflymf:原PO考的是基本觀念 有NEW 就有DELETE 不就這樣嗎?@@ 06/05 13:00
Cloud:這範例連delete都用錯了.... 06/05 13:39
achii:不懂就別自曝其短了...(搖頭) 06/05 20:16
ggg12345:有請各位高手指正!! 06/05 20:23
tyf99:前一個程式的最大問題是沒回傳ptr,main()的ptr一直都指null 06/05 20:30
tyf99:而你的new array最好改成struct,delete時直接砍掉struct 06/05 20:37
※ 編輯: ggg12345 來自: 140.115.4.12 (06/06 13:22)
Fenikso:都什麼年代了還在void main() 06/06 20:21
xsion:很多人都不知void main是錯的,甚至MSDN的範例也有void main 06/06 22:45
Fenikso:新資料都沒有吧..? 有的話也是vc6.0時代留下來的遺跡 06/06 22:57
swordsun:如果我沒記錯,g老師說話,連你們的主管都要乖乖聽 06/07 03:26
swordsun:g老師在講的, 跟你們在想的是兩碼子事 06/07 03:33
Fenikso:喔(挖鼻孔) 06/07 04:23
Fenikso:小弟愚昧無知 實在看不懂那比醬糊還不如的code想表達什麼. 06/07 04:23
bobhsiao:最前面的void fun(int* ptr);其實沒寫到main()的ptr 06/07 08:07
bobhsiao:後面的 QA 也沒寫這問題...這毛病我自己常犯所以印象深刻 06/07 08:07
Cloud:老師不是要授業解惑,怎麼搞的是我們幫他...... 06/07 08:22
※ 編輯: ggg12345 來自: 140.115.4.12 (06/07 08:51)
andymai:給個不一樣的觀念:老師不過是比較早學的人~老師不能犯錯? 06/07 08:45
Cloud:可惜這是網路...只能從打出來的字來判斷...XD 06/07 08:49
swordsun:只挑的出別人語法的錯,看不到人家考慮的問題 06/07 14:57
swordsun:猴子猴孫的智商, 一代不如一代 06/07 14:59
ggg12345:試了gcc4.0 delete後不會立即又被抓回來,但只清ptr[0]. 06/10 09:46
ggg12345:暫存pointer再用,delete的array其他的data仍然可以看得到 06/10 09:50