求救! 关于字符串二维数组(100分)

  • 主题发起人 主题发起人 beyondeast
  • 开始时间 开始时间
B

beyondeast

Unregistered / Unconfirmed
GUEST, unregistred user!
想在程序里使用一个字符串二维数组对象,希望具有类似stringgrid里内部数据的功能,
有cells, rowcount,colcount,rows,cols,动态分配内存……
不知道有没有现成的对象可以使用,请告知,多谢!
 
那么你就用一个隐藏的StringGrid好吗?据我所知,似乎没有这么一种类型或对像,你看看
StringGrid中对TStringList的处理就应该知道没有这种东东,不然TStringGrid就用它了。
 
用隐藏的stringgrid,内存用得多不说,还有问题:colcount,rowcount的最小值都是1,
而不是0
 
用Tstringlist吧,
stringlist.add('a1');
stringlist.add('a2');
stringlist.add('b1');
stringlist.add('b1');
'a1'=stringlist.string(0)
'b1'=stringlist.string(3)
 
to 枫:
注意,我要的是字符串二维数组。
 
据我所知没有。
不过你过可自己写这个对象。
很简单的
不要什么事都想找现成的哪样还要你干什么?????
 
最开始自己写了一个,但是效率很低,比stringgrid差多了,
看stringgrid的源代码又看得我晕乎,程序又要得急,没办法呀![:(]
 
我不知道是不是我对二维数组的理解有问题,我是这样理解的
二维数组的排列是 0,0 0,1 1,0 1,1,如果你把它排一个一维的话就成了 0 1 2 3 4 5 6 7 8
了,一维中的0元素等于二维中的(0,0) 1等于二维中的(0,1)元素
所以我给你的也就是把二维变成1维的,操作的时时候只要加上偏移量就可以按二维那样操作了
 
to 枫:
但是分配内存、释放内存等操作就很不方便。
 
释放的话,设nil就可以,就是分配的时候会麻烦点。如果你要求不高这也是个办法,
要求高的话,建议你看看stringgrid代码,看他是怎么分配,管理的
 
to 枫:光置为nil行吗?
一个字符串变量实际上是一个指针变量,所以它有4字节大小。
所以,你可以给它赋nil值,而Delphi并不会报告Pointer和string类型不兼容。
你也可以给它赋空串,如:MyStr := ''
Delphi会自动给它赋nil值。
如果一个字符串变量中有值,这个指针指向堆上的一块内存,这块内存里就存了字符串,
在这块内存的-8字节偏移处,有一个整数,记着这块内存的引用计数,就是有多少个string变量指向了这块区域。
在这块内存的-4字节偏移处,有一个整数,标明此字符串的大小。
当你给一个字符串赋nil的时候,Delphi会先根据此变量原来的指向,将原字符串的引用计数减一。
如果一个字符串的引用计数减到了零,Delphi就释放掉这块区域。
Delphi就是这样自动管理字符串的分配和释放的。
所以,你会认为只要赋nil值就可以释放内存。

但是,可能你没有看清人家的要求,人家要实现的是一个“动态动态动态动态”的二维字符串数组,
其实,不论是不是字符串数组,不论是几维,只要你想实现“动态”数组,你就避免不了分配和释放。
字符串本身的值是可以有Delphi自动管理,可以不操心,那字符串变量所占的空间呢?
每个字符串变量要4字节(指针嘛),你自己试着做做看?
就是实现一个整数动态数组,也免不了内存管理。

to beyondeast:
如果觉得复杂,你可以先看看TStringList的代码,
它实现了一个动态一维字符串数组,
呵呵,从一维到二维,循序渐进嘛!
其实它就是用ReallocMem来分配、再分配和释放内存的。
你要的东西,VCL里面应该没有,可能是要你自己来实现,
我看了一下TStringGrid的代码,其实并不复杂,
如果你觉得什么地方不明白,
可以来问大家嘛,大家一起帮你看。
 
定义一个.
FCellsText: array of String;
然后
procedure TCustomFrameGrid.InitCellsText;
var
i: Integer;
begin
SetLength(FCellsText, RowCount*ColCount);
for i:=0 to RowCount*ColCount-1 do
FCellsText:='';
end;

procedure TCustomFrameGrid.InitCellsText;
var
i: Integer;
begin
SetLength(FCellsText, RowCount*ColCount);
for i:=0 to RowCount*ColCount-1 do
FCellsText:='';
end;
思路就是二维变为一维处理.
 
to 坏蟑螂
呵呵,谢谢教导,,我还有不明地方请教,,如果将一个nil赋给一个数组名,那么数组会不会就是空的了呢?
按我的理解,数组名就是数组的第一个头指针,它指向下第一个数组元素,如果把这个指针置空了,那么整个数组就不是没有了?
不过这里也有问题存在,就是当置空的时候,它的那些元素所占的内存并没有释放呢。
需要把元素占的内存释放掉,再把头指针指向nil?
 
我非常不清楚为什么会有这种需求.
难道ARRAY OF ARRAY OF STRING
//甚至于VARARRAY还不够用么? VARARRAYCREATE...
TYPE TB=ARRAY OF STRING;
TA=ARRAY OF TB;
例如:
VAR A:TA;
倘若觉得使用LENGTH(A) = ROWCOUNTS
LENGTH(A[0])= COLCOUNTS
A[I,J]=CELLS[I,J]
A=ROWS
SETLENGTH(A)动态修改 ROWCOUNTS,
FOR I:=0 TO LENGTH(A)-1 DO
SETLENGTH(A,COLCOUNTS)来修改COLCOUNTS难道还不够简单么?
倘若如此,写一个最简单的CLASS
封装起来
TYPE ARRAYCLASS=CLASS
PRIVATE
FARR:TA;
PUBLIC
PROPERTY ROWCOUNTS:INTEGER READ GET... WRITE GET...
END;
难道这样还不够简单么?

难道我理解有问题?
 
是我愚笨,多谢各位!
 
多人接受答案了。
 
后退
顶部