在数组和哈希表上工作
在C语言中, 有两种不同的基础方法用来在一个结构体中存储任意数量的独立数据元素. 两种方法都有赞成者和反对者.
向量 Vs. 链表
应用的编写通常基于特定类型数据的特性的选择, 需要存储多少数据, 以及需要多快速度的检索. 为了能够有对等的认知, 我们先来看看简单的看看这些存储机制.
向量
向量是一块连续的内存空间, 它们包含的数据有规律的间隔. 向量最常见的例子就是字符串变量(char *或char []), 它包含了一个接着一个的字符(字节)序列.
char foo[4] = "bar";
这里, foo[0]包含了字符'b'; 紧接着, 你将在foo[1]中找到字符'a', 最后在foo[3]中是一个空字符'\0'.
将指向其他结构的指针存储到向量中的用法几乎是无所不在的, 比如在上一章, 使用zend_get_parameters_array_ex()函数时, 就使用了一个zval的向量. 那里, 我们看到var_dump()定义了一个zval ***的函数变量, 接着为它分配空间用来存储zval **指针(最终的数据来自zend_get_parameters_ex()调用)
zval ***args = safe_emalloc(ZEND_NUM_ARGS(), sizeof(zval**), 0);
和访问字符串中的数组一样, var_dump()实现中使用args[i]依次传递每个zval **元素到内部函数php_var_dump().
向量最大的优点在于运行时单个元素的访问速度. args[i]这样的变量引用, 可以很快的计算出它的数据地址(args + i * sizeof(args[0]). 这个索引结构的空间分配和释放是在单次, 高效的调用中完成的.
链表
另外一种常见的存储数据的方式是链表. 对于链表而言, 每个数据元素都是一个至少有两个属性的结构体: 一个指向链表中的下一个节点, 一个则是实际的数据. 考虑下面假设的数据结构:
typedef struct _namelist namelist; struct { struct namelist *next; char *name; } _namelist;
使用这个数据结构的引用需要定义一个变量:
static namelist *people;
链表中的第一个名字可以通过检查people变量的name属性得到: people->name; 第二个名字则访问next属性: people->next->name, 依此类推: people->next->next->name等等, 直到next为NULL表示链表中已经没有其他名字了. 更常见的用法是使用循环迭代链表:
void name_show(namelist *p) { while (p) { printf("Name: %s\n", p->name); p = p->next; } }
这种链表非常适合于FIFO的链式结构, 新的数据被追加到链表的末尾, 从另外一端线性的消耗数据:
static namelist *people = NULL, *last_person = NULL; void name_add(namelist *person) { person->next = NULL; if (!last_person) { /* 链表中没有数据 */ people = last_person = person; return; } /* 向链表末尾增加新的数据 */ last_person->next = person; /* 更新链表尾指针 */ last_person = person; } namelist *name_pop(void) { namelist *first_person = people; if (people) { people = people->next; } return first_person; }
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索数据
, 变量
, next
, 哈希
, 向量
, 链表数组
, 一个
, 哈希调用例子
php哈希表
哈希表和数组的区别、数组 链表 哈希表、哈希表 数组、哈希表 数组的交集、数组实现哈希表,以便于您获取更多的相关知识。