Zend引擎对栈常量的定义:
#define ZEND_STACK_APPLY_TOPDOWN 1//由顶部向底部对栈进行遍历操作
#define ZEND_STACK_APPLY_BOTTOMUP 2//由底部向顶部对栈进行遍历操作
#define STACK_BLOCK_SIZE 64 //每次扩容的元素个数
看一下Zend引擎栈的数据结构定义:
typedef struct _zend_stack {
int top;//栈顶,用数字表示(从底到顶分别为0,1,2...)
int max;//栈当前最大元素个数,当栈满后会将max+STACK_BLOCK_SZE来进行扩容
void **elements;//栈元素指针数组
} zend_stack;
栈的常用操作如下:
//初始化栈,不包含zend_stack结构的内存分配。仅初始化top, max的值和elements的值。
ZEND_API int zend_stack_init(zend_stack *stack)
{
stack->top = 0;
stack->max = 0;
stack->elements = NULL;
return SUCCESS;
}
//以memcpy的方式将element元素复制入栈。size表示元素的大小。
ZEND_API int zend_stack_push(zend_stack *stack, const void *element, int size)
{
if (stack->top >= stack->max) { /* we need to allocate more memory */
stack->elements = (void **) erealloc(stack->elements,
(sizeof(void **) * (stack->max += STACK_BLOCK_SIZE)));
//当栈满后会将max+STACK_BLOCK_SZE来进行扩容
if (!stack->elements) {
return FAILURE;
}
}
stack->elements[stack->top] = (void *) emalloc(size);
memcpy(stack->elements[stack->top], element, size);
return stack->top++;
}
//获取栈顶部元素的指针,并赋值给**element
ZEND_API int zend_stack_top(const zend_stack *stack, void **element)
{
if (stack->top > 0) {
*element = stack->elements[stack->top - 1];
return SUCCESS;
} else {
*element = NULL;
return FAILURE;
}
}
//删除栈顶。
ZEND_API int zend_stack_del_top(zend_stack *stack)
{
if (stack->top > 0) {
efree(stack->elements[--stack->top]);
}
return SUCCESS;
}
//返回栈顶元素的指针的值
ZEND_API int zend_stack_int_top(const zend_stack *stack)
{
int *e;
if (zend_stack_top(stack, (void **) &e) == FAILURE) {
return FAILURE; /* this must be a negative number, since negative numbers can't be address numbers */
} else {
return *e;
}
}
//根据stack->top的值来判断栈是否为空.stack->top用数字来表示的好处。
ZEND_API int zend_stack_is_empty(const zend_stack *stack)
{
if (stack->top == 0) {
return 1;
} else {
return 0;
}
}
//销毁栈。其实也可以while(stack->top--){zend_stack_del_top(stack)};stack->elements = NULL;
ZEND_API int zend_stack_destroy(zend_stack *stack)
{
int i;
if (stack->elements) {
for (i = 0; i < stack->top; i++) {
efree(stack->elements[i]);
}
efree(stack->elements);
stack->elements = NULL;
}
return SUCCESS;
}
//直接返回栈数据元素指针
ZEND_API void **zend_stack_base(const zend_stack *stack)
{
return stack->elements;
}
//返回栈元素个数。这就是用数字来表示栈顶而不直接用指针来表示的好处。
ZEND_API int zend_stack_count(const zend_stack *stack)
{
return stack->top;
}
//遍历栈并执行函数。注意,传入的函数返回值为int型。为0时表示函数执行成功,为1时表示函数执行失败。
ZEND_API void zend_stack_apply(zend_stack *stack, int type, int (*apply_function)(void *element))
{
int i;
switch (type) {
//自顶向下执行
case ZEND_STACK_APPLY_TOPDOWN:
for (i=stack->top-1; i>=0; i--) {
if (apply_function(stack->elements[i])) {
break;
}
}
break;
//自底向上执行
case ZEND_STACK_APPLY_BOTTOMUP:
for (i=0; itop; i++) {
if (apply_function(stack->elements[i])) {
break;
}
}
break;
}
}
//与zend_stack_apply函数一样,都是遍历栈并执行函数。但此函数支持调用函数传递参数。
ZEND_API void zend_stack_apply_with_argument(zend_stack *stack, int type, int (*apply_function)(void *element, void *arg), void *arg)
{
int i;
switch (type) {
case ZEND_STACK_APPLY_TOPDOWN:
for (i=stack->top-1; i>=0; i--) {
if (apply_function(stack->elements[i], arg)) {
break;
}
}
break;
case ZEND_STACK_APPLY_BOTTOMUP:
for (i=0; itop; i++) {
if (apply_function(stack->elements[i], arg)) {
break;
}
}
break;
}
}