線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:2859
推到 Plurk!
推到 Facebook!

請問如何將動態筆數的 array (自訂型態) 當參數傳送 ?

答題得分者是:change.jian
pcboy
版主


發表:177
回覆:1838
積分:1463
註冊:2004-01-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-09-10 16:47:44 IP:210.69.xxx.xxx 未訂閱
請問如何將動態筆數的 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

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-09-10 16:58:51 IP:211.20.xxx.xxx 未訂閱
pcboy2 你好    與前一篇是相同的原因喔! 因為沒uses 到TNameRecord  定義所在的單元檔(也就是要uses Unit1) 前一篇問題: http://delphi.ktop.com.tw/topic.php?TOPIC_ID=56125 _______________________________________ 深藍的魚,祝您好運..........連連
pcboy
版主


發表:177
回覆:1838
積分:1463
註冊:2004-01-13

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-09-11 00:53:57 IP:203.204.xxx.xxx 未訂閱
小弟 的 Unit2.pas 中有不少自己寫的 function 和 procedure 所以 Unit1 中必須 uses Unit2 , 您提的 "請調整uses 該單元的位置" 並不適用 還是說 uses Unit2 寫在 Interface區段 或implementation 區段有差異 ?
------
能力不足,求助於人;有能力時,幫幫別人;如果您滿意答覆,請適時結案!

子曰:問有三種,不懂則問,雖懂有疑則問,雖懂而想知更多則問!
Chance36
版主


發表:31
回覆:1033
積分:792
註冊:2002-12-31

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-09-11 02:24:27 IP:203.204.xxx.xxx 未訂閱
pcboy2 你好     一般來說uses語句放在 Interface區段 或implementation 差別不是太大的,唯一差別在Interface區段中會用到別的單元檔中的自定型別、元件類別時,該單元檔即需在Interface區段中uses它,其他狀況好像沒什麼差別了。     所以一般來說,系統(標準)元件、自訂元件或公用函數(可能會有一些自定型態)所在的單元檔,皆在Interface 區段中uses它,而專案相關的單元檔會放在implementation  後面uses 它,除非發生Circular unit reference (循環參考)的狀況時,才會將其中一個單元檔的uses搬家(移到Interface區段中)。     當然啦!以上只是我個人的習慣,它不是絕對的,只要不會衝突就可以了。    _______________________________________ 深藍的魚,祝您好運..........連連
pcboy
版主


發表:177
回覆:1838
積分:1463
註冊:2004-01-13

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-09-13 16:47:02 IP:61.220.xxx.xxx 未訂閱
***** 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

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-09-13 16:58:07 IP:61.220.xxx.xxx 未訂閱
想到一個問題, NameData 何時配置記憶體 ? 配置多少? 是否要增加什麼步驟 ? 滑鼠移到 NameData[k].Name 的 Name , 顯示 Inaccessible vale
------
能力不足,求助於人;有能力時,幫幫別人;如果您滿意答覆,請適時結案!

子曰:問有三種,不懂則問,雖懂有疑則問,雖懂而想知更多則問!
ha0009
版主


發表:16
回覆:507
積分:639
註冊:2002-03-16

發送簡訊給我
#7 引用回覆 回覆 發表時間:2004-09-13 17:54:30 IP:219.80.xxx.xxx 未訂閱
你好:
  插花
    其實有時候使用  >  > ->    < src="http://sourceprovide.deepen.com.tw/K_Top/bp.gif">
        
change.jian
版主


發表:29
回覆:620
積分:439
註冊:2003-06-02

發送簡訊給我
#8 引用回覆 回覆 發表時間:2004-09-14 21:42:21 IP:61.229.xxx.xxx 未訂閱
引言: ***** 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

發送簡訊給我
#9 引用回覆 回覆 發表時間:2004-09-15 16:07:15 IP:210.69.xxx.xxx 未訂閱
請問 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

發送簡訊給我
#10 引用回覆 回覆 發表時間:2004-09-15 17:43:27 IP:61.218.xxx.xxx 未訂閱
如果你的陣列是要隨時增加的話,那麼誠如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

發送簡訊給我
#11 引用回覆 回覆 發表時間:2004-09-16 20:07:47 IP:61.222.xxx.xxx 未訂閱
補充: 使用 陣列 Array 有筆數限制 超過將會出現 out of memory 訊息 建議使用 TLIST 方式 雖然麻煩點...
pcboy
版主


發表:177
回覆:1838
積分:1463
註冊:2004-01-13

發送簡訊給我
#12 引用回覆 回覆 發表時間:2004-09-17 10:22:39 IP:210.69.xxx.xxx 未訂閱
小弟會嘗試改用 TLIST "使用 陣列 Array 有筆數限制", 請問原因 ? 宣告的是不定筆數的動態陣列 而且 MS-Windows 下每個應用程式不是在 4G 虛擬記憶體空間上執行, 2G VRAM 給系統用, 2G VRAM 給應用程式用, 所以應該有 2G 記憶體可以使用嗎 ?
------
能力不足,求助於人;有能力時,幫幫別人;如果您滿意答覆,請適時結案!

子曰:問有三種,不懂則問,雖懂有疑則問,雖懂而想知更多則問!
wameng
版主


發表:31
回覆:1336
積分:1188
註冊:2004-09-16

發送簡訊給我
#13 引用回覆 回覆 發表時間:2004-09-17 12:36:00 IP:61.222.xxx.xxx 未訂閱
小弟我曾經使用這樣的方法, 開發一套軟體。 運行一段時間,就發生"out of Memory "錯誤訊息 原本以為 為記憶體不足! 但是,對方電腦記憶體為 1G 。而且怎樣計算過使用容量也不會超過 60M 後來,嘗試不要開啟太多的陣列。 就不會出現這樣的問題。 記得開啟到兩萬多個陣列,就會出現這樣的錯誤訊息。 目前使用 TList 的方法,尚未出過任何問題
change.jian
版主


發表:29
回覆:620
積分:439
註冊:2003-06-02

發送簡訊給我
#14 引用回覆 回覆 發表時間:2004-09-17 17:14:01 IP:61.229.xxx.xxx 未訂閱
hi,pcboy2:    1.我還沒有遇到過out of memory的問題. 2.動態陣列與TList最大的差別,應該說是陣列元素可不可以被知道的差別.   只要是使用陣列,不管是在程式裡就已指定陣列大小,或者是程式執行時才會得知陣列大小,最基本的原因,就是都要指定陣列的大小,然後才能在這個陣列範圍內使用.   而使用TList之類的物件,你可以不用去管這個陣列最後會長多大,只要有新的元素就是給他加上去,有不要用的元素就是把他刪除,你壓根不用去管這個TList最多會有幾個元素.(就像DataSet一樣,你有需要就累加上去,不用去管這個DataSet最多會有幾筆).      不曉得這樣解釋能不能讓你判斷你該用array還是TList?    
引言: 小弟會嘗試改用 TLIST "使用 陣列 Array 有筆數限制", 請問原因 ? 宣告的是不定筆數的動態陣列 而且 MS-Windows 下每個應用程式不是在 4G 虛擬記憶體空間上執行, 2G VRAM 給系統用, 2G VRAM 給應用程式用, 所以應該有 2G 記憶體可以使用嗎 ?
系統時間:2024-04-26 8:42:43
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!