社区
语言基础/算法/系统设计
帖子详情
请教各位大虾:如何判断一个字符串的最后一位是不是null(即#0)
L_Lei
2003-09-15 09:20:48
请教各位大虾:如何判断一个字符串的最后一位是不是null(即#0)
...全文
642
104
打赏
收藏
请教各位大虾:如何判断一个字符串的最后一位是不是null(即#0)
请教各位大虾:如何判断一个字符串的最后一位是不是null(即#0)
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
104 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
RamjetZhang
2003-09-19
打赏
举报
回复
0 是当然有的,这样传string(AnsiString)给windows api 的时候,把字符串第一个字的地址传过去就是了--后面的'\0'就自动传给c-style的函数了,多省事。
telossoft
2003-09-19
打赏
举报
回复
不懂汇编,佩服 Raptor(猛禽) ,我只是习惯用DELPHI,我用copymemory到一个缓冲区去分析
telossoft
2003-09-19
打赏
举报
回复
抱歉,写错一行:
定义类型:
Pint = ^integer;
telossoft
2003-09-19
打赏
举报
回复
string是一个指针,长度4个字节
string是引用记数的,它记录有其长度
string是一个指针,指向具体字符串的第一个字符
为与pchar兼容,string自动在尾后加了#0
pchar(string) = pointer(string)
有朋友要问引用记数器和其长度记录在那里了?
定义类型:
Pint = integer^;
引用记数: pointer(integer(pointer(string)) - 8)
其长度: pointer(integer(pointer(string)) - 4)
引用记数: edit1.text:= inttostr(pint(integer(pointer(string)) - 8)^);
其长度: edit2.text:= inttostr(pint(integer(pointer(string)) - 4)^);
原来DELPHI在具体字符串的前面保存了string引用记数和长度
我在找工作,有合适的告诉我: QQ:45904680
猛禽
2003-09-17
打赏
举报
回复
相关的汇编函数:
@LStrFromPChar:根据一个PChar来创建一个String的Instance
@LStrFromPCharLen:根据一个长度来创建一个String的Instance
@NewAnsiString:根据Len创建一个新的String Instance
@GetMem:分配内存
有兴趣的可以自己在CPU Windows里看:)
猛禽
2003-09-17
打赏
举报
回复
偶看了风兄的建议,看了一下汇编代码。
基本上是这样:
当新建一个String并向它赋一个串值时:
首先,计算其串长度,得nLen,以前面那个17char的例子来说,就是$11(#17)
然后,根据nLen创建一个Instance
在NewInstance时,计算所需要空间:
nSize := ( nLen + 10 ) and ( -2 ); // nLen=$11时,nSize=$1A
估计上述算法是基于:加上8Byte的nRefCnt和nLen,及最后一个#0,然后按16bit Word对齐
然后,调用GetMem分配内存,设分配的地址为pAddr
其结构如下:
strAnsi = record
unknown : Integer;
nSize : Integer;
nRefCnt : Integer; // pAddr指向这里
nLen : Integer;
szBuf : Array [0..17] of char; // 包括最后的#0所占空间
end;
然后,将Result设置为pAddr+$8(即指向szBuf)
再把nLen赋给strAnsi.nLen,把1(refCnt)赋给strAnsi.nRefCnt
好啦,分析完毕,显然:
一个String的Instance中只包括:nRefCnt,nLen,szBuf三部分,前面的nSize是分配内存时留下的,至于nSize前面一个是什么东东,偶也不知道了,应该是DELPHI内存管理用的东东,这也就是为什么nSize总是会多出来的四个byte了。
blucecat
2003-09-17
打赏
举报
回复
zjqyb(风清扬*任它溺水三千,我只取一瓢饮*)
你能不能给大家分析一下你的结论怎样从汇编里面得来的?
现在小弟正在学汇编,请多指教,在此谢过
cll007
2003-09-17
打赏
举报
回复
我是菜鸟
我喜欢以上大虾们的这种辩论
能让人深入的了解Delphi底层的东西,有益我等菜鸟的健康成长
佩服
感谢大虾们
L_Lei
2003-09-16
打赏
举报
回复
看来这个问题大家还不是都很清楚啊,建议开个网络会议,大家都可以发言参与讨论
zjqyb
2003-09-16
打赏
举报
回复
s:='My name is delphi';
strAnsi = record
nSize: Integer;//4
nRef: Integer; //4
nLength: Integer;//4
szBuf: array[0..0] of Char; //4
end;
所以应该是4+4+4+4+17+1
blucecat
2003-09-16
打赏
举报
回复
s:='My name is delphi';//17个字节
按你给的结构,占用4+4+4+17+1=30个字节,没错吧?
我这样计算s占用空间:
integer(pointer((integer(@s[1])-12))^); //应该没错吧?
为什么占用了34个字节?
FrameSniper
2003-09-16
打赏
举报
回复
To BlueCat
AnsiString类型的结构如下:
strAnsi = record
nSize: Integer;
nRef: Integer;
nLength: Integer;
szBuf: array of Char;
end;
这是我前面给出的结构示意,和你说的4+4+4+17+1的结果有什么区别吗?
FrameSniper
2003-09-16
打赏
举报
回复
To Zjqyb
应该不是这个样子吧!
blucecat
2003-09-16
打赏
举报
回复
FrameSniper:我是按你的计算方式来的,请问另外4个字节在哪去了?
blucecat
2003-09-16
打赏
举报
回复
FrameSniper:
var
s:string;
itemp:integer;
begin
s:='My name is delphi';//17个字节
itemp:=integer(pointer((integer(@s[1])-4))^); //字符串长度等于17 正确
showmessage(inttostr(itemp));
itemp:=integer(pointer((integer(@s[1])-8))^); //引用计数等于1 正确
showmessage(inttostr(itemp));
itemp:=integer(pointer((integer(@s[1])-12))^); //占用空间等于34 不正确 应该是:4+4+4+17+1=30;
showmessage(inttostr(itemp));
end;
你如何解释?
blucecat
2003-09-16
打赏
举报
回复
var
s:string;
itemp:integer;
begin
s:='My name is delphi';//17个字节
itemp:=integer(pointer((integer(@s[1])-4))^); //字符串长度等于17 正确
showmessage(inttostr(itemp));
itemp:=integer(pointer((integer(@s[1])-8))^); //引用计数等于1 正确
showmessage(inttostr(itemp));
itemp:=integer(pointer((integer(@s[1])-12))^); //占用空间等于34 不正确 应该是:4+4+4+17+1=30;
showmessage(inttostr(itemp));
end;
FrameSniper你如何解释?
zjqyb
2003-09-16
打赏
举报
回复
4+4+4+1=13
FrameSniper
2003-09-16
打赏
举报
回复
To zjqyb
请教一个问题,如果一个AnsiString的内容是1234,那么你认为实际给这个字串分配的空间是多少?
blucecat
2003-09-16
打赏
举报
回复
当然指针是占用4个字节的空间
getmem应该是给指针指定一个可操作的地址范围(内存空间)
strcopy就应该是将具体的字符串copy到这个地址范围(内存空间)里,这个地址就是指针指向的地址
所以,大家都是正确的
zjqyb
2003-09-16
打赏
举报
回复
////
var p:pchar;
s:string;
s:='12345678';
分配Refcount(4)+存放实际长度(4)+实际字符串(8)+#0(1)
是不是这样分配空间可以去问Borland
p:=Pchar(s);
简单的PChar(s)强制转换,确实是没有再重新分配内存,因为S已经分配了内存
但是如果要复制它,则要分配Length(s)+1个空间
getmem(p,Length(s)+1);
strcopy(p,pchar(s));//p结尾自动加#0;
难道这还有疑问!!!
加载更多回复(84)
C# For Unity系列之入门篇
有一定自主学习能力,跟着刘老师从“编程小白”修炼为游戏研发“
大虾
”吧!!!学习好Unity,其先决条件是一定要有稳固、扎实的编程基础!课程 《C# For Unity系列之入门篇》配套学习资料链接:...
关于
字符串
的总结
Some notes on data structure transformation in VC0.by 程佩君女侠,Vision Dengfrom http://www.csdn.netint i = 100;long l = 2001;float f=300.2;double d=12345.119;char username[]="程佩君";char temp[200];char *b
C语言面试题精粹(三)
有
一个
数组a[1000]存放0--1000;要求每隔二个数删掉
一个
数,到末尾时循环至开头继续进行,求
最后
一个
被删掉的数的原始下标位置。以7个数为例: {0,1,2,3,4,5,6,7} 0-->1-->2(删除)-->3-->4-->5(删除)-->6-->7-->0(删除),如此循环直到
最后
一个
数被删除。方法1:数组#include using namespace std;#define n
字符串
转换:wchar_t MultiByteToWideChar Unicode等
T:关于unicode,把包含中文的CString的各个char取出来Q:CString str="12ab大小";用什么方法能转变成下面的形式char ch(20);ch(1)="1";ch(2)="2";ch(3)="a";ch(4)="b";ch(5)="大";ch(6)="小";A:有点乱定义数组应该用char ch[20];字符赋值应该用ch[0]=1;ch[1]=2;用单引号注
C++笔试题汇总(6)
1.引言本文的写作目的并不在于提供C/C++程序员求职面试指导,而旨在从技术上分 析面试题的内涵。文中的大多数面试题来自各大论坛,部分试题解答也参考了网友的意见。 许多面试题看似简单,却需要深厚的基本功才能给出完美的解答。企业要求面试者写
一个
最 简单的strcpy 函数都可看出面试者在技术上究竟达到了怎样的程度,我们能真正写好
一个
strcpy 函数吗?我们都觉得自己能,可是我们写出的strcpy 很可能只能拿到10 分中的2 分。 读者可从本文看到strcpy 函数从2 分到1
语言基础/算法/系统设计
16,748
社区成员
33,247
社区内容
发帖
与我相关
我的任务
语言基础/算法/系统设计
Delphi 语言基础/算法/系统设计
复制链接
扫一扫
分享
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章