c语言柔性数组,C 语言之柔性数组

一 历史

在c99标准出来之前。如果要在某个结构体中使用字符串变时,为了使字符串变量存储地址能与结构体整体连在一起,需要这样实现

#include

#include

#include

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

#include

#include

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...)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值