struct MyData 
{
    int nLen;
    char data[0];
};

在结构中,data是一个数组名;但该数组没有元素;该数组的真实地址紧随结构体MyData之后,而这个地址就是结构体后面数据的地址(如果给这个结构体分配的内容大于这个结构体实际大小,后面多余的部分就是这个data的内容);这种声明方法可以巧妙的实现C语言里的数组扩展。

这表明data没有占用空间。data是一个数组名;该数组没有元素;该数组的真实地址紧随结构体Info之后;这种声明方法可以巧妙的实现C语言里的数组扩展。

实际用时采取这样:
         struct MyData *p = (struct MyData *)malloc(sizeof(struct MyData )+strlen(str))
         这样就可以通过p->data 来操作这个str。

示例:
#include <iostream>

using namespace std;

struct MyData 
{
    int nLen;
    char data[0];
};

int main()
{
    int nLen = 10;
    char str[10] = "123456789";

cout << "Size of MyData: " << sizeof(MyData) << endl;

MyData *myData = (MyData*)malloc(sizeof(MyData) + 10);
    memcpy(myData->data,  str, 10);

cout << "myData's Data is: " << myData->data << endl;

free(myData);

return 0;
}
         输出:
Size of MyData: 4
myData's Data is: 123456789

C99标准为了让这种用法合法化,专门定义了flexible array member,直接就是
struct Name { int size, char foo[] }; 不再写 char foo[0] 了。

它只能放在结构体末尾, 
是申明一个长度为0的数组(eg. char data[0] ;或 int data[0];都行) 
可以使得这个结构体是可变长的。

引申:

 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
 #include <iostream>
 using namespace std;
 typedef struct test0{
     ];
     int b;
     char c;
 }sttest0;
 typedef struct test{
     ];
     ];
 }sttest;
 typedef struct test1{
     ];
     ];
 }sttest1;
 typedef struct test2{
     struct test tt;
     struct test1 tt1;
 }sttest2;

 int main()
 {
     ] = ";
     int len1 = sizeof(str);
     cout << len1 << endl;
     ] ="abcdefghij";
     int len2=sizeof(str2);
     cout << len2 << endl;
     printf("%lu %lu %lu\n", sizeof(sttest0), sizeof(sttest), sizeof(sttest1));
     cout << "Size of sttest2: " << sizeof(sttest2) << endl;
     sttest2 *tt2 = (sttest2*));

     memcpy(tt2->tt.a, str, len1);
     memcpy(tt2->tt1.a , str2, len2);

     //需要注意的是两者位置互换后的情况
 //    memcpy(tt2->tt1.a , str2, len2);
 //    memcpy(tt2->tt.a, str, len1);

     printf("#################value\n");
     printf("tt:%s\n%s\n", tt2->tt.a, tt2->tt.b);
     printf("tt1:%s\n%s\n", tt2->tt1.a, tt2->tt1.b);

     printf("#################address\n");
     printf("addr(tt2):%#x\n%#x\n", &tt2->tt, &tt2->tt1);
     printf("addr(tt):%#x\n%#x\n", &tt2->tt.a, &tt2->tt.b);
     printf("addr(tt1):%#x\n%#x\n", &tt2->tt1.a, &tt2->tt1.b);
     free(tt2);
     ;
 }

柔性数组 data[0]的更多相关文章

  1. C语言变长数组data[0]总结

    C语言变长数组data[0] 1.前言 今天在看代码中遇到一个结构中包含char data[0],第一次见到时感觉很奇怪,数组的长度怎么可以为零呢?于是上网搜索一下这样的用法的目的,发现在linux内 ...

  2. C语言变长数组data[0]

    1.前言 在刷题时遇到一个结构中包含char data[0],第一次见到时感觉很奇怪,数组的长度怎么可以为零呢?于是上网搜索一下这样的用法的目的,发现在linux内核中,结构体中经常用到data[0] ...

  3. C语言变长数组data[0]【总结】

    1.前言 今天在看代码中遇到一个结构中包含char data[0],第一次见到时感觉很奇怪,数组的长度怎么可以为零呢?于是上网搜索一下这样的用法的目的,发现在linux内核中,结构体中经常用到data ...

  4. c99柔性数组

    变长结构体 struct test { int nSize; char data[]; // 或者 char data[0];但建议使用 char data[]; 注意:c98 时不支持柔性数组,其仅 ...

  5. C/C++ 中的0长数组(柔性数组)

    转自C/C++ 中的0长数组(柔性数组) 在标准C和C++中0长数组如charArray[0]是不允许使用的,因为这从语义逻辑上看,是完全没有意义的.但是,GUN中却允许使用,而且,很多时候,应用在了 ...

  6. C语言0长度数组(柔性数组)

    0长度数组,又称为柔性数组(flexible array).通经常使用来实现变长数组.常见于TLV(type-length-value)的数据结构中. 在标准 C 和 C++ 中,不同意用 0 长度数 ...

  7. C语言变长数组 struct中char data[0]的用法

    版权声明:本文为博主原创文章,未经博主允许不得转载. 今天在看一段代码时出现了用结构体实现变长数组的写法,一开始因为忘记了这种技术,所以老觉得作者的源码有误,最后经过我深思之后,终于想起以前看过的用s ...

  8. (四)C语言柔性数组、指针赋值

    一.柔性数组 今天看了公司的代码,发现一个很奇怪的问题,后来自己写了类似代码,我先把代码贴出来吧. #include<stdio.h> #include<string.h> # ...

  9. C柔性数组

    柔性数组成员 柔性数组 .允许结构中包含一个大小可变的数组,sizeof返回的这种结构大小不包括柔性数组的内存. .包含柔性数组成员的结构要使用malloc()函数进行内存的动态分配.分配的内存大于结 ...

随机推荐

  1. 1-File类的使用

    package com.io; import java.io.File; import java.io.FileInputStream; import java.io.IOException; imp ...

  2. nginx命令

    window  cmd 到nginx的文件夹 start nginx    启动命令 nginx -s reload 重新启动 nginx -s stop   关闭   linux   到 sbin ...

  3. An error in projects

    Error能使系统产生Failure从而导致系统不能达到所需的功能. 曾经,做一个关于酒店管理系统的项目.因为数据库表主外键的连接错误,当对页面的添加桌位功能进行测试时,不能正确的添加. 后通过逐行对 ...

  4. 5分钟教你Windows 10中将“运行”固定到开始菜单

    导读 “运行”功能深受很多资深IT之家用户喜爱,因为它简约.方便.实用.在Win7等旧版系统中,用户可以让该功能直接在开始菜单显示,方便操作.但在Win10中,由于开始菜单已经重新编写,原有的设定已经 ...

  5. Mysql字段操作—增加字段、删除字段、修改字段名、修改字段类型(约束条件)

    1.增加字段:    alter table   tablename    add   new_field_id   type   not null default '0';     例:     a ...

  6. C#字符串和数据之间的转换

    c#中不仅仅存在数值类型的数据之间的转换,字符串和数值之间也是可以互相转换的,只是方法不同而已. 1 数值型转换为字符型 数值型数据转换为字符串用ToString()方法即可实现 int num1=1 ...

  7. C++ const用法 尽可能使用const [转载]

    C++ const 允许指定一个语义约束,编译器会强制实施这个约束,允许程序员告诉编译器某值是保持不变的.如果在编程中确实有某个值保持不变,就应该明确使用const,这样可以获得编译器的帮助. 1.c ...

  8. PictureCutting图片批量裁切(裁剪)工具

    PictureCutting图片批量裁切(裁剪)工具 写这个工具的原因是因为在获取一个软件的皮肤包中的图片的时候需要进行批量的裁切工作,而有没有找到在linux下简单好用的工具,干脆就用QT写了一个. ...

  9. 20 BasicTaskScheduler0 基本任务调度类基类(二)——Live555源码阅读(一)任务调度相关类

    这是Live555源码阅读的第二部分,包括了任务调度相关的三个类.任务调度是Live555源码中很重要的部分. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/ol ...

  10. php批量下载文件

    最近用codeigniter开发一个图片网站,发现单文件下载很容易实现,批量下载的话,就有点麻烦. 普通php下载比较简单,比如我封装的一个函数: function shao_download($fi ...