关于静态数组的参数调用!!(100分)

  • 主题发起人 For_Loop
  • 开始时间
上面的代码看起来是有一点问题,"设置长度为Len_X*Len_Y"但单位呢?每个字符串长度不一样!

但我在D6下竟然不出错!!!
 
给分!!!!
const
SWLL: array[1..4,1..10] of string
= (('Z','Q','AC','VA','VM','HS','ZS','QS','AS','VS'),
('3','4','5','6','7','8','109','110','111','112'),
('0','0','0','0','0','0','0','0','0','0'),
('','','','','','','','','',''));

procedure TForm1.Disp(P: PString
rLen, cLen: Integer);
var
i, j: Integer;
s: string;
begin
memo1.Clear;
for i := 1 to rLen do
begin
s := P^;
Inc(P);
for j := 2 to cLen do
begin
s := s + #9 + P^;
Inc(P);
end;
memo1.Lines.Add(s);
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Disp(PString(@SWLL), 4, 10);
end;
 
来自:lichaogang, 时间:2004-5-14 17:02:27, ID:2610587
上面的代码看起来是有一点问题,"设置长度为Len_X*Len_Y"但单位呢?每个字符串长度不一样!

是有问题但不是这个,因为数组类型是string,每个字符串长度虽然是不一样,但这个不需用数组使用者关心,因为string类型已经记录了自身长度。

Kisber的方法不错,直接用字符串类型把自数组首地址起,按传入的维数读字符串,而我的代码会把传入的地址按动态数组处理,而动态数组和ansistring处理方法类似,要设置长度和引用计数,就会对不该修改的地址进修改,从而引发内存错误。

Kisber得分!
 
oh,That's perfect.
 
呵呵,等我验证一下!
 
这个方法确实可以,在此很感谢!
但是大家有点忽略我的本意 ,我的本意是在过程中能直接通过二维A[x,y]或者通过一维A[x*len+y]来引用静态数组固定行、列的值。可是上面的程序我没法通过给出的x,y来确定给定的值。
我希望的是在过程中能实现


if x[i,j]<>'' then
就是说能得到对应静态数组固定行列的值。

大家再看看,如果到周一没什么其他方法,我把这帖结啦,分会给大家的。






 
给大家看一下我的本来程序!!

//判断是否是主标志符
Function GetMid(tsp:string
VAR TiD,TSN,TMN:integer
var Tdata:string):boolean;
var
i:integer;
b1,b2:integer;
c1,c2:string;
begin
result:=false;
//根据nowDM来判断

if NowDM in [1,2,3,4,5,6,7,8] then
begin
//JYXX 1
for i:=1 to 16 do
begin
if jYXX[1,i]=tsp then
begin
TiD:=1;
TSN:=strtoint(jYXX[2,i]);
TMN:=strtoint(jYXX[3,i]);
Tdata:=jYXX[4,i];
result:=true;
exit;
end;
end;

//JXXX 2
for i:=1 to 2 do
begin
if jXXX[1,i]=tsp then
begin
TiD:=2;
TSN:=strtoint(jXXX[2,i]);
TMN:=strtoint(jXXX[3,i]);
Tdata:=jXXX[4,i];
result:=true;
exit;
end;
end;

//BYXX 3
for i:=1 to 3 do
begin
if BYXX[1,i]=tsp then
begin
TiD:=3;
TSN:=strtoint(BYXX[2,i]);
TMN:=strtoint(BYXX[3,i]);
Tdata:=BYXX[4,i];
result:=true;
exit;
end;
end;
end;
我的本意是把上面对每个数组处理的部分用一个过程或函数代替,如下:
//判断是否是主标志符
Function GetMid(tsp:string
VAR TiD,TSN,TMN:integer
var Tdata:string):boolean;
var
i:integer;
b1,b2:integer;
c1,c2:string;
begin
result:=false;
//根据nowDM来判断

if NowDM in [1,2,3,4,5,6,7,8] then
begin
disp(jyxx,x1,x2,x3--参数);
disp(jxxx,x1,x2,x3--参数);
disp(byxx,x1,x2,x3--参数);

end;
end;
大家在帮看一下

 
不会吧,这还要我编!
 
function GetDim(P:pString
cLen, iRow, iCol: Integer): string;
begin
Inc(P, (iRow - 1) * cLen + iCol - 1)
//因为你的数组说明了从 1 开始
Result := P^;
end;
 
你这个方法确实可以,我也不是不会编写,不过看上去 很别扭罢啦,没有我想象的那样引用方便直观,不过确实是实现啦,再等一下,如果周一没有什么好答复的,我就结帖。
我看我在程序中还是用原来的代码,虽然麻烦,但是看上去很直观的。
 
我前两天想使用这样一个方法,我使用一个overload函数或过程,参数是多类型的,
type
X1=array[1..4,1..1] of string;
x2=array[1..4,1..2] of string;

......
x40=array[1..4,1..40] of string;//我的二维数组最多不会超过40
eg:
disp(p:x1;xlen,ylen:integer);overload;
disp(p:x2;xlen,ylen:integer);overload;
disp(p:x3;xlen,ylen:integer);overload;
disp(p:x4;xlen,ylen:integer);overload;
......
disp(p:x40;xlen,ylen:integer);overload;

这样写来代码会很直观的,但是有一个缺点,就是,我得写40个disp过程,太麻烦啦,大家看一下,如果以这个思路有没有改进的地方??
如果给出思路我会加新帖给大家分的!
希望关注。

 
我看楼主的最想解决的问题是想传一个二维数组的问题, 又不想用PString数组: 那么就用下面这个方法吧(直接拷贝运行):

unit u1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

const
XYJY1: array[1..4, 1..1] of string
= (('PX'),
('4'),
('3'),
(''));
ZFXX: array[1..4, 1..2] of string
= (('ES', 'ED'),
('3', '4'),
('0', '0'),
('preEnd', 'end'));
SWLL: array[1..4, 1..10] of string
= (('Z', 'Q', 'AC', 'VA', 'VM', 'HS', 'ZS', 'QS', 'AS', 'VS'),
('3', '4', '5', '6', '7', '8', '109', '110', '111', '112'),
('0', '0', '0', '0', '0', '0', '0', '0', '0', '0'),
('', '', '', '', '', '', '', '', '', ''));

type
TArrays = array of array of string;

procedure Disop(s: TArrays);
var
i, j: integer;
begin
for i := 0 to High(s) do
for j := 0 to High(s[0]) do
ShowMessage(s[i, j]);
// ....做各种动作
// ....做各种动作

end;

procedure TForm1.Button1Click(Sender: TObject);
var
i, j: integer;
TempArrs: TArrays;

procedure GiveTempArrsVals(APStr: PString
FirHigh, SecHigh: Integer);
var
i: Integer;
i2, i3: Integer;
begin
SetLength(TempArrs, FirHigh);
for i := 0 to FirHigh - 1 do
setLength(TempArrs, SecHigh);
i := 1;
i2 := 0;
i3 := 0;
while (i <= FirHigh * SecHigh) do
begin
TempArrs[i2, i3] := APStr^;
Inc(APStr);
Inc(i);
Inc(i3);
if i3 mod SecHigh = 0 then
begin
Inc(i2);
i3 := 0;
end;
end;
end;

begin
GiveTempArrsVals(PString(@ZFXX), High(ZFXX), High(ZFXX[1]));
Disop(TempArrs);

GiveTempArrsVals(@XYJY1, High(XYJY1), High(XYJY1[1]));
Disop(TempArrs);

GiveTempArrsVals(@SWLL, High(SWLL), High(SWLL[1]));
Disop(TempArrs);
end;


end.


1. 注意动态数组的下标从0开始.
2. 肯定不用overload40个方法了.
 
呵呵 ,楼上的方法不错,能满足我的要求,真是经典!!
我先改改程序,周一9时准时结帖!
大家再看一下,还有没有更简洁的方法?
------------------------------------------
Thanks Every Ones
 
结帖,给大家发分啦......
————————————————————————————————————
但是最终我没用上这个代码,我发现我把大富翁WW的代码单独运行的时候一切正常,我把这些代码移植到我的程序中,出现了不可思议的错误,单独跟踪都运行不正常,我不知道是为什么,
只好决定不用这个代码啦,还是恢复原来的代码,虽然麻烦,但是看上去直观,也简单。
我还是希望能有个更好的方法。
^*^
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
949
SUNSTONE的Delphi笔记
S
S
回复
0
查看
770
SUNSTONE的Delphi笔记
S
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
顶部