問題一:
為什麼delphi help中的代碼編繹後運行出錯, 如:
uses SysUtils;
const
  S: PChar = 'A fUnNy StRiNg'
begin
  Canvas.TextOut(5, 10, string(StrLower(S)) + ' ' +   string(StrUpper(S)));
end;回答:
windindance(风舞轻扬)   --   50分
 
S:= 'A fUnNy StRiNg'; 
这句话的含义是: 
把一个字符串常量'A fUnNy StRiNg'的地址赋给S。 
这里这个字符串常量不是动态分配给S的,而是在程序 
启动的时候在堆栈中预先分配好的,所以说是个字符串 
常量。这个常量的定义跟你定义S为变量还是常量没有 
关系。 而StrLower函数需要对传入的字符串直接做修改,(由于不能对常量进行修改),所以会报错。DWGZ(我不要分, 我讨厌分,谁给我分我跟他急)  --   50分procedure TForm1.Button1Click(Sender: TObject);
var
  P1, P2: PChar;
begin
  case RadioGroup1.ItemIndex of
    0:
      begin
        P1 := 'Hello';  //字符串常量, 将出错
      end;
    1:
      begin
        P1 := StrAlloc(10 * SizeOf(Char));
        StrPCopy(P1, 'Hello');
      end;
  end;
  P2 := StrNew(P1);
  P2 := StrUpper(P1);
  ShowMessage(P2);
end;
  
回答還有看不懂上面代碼的人的提問      --   50分 

解决方案 »

  1.   

    注: 原貼:
    http://expert.csdn.net/Expert/topic/2408/2408699.xml?temp=.1095545
      

  2.   

    请注意,如果你用了Pchar一定要对内存进行手工处理。这个不是Bug而是你对PChar使用不当!请你看看delphi开发人员指南对PChar的介绍。我的笔记:用string是会自动分配空间的,而PChar是要手动分配的。好像我的笔记上是这么记的(手工输入中……):在大多数情况下AnsiString类型能被用成PChar,应该尽可能的用AnsiString因为它对字符内存管理是自动的,极大的减少了应用程序中内存混乱的错误代码,因此,要尽可能的避免使用PChar类型以及对它相关的人工分配内存如下:内存分配函数        内存释放函数
    AllocMem()          FreeMem()
    GlobalAlloc()       GlobalFree()
    GetMem()            FreeMem()
    New()               Dispose()
    StrAlloc()          StrDispose()
    StrNew()            StrDispose()
    VirtualAlloc()      VirtualFree()如果用了PChar就应该用上面的函数来手工分配。
      

  3.   

    如果你不初始化,必定有AV错误出现。你还是考虑考虑吧。delphi还有多少你不知道的…… 这种问题看书就应该知道……
      

  4.   

    >>用string是会自动分配空间的,而PChar是要手动分配的。
    那如下: 是自動分配還是??
    var P: pchar;
    begin
      p := 'abcdefg';
      showmessage(StrPas(p));
      p := 'hijk';
      showmessage(StrPas(p));
    end;
      

  5.   

    唉…… 那你就自己去想吧。荀子《劝学》告诉我:吾尝终日而思矣,不如须臾之所学也。你研究这么多,还不如看一点delphi开发人员指南里面的一章。不跟你说了www.playicq.com就有电子版……
      

  6.   

    >>唉…… 那你就自己去想吧。
    如果你知道, 不如就說出來!!! 
    不要讓我底氣不足! 又覺得你高深莫測!!
      

  7.   

    PChar 指向null结束的Char字符串的指针,类似于C的char * 或lpstr类型。你为什么不自己去看书?我说的那些是从我的角度片面的看待而且加了我的主观想法看法。不是第一手资料。我说了我的解释,而你又拿出那种反例,如果我再解释,你一定又会拿出反例。叫我如何解释?而这些书上都有系统的地解释而且是图文的。我实在是不明白。你为什么不看。就像别人描述大象是什么样的,总是不全面……而你自己去看有什么坏?而且你还可以了解所有的字符串类型的机理。为什么会有Pchar这个东西。而且是互相有联系的,又独立存在的,解释PChar同时会解释ShortString以及AnsiString标准串。
      

  8.   

    如下节选一节,其余的,还是自己去看……4.以null结束的字符串
    正如前面所提到的,Delphi有三种不同的以null结束的字符串类型:PChar、PAnsiChar和
    PWideChar。它们都是由Delphi的三种不同字符组成的。这三种类型在总体上跟PChar是一致的。
    PChar之所以保留是为了跟Delphi1.0和Win32API兼容,而它们需要使用以null结束的字符串,PChar
    被定义成一个指向以null(零)结束的字符串指针(如果对指针的概念不熟悉,
    请继续读下去,在本章的后面要详细地介绍)。与AnsiString和WideString类
    型不同,PChar的内存不是由ObjectPascal自动产生和管理的,要用Object
    Pascal的内存管理函数来为PChar所指向的内存进行分配。PChar字符串的
    理论最大长度是4GB,PChar变量在内存中的分布见图2-3。提示在大多数情况下,AnsiString类型能被用成PChar,应该尽可能地使用AnsiString,因为它
    对字符串内存的管理是自动,极大地减少了应用程序中内存混乱的错误代码,因此,要尽可能
    地避免用PChar类型以及对它相应进行人工分配内存。
    正如在前面所提到的,PChar变量需要人工分配和释放存放字符串的内存。通常,用StrAlloc()函
    数为PChar缓冲区分配内存,但是其他几种函数也能用来为PChar类型分配函数,包括AllocMem()、
    GetMem()、StrNew()和VirtualAlloc()API函数。这些函数有相应的释放内存的函数。表2-6列出了几个
    分配内存的函数以及它们相应的释放内存的函数。
    表2-6内存分配和释放函数
    内存分配函数内存释放函数
    AllocMem()FreeMem()
    GlobalAlloc()GlobalFree()
    GetMem()FreeMem()
    New()Dispose()
    StrAlloc()StrDispose()
    StrNew()StrDispose()
    VirtualAlloc()VirtualFree()
    下面的例子演示了使用PChar和string类型时的内存分配技术:
    var
    P1,P2:PChar;
    S1,S2:string;
    begin
    P1:=StrAlloc(64*SizeOf(Char));//P1指向一个分配了63个字符的缓冲区
    StrPCopy(P1,'Delphi5');//复制一组字母到P1
    S1:='Developer'sGuide';//在S1中放几个字母
    P2:=StrNew(PChar(S1));//P2指向S1的备份
    StrCat(P1,P2);//连接P1和P2
    S2:=P1;//S2现在为'Delphi5Developer'sGuide’
    StrDispose(P1);//清除P1和P2的缓冲区。
    StrDispose(P2);
    end.
    首先注意到,在为P1分配内存时StrAlloc()中用到的SizeOf(char)。要记住在以后Delphi版本中一个
    字符的长度要从一个字节变成两个字节,因此,不能假定一个字符的长度为一个字节,Sizeof()就保
    证了不管字符长度是多少都能正确地分配内存。
    StrCat()用来连接两个PChar字符串。注意,这里不能像对长字符串和ShortString类型那样用+运算
    符来连接两个字符串。
    StrNew()函数用来把字符串S1中的值拷贝到P2中,使用这个函数要小心,要避免出现内存被覆盖
    的错误,因为StrNew()函数只为字符串分配足够但不浪费的内存,请看下面的例子:
    var
    P1,P2:PChar;
    begin
    P1:=StrNew(‘Hello’);//只分配够P1用的内存
    P2:=StrNew(‘World’);//只分配够P2用的内存
    StrCat(P1,P2);//小心:内存出现混乱了!
    .
    .
    .
    end;
    提示和其他字符串类型一样,ObjectPascal也为操作PChar类型提供了一些操作函数和过程,
    请在Delphi的联机帮助“String-handingroutines(null-terminated)”。
    另外,还可以在本书附带的CD-ROM的\Source\Utils目录中的StrUtils中找到更多的针对以null结束
    的字符串的过程和函数。
      

  9.   

    唉,说得真费事…… 请你告诉我,研究这个PChar有意思吗?就是一个保留的兼容形式。书上解释得清清楚楚,而且前面还有。反正我就是不明白,明明看书就能懂的问题而不去看书?
      

  10.   

    首先, 我想說明, 我是以討論問題的心態來參與, 歸你所說:
    >>我说了我的解释,而你又拿出那种反例,如果我再解释,你一定又会拿出反例。
    我提出反例, 你如果能證明我理解是錯的, 那才證明你的說法沒問題啊!!!!!
    我想不通你不讓別人反問你的命題的話??? 那還叫討論嗎?? 那命題就絕對對嗎??
    如果我想掩饰我的無知, 我不會提問題, 也不會反驳你的, 因為, 我問了, 就證明我不了解;
    反而是你, 老是要我看書! 自己去想??? 你覺得你這種態度是負責的態度嗎?? 
    說句實話, 我比較討厭動不動就說:這個你還不懂啊?? 回家去看書吧這類的話??你以為你就知道很多??而且, 你的例子也不夠解決我上面的提問!!!
    想要反駁一個人或問題, 你要根據提問來啊, 貼了一堆, 你認為能回答我的問題嗎??回到技術上的認識, 你的例子也許沒錯, 只能說明手動分配的操作沒錯,但我估計, 你的理解是錯的, 不敢肯定, 等你回答我下面的問題後再說!
    那你說明要手動分配, 我做了個沒有手動分配的, 錯在那, 你要指出來啊??
      

  11.   

    >>而你自己去看有什么坏?而且你还可以了解所有的字符串类型的机理。为什么会有Pchar这
    >>个东西。而且是互相有联系的,又独立存在的,解释PChar同时会解释ShortString以及
    >>AnsiString标准串。
    我不要你解釋那麼多, 就要你證明:
    你說必須手動給 Pchar 分配內存, 那我的例子錯在那?? 這麼簡單的問題, 你不會還:
    >>叫我如何解释?
    解釋不了吧??我沒有說我的例子沒問題, 沒錯, 我只想知道, 如果有錯, 錯在那?? 會引致什麼後果??>>PChar的内存不是由ObjectPascal自动产生和管理的,要用Object Pascal的内存管理函数来
    >>为PChar所指向的内存进行分配。
    手動??自動??
      

  12.   

    唉,请让我保持沉默吧。如果哪位高手能解决他的疑问。请现身吧。>>我沒有說我的例子沒問題, 沒錯, 我只想知道, 如果有錯, 錯在那?? 會引致什麼後果??是的,没有错。当然能显示,因为你的内存是空的。而且PChar的理论空间非常大!不过它没有申请连续的内存空间,因为它是指针串,所有地址都是随机的。而且你也没有用StrNew复制给Pchar,而' '之间所表示的是字符串类型。如果有其他的操作访问了它所占有的地址,自然就会有AV错误!
      

  13.   

    >>我不反驳你的观点,那不叫讨论,那叫争论。
    用技術來說明你的正确, 不要用詞上爭論!!!
    我真的還不是很清楚 "討論" 與 "爭論" 的語義區別!!>>等您不正确初始化,突然弹出一个对话框的时候我不说什么。
    你認為我上面的例子會嗎?? 
    不要轉移! 不要說些不着邊際的話!! 如果你不懂, 你可以承認啊!! 不要說些, 無法定性的話!!!  >>答案就在书里面。看不看随便你。
    我并沒有說我的就是對的, 只是, 你說我的做法有問題, 然後說答案在書里???你覺得這樣就叫答案?? 
    還有, 我也不想做過多非技術的爭論! 如果你再留言, 請給點技術上的, 回到你上面貼的書的"東西", 我再次說明, 那不足夠解釋你的論點!!!
      

  14.   

    >>请你告诉我,研究这个PChar有意思吗?就是一个保留的兼容形式。
    再說一點, 在我日常的與硬件通訊的開發中, 大量使用到 Pchar, 在.net 到來前, 我想 Pchar還是很有意思的!!!
      

  15.   

    >>请您好好去了解一下内存处理机制。看书,学习。
    我也請你回去再好好看看書, 好好去了解一下内存处理机制, 再來這裹回答問題!!
    你給我的感覺, 避重就輕, 老是叫你看書?? 如果很簡單的問題, 你又為什麼不給出一個解釋, 讓人服你, 好過打了這麼多無聊的字!!?????
      

  16.   

    >>我沒有說我的例子沒問題, 沒錯, 我只想知道, 如果有錯, 錯在那?? 會引致什麼後果??是的,没有错。当然能显示,因为你的内存是空的。而且PChar的理论空间非常大!不过它没有申请连续的内存空间,因为它是指针串,所有地址都是随机的。而且你也没有用StrNew复制给Pchar,而' '之间所表示的是字符串类型。如果有其他的操作访问了它所占有的地址,自然就会有AV错误!这些解释你是否看了?????????????????????如果书本上给出了合理的使用方法,为什么不用?StrAlloc申请StrDispose结束,StrNew来copy,为什么不用?要用为什么来证明吗?
      

  17.   

    我写这么多字,其实就是让你有个好的自学态度。如果你有了什么问题,不是在CSDN上问出来的,而是去找参考书以及资料。而我一再的建议被你误解……好了,我要看书了。无暇和你理论……
      

  18.   

    說明一下, 我确實沒看到你的第一個解釋, 我一提交, 已經看到你的下個留言了!
    你的解釋 我 保留的 接受!!>>如果书本上给出了合理的使用方法,为什么不用?
    >>StrAlloc申请StrDispose结束,StrNew来copy,为什么不用?
    >>要用为什么来证明吗?
    上面都是你強加給我的!!>>我写这么多字,其实就是让你有个好的自学态度。
    憑你是上面的回復, 我覺得還不夠讓我覺得 在人生, 做人的態度上要向你學習!!!
    有什麼好的"自學態度", 你自己留著吧對我, 很簡單, 我只接受技術上的
      

  19.   

    使用指针变量之前必须申请内存,这个成为了一个常识性的概念了。作为C/C++的程序员,C用alloc,C++用new申请一段内存,不用问为什么。而作为用C/C++写的Api兼容,PChar这个指针串自然而然也要手工分配内存!这个问题用C解释最容易!因为delphi保留这个就是与C兼容!例如:main()
    {
      char *str;
      str = "Good";
    }
    *str表示str是一个字符型指针,即保留某个字符地址。在初始化时,str没有什么特殊的值,而在执行str = "Good"时,编译器先在目标文件的某处保留一个空间存放"Good\0"的字符串, 然后把这个字符串的第一个字母“G”的地址赋给str, 其中字符串结尾符"\0"是编译程序自动加上的,就是PChar的Null结束。 对于指针变量的使用要特别注意。上例中指针在说明前没有初始化,因此指针为随机地址,在小存储模式下使用将会有破坏机器的危险,而现在最低标准内存就是128M,相信你的更大。正确的使用办法如下: main()
    {
      char *str;
      str =(char *)malloc(20);
      str = "Good!";
    }而且不仅仅是指针串,就是整型的,浮点型的也一样!你还需要什么解释?你还有什么不明白,放马过来吧。
      

  20.   

    你看看我的名字,我就是这么写的。认真学习Cpp用Cpp考虑delphi!是的,你不是Cpp程序员,你对指针的不理解,自然会用这么个问题。我刚刚看书,看到数据结构的要申请头纪录,又是一段指针。又是一句AllocMem没有为什么。只有常识性的申请内存,然后使用指针。气不过我又上来看看。指针指针,真的就这么难理解吗?Pascal就这么个常用的指针串,就被翻来覆去的弄。还说delphi的bug,为什么不多看书充实自己???????????唉…………………………………………………………如果你不申请内存,在C/C++里面叫“野指针”!你刚才的几行代码造了一个delphi的野指针!
      

  21.   

    唉,难道这就是你需要的讨论吗??????????我和我的几个网友讨论过后,最后还是总结出一点:授之以鱼不如授之以渔。如果这次给你答案,但是下一次出现基本的问题,你是不是还来Csdn问?然后又是一番质疑,一番争论?何不去看书?我诚挚的建议,你看书,多看书之后,你的脾气态度也会改变。真的。书将是最好的朋友……
      

  22.   

    你在上面寫了很多, 反正, 技術上的, 我些有接受, 有些保留!
    如上面的, 我承認, 用 Pchar 先分配內存這個概念是正确的!!
    技術上的東西, 如果是我錯了, 我不會蠢到 還要 "爭論" 與 "討論" 個不休;我也看過一些討論與評論! 也可作些小代碼來測試!! 我有空時會試試, 有什麼新的看法我會提出來!!本來打了一堆字, 覺得沒意思, 刪掉了!! 其實無它, 就是下面一句:
    就算你說對了一個技術問題, 也不能掩饰我對這種目空一切, 自以為是的家伙的討厭!!!
      

  23.   

    还有,当你的程序出错。不要去怪编译器和IDE,甚至不要怪电脑!有的人会说:什么破电脑啊。嘻嘻。:〉首先找自身的错误。每一个程序都有bug,都有,哪怕是一行代码,也需要维护……
      

  24.   

    to reallike(认真学习Cpp用Cpp考虑delphi) :
    好不容易找到个问题就不可收拾了, 连带要教人家做人的道理!! 电脑的运行原理..中国与日本的关系....地球的起源...
    也许你的表现机会太少了吧????
    如果个个都有你这种表现欲, 那Csdn的服务器负担就重了!!!硬盘又要买多几百个了????
    如果你想表达这些, 可以到专门的灌水区去, 会有更多的人附和你的!!!
      

  25.   

    我想不通两句话就说明的问题!!! 要说多那么多屁话干吗??
    连带:
    >>甚至,女孩子为什么蹲着撒尿???? :〉
    只能说明你的无聊与无知!!!
      

  26.   

    var p: pchar;
    begin
     p := '1111';
     ShowMessage(IntToStr(Integer(p));
     p := '2222';
     ShowMessage(IntToStr(Integer(p));
    end;
    连续运行多次?? 你看到了什么???
    你懂"野指针"的意思吗?? 不要以为只有你懂 C++!!!继续用继续证明你自己, 或多回答别人几个问题吧!!!
      

  27.   

    =================================================================================
     
      精明的编程者听说了此道,并遵循它;平庸的编程者听说了此道,并寻觅它;愚蠢的编程者听说了此道,却嘲笑它。  要不是因为有嘲笑,道也就不复存在了。  最高的声音最难被听见。前进也是一种倒退。大器晚成。即使是一个完美的程序也仍然会有隐患。  道深藏不露,难于理解。===============================================================================哈哈,我不知道你要干什么。我实在受不了你的代码了…… PFPF。结束吧。
      

  28.   

    坚决抵制上Csdn来。Csdn现在是祸水阿。:〉(找个借口)我的TStream就没有好好看完……坚决抵制。不参与诸如这种类型的争论。不参加和评论这种自己不思考不翻阅资料的问题!坚决不赚取不属于自己的专家分!特此声明。
      

  29.   

    你知道吗??你引用别人的东西的时候, 大多数时候是对的, 包括你上面的转贴的书, 转贴的名言!!!
    但, 当你从中引出你的理解,判断, 却经常是错的!!!我以很认真负责的态度再次声明, 我第一次举的例子:
    var P: pchar;
    begin
      p := 'abcdefg';
      showmessage(StrPas(p));
      p := 'hijk';
      showmessage(StrPas(p));
    end;根本没有问题! 而你的回答判断:
    >>是的,没有错。当然能显示,因为你的内存是空的。
    >>而且PChar的理论空间非常大!
    >>不过它没有申请连续的内存空间,因为它是指针串,所有地址都是随机的。
    >>而且你也没有用StrNew复制给Pchar,而' '之间所表示的是字符串类型。
    >>如果有其他的操作访问了它所占有的地址,自然就会有AV错误!
    是错的!!! 我的例子, 永远不会出现你说的 非法访问!!!至于原因, 如果你稍微有点水平的话, 你看我后来的例子就可, 如果看不懂, 不明白, 你看本贴的第一个留言中的评述, 其实道理是一样的!!!
    如果你还不懂, 那我建议你真的还要去看看书了, 你确实看书看得太少!!!
    万一, 你还不懂, 我当然可以解释给你听, 但, 那就比较麻烦了, 
    我得从 宇宙的起源开始, 到地球的诞生, 但人类的进化, 到计算机原理... 
      

  30.   

    其实, 不要以为看了几本 开发指南, Thinking In XXX 就以为自己很了不起, 你又懂C++与delphi中的这些细微的区别吗???
    如果我的第一个例子是用C++实现, 我直觉就会知道可能错了!!
    但delphi却与vc中有点细微的差别!!
       你知道吗???
     
    我再次声明, 我是以认真, 负责的态度来 讨论 以上的技术问题的, 而且, 我再次表达, 你认为的结论是错的!!然后, 我觉得,你的思路有问题, 或者说你还不能真正找到解决问题的方法, 针对别人的提问, 回答不知所云, 指东打西, 也许, 你去做推销的工作比较适合!!
    如果, 你要发言, 我建议你先从技术上开始, 不要老是发表做人道理这些无聊的东西!!!等你真的明白这些做人的道理后, 再来教别人不迟啊!!!
      

  31.   

    唉。又有一个书呆子。态度是支持 aiirii(ari) 。
      

  32.   

    同意aiirii(ari) ;
    爱翔的确有点过火了,太激动,以后改之.
      

  33.   

    首先說明樓主的問題我回答不了
    通篇就看到 
     reallike(认真学习Cpp用Cpp考虑delphi )
    的高論﹐不過我沒有看懂他的話和問題到底有多少聯系整個一故弄玄虛的家伙﹐另外還有點自欺欺人的味道﹐其實不懂說出來沒有什么但是你老是顛來倒去說一句話﹐會讓人懷疑你智商有問題的。哎﹗這號人。。