C99 flexible array number 伸缩型数组成员

简介: 这种特性用来射你那个结构体中最后一个成员是特殊成员,它是不存在的 它包含如下规则: 1、必须是最后一个数组成员 2、结构体中至少有一个其他成员 3、使用[]进行定义 /********************************************...
这种特性用来射你那个结构体中最后一个成员是特殊成员,它是不存在的
它包含如下规则:
1、必须是最后一个数组成员
2、结构体中至少有一个其他成员
3、使用[]进行定义



/*************************************************************************
  > File Name: dongtai.c
  > Author: gaopeng
  > Mail: gaopp_200217@163.com
  > Created Time: Wed 25 May 2016 03:46:20 AM CST
 ************************************************************************/

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

#define LEN(a)  strlen(argv[a]) + sizeof(NFDATA) + 1

typedef struct nofixed
{
        int leng_t;
        char gs[];
} NFDATA;


int readpa(const int *ar,const int hmud)
{
        if(*ar == hmud)
        {
                return 1;
        }
        else
        {
                return 0;
        }

}

 

int main (int argc,char *argv[])
{
        FILE *fd;
        NFDATA *d1;
        NFDATA *d2;
        NFDATA *d3;

        if( readpa(&argc,5 ) != 1  )
        {
                printf("5 argc must\n");
                exit(1);
        }

        d1 = (NFDATA *)malloc(LEN(1));
        d1->leng_t = strlen(argv[1]);
        d1->gs[d1->leng_t] = '\0';
        memcpy(d1->gs , argv[1] , d1->leng_t);

        d2 = (NFDATA *)malloc( LEN(2));
        d2->leng_t = strlen(argv[2]);
        d2->gs[d2->leng_t] = '\0';
        memcpy(d2->gs , argv[2] , d1->leng_t);

        d3 = (NFDATA *)malloc( LEN(3));
        d3->leng_t = strlen(argv[3]);
        d3->gs[d3->leng_t] = '\0';
        memcpy(d3->gs , argv[3] , d3->leng_t);

        printf("argv1 %ld,%ld,%p,%p,%s,%d\n", sizeof(*d1),strlen(d1->gs),d1, d1->gs,d1->gs,d1->leng_t);
        printf("argv2 %ld,%ld,%p,%p,%s,%d\n", sizeof(*d2),strlen(d2->gs),d2, d2->gs,d2->gs,d2->leng_t);
        printf("argv3 %ld,%ld,%p,%p,%s,%d\n", sizeof(*d3),strlen(d3->gs),d3, d3->gs,d3->gs,d3->leng_t);
   
        if((fd = fopen(argv[4],"w")) == NULL)
        {
                printf("open file error!\n");
                exit(11);
        }

        fwrite(d1,1,LEN(1),fd);
        printf("file pointer: %ld\n",ftell(fd));
        fwrite(d2,1,LEN(2),fd);
        printf("file pointer: %ld\n",ftell(fd));
        fwrite(d3,1,LEN(3),fd);
        printf("file pointer: %ld\n",ftell(fd));

        free(d1);
        free(d2);
        free(d3);

        fclose(fd);

}

运行程序
./a.out  gao1 gao2 gao3 save3.dmp
这段代码就使用了这种特性将命令行参数这个不定的字符素组保存到了文件中,而且文件中没有浪费的空间
当然这样的做法也要内存中没有浪费的空间。不过兼容性可能有一些问题。
使用
 hexdump -Cv save3.dmp
查看二进制文件
00000000  04 00 00 00 67 61 6f 31  00 04 00 00 00 67 61 6f  |....gao1.....gao|
00000010  32 00 04 00 00 00 67 61  6f 33 00                        |2.....gao3.|
0000001b


如果要分析 实际上 ,主要取决于这里

#define LEN(a)  strlen(argv[a]) + sizeof(NFDATA) + 1

typedef struct nofixed
{
        int leng_t;
        char gs[];  //flexible array number
} NFDATA;

 d1 = (NFDATA *)malloc(LEN(1));
 d1->leng_t = strlen(argv[1]);
 d1->gs[d1->leng_t] = '\0'; 
 memcpy(d1->gs , argv[1] , d1->leng_t);

本来整个struct只需要4BYTES的空间,但是我们分配空间的时候加上了strlen(argv[a])+1
意思就是扩张一个参数长度+1出来,这里的+1就是保存'\0'结束符而已。
最后拷贝argv[1]的字符到d1->gs中

认为这种方式最好的地方在于内存中分配的空间的连续的 free起来方便,写文件也方便

如果
typedef struct nofixed
{
        int leng_t;
        char *gs; //a char pointer  
} NFDATA;
这种方式就不连续的,比较麻烦。

目录
打赏
0
0
0
0
91
分享
相关文章
|
10月前
|
使用array()函数创建数组
使用array()函数创建数组。
185 3
总结TypeScript 的一些知识点:TypeScript Array(数组)(下)
一个数组的元素可以是另外一个数组,这样就构成了多维数组(Multi-dimensional Array)。
|
3月前
|
go语言中的数组(Array)
go语言中的数组(Array)
126 67
拿下奇怪的前端报错(一):报错信息是一个看不懂的数字数组Buffer(475) [Uint8Array],让AI大模型帮忙解析
本文介绍了前端开发中遇到的奇怪报错问题,特别是当错误信息不明确时的处理方法。作者分享了自己通过还原代码、试错等方式解决问题的经验,并以一个Vue3+TypeScript项目的构建失败为例,详细解析了如何从错误信息中定位问题,最终通过解读错误信息中的ASCII码找到了具体的错误文件。文章强调了基础知识的重要性,并鼓励读者遇到类似问题时不要慌张,耐心分析。
104 5
|
5月前
|
Java“(array) <X> Not Initialized” (数组未初始化)错误解决
在Java中,遇到“(array) &lt;X&gt; Not Initialized”(数组未初始化)错误时,表示数组变量已被声明但尚未初始化。解决方法是在使用数组之前,通过指定数组的大小和类型来初始化数组,例如:`int[] arr = new int[5];` 或 `String[] strArr = new String[10];`。
137 2
JavaScript Array(数组) 对象
JavaScript Array(数组) 对象
53 3
JavaScript中通过array.filter()实现数组的数据筛选、数据清洗和链式调用,JS中数组过滤器的使用详解(附实际应用代码)
JavaScript中通过array.filter()实现数组的数据筛选、数据清洗和链式调用,JS中数组过滤器的使用详解(附实际应用代码)
|
6月前
|
Go
Golang语言之数组(array)快速入门篇
这篇文章是关于Go语言中数组的详细教程,包括数组的定义、遍历、注意事项、多维数组的使用以及相关练习题。
91 5
|
7月前
|
PyCharm View as Array 查看数组
PyCharm View as Array 查看数组
172 1
|
8月前
|
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等