文档章节

关于动态数组、静态数组转换为字符串的一些问题 - 给 "厨师" 的回复

涂孟超
 涂孟超
发布于 2014/09/26 15:37
字数 749
阅读 2
收藏 0
问题来源: http://www.cnblogs.com/del/archive/2008/05/21/1192113.html#1204252

首先, 只有字符类型的数组才可以直接转换为字符串!
//这是静态数组的例子:
var
  Arr: array[0..9] of Char;
  s: string;
  p: PChar;
  i: Integer;
begin
  {给 Arr 赋值: A B C D E F G H I J}
  for i := Low(Arr) to High(Arr) do
    Arr[i] := Chr(65+i);

  {把 Char 数组赋给 string}
  s := Arr;
  ShowMessage(s); {ABCDEFGHIJ}

  {把 Char 数组赋给 PChar}
  p := PChar(string(Arr));
  ShowMessage(p); {ABCDEFGHIJ}

  {直接把 Char 数组赋给 PChar, 会有意想不到的结果, 因为缺少 #0 结束}
  p := Arr;
  //p := @Arr;    {或者这样}
  //p := @Arr[0]; {再或者这样}
  ShowMessage(p); {ABCDEFGHIJ未知数据}
  {这种方式偏偏是我们在使用 API 函数时用得最多的, 但 API 函数都会返回给 #0 结束的, 所以没有问题}
end;


//这是动态数组的例子:
var
  Arr: array of Char;
  s: string;
  p: PChar;
  i: Integer;
begin
  {给 Arr 赋值: A B C D E F G H I J}
  for i := 0 to 9 do
  begin
    SetLength(Arr, i+1);
    Arr[i] := Chr(65+i);
  end;

  Pointer(s) := Arr;
  //Pointer(s) := @Arr[0]; {或者这样}
  ShowMessage(s); {ABCDEFGHIJ}

  p := PChar(Arr);
  //p := @Arr[0]; {或者这样}
  ShowMessage(p); {ABCDEFGHIJ}
end;

 
 
 
 
 

 

 

  
要想彻底理解上面的操作, 需要知道静态数组与动态数组指针问题.
var
  ArrS: array[0..9] of Char; {静态数组}
  ArrD: array of Char;       {动态数组}
  i: Integer;
begin
  {设置动态数组大小, 并给两个数组赋值}
  SetLength(ArrD, 10);
  for i := 0 to 9 do
  begin
    ArrS[i] := Char(65+i);
    ArrD[i] := Char(97+i);
  end;

  {测试赋值结果}
  ShowMessageFmt('%s, %s', [ArrS[0], ArrD[0]]); {A, a}

  {静态数组变量的指针(而非变量本身)和它的第一个元素的指针是同一个}
  ShowMessageFmt('%p, %p', [@ArrS[0], @ArrS]);  {0012FDE2, 0012FDE2}

  {动态数组变量本身(而非变量的指针)就是一个指针, 它和第一个元素的指针也是同一个}
  ShowMessageFmt('%p, %p, %p', [ArrD, @ArrD[0], @ArrD]); {00E7C970, 00E7C970, 0012FDEC}
end;

 
 
 
 
 

 

 

  
另外, 动态数组的构造和静态数组完全不同, 它和 String 的构造 倒是有些相似.

每个动态数组第一个元素前还有 8 个字节, 没 4 个字节记录一个整数;

最前面 4 个字节是用于生存管理的引用计数(当引用计数为 0 时数组自动释放);

第一个元素之前的 4 个字节记录数组的长度. 测试如下:
var
  Arr1,Arr2: array of Char; {定义两个动态数组, 其中一个是为了测试引用计数}
  i: Integer;  {用于指针运算}
  p: PInteger; {用于读取动态数组前面的两个 32 位整数}
begin
  SetLength(Arr1, 10); {设置数组长度}
  Arr2 := Arr1;        {增加一个引用}
  i := Integer(Arr1);  {获取数组地址(这也是数组第一个元素的位置)}

  {获取动态数组的长度}
  i := i-4;
  p := PInteger(i);
  ShowMessage(IntToStr(p^)); {10}

  {获取动态数组的引用计数}
  i := i-4; {再减 4}
  p := PInteger(i);
  ShowMessage(IntToStr(p^)); {2}
end;

 
 
 
 
 

 

 

  

本文转载自:http://www.cnblogs.com/del/archive/2008/05/21/1204264.html

共有 人打赏支持
涂孟超
粉丝 12
博文 2011
码字总数 14107
作品 0
深圳
程序员
阿拉伯人用阿拉伯数字吗?——记一次用String#format格式化字符串趟到的雷

要生成一个字符串,其中夹杂着一些动态变化的整数,我们一般是用String.format方法来完成,但是,如果用的不恰当,你可能是得不到正确的整数字符串的。 事情从一个线上崩溃说起,从崩溃堆栈来...

ZxLee
2017/09/25
0
0
Groovy 2.0 新特性之:静态类型检查

Groovy 2.0 刚刚发布,其中一项最大的改进就是支持静态类型检查。今天我们将对这个新特性进行全方位的介绍。 静态类型检查 Groovy 天生就是一个动态编程语言,它经常被当作是 Java 脚本语言,...

红薯
2012/06/30
3.6K
7
嵌入式开发之C基础学习笔记06--数组和指针(非常重要,难点)

C语言进阶学习 数组 1)数组的使用 2)字符串(String):数组(尤其是一维数组)最常用的地方——————>C语言中字符串就是一维数组 数组: 定义:具有相同类型的数据的有序集合,并用唯一的...

吴锦涛
2012/12/14
0
0
【C++探索之旅】第一部分第九课:数组威武,动静合一

内容简介 1、第一部分第九课:数组威武,动静合一 2、第一部分第十课预告:文件读写,海阔凭鱼跃 数组威武,动静合一 上一课《【C++探索之旅】第一部分第八课:传值引用,文件源头》中,我们...

frogoscar
2016/02/29
0
0
javascript(七) 内建对象

内建对象 全局属性: Infinity 表示正无穷大的数值 NaN 非数字值 undefined 未定义的值 decodeURI() 对encodeURI()转义的字符串解码。 decodeURIComponent() 对encodeURIComponent()转义的字...

年少爱追梦
2016/05/31
43
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

7 个致命的 Linux 命令

导读 如果你是一个 Linux 新手,在好奇心的驱使下,可能会去尝试从各个渠道获得的命令。以下是 7 个致命的 Linux 命令,轻则使你的数据造成丢失,重则使你的系统造成瘫痪,所以,你应当竭力避...

问题终结者
今天
0
0
设计模式:工厂方法模式(工厂模式)

工厂方法模式才是真正的工厂模式,前面讲到的静态工厂模式实际上不能说是一种真正意义上的设计模式,只是一种变成习惯。 工厂方法的类图: 这里面涉及到四个种类: 1、抽象产品: Product 2、...

京一
今天
0
0
区块链和数据库,技术到底有何区别?

关于数据库和区块链,总会有很多的困惑。区块链其实是一种数据库,因为他是数字账本,并且在区块的数据结构上存储信息。数据库中存储信息的结构被称为表格。但是,区块链是数据库,数据库可不...

HiBlock
今天
0
0
react native 开发碰到的问题

react-navigation v2 问题 问题: static navigationOptions = ({navigation, navigationOptions}) => ({ headerTitle: ( <Text style={{color:"#fff"}}>我的</Text> ), headerRight: ( <View......

罗培海
今天
0
0
Mac Docker安装流程

久仰Docker大名已久,于是今天趁着有空,尝试了一下Docker 先是从docker的官网上下载下来mac版本的docker安装包,安装很简易,就直接拖图标就好了。 https://www.docker.com/products/docker...

writeademo
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部