IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言:长度为0的数组 -> 正文阅读

[C++知识库]C语言:长度为0的数组

概述

长度为0的数组在标准c和c++中是不合法的,但是在gcc中是可行的。
长度为0数组它的最典型的用法就是位于结构体中的最后一项。

使用方式

如下面的例子,分别使用长度为0的数组和指针声明结构体,实现可变长度的数组功能:

#include <stdio.h>
#include <stdlib.h>

struct test1
{
    int a;
    int b[0];
};

struct test2
{
    int a;
    int *b;
};

struct test3
{
    int a;
    int reserved;//占位符,64位系统中保证结构体字节对齐,test2中是由编译器对齐的,所以两个结构体占用空间相同
    int *b;
};

int main()
{
    struct test1 *var1;
    struct test2 *var2;

    int iLength = 10;
    int i;

    printf("the length of struct test1:%d\n",sizeof(struct test1));
    printf("the length of struct test2:%d\n",sizeof(struct test2));
    printf("the length of struct test3:%d\n",sizeof(struct test3));

    var1=(struct test1*)malloc(sizeof(struct test1) + sizeof(int) * iLength);
    var1->a=iLength;
    for(i=0; i < var1->a; i++)
    {
        var1->b[i]=i;
        printf("var1->b[%d]=%d\t", i, var1->b[i]);
    }
    printf("\n"); 
    printf("p var1 = %p\n", var1);
    printf("p var1->a %p\n", &var1->a);
    printf("var1->b %p\n", var1->b);
    printf("p var1->b %p\n", &var1->b);
    printf("p var1->b[0] %p\n", &var1->b[0]);
    printf("p var1->b[1] %p\n", &var1->b[1]);

    printf("\n\n");

    var2=(struct test2*)malloc(sizeof(struct test2));
    var2->a=iLength;
    var2->b=(int *)malloc(sizeof(int) * iLength);
    for(i=0; i < var2->a; i++)
    {
        var2->b[i]=i;
        printf("var2->b[%d]=%d\t", i, var2->b[i]);
    }
    printf("\n"); 
    printf("p var2 = %p\n", var2);
    printf("p var2->a %p\n", &var2->a);
    printf("var2->b %p\n", var2->b);
    printf("p var2->b %p\n", &var2->b);
    printf("p var2->b[0] %p\n", &var2->b[0]);
    printf("p var2->b[1] %p\n", &var2->b[1]);

    free(var1);
    free(var2->b);
    free(var2);

    return 0;
}

64位linux系统中运行结果

the length of struct test1:4
the length of struct test2:16
the length of struct test3:16
var1->b[0]=0    var1->b[1]=1    var1->b[2]=2    var1->b[3]=3    var1->b[4]=4    var1->b[5]=5    var1->b[6]=6    var1->b[7]=7    var1->b[8]=8    var1->b[9]=9
p var1 = 0x55eb1a7d7670
p var1->a 0x55eb1a7d7670
var1->b 0x55eb1a7d7674
p var1->b 0x55eb1a7d7674
p var1->b[0] 0x55eb1a7d7674
p var1->b[1] 0x55eb1a7d7678


var2->b[0]=0    var2->b[1]=1    var2->b[2]=2    var2->b[3]=3    var2->b[4]=4    var2->b[5]=5    var2->b[6]=6    var2->b[7]=7    var2->b[8]=8    var2->b[9]=9
p var2 = 0x55eb1a7d76b0
p var2->a 0x55eb1a7d76b0
var2->b 0x55eb1a7d76d0
p var2->b 0x55eb1a7d76b8
p var2->b[0] 0x55eb1a7d76d0
p var2->b[1] 0x55eb1a7d76d4

使用长度为0的数组可以比指针更方便地进行内存的管理。
结构体test1在分配内存时,则是采用一次分配的原则,一次性将所需的内存全部分配给它,释放也是一次释放。数组和结构体的内存是连续的。
结构体test2在分配内存时,需采用两步:首先,需为结构体分配一块内存空间;其次再为结构体中的成员变量分配内存空间。这样两次分配的内存是不连续的,需要分别对其进行管理。当使用长度为0的数组时,则是采用一次分配的原则,一次性将所需的内存全部分配给它。相反,释放时也是一样的。

总结

长度为0的数组并不占有内存空间,而指针方式需要占用内存空间。

对于长度为0的数组,在申请内存空间时,采用一次性分配的原则进行;对于包含指针的结构体,才申请空间时需分别进行,释放时也需分别释放。

对于长度为0的数组元素的访问可正常采用数组方式进行。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章           查看所有文章
加:2021-10-15 11:36:23  更:2021-10-15 11:38:57 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:06:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码