common.c文件
这里的common.c是在samgr下面source一个子文件,samgr的作用是Manages system capabilities,也就是管理系统功能,它主要提供面向服务的体系结构(SOA)的开发框架基础。还提供了服务的基本模型、特性模型、功能模型和注册模型以及发现功能,我们还可以基于samgr框架节构开发自己的接口等功能,而common在里扮演什么角色呢?--------就是提供Samgr和外部模块的常用对象和函数,具体一点就是这个文件提供了简化的矢量容器和向下转换函数。
背景知识
1.C++ 中vector介绍
vector是一个线性顺序结构。相当于数组,但其大小可以不预先指定,并且自动扩展。它可以像数组一样被操作,由于它的特性我们完全可以将vector 看作动态数组。
在创建一个vector 后,它会自动在内存中分配一块连续的内存空间进行数据存储,初始的空间大小可以预先指定也可以由vector 默认指定,这个大小即capacity ()函数的返回值。当存储的数据超过分配的空间时vector 会重新分配一块内存块,但这样的分配是很耗时的,在重新分配空间时它会做这样的动作:
- 首先,vector 会申请一块更大的内存块;
- 然后,将原来的数据拷贝到新的内存块中;
- 其次,销毁掉原内存块中的对象(调用对象的析构函数);
- 最后,将原来的内存空间释放掉。
如果vector 保存的数据量很大时,这样的操作一定会导致糟糕的性能(这也是vector 被设计成比较容易拷贝的值类型的原因)。所以说vector 不是在什么情况下性能都好,只有在预先知道它大小的情况下vector 的性能才是最优的。
vector特点
(1) 指定一块如同数组一样的连续存储,但空间可以动态扩展。即它可以像数组一样操作,并且可以进行动态操作。通常体现在push_back() pop_back() 。
(2) 随机访问方便,它像数组一样被访问,即支持[ ] 操作符和vector.at()
(3) 节省空间,因为它是连续存储,在存储数据的区域都是没有被浪费的,但是要明确一点vector 大多情况下并不是满存的,在未存储的区域实际是浪费的。
(4) 在内部进行插入、删除操作效率非常低,这样的操作基本上是被禁止的。Vector 被设计成只能在后端进行追加和删除操作,其原因是vector 内部的实现是按照顺序表的原理。
(5) 只能在vector 的最后进行push 和pop ,不能在vector 的头进行push 和pop 。
(6) 当动态添加的数据超过vector 默认分配的大小时要进行内存的重新分配、拷贝与释放,这个操作非常消耗性能。 所以要vector 达到最优的性能,最好在创建vector 时就指定其空间大小。
Vectors 包含着一系列连续存储的元素,其行为和数组类似。访问Vector中的任意元素或从末尾添加元素都可以在常量级时间复杂度内完成,而查找特定值的元素所处的位置或是在Vector中插入元素则是线性时间复杂度。
我们这里的vector是自己建立的一个容器,并不是c++自带的封装好的,而是原理一样,使用c语言的进行封装的定义。下面来看代码部分
代码分析
1.VECTOR_Make
函数功能:创建一个vector容器
//这里是制作一个容器
Vector VECTOR_Make(VECTOR_Key key, VECTOR_Compare compare)
{
Vector vector = {
0, 0, 0, NULL, key, compare};
return vector;
}
2.VECTOR_Clear
函数功能:容器中元素和各个属性的清除
//容器的清楚
void VECTOR_Clear(Vector *vector)
{
if (vector == NULL) {
return;
}
if (vector->data == NULL) {
return;
}
//对容器判空或者容器中数据判空,如果是空值就返回
SAMGR_Free(vector->data);
vector->max = 0;
vector->top = 0;
vector->free = 0;
vector->data = NULL;
}
3.VECTOR_Add
函数功能:在容器中添加一个元素
int16 VECTOR_Add(Vector *vector, void *element)
{
if (vector == NULL || element == NULL) {
return INVALID_INDEX;
}
if (vector->top >= vector->max) {
int16 i;
// use released data elements preferentially
for (i = vector->top - (int16)1; i >= 0; --i) {
if (vector->data[i] == NULL) {
vector->data[i] = element;
vector->free--;
return i;
}
}
if (vector->max + GROW_STEP < 0) {
return INVALID_INDEX;
}
void **data = (void **)SAMGR_Malloc(sizeof(void *) * (vector->max + GROW_STEP));
if (data == NULL) {
return INVALID_INDEX;
}
if (vector->data != NULL) {
// data's length is bigger than vector->data's length and only copy vector->data's length's memory;
// no need to check return value
(void)memcpy_s(data, sizeof(void *) * (vector->max + GROW_STEP),
vector->data, sizeof(void *) * vector->max);
SAMGR_Free(vector->data);
}
vector->data = data;
vector->max += GROW_STEP;
}
vector->data[vector->top] = element;
return vector->top++;
}
void *VECTOR_At(Vector *vector, int16 index)
{
if (vector == NULL || vector->top <= index || index < 0) {
return NULL;
}
return vector->data[index];
}
4.VECTOR_At
函数功能:这里的at函数主要是根据索引值在容器的data对应区域拿出相应值
如果参数都合法,就是去除index对应的数据域的数据。
void *VECTOR_At(Vector *vector, int16 index)
{
if (vector == NULL || vector->top <= index || index < 0) {
return NULL;
}
return vector->data[index];
}
5.VECTOR_Swap
函数参数:
- vector:传入一个容器
- element:要替换位置的元素
- index:数据域的索引值,也是要交换的另一个数
函数原理:就是根据index对印的数据和函数传入的数据element进行swap,函数最后返回之前data[index]
函数功能:在容器数据与实现数据替换
void *VECTOR_Swap(Vector *vector, int16 index, void *element)
{
if (vector == NULL || vector->top <= index || index < 0) {
return NULL;
}
//先检查对应参数
if (element == NULL) {
vector->free++;
}
//查看要交换的数据是否为空
void *oldElement = vector->data[index];
vector->data[index] = element;
return oldElement;
//实现替换函数返回之前的值
}
6.VECTOR_Find
函数功能:函数元素的查找
函数实现:这个函数的原理就是调用findbykey函数,就是findbykey函数的封装
int16 VECTOR_Find(Vector *vector, const void *element)
{
if (vector == NULL || element == NULL) {
return INVALID_INDEX;
}
return VECTOR_FindByKey(vector, (vector->key == NULL) ? element : vector->key(element));
}
7.VECTOR_FindByKey
函数功能:根据传入的key值在容器中找到对应的元素索引
函数原理,就是遍历所有容器键值对,看哪个key值满足要求,拿出对应键值元素的索引
int16 VECTOR_FindByKey(Vector *vector, const void *key)
{
if (vector == NULL || key == NULL) {
return INVALID_INDEX;
}
//第一步是检查参数是否合法
int16 i;
for (i = 0; i < vector->top; ++i) {
if (vector->data[i] == NULL) {
continue;
}
void *first = (vector->key != NULL) ? vector->key(vector->data[i]) : vector->data[i];
//获取元素的key值
if (first == key) {
return i;
}
if (vector->compare == NULL || first == NULL) {
continue;
}
//判断上一步是否成功
if (vector->compare(first, key) == 0) {
return i;
}
//比较first获取的key值和函数传入key比对,看是否一样。
}
return INVALID_INDEX;
}
8.VECTOR_Size&VECTOR_Num
函数功能:这两个函数都是容器相关属性的计算,一个是计算容器的size(就决定于top),另一个是计算元素个数,就是top减去free
这两个函数都相对简单,就是容器一些属性的计算。
//容器size的计算
int16 VECTOR_Size(Vector *vector)
{
if (vector == NULL) {
return INVALID_INDEX;
}
return vector->top;
}
//容器元素的计数
int16 VECTOR_Num(Vector *vector)
{
if (vector == NULL) {
return INVALID_INDEX;
}
return vector->top - vector->free;
}
感谢阅读和点赞!