当前位置:首页
开发技术指南» 文章正文
    引言:
 

 

    摘要: 哪位大哥能告诉我将浮点型数据转化为整型的函数,手头没资料没处查,多多帮忙,谢谢 ......
    摘要: outlookbar是不是只能用在sdi或mdi中能不能在左边显示outlookbar右面显示一个类似对话筐的东西! ......


★★★一个值得研究的看似简单的古怪问题只有几行代码,大家猜猜结果是什么

program   Project2;  
   
  {$APPTYPE   CONSOLE}  
   
  uses  
      SysUtils;  
   
  var  
      ss:   string;  
      p:   pchar;  
   
  function   ShortStringAsPChar(S:ShortString):PChar;  
  var   s1:string;  
  begin  
      s1:=s;                             //将shortstring转换为string  
      Result:=pchar(s1);   {返回PChar化的字符串}  
  end   ;  
   
  begin  
      ss   :=   hello;  
      p   :=   ShortStringAsPChar(ss);      
      ss   :=   1;  
      ss   :=   2;  
      writeln(p);  
      readln;  
  end.  
  请大家先猜一下输出结果再看下面的内容!  
  ==================================================================================  
  begin  
      ss   :=   hello;  
      p   :=   ShortStringAsPChar(ss);  
      ss   :=   s;  
      ss   :=   ;  
      writeln(p);  
      readln;  
  end.会是什么输出结果?为什么?  
   
  begin  
      ss   :=   hello;  
      p   :=   PChar(ss);    
      ss   :=   1;  
      ss   :=   2;  
      writeln(p);  
      readln;  
  end.会是什么输出结果?为什么?  
   
  begin  
      ss   :=   hello;  
      p   :=   PChar(ss);  
      ss   :=   ;  
      ss   :=   ddd;  
      writeln(p);  
      readln;  
  end.会是什么输出结果?为什么?  
   
  前几天我看《Delphi5   开发人员指南》介绍一个ShortStringAsPChar函数,下面为原文([   ]内的):  
  [  
  ShortStringAsPChar()函数是在STRUTILS.PAS单元中定义的。    
  func   function   ShortStringAsPChar(var   S:ShortString):PChar;  
  {这函数能使一个字符串以null结尾,这样就能传递给需要PChar类型参数的Win32   API函数,如果字符串超过254个字符,多出的部分将被截掉}  
  begin  
  if   Length(S)=High(S)   then   Dec(S[0]);   {如果S太长,就截取一部分}  
  S[Ord(Length(S))+1]:=#0;   {把null加到字符串的最后}  
  Result:=@S[1];   {返回PChar化的字符串}  
  end   ;  
  ]  
  我在使用的时候发现在STRUTILS.PAS这个单元中根本没有这个函数!并且用上面这个函数有可能得到不正确的答案,于是我就写了下面这个函数:  
  function   ShortStringAsPChar(S:ShortString):PChar;  
  var   s1:string;  
  begin  
      s1:=s;                           //将shortstring转换为string  
      Result:=pchar(s1);   {返回PChar化的字符串}  
  end   ;  
  由于我对delphi的ansistring、pchar、shortstring什么的结构及他们之间的乱七八糟的转换不了解,于是我就写信问一个朋友,让它看看这个函数是否有毛病。他的答复是“ShortStringAsPChar函数有问题,你运行一下上面的代码看看会有什么结果”就是最上面的那段程序了。  
  我的思路是这样的:  
  ss为AnsiString型。  
  ss   :=   hello;时,ss指向hello所在的地址,hello的引用记数为1。  
  p   :=   ShortStringAsPChar(ss);时,函数ShortStringAsPChar(S:ShortString):PChar;开始执行,  
  因为参数s为值参,所以AnsiString型的hello(ss的)被复制到一块新的内存中,又因为S为ShortString型,因此要对AnsiString型的hello进行类型转换,所以AnsiString型的hello结构中的大小标记、引用记数及最后面的null都被去掉了,最后,将shortstring型的hello(s的)的地址赋给S   。  
  s1:=s;时,hello(s的)再次被复制到一块新的内存中并且转换成ansistring类型,最后将地址赋给s1。(hello变为s1的了)  
  Result:=pchar(s1);时,Result和s1指向同一块内存。然后将其赋给p。(P指向s1的hello)    
  ss   :=   1;时,hello(SS的)所在的那块内存被释放,   1被储存在新的内存块中,ss指向   1所在的新地址。  
  ss   :=   2;时,1所在的那块内存被释放,   2被储存在新的内存块中,ss指向   2所在的新地址。  
  writeln(p);时,由于hello(S1的)未受到上面ss重新赋值的影响,所以应输出:hello。  
  然而,输出的结果却是$      
  如果将ss   :=   1;或ss   :=   2;去掉,则输出为2或1,如果两个都去掉则输出为hello。怪哉!  
  想了半天突然发现既然是ShortStringAsPChar那么ss就应该是ShortString型,于是将ss声明为  
  var   ss:string[5];   运行上面的程序,输出结果为hello,不在受ss被重新赋值的影响了。问题看似解决了,可是转念又一想,为什么将ss声明为string类型就不行呢?  
  我是菜鸟,想了好久也想不出来,只好来请教各位了,希望各位老师不惜赐教!谢谢,谢谢了!我要崩溃了!!!!!!!  
  最好能给我讲一讲delphi是怎样在这些类型之间进行转换的!  
 

NO.1   作者: wangwpf

你够细心的,佩服,不过我不清楚,帮你UP,我也希望知道答案!

NO.2   作者: halfdream

上面罗里巴索一大堆。。。。  
  我想应该很简单的。。。  
  将一个STRING转成PCHAR类型,  
  你想想会丢掉什么信息?  
  1,字符长度,这个没有关系,PCHAR空字符结尾。  
  2,引用计数,这往往是被人忽略的,  
  当你在一个函数体里使用了STRING,并把它转变成PCHAR类型传出来,  
  这个过程会发生这样事情:  
  1,函数体的STRING,它的内存在堆中分配的,这不用担心。  
  2,一个指针指向这块内存。这也没有问题。  
  3,函数调用完成,内部使用的string完全使命,就是说没有string类型再引用  
        那块内存。这块内存被释放。  
  4,传出去的指针继续指着那块内存,运气好的话,这块释放的内存还比较完好。。。  
   
  为了防止没有引用的内存块释放,  
  三个办法。  
  一,让它的引用计数加一,  
  二,还是老实点,用STRING类型把参数传出来。  
  三,函数内手工分配这个内存,不使用STRING的引用。  
   
   
   
   
   
 

NO.3   作者: youngwhz

楼主的叙述太罗嗦了,没有仔细看——  
  不过在第一段程序中存在隐患:  
  函数的参数是S:ShortString为传值参数,而  
  s1:string是函数内部的局部函数,函数的  
  返回值又是返回s1的地址pchar(s1),这样返回的  
  地址不安全,因为s1在函数结束后是释放掉的,  
  以后这段地址可能做为它用!!  
 

NO.4   作者: rustle

看这个  
  function   GetAddr(I:   Integer):pointer;  
  begin  
      result   :=   @i;  
  end;  
   
  他们的两个问题是一样的

NO.5   作者: myling

这就好了:-)  
   
  function   ShortStringAsPChar(S:ShortString):PChar;  
  var   s1:string;  
            p1:   pchar;  
  begin  
      s1:=s;  
      P1:=StrAlloc(64*SizeOf(Char));  
      StrPCopy(P1,ss);                            
      Result:=p1;    
  end   ;

NO.6   作者: myling

StrPCopy(P1,s1);//哈哈。写错了,应该这样

NO.7   作者: myling

为什么将ss声明为string类型就不行呢?  
   
  ----------------------------------------------  
  正如halfdream(哈欠)所说,PChar变量需要人工分配和释放存放字符串的内存。  
   
  其实我上面的代码还不完善,还应该将他释放掉,但是因为你想把函数的返回值传出来  
   
  所以不能释放,哈哈哈,就交给编译器处理吧  
 

NO.8   作者: neoli

乱七八糟,看不下去。  
  不过还是帮你up!!!!!!!111


 ·crosstab,死了    »显示摘要«
    摘要: 我想做下面的dw, 科室 优秀票数 比例 良好票数 比例 一般票 比例 办公室 1 25% 2 50% 1 25 系办 2 50% 2 50% 0 0 数据库的数据如下,即一张票投给某个科室 科室 票类 票数 办公室 优秀 1 系办 一般 2 . . . . . . 当crosstab一个value时好办,在加一个比例,exprssion写 count(票类 for crosstab) ......
» 本期热门文章:

©2000-2007 All Rights Reserved. 最佳浏览:1024X768 MSIE