Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
C++_cpp
空数组使用的一些小技巧
1.00
发布于 2021-01-11 20:27:52 浏览:981
订阅该版
[tocm] # 空数组的使用技巧 ## 数组 数组(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
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和实际数据缓冲区一次分配大块问题,就没有这个问题。 ## 总结 空数组不占用任何空间,需要使用的时候可以在指定长度,这样就实现了动态数组,既不定长数组。
8
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
whj467467222
开源,分享,交流,共同进步
文章
32
回答
1222
被采纳
148
关注TA
发私信
相关文章
1
RT-STUDIO下加入TOUCHGFX?
2
有没有人在RTT上使用C++编程
3
nano c++ 报错如何处理
4
让成员函数能作为rt_device中的回调函数
5
成员函数作为回调函数
6
C++编译问题 undefined reference to `_exit'
7
开启C++功能后,rt_kprintf和单步调试功能无法使用
8
RT-Thread Studio C++ 异常处理 (与预期不一致)
9
C++继承Thread类报错怎么办?
10
STM32使用C++ 编译报错
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
机器人操作系统 (ROS2) 和 RT-Thread 通信
4
国产MCU移植系列教程汇总,欢迎查看!
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
ART-Pi
FinSH
USB
文件系统
DMA
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
ota在线升级
WIZnet_W5500
UART
flash
packages_软件包
cubemx
PWM
freemodbus
BSP
潘多拉开发板_Pandora
定时器
ADC
中断
flashDB
socket
Debug
GD32
编译报错
msh
keil_MDK
at_device
rt_mq_消息队列_msg_queue
ulog
C++_cpp
SFUD
本月问答贡献
出出啊
1512
个答案
341
次被采纳
小小李sunny
1437
个答案
289
次被采纳
张世争
774
个答案
167
次被采纳
crystal266
546
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
2
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
2
次点赞
crystal266
2
篇文章
1
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部