問題一:
為什麼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分
為什麼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分
http://expert.csdn.net/Expert/topic/2408/2408699.xml?temp=.1095545
AllocMem() FreeMem()
GlobalAlloc() GlobalFree()
GetMem() FreeMem()
New() Dispose()
StrAlloc() StrDispose()
StrNew() StrDispose()
VirtualAlloc() VirtualFree()如果用了PChar就应该用上面的函数来手工分配。
那如下: 是自動分配還是??
var P: pchar;
begin
p := 'abcdefg';
showmessage(StrPas(p));
p := 'hijk';
showmessage(StrPas(p));
end;
如果你知道, 不如就說出來!!!
不要讓我底氣不足! 又覺得你高深莫測!!
正如前面所提到的,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结束
的字符串的过程和函数。
>>我说了我的解释,而你又拿出那种反例,如果我再解释,你一定又会拿出反例。
我提出反例, 你如果能證明我理解是錯的, 那才證明你的說法沒問題啊!!!!!
我想不通你不讓別人反問你的命題的話??? 那還叫討論嗎?? 那命題就絕對對嗎??
如果我想掩饰我的無知, 我不會提問題, 也不會反驳你的, 因為, 我問了, 就證明我不了解;
反而是你, 老是要我看書! 自己去想??? 你覺得你這種態度是負責的態度嗎??
說句實話, 我比較討厭動不動就說:這個你還不懂啊?? 回家去看書吧這類的話??你以為你就知道很多??而且, 你的例子也不夠解決我上面的提問!!!
想要反駁一個人或問題, 你要根據提問來啊, 貼了一堆, 你認為能回答我的問題嗎??回到技術上的認識, 你的例子也許沒錯, 只能說明手動分配的操作沒錯,但我估計, 你的理解是錯的, 不敢肯定, 等你回答我下面的問題後再說!
那你說明要手動分配, 我做了個沒有手動分配的, 錯在那, 你要指出來啊??
>>个东西。而且是互相有联系的,又独立存在的,解释PChar同时会解释ShortString以及
>>AnsiString标准串。
我不要你解釋那麼多, 就要你證明:
你說必須手動給 Pchar 分配內存, 那我的例子錯在那?? 這麼簡單的問題, 你不會還:
>>叫我如何解释?
解釋不了吧??我沒有說我的例子沒問題, 沒錯, 我只想知道, 如果有錯, 錯在那?? 會引致什麼後果??>>PChar的内存不是由ObjectPascal自动产生和管理的,要用Object Pascal的内存管理函数来
>>为PChar所指向的内存进行分配。
手動??自動??
用技術來說明你的正确, 不要用詞上爭論!!!
我真的還不是很清楚 "討論" 與 "爭論" 的語義區別!!>>等您不正确初始化,突然弹出一个对话框的时候我不说什么。
你認為我上面的例子會嗎??
不要轉移! 不要說些不着邊際的話!! 如果你不懂, 你可以承認啊!! 不要說些, 無法定性的話!!! >>答案就在书里面。看不看随便你。
我并沒有說我的就是對的, 只是, 你說我的做法有問題, 然後說答案在書里???你覺得這樣就叫答案??
還有, 我也不想做過多非技術的爭論! 如果你再留言, 請給點技術上的, 回到你上面貼的書的"東西", 我再次說明, 那不足夠解釋你的論點!!!
再說一點, 在我日常的與硬件通訊的開發中, 大量使用到 Pchar, 在.net 到來前, 我想 Pchar還是很有意思的!!!
我也請你回去再好好看看書, 好好去了解一下内存处理机制, 再來這裹回答問題!!
你給我的感覺, 避重就輕, 老是叫你看書?? 如果很簡單的問題, 你又為什麼不給出一個解釋, 讓人服你, 好過打了這麼多無聊的字!!?????
你的解釋 我 保留的 接受!!>>如果书本上给出了合理的使用方法,为什么不用?
>>StrAlloc申请StrDispose结束,StrNew来copy,为什么不用?
>>要用为什么来证明吗?
上面都是你強加給我的!!>>我写这么多字,其实就是让你有个好的自学态度。
憑你是上面的回復, 我覺得還不夠讓我覺得 在人生, 做人的態度上要向你學習!!!
有什麼好的"自學態度", 你自己留著吧對我, 很簡單, 我只接受技術上的
{
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!";
}而且不仅仅是指针串,就是整型的,浮点型的也一样!你还需要什么解释?你还有什么不明白,放马过来吧。
如上面的, 我承認, 用 Pchar 先分配內存這個概念是正确的!!
技術上的東西, 如果是我錯了, 我不會蠢到 還要 "爭論" 與 "討論" 個不休;我也看過一些討論與評論! 也可作些小代碼來測試!! 我有空時會試試, 有什麼新的看法我會提出來!!本來打了一堆字, 覺得沒意思, 刪掉了!! 其實無它, 就是下面一句:
就算你說對了一個技術問題, 也不能掩饰我對這種目空一切, 自以為是的家伙的討厭!!!
好不容易找到个问题就不可收拾了, 连带要教人家做人的道理!! 电脑的运行原理..中国与日本的关系....地球的起源...
也许你的表现机会太少了吧????
如果个个都有你这种表现欲, 那Csdn的服务器负担就重了!!!硬盘又要买多几百个了????
如果你想表达这些, 可以到专门的灌水区去, 会有更多的人附和你的!!!
连带:
>>甚至,女孩子为什么蹲着撒尿???? :〉
只能说明你的无聊与无知!!!
begin
p := '1111';
ShowMessage(IntToStr(Integer(p));
p := '2222';
ShowMessage(IntToStr(Integer(p));
end;
连续运行多次?? 你看到了什么???
你懂"野指针"的意思吗?? 不要以为只有你懂 C++!!!继续用继续证明你自己, 或多回答别人几个问题吧!!!
精明的编程者听说了此道,并遵循它;平庸的编程者听说了此道,并寻觅它;愚蠢的编程者听说了此道,却嘲笑它。 要不是因为有嘲笑,道也就不复存在了。 最高的声音最难被听见。前进也是一种倒退。大器晚成。即使是一个完美的程序也仍然会有隐患。 道深藏不露,难于理解。===============================================================================哈哈,我不知道你要干什么。我实在受不了你的代码了…… PFPF。结束吧。
但, 当你从中引出你的理解,判断, 却经常是错的!!!我以很认真负责的态度再次声明, 我第一次举的例子:
var P: pchar;
begin
p := 'abcdefg';
showmessage(StrPas(p));
p := 'hijk';
showmessage(StrPas(p));
end;根本没有问题! 而你的回答判断:
>>是的,没有错。当然能显示,因为你的内存是空的。
>>而且PChar的理论空间非常大!
>>不过它没有申请连续的内存空间,因为它是指针串,所有地址都是随机的。
>>而且你也没有用StrNew复制给Pchar,而' '之间所表示的是字符串类型。
>>如果有其他的操作访问了它所占有的地址,自然就会有AV错误!
是错的!!! 我的例子, 永远不会出现你说的 非法访问!!!至于原因, 如果你稍微有点水平的话, 你看我后来的例子就可, 如果看不懂, 不明白, 你看本贴的第一个留言中的评述, 其实道理是一样的!!!
如果你还不懂, 那我建议你真的还要去看看书了, 你确实看书看得太少!!!
万一, 你还不懂, 我当然可以解释给你听, 但, 那就比较麻烦了,
我得从 宇宙的起源开始, 到地球的诞生, 但人类的进化, 到计算机原理...
如果我的第一个例子是用C++实现, 我直觉就会知道可能错了!!
但delphi却与vc中有点细微的差别!!
你知道吗???
我再次声明, 我是以认真, 负责的态度来 讨论 以上的技术问题的, 而且, 我再次表达, 你认为的结论是错的!!然后, 我觉得,你的思路有问题, 或者说你还不能真正找到解决问题的方法, 针对别人的提问, 回答不知所云, 指东打西, 也许, 你去做推销的工作比较适合!!
如果, 你要发言, 我建议你先从技术上开始, 不要老是发表做人道理这些无聊的东西!!!等你真的明白这些做人的道理后, 再来教别人不迟啊!!!
爱翔的确有点过火了,太激动,以后改之.
通篇就看到
reallike(认真学习Cpp用Cpp考虑delphi )
的高論﹐不過我沒有看懂他的話和問題到底有多少聯系整個一故弄玄虛的家伙﹐另外還有點自欺欺人的味道﹐其實不懂說出來沒有什么但是你老是顛來倒去說一句話﹐會讓人懷疑你智商有問題的。哎﹗這號人。。