请问在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的真实地址?
解决方案 »
- 使用Qreport控件做打印报表时,为什么会出先打印出来的和预览的不一致
- 请问,窗体的属性borderstyle为bsnone的时候。怎么能让窗体上下,左右拉伸呢。
- 如何锁定DBGrid的列
- 在delphi中怎样制作动态菜单,要显示的菜单项从文件中获取??
- 在DELPHI中如何实现获取PARADOX表结构定义的列表?
- 请教对法律有研究的朋友有关违约金的问题
- 我得到了Msg.LParam,并且知道它发过来的是一串字符,请问怎样将Msg.LParam转成字符串显示出来?
- ADO 组件查询
- 应该是nimada惹的祸,100分求解
- To:tikkypeng(一两狂死郎之天衣有缝) 帮我看看这个问题好吗? http://www.csdn.net/expert/topic/357/357383.shtm(无内容)
- 高难度问题--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中存放的是指向字符串存放区的首地址