1、zend_hash_num_elements 获取数组元素个数。宏定义如下:
 #define zend_hash_num_elements(ht) \
(ht)->nNumOfElements
2、ZEND_HASH_FOREACH_KEY_VAL 遍历数组键值。使用方法:
 ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_key, string_key, entry) {
// code
} ZEND_HASH_FOREACH_END();
 ZEND_HASH_FOREACH_KEY_VAL是个宏函数:
 #define ZEND_HASH_FOREACH_KEY_VAL(ht, _h, _key, _val) \
ZEND_HASH_FOREACH(ht, ); \
_h = _p->h; \
_key = _p->key; \
_val = _z;

   继续展开 ZEND_HASH_FOREACH:

 #define ZEND_HASH_FOREACH(_ht, indirect) do { \
Bucket *_p = (_ht)->arData; \
Bucket *_end = _p + (_ht)->nNumUsed; \
for (; _p != _end; _p++) { \
zval *_z = &_p->val; \
if (indirect && Z_TYPE_P(_z) == IS_INDIRECT) { \
_z = Z_INDIRECT_P(_z); \
} \
if (UNEXPECTED(Z_TYPE_P(_z) == IS_UNDEF)) continue;
ZEND_HASH_FOREACH_END展开:
 #define ZEND_HASH_FOREACH_END() \
} \
} while ()
ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_key, string_key, entry) {
// code
} ZEND_HASH_FOREACH_END();
完全展开:
 do {
Bucket *_p = (_ht)->arData; // Z_ARRVAL_P(array) ---> ht ---> _ht
Bucket *_end = _p + (_ht)->nNumUsed; // 起始地址+偏移地址
for (; _p != _end; _p++) {
zval *_z = &_p->val;
if (indirect && Z_TYPE_P(_z) == IS_INDIRECT) {
_z = Z_INDIRECT_P(_z);
}
if (UNEXPECTED(Z_TYPE_P(_z) == IS_UNDEF)) continue;
_h = _p->h; // zend_ulong num_key ---> _h
_key = _p->key; // zend_string *string_key ---> _key
_val = _z; // zval *entry ---> _val
{
//code
}
}
} while ()

 
 

php内核之数组的更多相关文章

  1. 深入PHP内核之数组

    定义: PHP 中的数组实际上是一个有序映射.映射是一种把 values 关联到 keys 的类型.此类型在很多方面做了优化,因此可以把它当成真正的数组,或列表(向量),散列表(是映射的一种实现),字 ...

  2. [翻译] Linux 内核中的位数组和位操作

    目录 Linux 内核里的数据结构 原文链接与说明 Linux 内核中的位数组和位操作 位数组声明 体系结构特定的位操作 通用位操作 链接 Linux 内核里的数据结构 原文链接与说明 https:/ ...

  3. Netlink 内核实现分析 2

    netlink 应用层如何创建socket 应用层通过socket()系统调用创建Netlink套接字,socket系统调用的第一个参数可以是AF_NETLINK或PF_NETLINK(在Linux系 ...

  4. kernel编程规范

    1. 制表符8个空格2. 每行最长80字符3. 代码块的{放在首行,但是函数的{放在次行4. 只有一行的if块,不加{}5. 不在()前后加空格6. 正常关键字后加一个空格,if, switch, c ...

  5. select、poll、epoll三组IO复用

    int select(int nfds,fd_set* readfds,fd_set* writefds,fd_set* exceptfds,struct timeval* timeout)//其中n ...

  6. Linux中的IO复用接口简介(文件监视?)

    I/O复用是Linux中的I/O模型之一.所谓I/O复用,指的是进程预先告诉内核,使得内核一旦发现进程指定的一个或多个I/O条件就绪,就通知进程进行处理,从而不会在单个I/O上导致阻塞. 在Linux ...

  7. Linux Platform驱动模型(二) _驱动方法

    在Linux设备树语法详解和Linux Platform驱动模型(一) _设备信息中我们讨论了设备信息的写法,本文主要讨论平台总线中另外一部分-驱动方法,将试图回答下面几个问题: 如何填充platfo ...

  8. Linux Platform驱动模型(二) _驱动方法【转】

    转自:http://www.cnblogs.com/xiaojiang1025/archive/2017/02/06/6367910.html 在Linux设备树语法详解和Linux Platform ...

  9. 嵌入式:UCOSIII的使用(17.01.24补充)

    0.一些移植.系统相关 OS_CFG_APP.H /* --------------------- MISCELLANEOUS ------------------ */ #define OS_CFG ...

随机推荐

  1. CentOS7--删除virbr0

    https://blog.csdn.net/aienjoy/article/details/78994128

  2. 树链剖分&咕咕咕了好久好久的qtree3

    前言 显然qtree系列都是树链剖分辣 发现自己没有专门整理过树链剖分耶 辣么就把这篇博客魔改成树链剖分好辣(貌似除了树剖也没什么好写的) 正文 废话了辣么多终于开始了 一.树剖怎么写鸭 二.树剖有什 ...

  3. GTX 1060 3GB 能否使用DeepFaceLab ?

    大部分人都知道跑换脸软件对电脑配置的要求比较高.所以当你想要开始玩之前都会有一个疑问:我的电脑能跑起来了么?或者我的电脑能跑那个模型? 之前写过一篇750 1G显卡如何玩deepfakes的文章.今天 ...

  4. linux shell 中"2>&1"含义-完美理解-费元星

    笨鸟先飞,先理解.   脚本是:      nohup /mnt/Nand3/H2000G  >/dev/null  2>&1  &      对于& 1 更准确的 ...

  5. java dwg转svg

    package com.example.demo.dxf2svg; import com.aspose.cad.InterpolationMode; import com.aspose.cad.Smo ...

  6. 阶段3 1.Mybatis_04.自定义Mybatis框架基于注解开发_2 回顾自定义mybatis的流程分析

  7. c++ 创建 uuid guid

    如果没安装,先安装: [root@localhost]# yum install libuuid-devel #include "uuid/uuid.h" 引用 libuuid.s ...

  8. 【MM系列】SAP 物料进销存报表查看

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]在SAP里查看数据的方法   前言部 ...

  9. 【MM系列】SAP MM模块-配置PO的创建时间

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP MM模块-配置PO的创建时间 ...

  10. cocos2dx基础篇(21) 进度条CCProgressTimer

    [3.x] (1)去掉 "CC" (2)CCProgressTimerType 改为强枚举 ProgressTimer::Type:: // RADIAL //扇形进度计时器 BA ...