其他栈操作

简介: 其他栈操作

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_rotate (lua_State *L, int index, int n);
void lua_remove (lua_State *L, int index);
void lua_insert (lua_State *L, int index);
void lua_replace (lua_State *L, int index);
void lua_copy (lua_State *L, int fromidx, int toidx);点击复制复制失败已复制


函数 lua_gettop 返回栈中元素的个数,也即栈顶元素的索引。函数 lua_settop 将栈顶设置为一个指定的值,即修改栈中的元素数量。如果之前的栈顶比新设置的更高,那么高出来的这些元素就会被丢弃;反之,该函数会向栈中压入 nil 来补足大小。特别的,函数 lua_settop(L, 0) 用于清空栈。在调用函数 lua_settop 时也可以使用负数索引;基于这个功能, C API 提供了下面的,用于从栈中弹出 n 个元素:

#define lua_pop(L, n)   lua_settop(L, -(n) -1)点击复制复制失败已复制


函数 lua_pushvalue 用于将指定索引上的元素的副本压入栈。


函数 lua_rotateLua5.3 中新引入的。顾名思义,该函数将指定索引的元素向栈顶转动n 个位置。若 n 为正数,表示将元素向栈顶方向移动,而 n 为负数则表示向相反的方向转动。这是一个非常有用的函数,另外两个 C API 操作实际上是基于使用该函数的宏定义的。其中一个是 lua_remove ,用于删除指定索引的元素,并将该位置之上的所有元素下移以填补空缺,其定义如下:

# define lua_remove(L, idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1))点击复制复制失败已复制


也就是说,该函数会将栈转动一格,把想要的那个元素移动到栈顶,然后弹出该元素。

另一个宏是 lua_insert ,用于将栈顶元素移动到指定位置,并上移指定位置之上的所有元素以开辟出一个元素的空间:

# define lua_insert(L, idx)   lua_rotate(L, (idx), 1)点击复制复制失败已复制


函数 lua_replace 弹出一个值,并将栈顶设置为自定索引上的值,而不移动任何元素。最后,函数 lua_copy 将一个索引上的值复制到另一个索引上,并且原值不受影响。


提示

函数 lua_copy 是在 Lua5.2 中引入的。


请注意:以下的操作不会对空栈产生影响:

lua_settop(L, -1);  // 将栈顶设置为当前的值
lua_insert(L, -1);  // 将栈顶的元素移动到栈顶
lua_copy(L, x, x);  // 把一个元素复制到它当前的位置
lua_rotate(L, x, 0);  // 旋转零个位置点击复制复制失败已复制


演示示例:

#include <stdio.h>
#include "lauxlib.h"
#include "lua.h"
static void stackDump(lua_State *L) {
  int i;
  int top = lua_gettop(L);      // 栈的深度
  for (i = 1; i <= top; i++) {  // 循环
    int t = lua_type(L, i);
    switch (t) {
      case LUA_TSTRING: {  // 字符串类型
        printf("'%s'", lua_tostring(L, i));
        break;
      }
      case LUA_TBOOLEAN: {  // 布尔类型
        printf(lua_toboolean(L, i) ? "true" : "false");
        break;
      }
      case LUA_TNUMBER: {  // 数值类型
        printf("%g", lua_tonumber(L, i));
        break;
      }
      default: {  // 其他类型
        printf("%s", lua_typename(L, t));
        break;
      }
    }
    printf("  ");  // 输出分隔符
  }
  printf("\n");  // 换行符
}
int main(void) {
  lua_State *L = luaL_newstate();
  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_rotate(L, 3, 1);
  stackDump(L);   // --> true  10  nil  true  'hello'  nil
  lua_remove(L, -3);
  stackDump(L);   // --> true  10  nil  'hello'  nil
  lua_settop(L, -5);
  stackDump(L);   // --> true 
  lua_close(L);
  return 0;
}
目录
相关文章
|
2天前
|
算法 安全 测试技术
golang 栈数据结构的实现和应用
本文详细介绍了“栈”这一数据结构的特点,并用Golang实现栈。栈是一种FILO(First In Last Out,即先进后出或后进先出)的数据结构。文章展示了如何用slice和链表来实现栈,并通过golang benchmark测试了二者的性能差异。此外,还提供了几个使用栈结构解决的实际算法问题示例,如有效的括号匹配等。
golang 栈数据结构的实现和应用
01_设计一个有getMin功能的栈
01_设计一个有getMin功能的栈
|
2天前
|
前端开发
07_用队列实现栈
07_用队列实现栈
06_用栈来求解汉诺塔问题
06_用栈来求解汉诺塔问题
05_用一个栈实现另一个栈的排序
05_用一个栈实现另一个栈的排序
03_如何仅用递归函数和栈操作逆序一个栈
03_如何仅用递归函数和栈操作逆序一个栈
|
2天前
|
测试技术
02_由两个栈组成的队列
02_由两个栈组成的队列
|
6天前
|
存储
|
21天前
|
存储 人工智能 C语言
数据结构基础详解(C语言): 栈的括号匹配(实战)与栈的表达式求值&&特殊矩阵的压缩存储
本文首先介绍了栈的应用之一——括号匹配,利用栈的特性实现左右括号的匹配检测。接着详细描述了南京理工大学的一道编程题,要求判断输入字符串中的括号是否正确匹配,并给出了完整的代码示例。此外,还探讨了栈在表达式求值中的应用,包括中缀、后缀和前缀表达式的转换与计算方法。最后,文章介绍了矩阵的压缩存储技术,涵盖对称矩阵、三角矩阵及稀疏矩阵的不同压缩存储策略,提高存储效率。
|
23天前
|
存储 C语言
数据结构基础详解(C语言): 栈与队列的详解附完整代码
栈是一种仅允许在一端进行插入和删除操作的线性表,常用于解决括号匹配、函数调用等问题。栈分为顺序栈和链栈,顺序栈使用数组存储,链栈基于单链表实现。栈的主要操作包括初始化、销毁、入栈、出栈等。栈的应用广泛,如表达式求值、递归等场景。栈的顺序存储结构由数组和栈顶指针构成,链栈则基于单链表的头插法实现。
142 3