![]() |
|
[教程] Pawn 中的压缩字符串 原文作者: Emmet_ - 打印版本 +- samp | open.mp 联机社区论坛 (https://open-mp.cn) +-- 板块: SA-MP (https://open-mp.cn/forumdisplay.php?fid=12) +--- 板块: 教程 (https://open-mp.cn/forumdisplay.php?fid=17) +--- 主题: [教程] Pawn 中的压缩字符串 原文作者: Emmet_ (/showthread.php?tid=25) |
[教程] Pawn 中的压缩字符串 原文作者: Emmet_ - 小鸟unsigned - 03-21-2026 Pawn 中的压缩字符串原文作者: Emmet_ 本篇教程仅为翻译搬运 引言压缩字符串自 SA-MP 和 Pawn 诞生之初就已存在。然而,很多人并不了解压缩字符串以及它能节省多少内存!本教程将教你压缩字符串的基础知识,以及如何正确操作它们。 什么是压缩字符串?压缩字符串是一种数组,它将数据存储在每个字节中,而不是像普通数组那样存储在每个单元格中。压缩字符串以小端序存储(即低位字节在前),并且只能容纳 0 到 255 的 ASCII 字符,超出这个范围的数值会绕回。 看这段代码: 代码: new string[5];'a' 存储在单元格 0,'b' 存储在单元格 1,依此类推。一个单元格基本上占用 4 个字节,所以算一下,上面的字符串大约占用 20 个字节,每个字符占用 4 个字节的空间。然而,使用下面的代码: 代码: new string[5 char];'a' 存储在字节 0,'b' 存储在字节 1,依此类推。实际上,上面的字符串只占用 8 个字节,仅包含 2 个单元格!你可能在想为什么这个字符串不是 5 个字节。使用 char 修饰符会自动将数组大小向上取整到最近的 4 的倍数(例如,1 变成 4,3 变成 4,5 变成 8,23 变成 24,依此类推)。代码: // 这个数组占用 5 个单元格,共 20 个字节。因此,使用压缩字符串可以节省 3 到 4 倍的内存! 适用场景你可能认为压缩数组没什么用。如果这么想,那你就错了。压缩数组有很多用途,不仅仅是节省内存! 稀疏数组首先,你可以阅读我关于稀疏数组的教程: https://sampforum.blast.hk/showthread.php?tid=480439 稀疏数组就是那些大部分数据经常为空的数组。使用压缩数组可以轻松节省内存! 代码: #define MAX_ITEMS (64)不常使用的字符串很多时候,你会把字符串保存到内存中,但很少使用它们(例如几乎不用)。对于这类数组,压缩数组非常适用。 大量数据存储回到上面的“稀疏数组”部分,如果你需要存储大量数据,最好使用压缩字符串。 内存节省!压缩数组能节省 4 倍的内存,既然可以用压缩数组,为什么还要用那些多占 4 倍内存的方式存储数据呢? SA-MP 中的不支持情况压缩字符串在纯 Pawn 中完美支持。但是,大多数 SA-MP 原生函数不支持压缩字符串,比如 format、GetPlayerName 等。如果你打算使用压缩字符串,就必须依赖 strpack、strunpack 以及 string.inc 中的其他字符串函数。格式化字符串format 和 printf 函数不支持压缩字符串,因此你必须使用 strpack:代码: new你也可以这样做: 代码: new 支持压缩字符串的函数string.inc 中的所有字符串函数都同时支持压缩数组和非压缩数组。fread 和 valstr 函数也接受一个可选的 pack 参数来支持压缩数组,因此你不用担心它们是否能与压缩数组一起工作。访问数据在 Pawn 中,非压缩数组将数据存储在每个单元格中。而压缩数组将数据存储在每个字节中,这意味着你不能像访问非压缩数组那样使用方括号 [] 来访问和获取压缩数组中的数据。代码: // 错误。另外,要设置一个压缩字符串,你需要在字符串前加上感叹号,以表示这是压缩输入。 代码: // 错误。这会尝试将字符串按单元格存储,这不是我们想要的! |