c vector
1.0.0
这是一个类似于std::vector
可增长数组的实现,但采用纯 C89 代码。结果是一个类型安全、易于使用的动态数组,具有一组熟悉的操作。
它的工作原理是使用与许多分配器相同的技巧,即稍微分配比请求更多的数据,并使用前面的额外填充作为元数据的存储。因此,任何非空向量在内存中看起来都是这样的:
+-----------------+------+----------+---------+
| elem_destructor | size | capacity | data... |
+-----------------+------+----------+---------+
^
| user's pointer
其中向用户提供指向data
第一个元素的指针。这样,代码可以轻松访问必要的元数据,但用户无需关心这些细节。每个向量的总开销为2 * sizeof(size_t) + sizeof(void (*)(void *))
。
为了使代码最大限度地通用,它被实现为所有宏,因此仅是标头。用法很简单:
/* if this is defined, then the vector will double in capacity each
* time it runs out of space. if it is not defined, then the vector will
* be conservative, and will have a capcity no larger than necessary.
* having this defined will minimize how often realloc gets called.
*/
#define CVECTOR_LOGARITHMIC_GROWTH
#include "cvector.h"
#include <stdio.h>
int main ( int argc , char * argv []) {
/* this is the variable that will store the array, you can have
* a vector of any type! For example, you may write float *v = NULL,
* and you'd have a vector of floats :-). NULL will have a size
* and capacity of 0. Additionally, vector_begin and vector_end will
* return NULL on a NULL vector. Alternatively, for clarity of writing
* you can use the cvector_vector_type macro to define a vector of a
* given type.
*/
cvector_vector_type ( int ) v = NULL ;
( void ) argc ;
( void ) argv ;
/* add some elements to the back */
cvector_push_back ( v , 10 );
cvector_push_back ( v , 20 );
cvector_push_back ( v , 30 );
cvector_push_back ( v , 40 );
/* remove an element by specifying an array subscript */
cvector_erase ( v , 2 );
/* remove an element from the back */
cvector_pop_back ( v );
/* print out some stats about the vector */
printf ( "pointer : %pn" , ( void * ) v );
printf ( "capacity: %lun" , cvector_capacity ( v ));
printf ( "size : %lun" , cvector_size ( v ));
/* iterator over the vector using "iterator" style */
if ( v ) {
int * it ;
int i = 0 ;
for ( it = cvector_begin ( v ); it != cvector_end ( v ); ++ it ) {
printf ( "v[%d] = %dn" , i , * it );
++ i ;
}
}
/* iterator over the vector standard indexing too! */
if ( v ) {
size_t i ;
for ( i = 0 ; i < cvector_size ( v ); ++ i ) {
printf ( "v[%lu] = %dn" , i , v [ i ]);
}
}
/* well, we don't have destructors, so let's clean things up */
cvector_free ( v );
return 0 ;
}
std::vector | cvector |
---|---|
std::vector<int> v | cvector(int) v |
析构函数 | cvector_free(v) |
v.at(3) | cvector_at(v, 3) |
v[3] | v[3] |
v.front() | cvector_front(v) |
v.back() | cvector_back(v) |
v.begin() | cvector_begin(v) |
v.end() | cvector_end(v) |
v.empty() | cvector_empty(v) |
v.size() | cvector_size(v) |
v.capacity() | cvector_capacity(v) |
v.shrink_to_fit() | cvector_shrink_to_fit(v) |
v.clear() | cvector_clear(v) |
v.insert(pos, value) | cvector_insert(v, pos, value) |
v.erase(v.begin() + 2) | cvector_erase(v, 2) |
v.push_back(value) | cvector_push_back(v, value) |
v.pop_back() | cvector_pop_back(v) |
v.reserve(new_cap) | cvector_reserve(v, new_cap) |
v.resize(count) | cvector_resize(v, count) |
v.swap(other) | cvector_swap(v, other) |
std::vector<int> other = v; | cvector(int) other; cvector_copy(v, other); |