C语言数据结构的套路
搬运自我的CSDN https://blog.csdn.net/u013213111/article/details/93784522
跟着DSAA in C写代码,总结起来各种数据结构大概都是这个套路:
首先是定义:
typedef struct XXXXX{
//数据结构包含的元素
} XXX
然后分配空间,malloc(sizeof(XXX))
对于用到数组来存储数据元素的,还要额外给数组分配空间,比如队列: Q->array = malloc(sizeof(int) * max);
最后用完之后一定要记得free!
这个套路用途广泛,比如想要把图片作为一个数据结构,首先可以这么定义:
typedef struct ImgStruct{
uint8_t *data;
int width;
int height;
} Image;
然后导入图片(这里用了OpenCV,是C++,需要给函数包装一下才可以被C调用):
Image *image_import(char *img_name){
Image *img;
img = (Image *)malloc(sizeof(Image));
cv::Mat img_mat = cv::imread(img_name, cv::IMREAD_GRAYSCALE);
img->width = img_mat.cols;
img->height = img_mat.rows;
int img_size = img_mat.cols * img_mat.rows;
img->data = (uint8_t *)malloc(img_size);
//cv::imshow("image", img);
for (int i = 0; i < img_mat.rows; i++)
{
for (int j = 0; j < img_mat.cols; j++)
{
img->data[i * img_mat.rows + j] = img_mat.at<uchar>(i, j);
}
}
return img;
}
在main函数中只需要这样既可:
Image *src; src = image_import("demo.bmp");
最后是free,设置NULL是防止悬空指针:
void image_free(Image *img){
free(img->data);
img->data = NULL;
free(img);
img = NULL;
}
强调一下悬空指针的问题,参考悬空指针(Dangling pointer)避免方法:
什么是悬空指针? 一个指针所指的内存被释放后,这个指针就被悬空了。 悬空指针的危害? 访问悬空指针,结果随机。可能导致程序功能不正常,也可能导致程序崩溃。如果受到影响的是其它功能,问题通常很难定位。 如何避免悬空指针? 基本思路:在释放一块内存时,将指向这块内存的指针变量设置为NULL。访问指针变量前,先判断是否为NULL。 进阶:当有多个指针变量都指向同一块内存时,释放这块内存时,需要将所有指针变量的值都置为NULL,这需要维护所有指向这块内存的指针变量的信息,但是这种方式开销大,所以通常很少使用。使用频率不是非常高的对象,可以在使用前先根据id等索引查找,如果找不到,则不要使用。如果有使用者时,不能释放这块内存,我们可以使用引用计数,只有当引用计数为0时,才真正释放内存,否则,只是引用计数减1。
BTW,DSAA中数据结构的各种函数多是传指针作为参数,传值的方法当然也可以,两者的区别可以参考C语言 结构体传值与传址分析:
结构体对象作为参数时,编译器对其进行了copy,(我们通过传入的地址和main中不同可以发现)。此时在函数中的操作都是对其拷贝的操作,不影响main函数中的origin value。缺点是,当结构体变量非常大时,编译器对其进行复制,开销较大。结构体地址作为参数时,子函数中操作和main函数操作的是同一个结构体,此时传递的参数时一个地址。优点是不需要进行copy,但是使用时要小心,如果不想修改其值,需用const关键字修饰。
以上是 C语言数据结构的套路 的全部内容, 来源链接: utcz.com/z/508950.html