比较C/C++和Delphi中的字符串和字符数组(数组和动态分配内存的情况)

  本文所讲解的只是从其中一个方面来看待进行的总结,所以有必要结合《Delphi字符串与字符数组之间的转换(初始化的重要性)》等文章进行更全面的了解,会从更多方面来理解字符串、内存、类型转换

C/C++中的字符串、字符数组、字符指针分配的内存空间

  我们知道在C/C++中,我们可以这样理解字符串和字符数组

1)字符串,就是一个以 ‘\0‘ 结尾的字符数组

2)字符数组,包括字符串,但是不一定要以 ‘\0‘ 结尾,如果不是以‘\0‘ 结尾,那么就不能当做字符串使用

  在C/C++中,使用字符串可以通过数组,也可以通过为字符指针动态分配内存来存放字符串,类似于字符数组,不过这种方法的内存需要程序员自己管理

一、不是以 ‘\0‘ 结尾的字符数组,不能作为字符串使用

char c[2];
c[0] = ‘a‘;
c[1] = ‘b‘;

二、以 ‘\0‘ 结尾的字符数组,可以作为字符串使用

char c[4];
c[0] = ‘a‘; c[1] = ‘b‘; c[2] = ‘c‘;
c[3] = ‘\0‘;

/*
等价于下面的方法
char c[4] = "abc";
*/

三、动态分配的char指针指向的内存,不是以 ‘\0‘ 结尾的,不能作为字符串使用

char *p = (char *)malloc(2);
p[0] = ‘a‘;
p[1] = ‘b‘;

四、动态分配的char指针指向的内存,以 ‘\0‘ 结尾的,能作为字符串使用

char *p = (char *)malloc(4);
p[0]=‘a‘; p[1]=‘b‘; p[2]=‘c‘;
p[3]=‘\0‘;

  但是它并不等价于下面的代码

char *p = (char *)malloc(4);
p="abc";

  这样不是往 p 所指向的内存中存储"abc",而是将p 指针指向了字符串常量"abc"的地址,因此会造成之前分配的内存的地址没有被记录,也就没办法进行释放,所以就会造成内存泄露。

  你可以通过两次输出 p 的地址来验证这个说法

#include<stdio.h>

int main(){
char * p;
p = (char *)malloc(4);

printf("%d\n", (p));

p="abc";

printf("%d", p);

return 0;
}

  我的测试时,两次输出的地址,一个是202720,一个是4206632,显然不是指向同一个地址。而

char *p = (char *)malloc(4);
printf("%d\n", p);
p[0]=‘a‘; p[1]=‘b‘; p[2]=‘c‘;
p[3]=‘\0‘;
printf("%d\n", p);

  因为是操作p 的元素,而不是直接操作 p指针的指向,所以上面的输出的两个地址一样

  所以要理解 char型数组和char* 动态分配的内存、不同的赋值方法的本质是什么

  

Delphi中有字符串类型string等等,但是这里只讨论字符数组、字符指针分配的内存空间和它们表示字符串的情况

  其实Delphi的这方面的知识是和C/C++中的一样的,就像前面所讲的那样,它们是兼容的,所以在编写C/C++和Delphi兼容的代码时,Delphi要使用Char数组或者Pchar动态内存分配,而不使用string等字符串类型

  数组无非就是内存分配在栈上,所以其他几个方面都类似下面讲解的PChar动态内存分配的情况

  如果是对PChar指针进行内存分配(GetMem(p, size))的话,那么这时候有两种情况(主要是一和二,三是额外讲解的一个特例情况)

    以 ‘\0‘ 结尾的字符数组,可以作为字符串使用,不是以 ‘\0‘ 结尾的字符数组或PChar动态内存,不能作为字符串使用

一、类似于数组

var
    p: PChar;
    i: Integer;
begin
    GetMem(p, 3);
    for i:= 0 to 2 do
        p[i]:=‘j‘;
end;

  这样就是一个字符数组,并且不是以#0结尾的,

二、或者指明最后一个元素为#0

var
    p: PChar;
    i: Integer;
begin
    GetMem(p, 3);
    for i:= 0 to 1 do
        p[i]:=‘j‘;
    p[2]:= #0;
end;

  这里面并没有改变p 的指向

三、字符串

var
    p: PChar;
    i: Integer;
begin
    GetMem(p, 3);
    p:= ‘jo‘;
end;

  参考C/C+部分的第四个例子,其实这里的程序三和程序二也是上面所讲的那种操作PChar指针的元素和直接操作PChar指针的情况

  如果还不相信,那就进行测试来验证

procedure TForm1.btn1Click(Sender: TObject);
var
    p: PChar;
    i: Integer;
begin
    GetMem(p, 3);
    i:= Integer(p); //保存为p动态分配内存之后的地址
    p:= ‘jo‘;

    //下面比较P:= ‘jo‘;前后的p所指向的内存的地址
    ShowMessage(IntToStr(i)+‘ ‘+IntToStr(Integer(p)));
end;

  结果如下(显然和C/C++中所讲的一样)

时间: 2024-10-07 19:59:40

比较C/C++和Delphi中的字符串和字符数组(数组和动态分配内存的情况)的相关文章

关于Delphi中的字符串的详细分析

关于Delphi中的字符串的详细分析 只是浅浅的解析下,让大家可以快速的理解字符串. 其中的所有代码均在Delphi7下测试通过. Delphi 4,5,6,7中有字符串类型包括了: 短字符串(Short String) 长字符串(Long String) 宽字符串(Wide String) 零结尾字符串(Null-Terminated String).PChar和字符数组 1.短字符串(Short String) 固 定长度,最大字符数个数为255,短字符串也成为长度字节(Length-byt

关于Delphi中的字符串的浅析(瓢虫大作,里面有内存错误的举例)

关于Delphi中的字符串的浅析 只是浅浅的解析下,让大家可以快速的理解字符串. 其中的所有代码均在Delphi7下测试通过. Delphi 4,5,6,7中有字符串类型包括了: 短字符串(Short String) 长字符串(Long String) 宽字符串(Wide String) 零结尾字符串(Null-Terminated String).PChar和字符数组 1.短字符串(Short String) 固定长度,最大字符数个数为255,短字符串也成为长度字节(Length-byte)字

Python中的字符串与字符编码

原文地址:点击这里 本节内容: 前言 相关概念 Python中的默认编码 Python2与Python3中对字符串的支持 字符编码转换 一.前言 Python中的字符编码是个老生常谈的话题,同行们都写过很多这方面的文章.有的人云亦云,也有的写得很深入.近日看到某知名培训机构的教学视频中再次谈及此问题,讲解的还是不尽人意,所以才想写这篇文字.一方面,梳理一下相关知识,另一方面,希望给其他人些许帮助. Python2的 默认编码 是ASCII,不能识别中文字符,需要显式指定字符编码:Python3的

(转)Delphi 中的字符串

一.Delphi 2009 之前的字符串(不支持 Unicode): Delphi 2009 之前的字符串分为 3 种:ShortString.AnsiString.WideString. [ShortString] ShortString 是一种比较古老的 Pascal 字符串格式,它最多只能容纳 255 个字节的字符.当我们声明一个 ShortString 类型的变量时,Delphi 会自动申请 256 个字节的内存空间给该变量,其中第一个字节用来存放字符串的长度,后面的 255 个字节用来

Delphi中分隔字符串函数的使用

下面介绍Delphi自带的字符串分割函数,根据你的需要来使用. 1.ExtractStrings function ExtractStrings(Separators, WhiteSpace: TSysCharSet; Content: PChar; Strings: TStrings): Integer; 第一个参数是分隔符,可以是多个,例如 [';',',',':'] 可以按分号.逗号.分号来同时分割. 第二个参数是开头被忽略的字符,例如['<','>',''],被分割出的字符,如果开头有

C#中分割字符串输出字符数组

来自博客园 http://www.cnblogs.com/yugen/archive/2010/08/18/1802781.html 1.用字符串分隔: using System.Text.RegularExpressions;string str="aaajsbbbjsccc";string[] sArray=Regex.Split(str,"js",RegexOptions.IgnoreCase);foreach (string i in sArray) Res

delphi 中一种好用的数组定义方法以及函数嵌套的使用源代码

type TByteBuff;= array of integer; function abc(a:integer):TByteBuff;; var tempArr:TByteBuff; begin setlength(tempArr,2); tempArr[0] := a; tempArr[1] := a + 10; result:=tempArr; end; procedure TForm1.Button1Click(Sender: TObject); var a : integer; be

第48篇 说说.Net与Java中的字符串

原文地址:http://blog.laofu.online/2017/08/18/String-In-dotnet-Java/ Java字符串碰到的问题 在写Java程序碰到一个问题,而正是这个问题引发了我对字符串的思考,Java示例代码如下: public void TestStr(String success) { if(success=="Y"){ System.out.println("Equal"); } else { System.out.println

在字符串中删除特定的字符

题目:输入两个字符串,从第一字符串中删除第二个字符串中所有的字符.例如,输入"I am lavor_zl."和"I love you.",则删除之后的第一个字符串变成"amar_z".要求相对于第一个字符串的长度n时间复杂度为O(n). 解题思路:用一个bool数组保存是否在第二个字符串中出现的所有字符,数组下标表示字符,这个数组的长度为256,因为C/C++中字符总共有256个.遍历第一个字符串,用一个指针或数组下标access来表示当前访问第