第一版是针对 Lua 5.0 编写的。虽然在很大程度上仍然适用于更高版本,但还是有一些区别。
第四版针对 Lua 5.3,可在 亚马逊 和其他书店购买。
购买本书,您还可以帮助 支持 Lua 项目。
![]() |
用 Lua 编程 | ![]() |
| 第四部分。C API 第 24 章。C API 概述 |
除了上述函数(在 C 和堆栈之间交换值)之外,API 还提供以下操作用于通用堆栈操作
int lua_gettop (lua_State *L);
void lua_settop (lua_State *L, int index);
void lua_pushvalue (lua_State *L, int index);
void lua_remove (lua_State *L, int index);
void lua_insert (lua_State *L, int index);
void lua_replace (lua_State *L, int index);
lua_gettop 函数返回堆栈中的元素数量,这也是顶部元素的索引。请注意,负索引 -x 等于正索引 gettop - x + 1。
lua_settop 将顶部(即堆栈中的元素数量)设置为特定值。如果之前的顶部高于新的顶部,则会丢弃顶部值。否则,该函数会在堆栈上压入 nil,以获得给定的大小。作为特殊情况,lua_settop(L, 0) 会清空堆栈。您还可以对 lua_settop 使用负索引;这会将顶部元素设置为给定的索引。使用此功能,API 提供以下宏,该宏从堆栈中弹出 n 个元素
#define lua_pop(L,n) lua_settop(L, -(n)-1)
lua_pushvalue 函数在堆栈顶部压入给定索引处元素的副本;lua_remove 删除给定索引处的元素,将该位置上方的所有元素向下移动以填补空缺;lua_insert 将顶部元素移动到给定位置,将该位置上方的所有元素向上移动以腾出空间;最后,lua_replace 从顶部弹出值并将其设置为给定索引的值,而不移动任何内容。请注意,以下操作对堆栈没有影响
lua_settop(L, -1); /* set top to its current value */
lua_insert(L, -1); /* move top element to the top */
为了说明这些函数的使用,这里有一个有用的帮助函数,用于转储堆栈的全部内容
static void stackDump (lua_State *L) {
int i;
int top = lua_gettop(L);
for (i = 1; i <= top; i++) { /* repeat for each level */
int t = lua_type(L, i);
switch (t) {
case LUA_TSTRING: /* strings */
printf("`%s'", lua_tostring(L, i));
break;
case LUA_TBOOLEAN: /* booleans */
printf(lua_toboolean(L, i) ? "true" : "false");
break;
case LUA_TNUMBER: /* numbers */
printf("%g", lua_tonumber(L, i));
break;
default: /* other values */
printf("%s", lua_typename(L, t));
break;
}
printf(" "); /* put a separator */
}
printf("\n"); /* end the listing */
}
此函数从底部到顶部遍历堆栈,根据每个元素的类型打印每个元素。它在引号之间打印字符串;对于数字,它使用 `%g´ 格式;对于其他值(表、函数等),它仅打印其类型(lua_typename 将类型代码转换为类型名称)。
以下程序使用 stackDump 进一步说明 API 堆栈的操作
#include <stdio.h>
#include <lua.h>
static void stackDump (lua_State *L) {
...
}
int main (void) {
lua_State *L = lua_open();
lua_pushboolean(L, 1); lua_pushnumber(L, 10);
lua_pushnil(L); lua_pushstring(L, "hello");
stackDump(L);
/* true 10 nil `hello' */
lua_pushvalue(L, -4); stackDump(L);
/* true 10 nil `hello' true */
lua_replace(L, 3); stackDump(L);
/* true 10 true `hello' */
lua_settop(L, 6); stackDump(L);
/* true 10 true `hello' nil nil */
lua_remove(L, -3); stackDump(L);
/* true 10 true nil nil */
lua_settop(L, -5); stackDump(L);
/* true */
lua_close(L);
return 0;
}
| 版权所有 © 2003–2004 Roberto Ierusalimschy。保留所有权利。 | ![]() |