1. lua全局环境和局部环境

local cf = loadstring(" local i=0  i=i+1 print(i) ")

--从后面两个输出我们可以看出,生成的函数的环境就是全局_G
print(cf,getfenv(cf),_G) -- function: 0058AAB0 table: 00582ED8 table: 00582ED
--改变_G的值
_G = {}
cf() --
--虽然改变了_G的值,但函数的的环境仍然是全局环境table,地址仍然是0058AAB0
print(cf,getfenv(cf),_G) -- function: 0058AAB0 table: 00582ED8 table: 0058BFF0 -- function: 0058AAB0 table: 00582ED8 table: 00582ED8
--
-- function: 0058AAB0 table: 00582ED8 table: 0058BFF0
-- [Finished in 0.1s]
-- -- 用局部变量list模拟_G(用list表的元素_A保存list表自身,为什么这样做??)
-- local list = {_A = "ddddd", _B = "bbbbb", _C = "ccccc",}
-- list._A = list
-- -- print(list)
-- -- print(list._A)
-- -- print(list._A._A) -- 类似:_G._G = _G -- for k, v in pairs(list) do
-- -- print(k, "=", v, type(v))
-- end -------------------------------------------------------
-- 搜索:局部变量 -> 全局变量 -> 环境
-- 用局部变量 _A 模拟_G(用list表的元素_A保存list表自身,为什么这样做??)
local _A = {_A = "ddddd", _B = "bbbbb", _C = "ccccc",}
_A._A = _A
print(_A)
print(_A._A) -- 类似:_G._G = _G
print(_A._A._A) for k, v in pairs(_A) do
print(k, "=", v, type(v))
end -- output --
-- table: 004FBFF0
-- table: 004FBFF0
-- table: 004FBFF0
-- _A = table: 004FBFF0 table
-- _C = ccccc string
-- _B = bbbbb string
-- [Finished in 0.1s]

[参见]

http://blog.sina.com.cn/s/blog_4458fdda01012f4b.html

http://www.tuicool.com/articles/RVZvMbn

http://blog.csdn.net/maximuszhou/article/details/24105673?utm_source=tuicool

http://blog.csdn.net/ball32109/article/details/11402727
http://blog.codingnow.com/2011/12/lua_52_env.html
http://www.cnblogs.com/ringofthec/archive/2010/11/09/lua_State.html

--------------------------------------------------------------------------------------------------

2. C中遍历lua表结构

// 进行下面步骤前先将 table 压入栈顶
int nIndex = lua_gettop( pLua ); // 取 table 索引值
lua_pushnil( pLua ); // nil 入栈作为初始 key
while( != lua_next( pLua, nIndex ) )
{
// 现在栈顶(-1)是 value,-2 位置是对应的 key
// 这里可以判断 key 是什么并且对 value 进行各种处理
lua_pop( pLua, ); // 弹出 value,让 key 留在栈顶
}
// 现在栈顶是 table

lua_next() 这个函数的工作过程是:

  1) 先从栈顶弹出一个 key(这也是为什么需要首先压入一个nil (lua_pushnil(pLua)) ) .

  2) 从栈指定位置的 table 里取下一对 key-value,先将 key 入栈再将 value 入栈

  3) 如果第 2 步成功则返回非 0 值,否则返回 0,并且不向栈中压入任何值

第 2 步中从 table 里取出所谓“下一对 key-value”是相对于第 1 步中弹出的 key 的。table 里第一对 key-value 的前面没有数据,所以先用 lua_pushnil() 压入一个 nil 充当初始 key。

注意:

  开始的时候先用 lua_gettop() 取了一下 table 在栈中的正索引(前面说过了,在进行这个 lua_next() 过程之前先将 table 入栈,所以栈大小就是 table 的正索引),后面的 lua_next() 过程中不断的有元素出入栈,所以使用正索引来定位 table 比较方便。

  到了 table 中已经没有 key-value 对时,lua_next() 先弹出最后一个 key,然后发现已经没有数据了会返回 0,while 循环结束。所以这个 lua_next() 过程结束以后 table 就又位于栈顶了。

  问题概要: 用lua写了个函数,返回的是一个表.需要在C里对返回的表里元素做二次处理. 在C里我们可以通过lua_gettable()或者lua_rawget()来获取表里元素值,但使用这两个接口的前提是你得知道key,它才能给你 value. 当然对于顺序下标倒无所谓,但恰巧这次我用到的是关联数组,下标是无规则字符串.这时候如何遍历出表里元素就是个问题. lua_next()就成了比较合适的选择.

上图对简单的表遍历做了介绍, 但事实上的情况是我返回了一个二维表,如果你了解了lua_next()的处理过程,那下面的代码看起来就没什么问题了.

t_idx = lua_gettop(L);
lua_pushnil(L);
while (lua_next(L, t_idx))
{
printf("============================\n");
it_idx = lua_gettop(L);
lua_pushnil(L);
while(lua_next(L, it_idx))
{
printf("%s\n", lua_tostring(L, -));
lua_pop(L, );
}
lua_pop(L, );
}

[参见]  Lua 5.3 Reference Manual

lua知识点整理的更多相关文章

  1. ACM个人零散知识点整理

    ACM个人零散知识点整理 杂项: 1.输入输出外挂 //读入优化 int 整数 inline int read(){ int x=0,f=1; char ch=getchar(); while(ch& ...

  2. Android 零散知识点整理

    Android 零散知识点整理 为什么Android的更新试图操作必须在主线程中进行? 这是因为Android系统中的视图组件并不是线程安全的.通常应该让主线程负责创建.显示和更新UI,启动子线程,停 ...

  3. vue前端面试题知识点整理

    vue前端面试题知识点整理 1. 说一下Vue的双向绑定数据的原理 vue 实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫 ...

  4. kafka知识点整理总结

    kafka知识点整理总结 只不过是敷衍 2017-11-22 21:39:59 kafka知识点整理总结,以备不时之需. 为什么要使用消息系统: 解耦 并行 异步通信:想向队列中放入多少消息就放多少, ...

  5. JSP页面开发知识点整理

    刚学JSP页面开发,把知识点整理一下. ----------------------------------------------------------------------- JSP语法htt ...

  6. JS知识点整理(二)

    前言 这是对平时的一些读书笔记和理解进行整理的第二部分,第一部分请前往:JS知识点整理(一).本文包含一些易混淆.遗漏的知识点,也会配上一些例子,也许不是很完整,也许还会有点杂,但也许会有你需要的,后 ...

  7. css入门知识点整理

    css入门知识点整理 不要嘲笑我这个蒟蒻..例子来源:w3school css其实就分为两个东西,一个是选择器,另外一个是声明.声明定义了某个对象的属性的值,这都是html的内容.重点要关注的是选择器 ...

  8. activity生命周期知识点整理

    activity生命周期知识点整理 Activity: 是一个应用组件,用户可与其提供的屏幕进行交互.窗口通常会充满屏幕,但也可以小于屏幕并浮动在其他窗口之上. 一个activity的什么周期: 启动 ...

  9. 【Android 面试基础知识点整理】

    针对Android面试中常见的一些知识点整理,Max 仅仅是个搬运工.感谢本文中引用文章的各位作者,给大家分享了这么多优秀文章.对于当中的解析,是原作者个人见解,有错误和不准确的地方,也请大家积极指正 ...

随机推荐

  1. windows 批处理-重命名

    从数字1递增批量重命名ren.bat: @echo off SETLOCAL ENABLEDELAYEDEXPANSION set /A num= FOR /F "tokens=*" ...

  2. OpenLdap 相关命令

    相关命令: |-slapd 目录服务的主要程序|-slurpd 目录服务进行复制的程序|-slapadd 向目录中添加数据|-slapcat 把目录中的条目导出成ldif文件|-slapindex 重 ...

  3. 纯CSS3实现漂亮的价格表样式代码

    分享一款纯CSS3实现漂亮的价格表样式代码是一款常见的主机商发布产品价格信息页.效果图如下: 在线预览   源码下载 实现的代码. html代码: <div id="main" ...

  4. ReentrantReadWriteLock锁例子

    锁所提供的最重要的改进之一就是ReadWriteLock接口和唯一 一个实现它的ReentrantReadWriteLock类.这个类提供两把锁,一把用于读操作和一把用于写操作.同时可以有多个线程执行 ...

  5. windows系统IIS服务安装

    打开控制面板,win8可以使用快捷键win键+X打开列表   打开程序和功能   打开左上角启用或关闭windows功能   打开internet信息服务下拉单   按照下列图中进行对应项勾选 第一个 ...

  6. 怎样使用 RMAN 增量备份恢复 data guard log gap(日志断档)

    主库查询最小scn 信息: SQL> col current_scn for 999999999999999 SQL>  SELECT CURRENT_SCN FROM V$DATABAS ...

  7. ElasticSearch自定义分析器-集成结巴分词插件

    关于结巴分词 ElasticSearch 插件: https://github.com/huaban/elasticsearch-analysis-jieba 该插件由huaban开发.支持Elast ...

  8. java web中读取properties文件时的路径问题

    在web开发时,难免会有一些固定的参数,我们一般把这些固定的参数存在properties文件中,然后用的时候要读出来.但经常出现一些错误,找不到相应的路径,所以,今天特地讲一些如何正确获得路径. 首先 ...

  9. unicode编码转汉字

    String hexB = Integer.toHexString(utfBytes[byteIndex]);   //转换为16进制整型字符串 if (hexB.length() <= 2)  ...

  10. 可供前端工程师选择的精彩CSS框架

    在这里你有一个很酷的框架,收集创建的CSS布局. 如果你不喜欢框架,宁愿使用自己的手写代码以促进自己的发展,请跳过本篇文章. 我想有一个建设性的意见,那就是有选择的使用其优点避开其缺点. 就个人而言, ...