空数组的使用技巧

空数组的使用技巧

数组

数组(Array)是有序的元素序列。一个长度为0的数组我们称之为“空数组”,空数组是一个真正的对象,只是包含元素个数为0。。

空数组

我们可以先做个实验。(本文实验在 64位机测试)

测试空数组

    int aa[1];
    int bb[0];

    printf("aa address %p \r\n",&aa);
    printf("aa sizeof %ld \r\n",sizeof(aa));   

    printf("bb address %p \r\n",&bb);
    printf("bb sizeof %ld \r\n",sizeof(bb));   

查看输出结果

aa address 0x7ffffef2fe5c
aa sizeof 4
bb address 0x7ffffef2fe58
bb sizeof 0

可得出结论:

  1. 空数组有地址
  2. 空数组不占空间

结构体中的空数组

还是先上代码

#include <stdio.h>

struct stu_test1
{
    int a;
    int b;
};

struct stu_test2
{
    int a;
    char str[0];
    int b;
};

struct stu_test3
{
    int a;
    char str[1];    
    int b;
};

struct stu_test4
{
    int a;
    char *str;    
    int b;
};

int main()
{
    int a;
    struct stu_test2 test2;

    /*没有空数组*/
    a = sizeof(struct stu_test1);
    printf("stu_test1 lengh is %d \r\n",a);

    /*包含空数组*/
    a = sizeof(struct stu_test2);
    printf("stu_test2 lengh is %d \r\n",a);

    /*数组长度为1*/
    a = sizeof(struct stu_test3);
    printf("stu_test3 lengh is %d \r\n",a);

    /*char类型的指针*/
    a = sizeof(struct stu_test4);
    printf("stu_test4 lengh is %d \r\n",a);

    /*打印结构体的地址*/
    printf("test2 a address is %p \r\n",&test2);
    printf("test2 char address is %p \r\n",&(test2.str));
    printf("test2 b address is %p \r\n",&(test2.b));

    return 0;
}

可以看一下测试结果

/*没有空数组*/
stu_test1 lengh is 8

/*包含空数组*/
stu_test2 lengh is 8

/*数组长度为1*/
stu_test3 lengh is 12

/*char类型的指针*/
stu_test4 lengh is 24

/*打印结构体的地址*/
test2 a address is 0x7ffffef2fe60
test2 char address is 0x7ffffef2fe64
test2 b address is 0x7ffffef2fe64

五组测试可得出结论:

  1. 结构体的大小等于两个 int 类型的大小;
  2. 结构体的大小等于两个 int 类型的大小,空数组不占用结构体大小;
  3. 结构体的大小等于三个 int 类型的大小,编译器优化的结果;
  4. 结构体的大小等于两个 int 类型的大小 加上一个指针的大小;
  5. 空数组的起始地址,是下一个成员的起始地址一致。

空数组的使用

空数组如何使用,我们可以从他的特性出发。

  1. 不需要初始化,数组名直接就是所在的偏移
  2. 不占任何空间,指针需要占用int长度空间,空数组不占任何空间。

空数组数组不占用任何内存,可以节省空间;
空数组的内存地址就和他后面的元素的地址相同,所以数组名就是后面元素的地址,直接就能当做指针使用。
这样的写法可以来制作动态缓存区。
所以我们可以这样来使用他:

struct stu_test
{
    int a;
    int b;
    char str[0];
};

malloc(sizeof(struct stu_test)+ buff_len);

buff_len 来指定 str 的长度,就可以直接使用了。
这样就只需要申请一次内存。如果是分两次分配(结构体和缓冲区),那么要是第二次malloc失败了,必须回滚释放第一个分配的结构体。这样带来了编码麻烦。其次,分配了第二个缓冲区以后,如果结构里面用的是指针,还要为这个指针赋值。同样,在free这个buffer的时候,用指针也要两次free。如果用空数组,所有问题一次解决。
另外小内存的管理是非常困难的,如果用指针,这个buffer的struct部分就是小内存了,在系统内存在多了势必严重影响内存管理的性能。要是用空数组把struct和实际数据缓冲区一次分配大块问题,就没有这个问题。

总结

空数组不占用任何空间,需要使用的时候可以在指定长度,这样就实现了动态数组,既不定长数组。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值