浅谈Object Pascal的指针

【Delphi 基础知识 16】指针和指针类型 Delphi 是一种基于 Object Pascal 编程语言的集成开发环境(IDE),它支持面向对象编程和指针的使用。在 Delphi 中,指针是一种强大的工具,用于直接操作内存地址,但同时也需要小心使用以避免出现内存泄漏和访问非法内存的问题。 阅读详情
浅谈Object Pascal的指针

大家都认为,C语言之所以强大,以及其自由性,很大部分体现在其灵活的指针运用上。因此,说指针是C语言的灵魂,一点都不为过。同时,这种说法也让很多人 产生误解,似乎只有C语言的指针才能算指针。Basic不支持指针,在此不论。其实,Pascal语言本身也是支持指针的。从最初的Pascal发展至今 的Object Pascal,可以说在指针运用上,丝毫不会逊色于C语言的指针。

以下内容分为八个部分,分别是
一、类型指针的定义
二、无类型指针的定义
三、指针的解除引用
四、取地址(指针赋值)
五、指针运算
六、动态内存分配
七、字符数组的运算
八、函数指针


一、类型指针的定义。对于指向特定类型的指针,在C中是这样定义的:
int *ptr;
char *ptr;
与之等价的Object Pascal是如何定义的呢?
var
ptr : ^Integer;
ptr : ^char;
其实也就是符号的差别而已。

二、无类型指针的定义。C中有void *类型,也就是可以指向任何类型数据的指针。Object Pascal为其定义了一个专门的类型:Pointer。于是,
ptr : Pointer;
就与C中的
void *ptr;
等价了。

三、指针的解除引用。要解除指针引用(即取出指针所指区域的值),C 的语法是 (*ptr),Object Pascal则是 ptr^。

四、取地址(指针赋值)。取某对象的地址并将其赋值给指针变量,C 的语法是
ptr = &Object;
Object Pascal 则是
ptr := @Object;
也只是符号的差别而已。

五、指针运算。在C中,可以对指针进行移动的运算,如:
char a[20];  
char *ptr=a;  
ptr++;
ptr+=2;
当执行ptr++;时,编译器会产生让ptr前进sizeof(char)步长的代码,之后,ptr将指向a[1]。ptr+=2;这句使得ptr前进两 个sizeof(char)大小的步长。同样,我们来看一下Object Pascal中如何实现:
var
  a : array [1..20] of Char;
  ptr : PChar; //PChar 可以看作 ^Char
begin
  ptr := @a;
  Inc(ptr); // 这句等价于 C 的 ptr++;
  Inc(ptr, 2); //这句等价于 C 的 ptr+=2;
end;

六、动态内存分配。C中,使用malloc()库函数分配内存,free()函数释放内存。如这样的代码:
int *ptr, *ptr2;
int i;
ptr = (int*) malloc(sizeof(int) * 20);
ptr2 = ptr;
for (i=0; i<20; i++){
  *ptr = i;
  ptr++;
}
free(ptr2);
Object Pascal中,动态分配内存的函数是GetMem(),与之对应的释放函数为FreeMem()(传统Pascal中获取内存的函数是New()和 Dispose(),但New()只能获得对象的单个实体的内存大小,无法取得连续的存放多个对象的内存块)。因此,与上面那段C的代码等价的 Object Pascal的代码为:
var ptr, ptr2 : ^integer;
  i : integer;
begin
  GetMem(ptr, sizeof(integer) * 20);
    //这句等价于C的 ptr = (int*) malloc(sizeof(int) * 20);
  ptr2 := ptr; //保留原始指针位置
  for i := 0 to 19 do
  begin
    ptr^ := i;
    Inc(ptr);
  end;
  FreeMem(ptr2);
end;
对于以上这个例子(无论是C版本的,还是Object Pascal版本的),都要注意一个问题,就是分配内存的单位是字节(BYTE),因此在使用GetMem时,其第二个参数如果想当然的写成 20,那么就会出问题了(内存访问越界)。因为GetMem(ptr, 20);实际只分配了20个字节的内存空间,而一个整形的大小是四个字节,那么访问第五个之后的所有元素都是非法的了(对于malloc()的参数同 样)。

七、字符数组的运算。C语言中,是没有字符串类型的,因此,字符串都是用字符数组来实现,于是也有一套str打头的库函数以进行字符数组的运算,如以下代码:
char str[15];
char *pstr;
strcpy(str, "teststr");
strcat(str, "_testok");
pstr = (char*) malloc(sizeof(char) * 15);
strcpy(pstr, str);
printf(pstr);
free(pstr);
而在Object Pascal中,有了String类型,因此可以很方便的对字符串进行各种运算。但是,有时我们的Pascal代码需要与C的代码交互(比如:用 Object Pascal的代码调用C写的DLL或者用Object Pascal写的DLL准备允许用C写客户端的代码)的话,就不能使用String类型了,而必须使用两种语言通用的字符数组。其实,Object Pascal提供了完全相似C的一整套字符数组的运算函数,以上那段代码的Object Pascal版本是这样的:
var str : array [1..15] of char;
  pstr : PChar; //Pchar 也就是 ^Char
begin
  StrCopy(@str, 'teststr'); //在C中,数组的名称可以直接作为数组首地址指针来用
          //但Pascal不是这样的,因此 str前要加上取地址的运算符
  StrCat(@str, '_testok');
  GetMem(pstr, sizeof(char) * 15);
  StrCopy(pstr, @str);
  Write(pstr);
  FreeMem(pstr);
end;

八、函数指针。在动态调用DLL中的函数时,就会用到函数指针。假设用C写的一段代码如下:
typedef int (*PVFN)(int); //定义函数指针类型
int main()
{
  HMODULE hModule = LoadLibrary("test.dll");
PVFN pvfn = NULL;
  pvfn = (PVFN) GetProcAddress(hModule, "Function1");
  pvfn(2);
  FreeLibrary(hModule);
}
就我个人感觉来说,C语言中定义函数指针类型的typedef代码的语法有些晦涩,而同样的代码在Object Pascal中却非常易懂:
type PVFN = Function (para : Integer) : Integer;
var
  fn : PVFN;
    //也可以直接在此处定义,如:fn : function (para:Integer):Integer;
  hm : HMODULE;
begin
  hm := LoadLibrary('test.dll');
  fn := GetProcAddress(hm, 'Function1');
  fn(2);
  FreeLibrary(hm);
end;  
delphi指针大全 大家都认为,C语言之所以强大,以及其自由性,很大部分体现在其灵活的指针运用上。因此,说指针是C语言的灵魂,一点都不为过。同时,这种说法也让很多人 产生误解,似乎只有C语言的指针才能算指针。Basic不支持指针,在此不论。其实,Pascal语言本身也是支持指针的。从最初的Pascal发展至今 的Object Pascal,可以说在指针运用上,丝毫不会逊色于C语言的指针。 立即下载

相关推荐

MFC工具栏增加EditBox和Button

1. 在资源视图中增加EditBox, Button控件,ID分别为ID_EDIT_SEED, ID_BTN_SEED 2. 在CMainFrame中增加成员变量 CMFCToolBarEditBoxButton *m_editSeed; CMFCToolBarButton *m_btnSeed; 3. 在CMainFrame::OnCreate中创建控件 m_editSeed = new CMFCToolBarEditBoxButton(ID_EDIT_SEED, GetCmdMgr()-&.

学习是为了探索这个世界的本质 802

delphi指针

浅谈Object Pascal的指针 大家都认为,C语言之所以强大,以及其自由性,很大部分体现在其灵活的指针运用上。因此,说指针是C语言的灵魂,一点都不为过。同时,这种说法也让很多人 产生误解,似乎只有C语言的指针才能算指针。Basic不支持指针,在此不论。其实,Pascal语言本身也是支持指针的。从最初的Pascal发展至今 的Object Pascal,可以说在指针运用上,丝毫不会逊...

231

本地部署llama3Chinese

这通常意味着你的构建环境可能不完整或者没有正确配置。通常是由 Visual Studio 的 C++ 工具提供的。(大模型对错误的解析)错误信息表明在尝试构建一个项目时,在 Windows 上,

m0_49343639的博客 1432

Delphi下指针使用总结

====================================================== 注:本文源代码点此下载 ====================================================== 由于最近公司太忙,好久没有更新我的blog了。原来想着写写关于hook驱动的文章,可是最后想想好久已经没有做驱动的东西了,怕写出来有错误,于是作罢

javazhuanzai的专栏 360

芯片硅前验证技术与驱动工程师实战指南

硅前验证是芯片开发流程中的关键环节,通过pre-silicon simulation等技术手段在流片前验证设计正确性。其核心技术包括软件仿真、FPGA原型验证和硬件仿真器解决方案,涉及Linux驱动开发、芯片架构理解和波形分析等核心技能。作为连接芯片设计与系统集成的桥梁,硅前验证能早期发现设计缺陷,节省数百万美元流片成本。以Cadence Palladium为代表的硬件仿真器,通过专用服务器系统实现比纯软件方案快100-1000倍的仿真速度,为驱动工程师提供完整的外设模型验证环境。掌握硅前验证技术可显著提升

weixin_42522857的博客 323

从零开始掌握Simscape Multibody:机械系统建模与仿真入门

本文为机械系统建模与仿真入门指南,详细介绍了如何从零开始使用Simscape Multibody。通过构建曲柄摇块机构的实战案例,系统讲解了刚体、关节、约束等核心模块的使用,以及模型验证、参数化设计和多领域系统集成等进阶技巧,帮助工程师和学生高效进行虚拟设计与测试。

weixin_29229261的博客 310

Delphi的指针

Pointers are like jumps, leading wildly from one part of the data structure to another. Their introduction into high-level languages has been a step backwards from which we may never recover.— Anthony Hoare 对指针可能有最让人误解和惧怕的数据类型,因此很多程序员喜欢躲避他们. 但是指针很重要.即使..

zp19860529的博客 2506

接地设计的本质:按电流类型选择物理连接方式

接地是电子系统中实现电位参考、噪声抑制与安全保护的基础技术,其核心原理在于为不同性质的电流提供可控的低阻抗返回路径。从直流到GHz频段,电流的频率特性、能量等级和持续时间决定了接地的物理实现方式——工频安全电流依赖低电阻导体,高频噪声需低感平面或磁珠衰减,ESD脉冲要求受控泄放电阻,浪涌能量则必须通过独立短路径导入大地。这种‘目的决定方式’的设计逻辑,直接关联EMC合规性、信号完整性与系统可靠性。本文聚焦PCB级与设备级工程实践,详解安全地、功能地、浪涌地与静电地的判据差异及六种典型连接策略,帮助硬件工程师

weixin_36369848的博客 260

Delphi 指针大全

Delphi 指针大全 - 1 - 目 录 1 DELPHI 的指针-引用.................................................................................- 1 - 2 delphi 的“引用/值”模型..............................................

weixin_33726318的博客 416

解决 maven编译项目-Fatal error compiling: 无效的目标发行版: 21 -> [Help 1]

惊奇的发现,maven没有用环境变量中设置好的JAVA_HOME目录,至此发现错误原因,原来执行java -version默认使用系统环境变量JAVA_HOME,而maven优先使用了windows的用户变量JAVA_HOME(这里之前忘记修改,仍然指向java8路径),修改用户变量JAVA_HOME指向java21或删除该用户变量JAVA_HOME(如无它用)后即可。打开maven包所在的目录,在maven的配置文件 mvn.cmd 文件中,设置java_home的目录。

litlit023的专栏 1799

游戏客户端开发工程师笔试题

1、已知有一个关键字序列:(27,23,34,14,1,55, 20,19,85,83,10,68)散列存储在一个哈希表中,若散列函数为H(key)=key%7,并采用链地址法来解决冲突,则在等概率情况下查找成功的平均查找长度为(4、出现死锁时,除了可以采用资源剥夺的方法解决死锁问题外,还可以使用的方法是()是被限定只能在表的一端进行插入运算,在另一端进行删除运算的线性表.5、大端模式,是指数据的高字节保存在内存的(3、在二叉查找树中, 最好情况下复杂度为。)地址中,而数据的低字节保存在内存的(

博客 1873
上一篇: 100个最佳Linux站点(推荐)
下一篇: [收藏]C语言测试:想成为嵌入式程序员应知道的0x10个基本问题
Mr-Chen
博客等级 码龄24年 57粉丝 31原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值