ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

utarray详解

2022-07-24 12:04:50  阅读:147  来源: 互联网

标签:int UT void icd 详解 utarray array


库函数

//必须要有,程序开头先声明UT_array变量,然后调用utarray_new,程序结束前要记得调用utarray_free,否则堆内存不被释放
utarray_new(UT_array *a, UT_icd *icd)
utarray_free(UT_array *a)
//最常用的函数
utarray_push_back(UT_array *a,void *p)
utarray_pop_back(UT_array *a)
utarray_front(UT_array *a)
utarray_back(UT_array *a)
utarray_len(UT_array *a)
utarray_eltptr(UT_array *a,int j)
utarray_eltidx(UT_array *a,void *e)
//相对不常用的函数
utarray_insert(UT_array *a,void *p, int j)
utarray_resize(UT_array *dst,int num)
utarray_concat(UT_array *dst,UT_array *src)
utarray_clear(UT_array *a)
utarray_sort(UT_array *a, cmpfunc *cmp)
utarray_find(UT_array *a, void *v, cmpfunc *cmp)

utarray_new: 先声明UT_array指针做第一个参数,第二个参数是自定义类型,库给了三种预设类型: ut_str_icd, ut_int_icd, ut_ptr_icd,要传地址进去。
utarray_free: 释放堆内存,最后必须有
utarray_push_back: 末尾添加节点,传入的是指针,所以数字必须取地址,字面量也不行(封装函数转一下就可以了)
utarray_pop_back: 弹出末尾节点。
utarray_front: 返回头节点指针。
utarray_back: 返回尾节点指针。
utarray_len: 返回数组长度。
utarray_eltptr: 根据索引返回节点指针。
utarray_eltidx: 根据节点地址返回索引。
utarray_insert: 在索引为j的位置插入一个元素,复杂度O(N),慎用。
utarray_resize: 把数组的长度改成参数二的值,长了截断断了增补。
utarray_concat: 拼接两个数组
utarray_clear: 数组清空,注意,这里会根据UT_icd注册的函数执行清空,如果注册的是NULL,就只是把长度变为0
utarray_sort: cmp书写规则类似于qsort。
utarray_find: 内部使用二分查找实现,所以必须排过序(升序降序都可以),比较函数必须和utarray_sort的一样。参数二是待搜索值的地址。

正文

int cmp(const void *a, const void *b)
{
	return *(int *)b - *(int *)a;
}

size_t Find(UT_array *arr, const int num)
{
	void *temp = utarray_find(arr, &num, cmp);
	if (temp)
	{
		return (int)utarray_eltidx(arr, temp);
	}
	else
	{
		return -1;
	}
}

int main()
{
	UT_array *arr;
	utarray_new(arr, &ut_int_icd);
	for (int i = 1; i <= 11111111; i = i * 10 + 1)
	{
		utarray_push_back(arr, &i);
	}

	for (int i = 0; i < utarray_len(arr); i++)
	{
		printf("%d: %d\n", i, *(int *)utarray_eltptr(arr, i));
	}
	utarray_pop_back(arr);
	utarray_pop_back(arr);
	printf("========pop %d times========\n", 2);
	for (int i = 0; i < utarray_len(arr); i++)
	{
		printf("%d: %d\n", i, *(int *)utarray_eltptr(arr, i));
	}
	utarray_sort(arr, cmp);
	printf("========sorted========\n");
	for (int i = 0; i < utarray_len(arr); i++)
	{
		printf("%d: %d\n", i, *(int *)utarray_eltptr(arr, i));
	}
	printf("11 idx: %d\n", Find(arr, 11));
	printf("111111 idx: %d\n", Find(arr, 111111));
	utarray_free(arr);
	return 0;
}

程序执行了以下操作:

  1. 数组内用棍填充,最大填充到八棍。
  2. 打印。
  3. pop两个元素。
  4. 再次打印。
  5. 降序排序数组。
  6. 再次打印。
  7. 搜索并打印11和111111的位置。

最终结果:

0: 1
1: 11
2: 111
3: 1111
4: 11111
5: 111111
6: 1111111
7: 11111111
========pop 2 times========
0: 1
1: 11
2: 111
3: 1111
4: 11111
5: 111111
========sorted========
0: 111111
1: 11111
2: 1111
3: 111
4: 11
5: 1
11 idx: 4
111111 idx: 0

搜索函数封装了下,写起来更加直观,查不到时总能正确返回-1。

后记

变长数组有什么用?
在某些场合下内存开销会更小,而且同时具有栈和数组的特性,但是时间开销上要比定长数组要大一些。
总的来说,就像C++里面vector一样。你说我只用定长数组行不行?当然可以,甚至大多数情况下时间复杂度更小。那为什么用vector?还不是因为香而且代价也不大?

标签:int,UT,void,icd,详解,utarray,array
来源: https://www.cnblogs.com/mrzono/p/16513969.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有