lua 中table的使用和分析

1.table有4种基本操作:读,写,迭代和获取长度。

lua中没有删除操作而是将对应键位的值设置为nil.

lua的内部定义是在lobject.h

</pre><pre code_snippet_id="580775" snippet_file_name="blog_20150115_1_6202329" name="code" class="python"><pre name="code" class="cpp">/*
** Tables
*/

typedef union TKey {
  struct {
    TValuefields;
    struct Node *next;  /* for chaining */
  } nk;
  TValue tvk;
} TKey;

typedef struct Node {
  TValue i_val;
  TKey i_key;
} Node;

<pre name="code" class="cpp">typedef struct Table {
  CommonHeader;
  lu_byte flags;  /* 1<<p means tagmethod(p) is not present */
  lu_byte lsizenode;  /* log2 of size of `node' array */     (哈希表的长度)
  struct Table *metatable;               (存储表对应的metatable)
  TValue *array;  /* array part */               (数组)
  Node *node;                                   (用来指向哈希表的指针)
  Node *lastfree;  /* any free position is before this position */ (用来获取hash表中最后一个nil的位置,hash表中插入值)
  GCObject *gclist;
  int sizearray;  /* size of `array' array */    (数组的长度)
} Table;




从后面的表的获取长度,读写和迭代中,都可以看出lua中表的存储是分为两个部分:一个是数组部分,一个是哈希表。相应指针,和对应长度如代码中注释。

table中的基本相关操作c实现都在ltable.c中.

LUAI_FUNC Table *luaH_new (lua_State *L);

创建一个新的table 分配内存空间和对成员变量初始化。

LUAI_FUNC void luaH_free (lua_State *L, Table *t);

释放内存,先释放hash表部分,后释放数组部分。

LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize)

当需要开辟新的内存的时候,

LUAI_FUNC void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize);

是上面函数的具体实现。

LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key);

向lua中hash表部分插入一个新的key,插入的方式先查找hash表中,该建的主位置是不是有值,如果有值得话,先看该值的主位置是不是在这个Index上,如果是的话,新插入的key通过再散列找到下一个值为空的位置插入。如果它不是主位置,那么新插入的剑插入该位置,替换出来的值会放到其他位置,如果该位置没有值的话,那么就直接插入。

LUAI_FUNC int luaH_getn (Table *t);

获取长度,先找表中数组部分,如果数组部分有值的话,就返回数组部分的长度,如果数组部分没有值,就取hash表部分的长度

LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);

        lua通过这个函数实现table的递归,通过上一个键,来找到下一个键值对。先查找数组部分,如果没有再查找哈希表部分。其中首先通过finxdindex 根据传入的key找到对应的所在数组部分的位置,或者是放到所在hash表部分的索引,

2. 除了基础操作部分,lua还用c实现了直接操作table功能来提供给lua中进行使用。Table Manipulation在lua官方文档中这样写道:这个库为table的操作提供了一般的方法,它提供了在table中所有他得方法,记住,当一个操作需要table的长度的时候,这个table需要是一个当前本身的队列或者有一个__len
的元方法,所有方法都忽略在table中提供非数值的key作为参数。因为效率的原因,所有的通过这些方法对table访问执行都是未加工的(raw)

其中存储函数地址数组

</pre><pre code_snippet_id="580775" snippet_file_name="blog_20150115_3_4420509" name="code" class="python"><pre name="code" class="cpp">static const luaL_Reg tab_funcs[] = {
  {"concat", tconcat},
#if defined(LUA_COMPAT_MAXN)
  {"maxn", maxn},
#endif
  {"insert", tinsert},
  {"pack", pack},
  {"unpack", unpack},
  {"remove", tremove},
  {"sort", sort},
  {NULL, NULL}
};

maxn 函数,其中用到了luaH_next  查找table中所有正数key值中最大的key值,如果不存在key为正数的元素返回0,包括数组和hash表部分

tinsert 函数  在表的某个位置插入一个元素。

tremove 函数   移除某一个元素,从pos位置开始 通过t[pos] = t[pos+1] 将前面的元素覆盖掉。

tconcat 函数 table中元素全都是string类型的,将他们用指定的连接符连成一个字符串

pack 函数 返回一个新的table 通过数组存储对应的值

unpack函数  返回table的元素,这个方法等同于  return list[i], list[i+1], ···, list[j]   默认是 1 到 #table

sort函数 对table中元素进行排序,可以通过设置比较器来设置排序规则,如果没有给出的话,那么就会是使用<号来代替。同c++中快速排序.

由此可见  lua5.2中已经将table.getn这个函数去掉。之前看书和其他人的博客总是找不到这个函数用法。。。。

时间: 2024-10-13 16:38:04

lua 中table的使用和分析的相关文章

c/c++_Lua交互----关于Lua中table类型的使用实例

lua中的复合类型 只有table 类型,你可以当做任意容器使用  ,比如 数组    PHP中的关联数组  C++中的 std::map 等等  而且提供了很方便的使用 下面是lua中 table类型的使用 c++加载代码 #include "string.h" extern "C" { #include "lualib.h" //包含lua lib #include "lauxlib.h" //辅助函数 }; #pragm

Lua中table类型的源码实现

  1.概述 table是lua中唯一的表示数据结构的工具.它可以用于实现数据容器.函数环境(Env).元表(metatable).模块(module)和注册表(registery)等其他各种用途.因此了解table的实现是非常有必要的,根据<Lua中数据类型的源码实现>中知道,在Lua中,table是由结构体体Table来实现的.下面将以Lua 5.2.1的源码来看table的实现.   2.实现原理 在Lua5.0以后,table是以一种混合型数据结构来实现的,它包含一个哈希表部分和一个数

lua中table需要注意的一点东西

关于table的文字说明我引用了lua程序设计的一些语句来概括表述: table类型实现了"关系数组"."关系数组"是一种具有特殊索引方式的数组.不仅可以通过整数来索引他,还可以使用字符串活着其他类型的值(除了nil)来索引他.此外,table没有固定大小,可以动态的添加任意数量的元素到一个table中. 在lua中,table既不是"值"也不是"变量",而是"对象",可以将一个table想象成一种动态分配

lua中table的实现

table 在lua中是一个非常常用的数据结构,可以用来存放各种类型的元素,那么就会让人好奇,它这么强大,它是用什么数据结构实现的呢 首先,考虑 table = {1, 2, 3, 4, 5, 6, 7, 8} 这样的结构, 为了获得最快的访问速度,它是用数组实现的 那么如果执行table[10000] = 10; 莫非要创建10000个元素的数组,没有值的都存为nil,这样的空间利用效率太低无法接受,所有除了数组段之外,table还有一个哈希段,10000这个key会存在哈希段中,当太大的ke

lua中table的遍历,以及删除

Lua 内table遍历 在lua中有4种方式遍历一个table,当然,从本质上来说其实都一样,只是形式不同,这四种方式分别是: 1. ipairs for index, value in ipairs(table) do end 注:这种方式的遍历只会从key为1的地方开始,一直以key递增1的顺序来遍历,若找到一个递增不是1的key就结束遍历,无论后面是否仍然是顺序的key. 1 --Sample_1: 2 local tab1 = 3 { 4 [1] = 1, 5 [2] = 2, 6 [

Lua中table内建排序与C/C++/Java/php/等内排序算法的排序效率比较

Lua这类脚本语言在处理业务逻辑作为配置文件的时候方便省事 但是在大量需要 运算的地方就显得略微不足   按照 Lua内建排序算法 对比C/C++ PHP Java等的快速排序算法进行一下比较. 快速排序算法是基于冒泡排序,优化而来,时间复杂度T(n)=O(nLog2n)  ,可见内部采用了二分策略 . 发现在LuaIDE LDT下直接运行效率要比 通过C++加载运行Lua脚本效率高的多  拿500W个数据排序 来说  ,脚本如下 同样的排序脚本Lua解释器的内置排序算法在LDT下,运行速度比通

lua中table 库函数 insert、remove、concat、sort的简单使用【简记】

1.insert  1 do 2 t1 = {"欲", "泪", "成", "雪"} 3 table.insert(t1,"seeyou")-- 往t1末尾插入元素 "seeyou" 4 table.insert(t1, 3, "bug")-- 往t1索引为3的位置插入元素"bug" 5 for i,v in ipairs(t1) do print

lua中遍历table的几种方式比较

在工作中使用lua进行开发时,发现在lua中有4种方式遍历一个table,当然,从本质上来说其实都一样,只是形式不同,这四种方式分别是: for key, value in pairs(tbtest) do XXX end for key, value in ipairs(tbtest) do XXX end for i=1, #(tbtest) do XXX end for i=1, table.maxn(tbtest) do XXX end 前两种是泛型遍历,后两种是数值型遍历.当然你还会说

Lua中的Table操作

Lua中table类似与C#种的字典,其实就是一个key-value键值对数据结构.来学习下table基本操作 Table的创建 myTable = {} --表名后面使用{}赋值,表示一个空的表 myTable = {name="海洋",age=18,isMan=true} --创建时候就添加键-值 myTable = {10,20,30,"Ocean"} --创建数字下标值的table,默认是从1开始 Table的赋值 myTable[3] = 34 --当键是