请问在Object Pascal中@操作符和Pointer有什么区别?
例如:
var
m, n: Integer;
s: String;
begin
s := 'abc';
m := Integer(@s);
n := Integer(Pointer(s));
end;
哪个才能代表s的真实地址?
例如:
var
m, n: Integer;
s: String;
begin
s := 'abc';
m := Integer(@s);
n := Integer(Pointer(s));
end;
哪个才能代表s的真实地址?
解决方案 »
- delphi 如何关闭窗体
- 死机后Delphi不能使用,重装后也不能用,请帮忙
- 日期型数据如何显示的时候只为年月,不要日.
- 一个简单的问题?
- 怎样获得delphi编译之后的版本号,在线急
- delet键,和backspace键 的ANSCII码是多少?在线急等
- fastreport的横向怎么出不来。是怎么回事!
- 关于软件加密问题,求算法程序或算法的大致思路,谢谢
- ◆◆◆晕,DELPHI的Undo功能极为不爽◆◆◆谁知道TRW(著名的调试跟踪软件)作者朱南灏开发的那个叫Clip什么来着,是剪贴板工具软件!!!
- 如何使MDI听话
- 高难度问题--ReportBuilder的横打问题!!!高分相送!!!
- 请各位帮帮忙,急急。。。!!!!
m := Integer(@s); 改为 m := Integer(@s[1]); 则m就是s的地址。
那么我们可以把s:string;这样解释,s在定义时确实是一个指针,通过他delphi可以非常容易的访问字符串'abc',但s却不是指向'abc'的首地址的(否则岂不是与pchar类型一致了),s指向的是一个string类型的对象,s是对该对象的引用。
那么按这样推理,Pointer(s)是将string类型的“指针”s转换成无类型指针了,那么就是n=s,n与s的差别只是在类型上。
@s就不同,他取得的是s的地址,所以(m^)=s
但不论是m、n、s甚至本身都不是指向'abc'的指针,(根据前面的描述s是一个字符串对象的指针),只有当@s[1]时,你才真正取到了串'abc'的首地址
borland在编译器里优化了string的用法(string不是一个真正的对象,他的一些功能是不能用delphi pascal来描述的),这使得string用起来就像普通的字符串那样,只是有点神奇,事实上不是这样,看看微软的cstring类的源码,ctring的用法与delphi的string的用法一样好用,但cstring是真正的对象,他完全可以用c++实现,应为c++有操作符重载等等不可思议的魔法个人意见 仅供参考 恳请大家批评指正
1.使用操作符号@或函数Addr
2.直接对指针变量进行类型转换var
m, n: Integer;
s: String; //OP中的字串类型和普通简单类型不同,在内存的存在方式类似于对象引用模型,实际的字串内容放在堆上,而引用指针放在栈上,至于引用计数是否存在要看字串类型了(堆上字串内容也要依类型而定)。执行到这里的时候仅仅是在栈上开辟了一个4字节的指针空间,但内容是无意义的
begin
s := 'abc'; //字串使用的是Copy-On-Write技术。这个时候才在堆上分配内存并将实际内容放进去,同时将栈上无意义的字串指针的内容设置为堆上物理字串的首地址
//在进行其他关于s的操作的时候会对引用计数进行不断的改变(要看字串类型),同时也可能会派生其他的物理字串(在堆上)
m := Integer(@s); //这里是利用方法一进行去地址操作,取的是字串中指针部分在栈上的地址,也可以使用函数Addr代替操作符@
n := Integer(Pointer(s)); //由于字串变量本身就是一个栈上的指针,所以里面的内容实际上存放的就是实际物理字串在堆空间中的首地址----一个指针,所以这里仅仅是进行安全的强制类型转换----这里也是取地址的一种方式,直接对指针变量内容(一个指针)进行类型转换后取得
end;
Pointer相当于C语言的 (void *)
n是用POINTER进行强制转换,由于S是STRING型,S中存放的是指向字符串存放区的首地址,因此N中存放的是指向字符串存放区的首地址