内容简介:在c99标准出来之前。如果要在某个结构体中使用字符串变时,为了使字符串变量存储地址能与结构体整体连在一起,需要这样实现通过上文我们可以看到,data字段是一个被浪费的指针(8个字节)。并且我们想取到结构体下的字符串变量时需要(char *)(p+1)写这么一串东西,既不好看,也容易出错,那有没有可以直接用C99使用不完整类型实现柔性数组成员,在C99 中,结构中的最后一个元素允许是未知大小的数组,这就叫做柔性数组(flexible array)成员(也叫伸缩性数组成员),但
一 历史
在c99标准出来之前。如果要在某个结构体中使用字符串变时,为了使字符串变量存储地址能与结构体整体连在一起,需要这样实现
#include <stdio.h> #include <malloc.h> #include <string.h> typedef struct pen { int len; char *data;//字符串变量 }pen; int main(int argc, char **argv) { char str[] = "this is a string";//需要填入的字符串 /* 动态申请一个pen类型结构体变量, 它的大小为,pen类型的本身长度, 再加上str(需要填入字符串的长度),再加1, */ struct pen *p = (struct pen*)malloc(sizeof(pen) + strlen(str) + 1); p->data= NULL; //设置p的长度为目标字符串的长度 p->len = strlen(str); /* 将目标字符串拷贝到结构体对应的位置 此处为什么p+1之后指向的是pen结构体存储空间后的位置,而不是只加一呢? 因为此处的p+1偏移的是p指向类型大小的偏移量,什么意思呢?p指向的类型为pen类型的结构体, 而pen类型的结构体大小为 len(4字节)加上 data(8个字节),由于此处有内存对齐的情况, 所以实际上pen大小为 4 + 8 + 4(这个4为内存对齐的多余空间,如果再增加一个int类型的变量, pen的大小还是为16)=16字节 所以此处p+1向后偏移了16字节,通过下方地址打印可以详细看出 */ strcpy((char*)(p + 1), str); //int所占字节数,不同机器不同。一般64位为4字节 printf("sizeof(int): %ld\n", sizeof(int)); //上文已说明,16字节 printf("sizeof(pen): %ld\n", sizeof(pen)); //起始地址 printf("start: %p\n\n", (char*)p); //上文已说明,偏移后的地址 printf("(p+1) : %p\n", (char*)(p+1)); //偏移后,对应的字符串 printf("(char*)(p+1): %s\n\n", (char*)(p+1)); //结构体变量data的地址 printf("&(p->data): %p\n", &(p->data)); //数据,null,此处为空,故此变量已经被浪费。访问对应字符串数据需要(char *)(p+1) printf("p->data: %s\n\n", p->data); }
二 柔性数组
通过上文我们可以看到,data字段是一个被浪费的指针(8个字节)。并且我们想取到结构体下的字符串变量时需要(char *)(p+1)写这么一串东西,既不好看,也容易出错,那有没有可以直接用 p->data
取到字符串并且内存是连续的,而且又不浪费 data
字段呢, 柔性数组
就是用来干这个的。
#include <stdio.h> #include <malloc.h> #include <string.h> typedef struct pen { int len; char data[];//柔性数组 }pen; int main(int argc, char **argv) { char str[] = "this is a new string";//需要填入的字符串 struct pen *p = (struct pen*)malloc(sizeof(pen) + strlen(str) + 1); p->data= NULL; p->len = strlen(str); strcpy((char *)(p+1), str); printf("pen->data: %s\n", p->data); }
C99使用不完整类型实现柔性数组成员,在C99 中,结构中的最后一个元素允许是未知大小的数组,这就叫做柔性数组(flexible array)成员(也叫伸缩性数组成员),但 结构中的柔性数组成员前面必须至少一个其他成员 。柔性数组成员允许 结构中包含一个大小可变的数组 。 柔性数组成员只作为一个符号地址存在 ,而且必须是结构体的最后一个成员,sizeof 返回的这种结构大小不包括柔性数组的内存 (此段话摘自: https://blog.csdn.net/ce123_z... )
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 分布式柔性事务的 TCC 方案
- 分布式事务之柔性事务 TCC 介绍
- 架构设计:基于消息中间件,图解柔性事务一致性
- C语言指针数组和数组指针
- 数组 – 如何在Swift中将数组拆分成两半?
- 菜鸡的算法修炼:数组(旋转数组的最小数字)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
明解C语言(第3版)
[日] 柴田望洋 / 管杰、罗勇、杜晓静 / 人民邮电出版社 / 2015-11-1 / 79.00元
本书是日本的C语言经典教材,自出版以来不断重印、修订,被誉为“C语言圣经”。 本书图文并茂,示例丰富,第3版从190段代码和164幅图表增加至205段代码和220幅图表,对C语言的基础知识进行了彻底剖析,内容涉及数组、函数、指针、文件操作等。对于C语言语法以及一些难以理解的概念,均以精心绘制的示意图,清晰、通俗地进行讲解。原著在日本广受欢迎,始终位于网上书店C语言著作排行榜首位。一起来看看 《明解C语言(第3版)》 这本书的介绍吧!