文档章节

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

涂孟超
 涂孟超
发布于 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
嵌入式开发之C基础学习笔记06--数组和指针(非常重要,难点)

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

吴锦涛
2012/12/14
0
0
Groovy 2.0 新特性之:静态类型检查

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

红薯
2012/06/30
3.6K
7
【C++探索之旅】第一部分第九课:数组威武,动静合一

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

frogoscar
2016/02/29
0
0
sqlite 在 android中使用注意事项

1、模糊查询的陷阱 1 cursor = db.rawQuery("select * from song where song_title like '?%' ", selectionArgs); 这行代码中由于占位符 ? 在单引号内,因此不会被当做占位符,而是对?进行了...

小克898
2012/12/19
0
2

没有更多内容

加载失败,请刷新页面

加载更多

Ubuntu18.04 安装最新版WPS

1.手动卸载libreoffice:sudo apt-get remove --purge libreoffice* 2.官网下载WPS和字体: WPS:http://wps-community.org/download.html 字体:http://wps-community.org/download.html?vl......

AI_SKI
35分钟前
3
0
数据结构(算法)-图(深度优先搜索 DFS)

#include <iostream>using namespace std;#define MaxVex 30typedef char VertexType;typedef struct vexNode adjList[MaxVex];struct edgeNode{int adjvex;//邻接点......

ashuo
40分钟前
0
0
1024 搞事倒计时!距程序员节还有 2 天!

详情请关注微信公众号:七牛云

七牛云
40分钟前
0
0
Java泛型方法

1. 定义泛型方法 (1) 如果你定义了一个泛型(类、接口),那么Java规定,你不能在所有的静态方法、静态初块等所有静态内容中使用泛型的类型参数。例如: public class A<T> { public st...

两广总督bogang
41分钟前
1
0
如何解决JavaScript中0.1+0.2不等于0.3

console.log(0.1+0.2===0.3)// true or false??   在正常的数学逻辑思维中,0.1+0.2=0.3这个逻辑是正确的,但是在JavaScript中0.1+0.2!==0.3,这是为什么呢?这个问题也会偶尔被用来当...

peakedness丶
41分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部