当前位置: 首页 > news >正文

长治企业网站建设价格潍坊装饰网站建设

长治企业网站建设价格,潍坊装饰网站建设,创建网站怎么弄,wordpress底部链接修改柔性数组 一、前言二、柔性数组的用法三、柔性数组的内存分布四、柔性数组的优势五、总结 一、前言 仔细观察下面的代码#xff0c;有没有看出哪里不对劲#xff1f; struct S {int i;double d;char c;int arr[]; };还有另外一种写法#xff1a; struct S {int i;double … 柔性数组 一、前言二、柔性数组的用法三、柔性数组的内存分布四、柔性数组的优势五、总结 一、前言 仔细观察下面的代码有没有看出哪里不对劲 struct S {int i;double d;char c;int arr[]; };还有另外一种写法 struct S {int i;double d;char c;int arr[0]; };你应该一眼就看到了结构体的最后一个成员数组的写法是int arr[];或者是int arr[0]这两种写法是等价的意思是这个数组的大小是不确定的、未知的、可以变化的。 C99允许这种特殊的结构体存在。这样的结构体满足下面两个条件 最后一个成员变量是一个大小可以变化的数组。这个成员数组前面至少有另外一个成员变量。 我们称这个大小可以变化的成员数组为柔性数组。 注意柔性数组不能是结构体里唯一一个成员下面的代码是不允许的 struct S {int arr[0]; };这篇文章里我将重点探讨柔性数组的用法、内存分布以及和优势。 二、柔性数组的用法 我不建议在栈上直接定义有柔性数组的结构体也就是这么写 struct S s;因为柔性数组的大小是可以变化的我建议在堆上申请空间采取动态内存管理的方法这样就能发挥出柔性数组大小可以改变的优势。 假设我们使用malloc()函数来开辟空间一开始应该malloc出多大的空间呢要回答这个问题首先我们要知道sizeof(struct S)是多少。 事实上sizeof(struct S)计算出来的结果是该结构体不考虑柔性数组的大小。如果我们想要给柔性数组开辟空间malloc出来的大小应该是sizeof(struct S)加上柔性数组的大小。 假设这个柔性数组在结构体中的声明是int arr[0];我想给这个数组的大小是40个字节这样这个数组就能存储10个int那么一开始malloc的大小就应该是sizeof(struct S)10*sizeof(int)具体的例子如下 #include stdio.h #include stdlib.h #include string.h #include errno.hint main() {struct S* ps (struct S*)malloc(sizeof(struct S) 10 * sizeof(int));if (ps NULL){printf(malloc()-%s\n, strerror(errno));return 1;}return 0; }该结构体中的i,d,c等变量可以正常使用。 #include stdio.h #include stdlib.h #include string.h #include errno.hint main() {struct S* ps (struct S*)malloc(sizeof(struct S) 10 * sizeof(int));if (ps NULL){printf(malloc()-%s\n, strerror(errno));return 1;}ps-i 10;ps-d 3.14;ps-c F;return 0; }柔性数组也可以像正常的数组一样访问比如把1~10放进去。注意此时这个数组的容量是10个int不能越界访问。使用的例子如下 #include stdio.h #include stdlib.h #include string.h #include errno.hint main() {struct S* ps (struct S*)malloc(sizeof(struct S) 10 * sizeof(int));if (ps NULL){printf(malloc()-%s\n, strerror(errno));return 1;}ps-i 10;ps-d 3.14;ps-c F;for (int i 0; i 10; i){ps-arr[i] i 1;}for (int i 0; i 10; i){printf(%d , ps-arr[i]);}printf(\n);return 0; }我们还可以对柔性数组扩容如果我们想让这个柔性数组的容量是20个int整个结构体的新的大小就是sizeof(struct S)20*sizeof(int)因为sizeof(struct S)是不考虑柔性数组的大小时计算的结构体大小。只需要对ps进行realloc就行了。实现代码如下 #include stdio.h #include stdlib.h #include string.h #include errno.hint main() {struct S* ps (struct S*)malloc(sizeof(struct S) 10 * sizeof(int));if (ps NULL){printf(malloc()-%s\n, strerror(errno));return 1;}ps-i 10;ps-d 3.14;ps-c F;for (int i 0; i 10; i){ps-arr[i] i 1;}for (int i 0; i 10; i){printf(%d , ps-arr[i]);}printf(\n);struct S* tmp (struct S*)realloc(ps, sizeof(struct S) 20 * sizeof(int));if (tmp NULL){printf(realloc()-%s\n, strerror(errno));return 1;}else{ps tmp;}return 0; }扩容后的柔性数组的空间更大了我们可以把11~20都放进去。实现代码如下 #include stdio.h #include stdlib.h #include string.h #include errno.hint main() {struct S* ps (struct S*)malloc(sizeof(struct S) 10 * sizeof(int));if (ps NULL){printf(malloc()-%s\n, strerror(errno));return 1;}ps-i 10;ps-d 3.14;ps-c F;for (int i 0; i 10; i){ps-arr[i] i 1;}for (int i 0; i 10; i){printf(%d , ps-arr[i]);}printf(\n);struct S* tmp (struct S*)realloc(ps, sizeof(struct S) 20 * sizeof(int));if (tmp NULL){printf(realloc()-%s\n, strerror(errno));return 1;}else{ps tmp;}for (int i 10; i 20; i){ps-arr[i] i 1;}for (int i 0; i 20; i){printf(%d , ps-arr[i]);}return 0; }当然最后别忘了free掉ps否则会导致内存泄漏。 #include stdio.h #include stdlib.h #include string.h #include errno.hint main() {struct S* ps (struct S*)malloc(sizeof(struct S) 10 * sizeof(int));if (ps NULL){printf(malloc()-%s\n, strerror(errno));return 1;}ps-i 10;ps-d 3.14;ps-c F;for (int i 0; i 10; i){ps-arr[i] i 1;}for (int i 0; i 10; i){printf(%d , ps-arr[i]);}printf(\n);struct S* tmp (struct S*)realloc(ps, sizeof(struct S) 20 * sizeof(int));if (tmp NULL){printf(realloc()-%s\n, strerror(errno));return 1;}else{ps tmp;}for (int i 10; i 20; i){ps-arr[i] i 1;}for (int i 0; i 20; i){printf(%d , ps-arr[i]);}free(ps);ps NULL;return 0; }对于柔性数组的使用在上面的例子中可以总结出几个要点 malloc出来的大小是sizeof(struct S)加上柔性数组的大小calloc同理。扩容时realloc出来的新大小也是sizeof(struct S)加上柔性数组的新大小。每次使用malloc和realloc等函数时需要检查返回值否则可能导致对NULL指针的解引用这点是动态内存管理的常识了。一定要记得柔性数组的容量是多少不要越界访问了空间不够记得扩容。记得free防止内存泄漏。 三、柔性数组的内存分布 柔性数组是结构体的一个成员数组在前面的例子中整个结构体都是在堆上malloc出来的。此时整个结构体都存储在堆上的一块连续的空间里包括前面几个成员变量i,d,c和柔性数组arr。也就是这样 只不过数组arr的大小是可以改变的所以叫“柔性数组”。 有些朋友可能会说了我不需要柔性数组也能实现类似这样的效果呀我在结构体里存一个指针指向一块malloc出来的空间这块空间也是堆上的可以动态管理。也就是说像下面这样定义结构体 struct S {int i;double d;char c;int* arr; };这样似乎还简单一点先malloc出一个struct S出来malloc的大小就是sizeof(struct S)像这样 #include stdio.h #include stdlib.h #include string.h #include errno.hint main() {struct S* ps (struct S*)malloc(sizeof(struct S));if (ps NULL){printf(malloc()-%s\n, strerror(errno));return 1;}return 0; }然后再malloc出10个int的大小出来用结构体中的arr指针来管理这块空间像这样 #include stdio.h #include stdlib.h #include string.h #include errno.hint main() {struct S* ps (struct S*)malloc(sizeof(struct S));if (ps NULL){printf(malloc()-%s\n, strerror(errno));return 1;}ps-arr (int*)malloc(10 * sizeof(int));if (ps-arr NULL){printf(2: malloc()-%s\n, strerror(errno));return 1;}return 0; }此时arr就可以当成一个数组来使用了比如把1~10放进去。同样还是要注意不要越界访问。示例代码如下 #include stdio.h #include stdlib.h #include string.h #include errno.hint main() {struct S* ps (struct S*)malloc(sizeof(struct S));if (ps NULL){printf(malloc()-%s\n, strerror(errno));return 1;}ps-arr (int*)malloc(10 * sizeof(int));if (ps-arr NULL){printf(2: malloc()-%s\n, strerror(errno));return 1;}for (int i 0; i 10; i){ps-arr[i] i 1;}for (int i 0; i 10; i){printf(%d , ps-arr[i]);}printf(\n);return 0; }你如果觉得空间不够还可以扩容。比如你可以把结构体中的arr进行realloc新的大小能存放20个int。示例代码如下 #include stdio.h #include stdlib.h #include string.h #include errno.hint main() {struct S* ps (struct S*)malloc(sizeof(struct S));if (ps NULL){printf(malloc()-%s\n, strerror(errno));return 1;}ps-arr (int*)malloc(10 * sizeof(int));if (ps-arr NULL){printf(2: malloc()-%s\n, strerror(errno));return 1;}for (int i 0; i 10; i){ps-arr[i] i 1;}for (int i 0; i 10; i){printf(%d , ps-arr[i]);}printf(\n);int* tmp (int*)realloc(ps-arr, 20 * sizeof(int));if (tmp NULL){printf(realloc()-%s\n, strerror(errno));return 1;}else{ps-arr tmp;}return 0; }此时你就可以把11~20也放进去。实现代码如下 #include stdio.h #include stdlib.h #include string.h #include errno.hint main() {struct S* ps (struct S*)malloc(sizeof(struct S));if (ps NULL){printf(malloc()-%s\n, strerror(errno));return 1;}ps-arr (int*)malloc(10 * sizeof(int));if (ps-arr NULL){printf(2: malloc()-%s\n, strerror(errno));return 1;}for (int i 0; i 10; i){ps-arr[i] i 1;}for (int i 0; i 10; i){printf(%d , ps-arr[i]);}printf(\n);int* tmp (int*)realloc(ps-arr, 20 * sizeof(int));if (tmp NULL){printf(realloc()-%s\n, strerror(errno));return 1;}else{ps-arr tmp;}for (int i 10; i 20; i){ps-arr[i] i 1;}for (int i 0; i 20; i){printf(%d , ps-arr[i]);}return 0; }最后别忘了把arr和ps都free掉而且顺序不能错了。如果你先free掉了ps结构体就没了里面的arr就成为了野指针内存就泄露了。实现代码如下 #include stdio.h #include stdlib.h #include string.h #include errno.hint main() {struct S* ps (struct S*)malloc(sizeof(struct S));if (ps NULL){printf(malloc()-%s\n, strerror(errno));return 1;}ps-arr (int*)malloc(10 * sizeof(int));if (ps-arr NULL){printf(2: malloc()-%s\n, strerror(errno));return 1;}for (int i 0; i 10; i){ps-arr[i] i 1;}for (int i 0; i 10; i){printf(%d , ps-arr[i]);}printf(\n);int* tmp (int*)realloc(ps-arr, 20 * sizeof(int));if (tmp NULL){printf(realloc()-%s\n, strerror(errno));return 1;}else{ps-arr tmp;}for (int i 10; i 20; i){ps-arr[i] i 1;}for (int i 0; i 20; i){printf(%d , ps-arr[i]);}free(ps-arr);ps-arr NULL;free(ps);ps NULL;return 0; }那这种实现的内存分布是怎么样的呢这个结构体是存储在堆上的用ps来管理结构体里的一个指针arr又指向了堆上的另一块空间如下图 这种实现方式和柔性数组的方式感觉差不多呀都是在堆上有个结构体结构体里有个大小可以变化的数组。那为什么非要搞出来个柔性数组的概念呢那是因为柔性数组有它独特的优势。 四、柔性数组的优势 前面我们先用柔性数组实现了一种效果又不使用柔性数组实现了相似的效果对比两种实现方式我们可以做一些总结 使用上柔性数组malloc了一次free了一次不使用柔性数组要malloc两次free两次。柔性数组的使用更加简单不容易出错。如果不使用柔性数组可能会忘记free掉结构体里的arr指针导致内存泄漏。效率上柔性数组的存储空间是连续的访问时效率更高。 所以虽然有相似的效果我更推荐使用柔性数组的方式。 五、总结 在这篇博客里重点需要掌握以下几点 如果结构体里最后一个成员变量是一个数组并且大小可以变化这个成员数组就叫做柔性数组。一个结构体里除了柔性数组外必须至少有一个成员变量。使用sizeof计算含有柔性数组的结构体大小时只计算除柔性数组之外的空间大小。使用柔性数组比不使用柔性数组操作更加简单不易出错且效率更高。
http://www.w-s-a.com/news/262516/

相关文章:

  • 网站域名列表dede网站白屏
  • 站长工具一区品牌建设卓有成效
  • 电子商务网站建设案例wordpress批量编辑
  • 想代理个网站建设平台100个最佳市场营销案例
  • 钟表东莞网站建设石家庄做网站时光
  • 织梦 图片网站源码成都建设工程安监局网站
  • 做兼职的网站策划书湖北省建设工程造价信息网
  • 企业网站网址长期做网站应该购买稳定的空间
  • 网站静态化设计html5手机网站制作
  • 深圳最简单的网站建设家居网站建设全网营销
  • 如何取消网站备案佛山网站优化公司
  • 网站开发 成都广水网站设计
  • 音乐网站建设目标合同管理系统
  • jq网站特效插件如何知道网站是否被k
  • 自己的网站怎么接广告网站搭建收费
  • 宁波大型网站制作建立一个网站 优帮云
  • 大连零基础网站建设教学电话有哪些比较好的做ppt好的网站
  • 哪个网站做logo设计我的建筑网
  • php电子商务网站开发沂源手机网站建设公司
  • html和php做网站哪个好3gcms企业手机网站整站源码asp
  • 网站建设网页设计案例云南建设厅网站删除
  • 杏坛网站制作太原做网站要多少钱呢
  • 做新闻类网站还有市场吗东莞黄页网广告
  • 地方网站做外卖专业做互联网招聘的网站有哪些
  • 网站推广公司兴田德润紧急网页升级紧急通知
  • 厦门做网站哪家强企业网站网页设计的步骤
  • 普拓网站建设济南行业网站建设
  • 燕郊 网站开发网站里的地图定位怎么做
  • 门户网站建设招标互联网创业项目概述
  • 用什么做网站比较好市场调研公司是做什么的