请问在delphi中使用指针有什么好处?(60)

  • 主题发起人 主题发起人 tom12345
  • 开始时间 开始时间
T

tom12345

Unregistered / Unconfirmed
GUEST, unregistred user!
请问在delphi中使用指针有什么好处?比如说提高效率什么的?
 
使用得到可以比普通不使用指针节省内存,以及大量数据处理的时候速度提升数十倍。
 
快速方便
 
与C/C++中指针的好处差不多。
 
指针还分语言??
 
各位大侠,可以给个实例吗?
 
快速方便
 
S:string
<=====指针Form1: TForm
<=====指针button1: TButton
<=====指针...所有的类和string都是指针,你应该用过了
 
哦,我是想知道在delphi引入中自定义指针变量有什么好处,能提高程序运行速度吗?书本上讲的都是理论上的,我想知道实际上是否如此。
 
使用指针是不得已而为之。通常都是为了效率,但是程序会非常的不安全。一切取决与开发者的功力。
 
打个比喻,枪手会拆解清理枪支好不好?那要看你技能用得好不好,拆完了再组装起来结果多出几个零件来,那就不好了吧?指针也一样。用指针可以把数据拆解出来使用,但用完了,你又多拆出几个数据来(数据越界访问)就不好了吧?例子:varpc: pchar
ps: string;begin ps:= 'abcdefg';// pc:= @ps[Length(ps)+ 1];// pc^:= 'h'
//此时输出pc你会越界访问内存。结果未知。 pc:= @ps[1]
//若此时输出pc会得到 ‘abcdefg’串 inc(pc)
pc^:= #0
pc:= @ps[1]
//此时输出只有‘a’ ShowMessage(pc);end;
 
dark_power,以上语句用下面一句代替即可: ShowMessage(ps[1]);没必要用指针啊。
 
ps 本来就是指针,怎么叫没必要,你不用也不行。
 
ps应当算是一个引用类型,相当于常量指针。当通过这个引用来改变内容时会发生写复制,注意是通过这个“引用”,不是通过提取这个引用的指针的形式(形如:ps[n]{n>=1})。但是,使用引用的指针形式可以越界访问这个字串,例如,你可以ps[n]:= 'x'{n>Length(ps)},但越界的部分打印不出来,为什么?原因就是Delphi的字符串原本是基于字符计数的。你在个字符串赋值的时候编译器就已经把字符串的字符数固定了,当然,可以手动修改,但这绝不是什么好主意。
 
dark_power,可以举一个使用指针提高程序运行速度的例子吗?
 
字符串的解析和排序。这是我所能最快想到的应用。这个也许让你对指针的了解有帮助。http://www.delphibbs.com/delphibbs/dispq.asp?lid=3981121如果不用指针而使用 Copy()和Pos()则要慢很多,因为要大量复制字串。
 
你也可用下面这个试一试。var pc, pcs: PChar
ps, sWatch: string
npos,i,s,t: Integer
ticktock: Cardinal;begin ps:= '-abcd-efgh-ijkl-mnop-efgh-ijkl-mnop-efgh-ijkl-mnop-efgh-ijkl-mnop'
ps:= ps+ps+ps+ps
pc:= @ps[1]
npos:= 1
ticktock:= GetTickCount();//Method 1: for s := 1 to 100000 do begin pc:= @ps[1]
for i:= 1 to Length(ps) do begin if (pc^= '-')then begin inc(pc);// ShowMessage(pc)
//这里是打印,但应用中可能是复制或操作。// mmo1.Lines.Add(pc)
end
inc(pc)
end
end;//Method 2:// for t := 1 to 100000 do// begin// npos:= 1;// while (npos< Length(ps)-4) do// begin// npos:= PosEx('-', ps, npos);// Inc(npos);// sWatch:= Copy(ps, npos, Length(ps));//// mmo1.Lines.Add(sWatch);// end;// end
ticktock:= GetTickCount() - ticktock
ShowMessage(IntToStr(ticktock));end;
 
对于内存中有结构的对象,使用带指针的好处就大很明显了。拿灌水灌到底,发个c#写的例子(那种语言无所谓把) //内存相对偏移地址转文件偏移地址,返回值 unsafe static public uint RvaToOffset(DosHeardStructure* lpDosHead, uint rva) { uint ret = 0
ImageNtHeaders32* lpImageNtHeader = (ImageNtHeaders32*)((uint)lpDosHead + (*lpDosHead).e_lfanew)
//此处申明一个节表头仅用来获取尺寸,防止后续工作中产生多余的内存浪费 ImageNtHeaders32 imageNt = new ImageNtHeaders32()
ImageSectionHeader ish = new ImageSectionHeader()
ImageSectionHeader* lpImageSectionHeader = (ImageSectionHeader*)((uint)lpImageNtHeader + Marshal.SizeOf(imageNt))
for (int i = 0
i < (*lpImageNtHeader).FileHeader.NumberOfSections
i++) { if ((rva >= (*lpImageSectionHeader).VirtualAddress) && (rva < ((*lpImageSectionHeader).VirtualAddress + (*lpImageSectionHeader).SizeOfRawData))) { //数据相对于节的起始地址的偏移地址RVA uint sectionOffset = rva - (*lpImageSectionHeader).VirtualAddress
ret = (*lpImageSectionHeader).PointerToRawData + sectionOffset
break
} lpImageSectionHeader = (ImageSectionHeader*)((uint)lpImageSectionHeader + Marshal.SizeOf(ish))
} return ret
}总结下:指针需要注意几个基本概念,指针的地址,指针的值,指针指向的地址,指针所指向地址的值指针的好处就是指针的地址可以做算术运算,如:ImageSectionHeader* lpImageSectionHeader = (ImageSectionHeader*)((uint)lpImageNtHeader + Marshal.SizeOf(imageNt));文笔不好,时间也不早,墨水也不多,剩余的看你自己理会mov ecx,[ecx]
 
dark_power,下面这条编译错误: npos:= PosEx('-', ps, npos);[Error] Unit1.pas(93): Undeclared identifier: 'PosEx'
 
dark_power,上面说的编译错误解决了,下面这条编译错误: mmo1.Lines.Add(sWatch);[Error] Unit1.pas(96): Undeclared identifier: 'mmo1'
 
后退
顶部