随笔 - 33  文章 - 0  评论 - 0  阅读 - 6459

实例12 指针指向何方,前途各不一样

指针的优点是处理速度快,而现在的电脑运行速度已经相当惊人了,并且还向更惊人的速度发展。在这种的硬件环境下,指针的处理速度已经显得不重要了,因此建议慎用指针,一旦把握不好,会弄巧成拙,造成系统崩溃。

用的比较多的可能算字符指针了,比如如下的代码:

var

  P:Pchar;

  ii:Integer;

begin

  for ii:=0 to 99 do

  begin

    p[ii]:=Char(ii);

  end;

end;

运行上面那段代码肯定会出现问题,因为这个P可能是个空指针,事先没有给它分配空间,所以不能赋值。可以改成下面代码:

var

  P:Pchar;

  ii:Integer;

begin

  GetMem(p,100);

  for ii:=0 to 99 do  //留意不要超出给定地址的范围

  begin

    p[ii]:=Char(ii);

  end;

  FreeMem(p);

end;

指针还有一点值得注意,也是最重要的,一旦指针已分配给你,这个值是一个起始地址,这个起始地址以后的范围,可就全向你开放。在赋值时,不能超出已分配的空间范围。如果超出了,可能修改操作系统的重要数据,严重时将引起系统崩溃。

Pascal有一种Point类型,它叫无类型指针,即它只指示内存地址,而不管这个地址对应的是整数还是字符串,它有点类似于C语句中的void*类型。有类型指针用^符号声明,且声明在程序的Type说明符下,例如:

type

  PInt=^Integer;

var

  P:PInt;

  nn:Integer;

begin

  GetMem(p,100);

  P^:=50;  //给指针赋值

  nn:=P^;  //取出指针中的内容

  Edit1.Text:=IntToHex(nn,0); //输出32,是十六进制

  FreeMem(P);

end;

IntToHex(Value,Digits)函数是把整数转成16进位的AnsiString,Value是转换的整数,Digits是指16进制字符串的位数。(实际测试中,第二个参数好像不起作用,限制不了位数)

var

  lpFarProc:FARPROC;

begin

  .......

  lpFarProc:=GetProcAddress(hComm,'MyFunc');

  @MyFunc:=lpFarProc;  //指针类型转换

  MyFunc();

end;

从语法上讲一点问题没有,如果正常使用,也没有一点问题。但是,如果不正常使用呢?

我们不能说该程序有什么问题,但是至少它是不严谨的,它没有对指针是否为空指针进行判断,如果程序一旦运行,万一出现了空指针的情况,程序必死无疑。如果将程序稍微修改一下,加一个条件判断,隐患就消除了。

var

  lpFarProc:FARPROC;

begin

  lpFarProc:=GetProcAddress(hComm,'MyFunc');

  if lpFarProc<>nil then

  begin

    @MyFunc:=lpFarProc;  //指针类型转换

    MyFunc();

  end;

end;

这些看似简单的地方,最鞥体现一个程序设计者的水平。熟练的程序设计者为什么出现的错误比较少,关键在于他注意了一些细小的环节。

 

posted on   Delphi搬运工  阅读(59)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示