Re: [語法] 關於陣列裡的陣列

看板C_and_CPP (C/C++)作者 (我要加入劍道社!)時間15年前 (2009/04/27 17:36), 編輯推噓31(310116)
留言147則, 16人參與, 最新討論串2/3 (看更多)
因為有人推文認為我在酸人 我只好一行一行來解釋你的 code 有哪些問題 ※ 引述《seedpk5079 (fhcrc 99th ooxx)》之銘言: : #include<stdio.h> : #include<string.h> : #include<stdlib.h> : typedef struct big_number{ : int number; : big_number(){ : int number[50]={}; : } : }; 首先這邊讓人搞不太清楚你是在寫 C 或是在寫 C++。 若你要用 C,就不能寫 constructor,因為那是 C++ 才有的功能。 若你要用 C++,就別再用舊式的 C 寫法,C++ 不需要針對每個 struct 去 typedef。 然後 stdio.h、string.h、stdlib.h 改成 cstdio、cstring、cstdlib 會比較標準。 再來,你的 number 到底是陣列還是單純的整數? 從你後面的 code 來看,number 應該要宣告成陣列,所以你的定義應該改成: #include <algorithm> struct big_number { int number[50]; big_number() { std::fill(number, number+50, 0); } }; 我們沒辦法直接用等號來清空陣列的全部元素,所以用 std::fill 來把每個元素 填為 0。這個做法會比用 memset 好一點。 : int b; : struct big_number dp[120]; : struct big_number *w,*e; 像 b、w、e 這類沒有意義的名稱,絕對不應拿來宣告為全域變數。 : void first(void){/*進行費氏最初2項初始化*/ : dp[0].number[0]=1; : dp[1].number[0]=1; : } : int *t,*tt,ll,*replace,*rr; : int get_number(int *t){ : int v; : for(v=0;t[v]!=0;++v){} : return v; : } : void give(int* replace,int *rr){ : int z; : for(z=0;z<50;++z){ : rr[z]=replace[z]; : } : } 你把 t、tt、ll、replace、rr 都宣告為全域變數, 然而又用相同的名稱去宣告函式的參數, 我看不出你這樣做的用意何在。 : int * string_reversal(int *tt,int ll){ : int ttt[50]={},tttt=0; : if(tt[ll]==0){ : ll--; : } : for(;ll>=0;ll--){ : ttt[tttt]=tt[ll]; : tttt++; : } : return ttt; : } 這邊是個明顯的錯誤,ttt 並非靜態變數,它的生命週期在 return 後就會 結束。回傳 ttt 將導致未定義的結果 (通常是你的變數內容莫名奇妙被毀)。 : int * add(int *w,int *e){ : int total[50]={},i,j,k,h,m,l=0; : i=get_number(w); : j=get_number(e); : i--;j--; : give(string_reversal(w,i),w); : give(string_reversal(e,j),e); : k=((i>=j)?i:j); : for(m=0;m<=k;++m){ : total[l]=w[m]+e[m]+total[l]; : if(total[l]>=10){ : total[l+1]=total[l]/10; : total[l]=total[l]%10; : } : l++; : } : give(string_reversal(total,l),total); : return total; : } 這邊的錯誤和前面一樣,total 是區域變數陣列,你不應該拿來回傳。 另外因為你的變數名稱幾乎都沒有意義,我很難看出這段 code 是否有錯誤。 : int* Fibonacc(int b){ : if(b==1||b==2){ : return dp[0]->number; : } : else if(dp[b].number[0]<10&&dp[b]->number[0]>0){ : return dp[b]->number; : } : else{ : give(add(Fibonacc(b-1),Fibonacc(b-2)),dp[b]->number); : return dp[b]->number; : } : } 這邊 return dp[b]->number 是可以的,因為 dp 是全域變數。 但這樣做不是好的設計,因為接受端很容易誤用得到的記憶體。 : int main(){ : int n; : while(scanf("%d",&n)!=EOF ){ : int day=0,number=0,u,*o,mm[50]={},cc[50]={}; : first(); : mm[0]=9;mm[1]=2;cc[0]=1;cc[1]=9; : o=add(mm,cc); : printf("\n"); : for(u=0;u<50;++u){ : printf("%d",o[u]); : } : } : return 0; : } 最後的問題,程式碼最好進行縮排,這樣也容易讓你一眼就看出程式結構。 上面的 main 經過適當排版後如下: int main(){ int n; while(scanf("%d", &n) != EOF){ int day = 0, number = 0; int mm[50] = {9, 2}; int cc[50] = {1, 9}; first(); int* o = add(mm, cc); printf("\n"); for(int u = 0; u < 50; ++u){ printf("%d", o[u]); } } return 0; } 這樣看起來會比較清楚。當然你的程式還是有問題,最主要出在你把區域陣列 直接回傳的部份。雖然我可以直接寫一個 big_number 的 class 出來讓你當正 確答案參考,但這樣對你沒有幫助。建議你還是再重頭念一次你的 C++ 教科書, 了解之前的 code 錯在哪裡,再繼續寫這支程式。 : 以上是我寫的程式碼 : 內容是要把費氏數列做大數跟DP : 可是我現在卡在紅色那幾行 : 到底要怎麼做才能把結構裡的陣列抓出來用啊... : 希望會的人能幫忙解答一下XD -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 124.9.6.2

04/27 17:43, , 1F
我收回我之前說的話,l大願意這樣詳細地幫忙解說的精神,
04/27 17:43, 1F

04/27 17:43, , 2F
很值得大家的尊敬~:)
04/27 17:43, 2F

04/27 17:51, , 3F
基本上, 貼上難以閱讀的 code 本身就是一種不禮貌
04/27 17:51, 3F

04/27 17:51, , 4F
就算我很常幫人看 code 解決問題, 看到這種的還是難以下手
04/27 17:51, 4F

04/27 18:01, , 5F
倒也不能這樣說,畢竟學程式的人,不見得每個都是科班訓練
04/27 18:01, 5F

04/27 18:02, , 6F
出來的,太過苛責,反而顯得肚量太小.
04/27 18:02, 6F

04/27 18:11, , 7F
不是科班訓練? 這是單純發問的禮貌, 要科班訓練才會有
04/27 18:11, 7F

04/27 18:11, , 8F
禮貌? 這是什麼道理?...
04/27 18:11, 8F

04/27 18:19, , 9F
貼無法閱讀的程式碼就跟貼注音文的文章差不了多少
04/27 18:19, 9F

04/27 18:19, , 10F
樓上的不要硬凹,我不相信你剛學程式時,就用正規的變數命
04/27 18:19, 10F

04/27 18:19, , 11F
當然如果你閱讀注音文無礙, 那我也無話可說
04/27 18:19, 11F

04/27 18:20, , 12F
名方式,而不會用a b c這些東西.
04/27 18:20, 12F

04/27 18:20, , 13F
那如果我說是, 你又要怎麼回答呢
04/27 18:20, 13F

04/27 18:20, , 14F
= = 我要說的是樓樓上,樓上的自動對號入座了.
04/27 18:20, 14F

04/27 18:22, , 15F
很不幸, 我也是. 第一天學寫程式, 就有教命名要有意思
04/27 18:22, 15F

04/27 18:23, , 16F
況且, 我說的是禮貌. 問人, 要讓別人看得懂你問什麼,
04/27 18:23, 16F

04/27 18:23, , 17F
不過就算命名取得沒意義... 這排版也不會花你很多時間呀
04/27 18:23, 17F

04/27 18:23, , 18F
這是禮貌, 我管你自己寫的時候用什麼命名, 但出來發問,
04/27 18:23, 18F

04/27 18:24, , 19F
那是因為你們是科本出身的,有人告訴你們要用正規命名法.
04/27 18:24, 19F

04/27 18:24, , 20F
就要把你的程式簡化整理得別人看得懂, 這就是禮貌
04/27 18:24, 20F

04/27 18:24, , 21F
一開始沒學到這些 那代表你的書本或老師有問題
04/27 18:24, 21F

04/27 18:24, , 22F
自己看書學的,很多書上不會特別說明變數要好好命名,況且
04/27 18:24, 22F

04/27 18:24, , 23F
還要硬凹嗎? 我就不算是本科出身的, 我讀 BBA 的
04/27 18:24, 23F

04/27 18:25, , 24F
爛書還扯那麼多
04/27 18:25, 24F

04/27 18:25, , 25F
有很多人英文不夠好,要他們用英文幫變數命名不太容易
04/27 18:25, 25F

04/27 18:25, , 26F
況且, 把發問的東西寫得別人看得明白, 這種基本禮貌
04/27 18:25, 26F

04/27 18:25, , 27F
也要別人教嗎?
04/27 18:25, 27F

04/27 18:26, , 28F
爛書也是學資訊出身的人寫出來的爛書啊,你怪讀者就不對
04/27 18:26, 28F

04/27 18:26, , 29F
英文不好不能當理由...
04/27 18:26, 29F

04/27 18:26, , 30F
怪讀者就不對 XD 可以轉 joke 嗎? XDXD
04/27 18:26, 30F

04/27 18:26, , 31F
英文不好, 也至少要有意識, tt t rr ll 這些能用英文差
04/27 18:26, 31F

04/27 18:27, , 32F
看來我聯考考不好只好怪書編得爛了 XD
04/27 18:27, 32F

04/27 18:27, , 33F
做藉口嗎?? 別再凹了好不好?
04/27 18:27, 33F

04/27 18:30, , 34F
寫爛書,然後還怪讀者自己不懂得變通,讀者要是有分辨好壞
04/27 18:30, 34F

04/27 18:30, , 35F
的能力,我想就不至於選爛書來看了吧?
04/27 18:30, 35F

04/27 18:33, , 36F
所以大家都不要鞭, 繼續沉迷在爛書中而不自知
04/27 18:33, 36F

04/27 18:33, , 37F
你是這個意思?
04/27 18:33, 37F

04/27 18:35, , 38F
我在五樓時已經說得很清楚了,是一堆資訊出身的要高高在
04/27 18:35, 38F

04/27 18:35, , 39F
上,硬凹自己肚量大.
04/27 18:35, 39F
還有 68 則推文
04/27 20:37, , 108F
所以說你為何非得要認為那「無意義」又是「酸」?很主觀呢
04/27 20:37, 108F

04/27 20:38, , 109F
喔~那你呢?自打嘴巴~
04/27 20:38, 109F

04/27 20:40, , 110F
我沒有幫回答,因為我沒有那麼像littleshan那麼熱心,可至
04/27 20:40, 110F

04/27 20:40, , 111F
少我不會去嘲笑新手!!
04/27 20:40, 111F

04/27 20:41, , 112F
基本上大家都在笑你
04/27 20:41, 112F

04/27 20:42, , 113F
就跟你說了,或許根本只有你一人認為那是嘲笑
04/27 20:42, 113F

04/27 20:42, , 114F
其他人認為那是「建議」
04/27 20:42, 114F

04/27 20:43, , 115F
有提出具體不正確之處,而不是「爛死了,學什麼程式」這
04/27 20:43, 115F

04/27 20:43, , 116F
喔~是啊~就群眾暴力嘛~你們這些人就這樣,只會笑別人而已
04/27 20:43, 116F

04/27 20:43, , 117F
種嘲笑的沒建設性發言
04/27 20:43, 117F

04/27 20:44, , 118F
你自己想想看為啥從頭到尾都是你一人在支持嘲笑說好了
04/27 20:44, 118F

04/27 20:45, , 119F
群眾暴力也出來了...不是跟你說不要把那個當嘲笑就好了?
04/27 20:45, 119F

04/27 20:46, , 120F
你確定發問的原PO真的認為自己被嘲笑?
04/27 20:46, 120F

04/27 20:51, , 121F
要是連發問者怎麼認為都還不知道就自顧自的認為「你被嘲
04/27 20:51, 121F

04/27 20:51, , 122F
笑了!」,那或許你才是那個用高姿態看人的人。
04/27 20:51, 122F

04/27 21:21, , 123F
感謝指導 小弟會再去想辦法研讀
04/27 21:21, 123F

04/27 21:58, , 124F
推這篇的原po 命名跟縮排是很基本的觀念 變數章節一定有講
04/27 21:58, 124F

04/28 12:41, , 125F
樓上講的我在仿間電腦書上沒看過...
04/28 12:41, 125F

04/28 12:44, , 126F
變數的命名(無誤的話)基本上不影響程式的執行結果....
04/28 12:44, 126F

04/28 12:45, , 127F
但是對於後續的開發維護有非常舉足輕重的影響....
04/28 12:45, 127F

04/28 12:45, , 128F
大底來說大家都會說取個有意義/合適的名字, 但是我相信
04/28 12:45, 128F

04/28 12:45, , 129F
許多人或許多派都有自己的style或主張, 比如可以去goo
04/28 12:45, 129F

04/28 12:46, , 130F
一下"匈牙利命名法"; 其實如果code只有自己看, 那麼變數
04/28 12:46, 130F

04/28 12:46, , 131F
你想怎麼取就取吧, 但是要給別人看或者是co-work的時候
04/28 12:46, 131F

04/28 12:47, , 132F
變數的命名是否有意義, 是否follow組織裡慣用的規則就很
04/28 12:47, 132F

04/28 12:48, , 133F
重要. (甚至是每個變數後面的註解與用法可能都是關鍵)
04/28 12:48, 133F

04/28 12:48, , 134F
小弟我的程度沒辦法說明/推薦什麼樣的命名才好, 事實上
04/28 12:48, 134F

04/28 12:49, , 135F
就算是'匈'這種應該也有人認為太過繁複冗長(沒記錯的話)
04/28 12:49, 135F

04/28 12:50, , 136F
argu你的書有沒有講這個沒什麼意義, 不過style各有不同,
04/28 12:50, 136F

04/28 12:50, , 137F
但大家應該都同意好的變數命名習慣很重要; 至於怎樣才算
04/28 12:50, 137F

04/28 12:50, , 138F
不錯的, 等其他的大大推荐參考資料或書籍再看看吧:)
04/28 12:50, 138F

04/28 13:31, , 139F
記得以前我們寫大數的時候有個笑話
04/28 13:31, 139F

04/28 13:32, , 140F
有個同學抱怨`英文字母不夠多` 因為他變數取 a0~zzz
04/28 13:32, 140F

04/28 13:33, , 141F
程式碼已經2000多行了 一個基本的操作都還沒完成
04/28 13:33, 141F

04/28 13:33, , 142F
一個for迴圈都沒有 全部用if/else 跟難看的變數硬幹
04/28 13:33, 142F

04/28 13:35, , 143F
過沒多久他就直接複製網路上的版本了,說「太長了 看不懂」
04/28 13:35, 143F

04/28 13:35, , 144F
自己都看不懂了 怎麼期待幫忙改的人看的懂呢
04/28 13:35, 144F

04/28 13:36, , 145F
最後這個同學跑去做VHDL的專題
04/28 13:36, 145F

04/28 14:08, , 146F
耐心強者L大 <(_._)>
04/28 14:08, 146F

04/28 17:53, , 147F
L大真是佛心~而且回答的很仔細耶
04/28 17:53, 147F
文章代碼(AID): #19zNobtU (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #19zNobtU (C_and_CPP)