目录
今天接着来讲解一下柔性数组知识。
C99中,结构中的最后一个元素允许是未知大小的数组,这就叫做【柔性数组】成员。
- 结构体中
- 最后一个成员
- 未知大小的数组【柔性数组】
- struct Stu
- {
- char c;
- int i;
- int arr[];
- //也可以这样写int arr[0]
- //未知大小的数组 -柔性数组成员
- };
我们来验证一下 【sizeof 返回的这种结构大小不包括柔性数组的内存。】--->【验证成功】
- #include
- struct Stu
- {
- char c;//1
- int i;//4
- //对齐规则:8
- int arr[];
- //也可以这样写int arr[0]
- //未知大小的数组 -柔性数组成员
- };
- int main()
- {
- printf("%d", sizeof(struct Stu));
- return 0;
- }
验证完之后,我们再来学习一下【动态内存函数在柔性数组上的应用】吧!
- #include
- struct Stu
- {
- char c;//1
- int i;//4
- //对齐规则:8
- int arr[];
- //也可以这样写int arr[0]
- //未知大小的数组 -柔性数组成员
- };
- int main()
- {
- struct Stu* p = (struct Stu*)malloc(sizeof(struct Stu)+20);//arr里放5个整型
- if (p == NULL)
- {
- perror("malloc");
- return 1;
- }
- free(p);
- p = NULL;
- return 0;
- }
- #include
- struct Stu
- {
- char c;//1
- int i;//4
- //对齐规则:8
- int arr[];
- //也可以这样写int arr[0]
- //未知大小的数组 -柔性数组成员
- };
- int main()
- {
- struct Stu* p = (struct Stu*)malloc(sizeof(struct Stu)+20);//arr里放5个整型
- if (p == NULL)
- {
- perror("malloc");
- return 1;
- }
- //发10个整型
- struct Stu* s = (struct Stu*)realloc(p, sizeof(struct Stu) + 40);
- if (s != NULL)
- {
- p = s;
- }
- else
- {
- perror("realloc");
- return 1;
- }
- //释放
- free(p);
- p = NULL;
- return 0;
- }
想必大家都知道为什么叫柔性数组,因为【利用realloc任意调整数组的空间大小】记得及时释放
柔性数组需要对齐吗?动动小手测试一下。需要40
对柔性数组赋值1,2,3,4,5并打印出来。
- #include
- #include
- struct Stu
- {
- char c;//1
- int i;//4
- //对齐规则:8
- int arr[];
- //也可以这样写int arr[0]
- //未知大小的数组 -柔性数组成员
- };
- int main()
- {
- struct Stu* p = (struct Stu*)malloc(sizeof(struct Stu)+20);//arr里放5个整型
- if (p == NULL)
- {
- perror("malloc");
- return 1;
- }
- p->c = 't';
- p->i = 7;
- int i = 0;
- for (i = 0;i < 5; i++)
- {
- p->arr[i] = i+1;
- }
- for (i = 0; i < 5; i++)
- {
- printf("%d ", p->arr[i]);
- }
- //放10个整型
- struct Stu* s = (struct Stu*)realloc(p, sizeof(struct Stu) + 40);
- if (s != NULL)
- {
- p = s;
- }
- else
- {
- perror("realloc");
- return 1;
- }
- //释放
- free(p);
- p = NULL;
- return 0;
- }
柔性数组还可以应用于【通讯录 】,后期我们也会去实现通讯录,并用【柔性数组】优化。
- #include
- #include
- struct S
- {
- char c;
- int i;
- int* a;
- };
- int main()
- {
- //为结构体开辟空间
- struct S* ps = (struct S*)malloc(sizeof(struct S));
- if (ps == NULL)
- {
- perror("malloc");
- return 1;
- }
- ps->c = 'T';
- ps->i = 7;
- ps->a = (int*)malloc(20);
- if ( ps->a == NULL)//注意写法ps->a
- {
- perror("malloc");
- return 1;
- }
- //使用
- int i = 0;
- for (i = 0; i < 5; i++)
- {
- ps->a[i] = i + 1;
- }
- for (i = 0; i < 5; i++)
- {
- printf("%d ", ps->a[i]);
- }
- //不够继续增加容
- int* pd = (int*)realloc(ps->a, 40);
- if (pd != NULL)
- {
- ps->a = pd;
- }
- else
- {
- perror("realloc");
- return 1;
- }
- printf("\n");
- //再次赋值
- int j = 0;
- for (j = 0; j < 10; j++)
- {
- ps->a[j] = j + 1;
- }
- for (j = 0; j < 10; j++)
- {
- printf("%d ", ps->a[j]);
- }
- //释放
- free(ps->a);
- ps->a = NULL;
- }
通过上面两端代码【柔性数组】和【指针】的比较,即便它们的功能一致,我们可以清晰的发现【柔性数组的优势】。
【优点1】方便释放 一次性就释放完全
如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,并把整个结构体返回给用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存一次性分配好了,并返回给用户一个结构体指针,用户做一次free就可以把所有的内存也给释放掉。
【优点2】这样有利于访问的速度,减少内存碎片,提高空间利用率
连续的内存有益于提高访问速度,也有益于减少内存碎片。
最后,有一篇文章,感谢他让我受益匪浅。
C语言结构体里的成员数组和指针 | 酷 壳 - CoolShell
【建议书】C陷阱与缺陷 高质量C\C++ 剑指offer 明解C语言等等
最后我想对我自己说,其实学习就是这样,刚开始并不喜欢计算机这门专业。其实我很想去选小语种西班牙语去到国外做翻译去看世界,而且我的理科思维并不好,但是在选择这门学科之后,当我开始认真的学习一些C语言的语法之后,我看到我自己独立写出来的游戏小程序的时候,还是挺有成就感,特别看到博客被大家看到,传递一些知识,还是很幸福的。写博客挺费时间的,但是我希望小唐可以一直坚持的学习,坚持写博客和交流知识。慢慢走,每一步都算数的。
✔✔✔✔✔最后,感谢大家的阅读,若有错误和不足,欢迎指正!
代码------→【gitee:唐棣棣 (TSQXG) - Gitee.com】
联系------→【邮箱:2784139418@qq.com】