请问在Object Pascal中@操作符和Pointer有什么区别?
例如:
var
  m, n: Integer;
  s: String;
begin
  s := 'abc';
  m := Integer(@s);
  n := Integer(Pointer(s));
end;
哪个才能代表s的真实地址?

解决方案 »

  1.   

    @是取地址。s其实是指针,@s取s变量的地址。n := Integer(Pointer(s)); n是s中存放地址的值
      

  2.   

    我认为 n 是s的真实地址,m 是s地址的地址。 
      m := Integer(@s); 改为 m := Integer(@s[1]); 则m就是s的地址。
      

  3.   

    jacky_shen(jacky) 说的很明了了
      

  4.   

    Pointer(s)是强制类型转换啊,即将s的类型:String转换为Pointer型,事实上取任何变量的地址都该使用@操作符,但楼主的描述含义不清。到底是要s的地址还是要字符串'abc'的手地址?string类型其实是一个很复杂的类型,你可以把他当作封装了所有字符串操作的类来看,事实上在vc中与delphi同样好用的cstring就是一个类。
    那么我们可以把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++有操作符重载等等不可思议的魔法个人意见 仅供参考 恳请大家批评指正
      

  5.   

    对了!@是取地址,pointer是强制类型转换。概念都不一样。
      

  6.   

    这个本不该成为什么问题的!OP中取地址只有两中方式
    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;
      

  7.   

    @相当于C语言的 &
    Pointer相当于C语言的 (void *)
      

  8.   

    m是s变量的首地址。
    n是用POINTER进行强制转换,由于S是STRING型,S中存放的是指向字符串存放区的首地址,因此N中存放的是指向字符串存放区的首地址