不用遍历,如何将记录或数组里的所有元素快速清零?(200分)

  • 主题发起人 主题发起人 雁孤行
  • 开始时间 开始时间

雁孤行

Unregistered / Unconfirmed
GUEST, unregistred user!
不用遍历,如何将记录或数组里的所有元素快速清零?
 
奇怪,不遍历?不明白。给点思路好吗?
 
就是说我想用最简单的方法将,记录、数组里所有的元素归零,也就是数字变为0,字符
变为'',指针变为nil。
 
不知道是不是这个的意思.
1.setlength函数.
procedure SetLength(var S
NewLength: Integer);
S is a string or dynamic-array variable.
setlength(x,0);

2.FillChar函数
procedure FillChar(var X
Count: Integer
Value: Byte);

Description
FillChar fills Count contiguous bytes (referenced by X) with the value
specified by Value (Value can be type Byte or Char).
Warning: This function does not perform any range checking.

e.g.
var
S: array[0..79] of char;
begin
{ Set to all spaces }
FillChar(S, SizeOf(S), Ord(' '));
end;
 
重新声明一遍行不行?
呵呵,听起来像以前懒的删除硬盘上的东西,直接format.
 
to bluerain:
  我是指对任何类型的数组,而不单是字符数组。
to bubble:
  不行,我用的是全局变量。
 
j:array [1..10] of integer;
...
FillMemory(@j,sizeof(j),0);
 
FillChar();
FillMemory();
ZeroMemory();
都可以实现。

但是虽然表面形式上不是遍历,其实质还是遍历!
如果真正做到不遍历,估计要使用硬件机制,发送高低电平给存储单元的每一位。
 
试试看
type
TArr = record
i : integer;
j : string;
end;
var
Form1: TForm1;
Arr : array[1..2] of TArr;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
Arr[1].i := 1;
Arr[1].j := 'a';
Arr[2].i := 2;
Arr[2].j := 'b';
end;

procedure TForm1.Button3Click(Sender: TObject);
var
i : integer;
begin
listbox1.Clear;
for i := 1 to 2 do
begin
listbox1.Items.Add(inttostr(Arr.i));
listbox1.Items.Add(Arr.j);
end;
end;

//清空
procedure TForm1.Button2Click(Sender: TObject);
begin
[blue] FillChar(Arr,sizeof(Arr),0);[/blue]
end;

end.
 
//,发送高低电平给存储单元的每一位。
还是遍历!!!!!!!
 
总之不管怎么做,都是变相的在利用遍历,^_^

唯一的解决方案:
要本质上不遍历而要连续的内存单元突然全部为零---断电---全部低电平了,^_^
 
不管事实是不是遍历,只要不用我去写遍历的代码,简单、快捷就行了。
 
FillChar();
FillMemory();
ZeroMemory();
三者清零其实是一样的。在windows.pas中的定义如下:
procedure FillMemory(Destination: Pointer
Length: DWORD
Fill: Byte);
begin
FillChar(Destination^, Length, Fill);
end;

procedure ZeroMemory(Destination: Pointer
Length: DWORD);
begin
FillChar(Destination^, Length, 0);
end;

而FillChar的实现是这样的(system.pas):
procedure _FillChar;
asm
{ ->EAX Pointer to destination }
{ EDX count }
{ CL value }

PUSH EDI

MOV EDI,EAX { Point EDI to destination }

MOV CH,CL { Fill EAX with value repeated 4 times }
MOV EAX,ECX
SHL EAX,16
MOV AX,CX

MOV ECX,EDX
SAR ECX,2
JS @@exit

REP STOSD { Fill count DIV 4 dwords }

MOV ECX,EDX
AND ECX,3
REP STOSB { Fill count MOD 4 bytes }

@@exit:
POP EDI
end;
-------------------------------------------------------------
所以我觉得FillChar并不只是对字符能清零,它以字节为单位,对某一段内存清零。
卷哥说得对,在汇编中还是用到了循环。
 
FillChar()、FillMemory()、ZeroMemory()三者有何区别?
 
如果是记录数组或多维数组呢?直接用FillChar()好像不行,是否依然要进行一次遍历?
如:
var
TMyRecord = record
X:integer;
Y:Double;
end;
TMyArray = array[1..5] of TMyRecord
如何将TMyArray里每个TMyRecord的成员清零?
 
>>如果是记录数组或多维数组呢?
  已经用FillChar()清零了。系别处导致清零没有执行,Sorry。
 
faint,能不能清空记录数组或多维数组,我上面的例子已经告诉你了,
FillChar()、FillMemory()、ZeroMemory()三者的区别zw84611也已经明明白白的
写清楚了.
 
to bluerain:
  Sorry!光顾着自己去试这几个函数了,请原谅。
 
可否声明一元素为空的记录或数组,然后赋于全局变量。
可行否?
 
既然都是要变相的循环,那就循吧,没必要钻牛角尖吧.
循环很麻烦么?
 
后退
顶部