請問如何將動態筆數的 array (自訂型態) 當參數傳送 ? |
答題得分者是:change.jian
|
pcboy
版主 發表:177 回覆:1838 積分:1463 註冊:2004-01-13 發送簡訊給我 |
請問如何將動態筆數的 array (自訂型態) 當參數傳送 ? Unit1.pas 的 type 中
引言: TNameRecord = record Name : String; Addr : String; end; TNameArray = array of TNameRecord; procedure TForm1.FormCreate(Sender: TObject); var NameData : TNameArray; begin ShowNameData(NameData); end;在 Unit2.pas 中 引言: uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; procedure ShowNameData(NameData: TNameArray); implementation結果產生錯誤 : 引言: [Error] Unit2.pas(11): Undeclared identifier: 'TNameArray'請問該如何解決 ? Thanks !
------
能力不足,求助於人;有能力時,幫幫別人;如果您滿意答覆,請適時結案! 子曰:問有三種,不懂則問,雖懂有疑則問,雖懂而想知更多則問! |
Chance36
版主 發表:31 回覆:1033 積分:792 註冊:2002-12-31 發送簡訊給我 |
|
pcboy
版主 發表:177 回覆:1838 積分:1463 註冊:2004-01-13 發送簡訊給我 |
|
Chance36
版主 發表:31 回覆:1033 積分:792 註冊:2002-12-31 發送簡訊給我 |
pcboy2 你好 一般來說uses語句放在 Interface區段 或implementation 差別不是太大的,唯一差別在Interface區段中會用到別的單元檔中的自定型別、元件類別時,該單元檔即需在Interface區段中uses它,其他狀況好像沒什麼差別了。 所以一般來說,系統(標準)元件、自訂元件或公用函數(可能會有一些自定型態)所在的單元檔,皆在Interface 區段中uses它,而專案相關的單元檔會放在implementation 後面uses 它,除非發生Circular unit reference (循環參考)的狀況時,才會將其中一個單元檔的uses搬家(移到Interface區段中)。 當然啦!以上只是我個人的習慣,它不是絕對的,只要不會衝突就可以了。 _______________________________________
深藍的魚,祝您好運..........連連
|
pcboy
版主 發表:177 回覆:1838 積分:1463 註冊:2004-01-13 發送簡訊給我 |
***** Unit1 ******** type TNameRecord = record
Name : String;
Addr : String;
end;
TNameArray = array of TNameRecord;
var
NameData : TNameArray
implementation uses Unit2; procedure TForm1.FormCreate(Sender: TObject);
begin
ShowNameData(NameData);
end; ***** Unit2 ******** interface uses Unit1; procedure ShowNameData(NameData:TNameArray); implementation ShowNameData(NameData);
begin
...
NameData[k].Name = NameString;
...
end; F9 直接執行結果發生錯誤 :
Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address
0040425C in module 'Project1.exe'. Write of address 00000020. Process stopped. Use Step or Run to
continue.
在 NameData[k].Name = NameString; 設定中斷點, 看到 NameString 確實有字串值
請問該如何處理 ? 謝謝
------
能力不足,求助於人;有能力時,幫幫別人;如果您滿意答覆,請適時結案! 子曰:問有三種,不懂則問,雖懂有疑則問,雖懂而想知更多則問! |
pcboy
版主 發表:177 回覆:1838 積分:1463 註冊:2004-01-13 發送簡訊給我 |
|
ha0009
版主 發表:16 回覆:507 積分:639 註冊:2002-03-16 發送簡訊給我 |
|
change.jian
版主 發表:29 回覆:620 積分:439 註冊:2003-06-02 發送簡訊給我 |
引言: ***** Unit1 ********type TNameRecord = record Name : String; Addr : String; end; TNameArray = array of TNameRecord; var NameData : TNameArray implementation uses Unit2; procedure TForm1.FormCreate(Sender: TObject); var i:Integer; begin //ShowNameData(NameData); //這裡錯了,要先為NameData配置記憶體 SetLength(NameData,2); //配置兩個 for i:=0 to high(NameData) do begin NameData[i].Name:='Name' IntToStr(i); NameData[i].Addr:='Addr' IntToStr(i); end; end; ***** Unit2 ******** interface uses Unit1; procedure ShowNameData(NameData:TNameArray); implementation ShowNameData(NameData); begin ... NameData[k].Name = NameString; ... end;F9 直接執行結果發生錯誤 : Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 0040425C in module 'Project1.exe'. Write of address 00000020. Process stopped. Use Step or Run to continue. 在 NameData[k].Name = NameString; 設定中斷點, 看到 NameString 確實有字串值 請問該如何處理 ? 謝謝 |
pcboy
版主 發表:177 回覆:1838 積分:1463 註冊:2004-01-13 發送簡訊給我 |
請問 change.jian 版主 因為 NameData 有幾筆不一定, 在 ShowNameData() 中, 每蒐集到一筆, 就會新增一筆
小弟將程式改為 SetLength(NameData,m);
因為 SetLength(NameData,m); 是在一個 repeat 迴圈中, 每跑一次 m 增加 1
結果跑到 m=10 的時候, NameData[k].Name = NameString; 又發生錯誤
Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address
00404262 in module 'Project1.exe'. Write of address 00000100. Process stopped. Use Step or Run to
continue.
------
能力不足,求助於人;有能力時,幫幫別人;如果您滿意答覆,請適時結案! 子曰:問有三種,不懂則問,雖懂有疑則問,雖懂而想知更多則問! |
change.jian
版主 發表:29 回覆:620 積分:439 註冊:2003-06-02 發送簡訊給我 |
如果你的陣列是要隨時增加的話,那麼誠如ha0009所以,用個TList來管理是個不錯的選擇.我的做法如下:
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons; type PNameRecord = ^TNameRecord; TNameRecord = record Name : String; Addr : String; end; TForm1 = class(TForm) BitBtn1: TBitBtn; Edit1: TEdit; Memo1: TMemo; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure BitBtn1Click(Sender: TObject); private FList:TList; function AddRecord:Integer; procedure DelRecord(Index:Integer); procedure DisplayRec; public { Public declarations } end; var Form1: TForm1; implementation uses Unit2; {$R *.dfm} function TForm1.AddRecord: Integer; var Rec:PNameRecord; begin new(Rec); //這裡就是在記憶體裡新開一個位置 Result:=FList.Add(Rec); //把這個新開的位置加入到TList來管理 end; procedure TForm1.DelRecord(Index: Integer); var Rec:PNameRecord; begin Rec:=FList.Items[Index]; //從TList找出要存取的那個記錄 Dispose(Rec); //把記憶體釋放掉 FList.Delete(Index); //管理的TList記得要跟著刪除 end; procedure TForm1.FormCreate(Sender: TObject); begin FList:=TList.Create; end; procedure TForm1.FormDestroy(Sender: TObject); var i:Integer; Rec:PNameRecord; begin for i:=0 to FList.Count-1 do begin Rec:=FList.Items[i]; Dispose(Rec); end; FList.Free; end; procedure TForm1.BitBtn1Click(Sender: TObject); var count,i:Integer; begin count:=StrToInt(Edit1.text); for i:=0 to Count-1 do AddRecord; ShowNameData(FList); DisplayRec; end; procedure TForm1.DisplayRec; var i:Integer; Rec:PNameRecord; begin Memo1.Lines.Clear; for i:=0 to FList.Count-1 do begin Rec:=FList.Items[i]; Memo1.Lines.Add('Index:' IntToStr(i) ' Name:' Rec.Name ' Addr:' Rec.Addr); end; end; end. unit Unit2; interface uses Classes,Unit1,SysUtils; procedure ShowNameData(List:TList); implementation procedure ShowNameData(List:TList); var i:Integer; Rec:PNameRecord; begin for i:=0 to List.Count-1 do begin Rec:=List.Items[i]; Rec.Name:='Name' IntToStr(i); Rec.Addr:='Addr' IntToStr(i); end; end; end. 引言: 請問 change.jian 版主 因為 NameData 有幾筆不一定, 在 ShowNameData() 中, 每蒐集到一筆, 就會新增一筆 小弟將程式改為 SetLength(NameData,m); 因為 SetLength(NameData,m); 是在一個 repeat 迴圈中, 每跑一次 m 增加 1 結果跑到 m=10 的時候, NameData[k].Name = NameString; 又發生錯誤 Project Project1.exe raised exception class EAccessViolation with message 'Access violation at address 00404262 in module 'Project1.exe'. Write of address 00000100. Process stopped. Use Step or Run to continue. |
wameng
版主 發表:31 回覆:1336 積分:1188 註冊:2004-09-16 發送簡訊給我 |
|
pcboy
版主 發表:177 回覆:1838 積分:1463 註冊:2004-01-13 發送簡訊給我 |
|
wameng
版主 發表:31 回覆:1336 積分:1188 註冊:2004-09-16 發送簡訊給我 |
|
change.jian
版主 發表:29 回覆:620 積分:439 註冊:2003-06-02 發送簡訊給我 |
hi,pcboy2: 1.我還沒有遇到過out of memory的問題.
2.動態陣列與TList最大的差別,應該說是陣列元素可不可以被知道的差別.
只要是使用陣列,不管是在程式裡就已指定陣列大小,或者是程式執行時才會得知陣列大小,最基本的原因,就是都要指定陣列的大小,然後才能在這個陣列範圍內使用.
而使用TList之類的物件,你可以不用去管這個陣列最後會長多大,只要有新的元素就是給他加上去,有不要用的元素就是把他刪除,你壓根不用去管這個TList最多會有幾個元素.(就像DataSet一樣,你有需要就累加上去,不用去管這個DataSet最多會有幾筆). 不曉得這樣解釋能不能讓你判斷你該用array還是TList?
引言: 小弟會嘗試改用 TLIST "使用 陣列 Array 有筆數限制", 請問原因 ? 宣告的是不定筆數的動態陣列 而且 MS-Windows 下每個應用程式不是在 4G 虛擬記憶體空間上執行, 2G VRAM 給系統用, 2G VRAM 給應用程式用, 所以應該有 2G 記憶體可以使用嗎 ? |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |