zend php 动态数组
浏览:1516次 出处信息
对C语言有过了解的同学,都知道C语内置了数组类型,可是C数组是静态的—数组的长度在编译时期便已确定了长度(分配了内存)。甚至你都不能这么着使用
const int arr_size = 100; char foo[arr_size];
使用数组即有较高的随机访问特性,但我们在很多实际运用场景都无法预先知道加载数据的长度,却又不舍得一开始就建立一个“巨大”的固定长度的表(数组)。解决这个问题,可以使用链表(参见链表ADT),或者使用动态数组。这里主要介绍一下后者—-动态数组。其基本思路是先使用库函数mallo()分配一块内存,这块内存块连续存放着相应的数据单元,每个单元占用的内存空间是一样大小,然后,像引用数组那样借用指针引用这块内存,通过指针和偏移量可以随机访问各个单元的数据。当这块内存写满的时候,可以调用库函数realloc()重新分配更大空间的内存(函数realloc()不会丢失原来的内存块上的数据)。
我从php源码目录里zend目录扒了一份动态数据源代码,供大家一起学习。(http://lxr.php.net/xref/PHP_5_2/Zend/zend_dynamic_array.c)
/* file:zend_dynamic_arr.h */ #ifndef cstuff_zend_dynamic_arr_h #define cstuff_zend_dynamic_arr_h typedef struct _zend_dynamic_array { char *array; unsigned int element_size; unsigned int current; unsigned int allocated; } dynamic_array; int zend_dynamic_array_init(dynamic_array *darr, unsigned int element_size, unsigned int size); void *zend_dynamic_array_push(dynamic_array *darr); void *zend_dynamic_array_pop(dynamic_array *darr); void *zend_dynamic_array_get(dynamic_array *darr, unsigned int index); int zend_dynamic_array_destroy(dynamic_array *darr); int zend_dynamic_array_length(dynamic_array *darr); #endif /* @file:zend_dynamic_arr.c */ #include <stdio.h> #include <stdlib.h> #include "zend_dynamic_arr.h" int zend_dynamic_array_init(dynamic_array *darr, unsigned int element_size, unsigned int size) { darr->array = (char *)malloc(element_size * size); if (darr->array == NULL) { fprintf(stderr, "init(), out of memory\n"); return -1; } darr->element_size = element_size; darr->allocated = size; darr->current = 0; return 0; } void *zend_dynamic_array_push(dynamic_array *darr) { if (darr->current >= darr->allocated) { darr->allocated *= 2; darr->array = (char *)realloc(darr->array, darr->allocated); if (!darr->array) { fprintf(stderr, "push(), out of memory\n"); exit(EXIT_FAILURE); } } return (void *)(darr->array + (darr->current++) * darr->element_size); } void *zend_dynamic_array_get(dynamic_array *darr, unsigned int index) { if (index >= darr->current) { fprintf(stderr, "get(), key error\n"); return NULL; } return (void *)(darr->array + index * darr->element_size); } void *zend_dynamic_array_pop(dynamic_array *darr) { if (darr->current > 0) { return (void *)(darr->array + (--(darr->current)) * darr->element_size); } return NULL; } int zend_dynamic_array_destroy(dynamic_array *darr) { if (!darr->array) { free(darr->array); darr->current = 0; darr->allocated = 0; } return 0; } int zend_dynamic_array_length(dynamic_array *darr) { return darr->current; } char *zend_dynamic_array_ref(dynamic_array *darr) { if (darr->current > 0) { return (char *)darr->array[0]; } return NULL; } /* @file:zend_dynamic_arr_echo.c */ #include <stdio.h> #include <stdlib.h> #include "zend_dynamic_arr.h" #define INIT_SIZE 1024 int main(int argc, char **argv) { dynamic_array buffer; char *bp; int c; if (zend_dynamic_array_init(&buffer, sizeof(char), INIT_SIZE) == -1 ) { fprintf(stderr, "init failed\n"); exit(EXIT_FAILURE); } while ((c = getchar()) != EOF) { if ((bp = zend_dynamic_array_push(&buffer)) != NULL) { *bp = (char)c; } } bp = zend_dynamic_array_push(&buffer); if (bp != NULL) { *bp = '\0'; } bp = zend_dynamic_array_get(&buffer, 0); if (bp != NULL) {printf("%s", bp); zend_dynamic_array_destroy(&buffer); } return 0; } /* @file:Makefile_ZDarray */ echo_darr:zend_dynamic_arr.o zend_dynamic_arr_echo.c cc -o echo_darr zend_dynamic_arr.o zend_dynamic_arr_echo.c zend_dynamic_arr.o:zend_dynamic_arr.h clean: -rm -f echo_zd_array zend_dynamic_arr.o
我们可以另外用一个例程(使用数组)对比,参见代码如下:
#include <stdio.h> #define MAX_SIZE 1024 int main(int argc, char **argv) { char buffer[MAX_SIZE]; int i, c, limit; i = 0, limit = MAX_SIZE; while (--limit > 0 && (c = getchar()) != EOF) { buffer[i++] = (char)c; } if (i > 0) { buffer[i] = '\0';printf("%s", buffer); } return 0; }
最后,我们可以看看两个例程(echo_arr和echo_darr)输出对比,可以看到dynamic array和array的应用场景会不同。
ryoumatoMacBook-Pro:cstuff 3river$ cat linklist.c |./echo_darr |wc -c 3755 ryoumatoMacBook-Pro:cstuff 3river$ cat linklist.c |./echo_arr |wc -c 1023 ryoumatoMacBook-Pro:cstuff 3river$ cat linklist.c |wc -c 3755
建议继续学习:
- django中动态生成form表单 (阅读:3529)
- 建立动态规划状态转移方程的练习 (阅读:3128)
- 用C++面向对象的方式动态加载so (阅读:2881)
- 思考mysql内核之初级系列9---innodb动态数组的实现 (阅读:2116)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:C的那些事儿
后一篇:代码里的命名规则:错误的和正确的对比 >>
文章信息
- 作者:echo 来源: performance geeks
- 标签: 动态 动态数组
- 发布时间:2013-06-02 20:26:56
近3天十大热文
- [54] IOS安全–浅谈关于IOS加固的几种方法
- [52] android 开发入门
- [52] 如何拿下简短的域名
- [51] 图书馆的世界纪录
- [49] Go Reflect 性能
- [49] Oracle MTS模式下 进程地址与会话信
- [47] 【社会化设计】自我(self)部分――欢迎区
- [46] 读书笔记-壹百度:百度十年千倍的29条法则
- [35] 程序员技术练级攻略
- [27] 视觉调整-设计师 vs. 逻辑