aardio - 关于字符串指针的操作

一、前言:

aardio中的字符串,是不可修改的。

我们对字符串变量重新赋值一个不同的字符串,并不是“修改数据”,而是“更换地址”,实际上是赋予了一个新的内存指针。

先看下图,理解一下aardio中字符串变量的定义方式:

在aardio中,不同的变量、字符串,如果内容一样,则会指向同一个指针。

就如上图,变量a、变量b、"哈哈哈"立即数 三者的指针是一样的。

在这种情况下,如果根据一个变量的指针修改了其内容,实际上可能会影响很多其他变量甚至 "立即数" 的内容。其后果是未知的。

我猜测这也是aardio不允许直接修改字符串内容的原因之一吧。

二、获取指针的方法

aardio 中可以使用如下代码获取字符串指针的函数:

  • var a = "哈哈哈";
  • var p = raw.toPointer(a); //这是字符串"哈哈哈"的指针,同时也是变量a的指针

  • var p = raw.toPointer("哈哈哈"); //这是字符串"哈哈哈"的指针,同时也是变量a的指针

windows API 也提供了获取字符串指针的函数,我们可以直接使用:

  • var a = "哈哈哈";
  • var p = ::Kernel32.lstrcpynP(a,a,0); //这是字符串"哈哈哈"的指针,同时也是变量a的指针

  • var p = ::Kernel32.lstrcpynP("哈哈哈","哈哈哈",0); //这是字符串"哈哈哈"的指针,同时也是变量a的指针

三、修改字符串的方法

aardio中没有提供直接修改字符串内容的方法,但是提供了修改内存数据的方法。

可以通过 raw.convert( ) 、raw.copy( ) 等函数改写字符串内存内容。

import console;
var a = "哈哈哈";
var b = "哈哈哈";
var p = ..raw.toPointer(a);
//var p = ::Kernel32.lstrcpynP(a,0,0);
console.dump(p); //输出指针看一下
raw.copy(p,"123",3); //修改指针处内容
raw.copy(topointer(p,3),"完",3); //修改指针偏移3处内容
raw.copy(topointer(p,6),"活",3); //修改指针偏移6处内容
console.dump(a,b,"哈哈哈"); //显示原数据,看看是否被修改
console.pause(true);

可以看出,修改一个变量的内容后,其他同内容的变量,甚至立即数"哈哈哈"都被修改了。这样会造成不可预知的后果。慎用。

四、高级一点的测试,多线程中数据是否共享

因为 aardio 中,多线程是数据独立的,内存不共享,所以理论上来说,不同线程中声明的相同内容的字符串,内存地址也是不一样的。

测试一下:

import console;
import thread
//创建a变量
var a = "哈哈哈";
var p = ..raw.toPointer(a);
console.dump(p); //输出a指针
//启动一个线程,修改"哈哈哈"内存数据
thread.invokeAndWait(
function(){
var b = "哈哈哈";
var p = ..raw.toPointer(b);
import console;
console.dump(p); //输出b指针
raw.copy(p,"123",3); //修改指针处内容
console.dump(b);
}
)
//显示a变量数据,看看是否被修改
console.dump(a);
console.pause(true);

测试结果:

可以看出,变量 a 与 b 的指针是不一样的。在线程中修改b的内容,并不影响a的内容。

这就是“线程内存独立”,体现了线程的安全性。

五、看一下buffer

buffer与string相比,就有独立的内存地址了,可以在不改变指针的情况下修改某部分内容。

每次 raw.buffer( ) 都会重新分配一块独立内存,而不是与其他相同内容的 buffer 指向同一内存。

看以下代码:

import console;
//创建两个内容相同的buffer变量
var a = raw.buffer("哈哈哈");
var b = raw.buffer("哈哈哈");
console.dump(raw.toPointer(a)); //输出a指针
console.dump(raw.toPointer(b)); //输出b指针
//对a数据进行修改
a[1]='1'#;
a[2]='2'#;
a[3]='3'#;
console.dump(a)
console.dump(b)
//看一下变量指针在修改前后是否发生变化
console.dump(raw.toPointer(a)); //输出a指针
console.dump(raw.toPointer(b)); //输出b指针
console.pause(true);

执行结果:

可以看到,两个内容相同的buffer,地址是不一样的。修改一个,也不影响另一个。同时,对buffer内容进行修改,其指针也不变。

注意:以下方式给buffer赋值,会指向同一指针:

  • var a = raw.buffer("哈哈哈");
  • var b = a; // b 与 a 相当于是同一个变量。

用以下代码测试一下:

import console;
//创建buffer变量
var a = raw.buffer("哈哈哈");
var b = a;
console.dump(raw.toPointer(a)); //输出a指针
console.dump(raw.toPointer(b)); //输出b指针
//对a数据进行修改
a[1]='1'#;
a[2]='2'#;
a[3]='3'#;
console.dump(a)
console.dump(b)
//对比变量指针是否变化
console.dump(raw.toPointer(a)); //输出a指针
console.dump(raw.toPointer(b)); //输出b指针
console.pause(true);

执行结果:

可以看出,两个变量指针一样,修改一个,另一个也随之修改。

  • 17
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卢光庆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值