C99标准的柔性数组 (Flexible Array)

时间:2022-08-28 22:54:16

【什么是柔性数组(Fliexible Array)】

柔性数组在C99中的定义是:

6.7.2.1 Structure and union specifiers

As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member.

所以可以给出一个中文定义:

在至少两个成员的结构体中,最后一个成员其类型若是不完整类型的数组类型,则该成员称为柔性数组。

典型例子:

struct s { int n; char str[]; };

注意,str后面的中括号只能为空,数组类型不局限于char。

然而GCC编译器在C99发布之前就支持str[0]作为“柔性数组”,而且str[0]可以放在任何位置。这属于GCC对C语言的语法扩展。

这个语法扩展因为实用并且受欢迎,所以C99将其作为一个特殊情况并得到了支持。下面将具体说明。

【柔性数组的由来和作用】

有一些应用场景(如设计数据包)需要一个结构体里面包含因时而异的字符串,没有“柔性数组”概念之前,使用的方法是:

C99标准的柔性数组 (Flexible Array)
#include <stdio.h>
#include <string.h>
#include <stdlib.h> int main(void)
{
struct s { int n; char *str; };
char string[] = "ZhangHaiba";
struct char *ptos = malloc(sizeof (struct s) + strlen(string)+);
strcpy(ptos+, string);
//get the beginning address of str
char *p = (char *)(ptos+); printf("%s\n", p);
return ;
}
C99标准的柔性数组 (Flexible Array)

GCC超越当时的标准对C语法进行扩展,支持“柔性数组”,就可以使用下面的方法(移植性不好):

C99标准的柔性数组 (Flexible Array)
#include <stdio.h>
#include <string.h>
#include <stdlib.h> int main(void)
{
struct s { int n; char str[]; };
char string[] = "ZhangHaiba";
struct s *ptos = malloc(sizeof (struct s) + strlen(string)+);
strcpy(ptos->str, string);
//get the beginning address of str
char *p = ptos->str; printf("%s\n", p);
return ;
}
C99标准的柔性数组 (Flexible Array)

下面是GCC关于“柔性数组”的官方介绍和对比:http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html

由于上述方法符合C语言的精神(代码简单精炼),因此在C99中得到了支持。所以符合C99标准而且优雅的方法应该是:

C99标准的柔性数组 (Flexible Array)
#include <stdio.h>
#include <string.h>
#include <stdlib.h> int main(void)
{
struct s { int n; char str[]; };
char string[] = "ZhangHaiba";
struct s *ptos = malloc(sizeof (struct s) + sizeof (string));
strcpy(ptos->str, string);
//get the beginning address of str
char *p = ptos->str; printf("%s\n", p);
return ;
}
C99标准的柔性数组 (Flexible Array)

【C99柔性数组的特点】

柔性数组作为不完整类型,即使用struct s test定义了变量test之后,sizeof (test.str)肯定是不行的。哪怕给str分配了空间也不行。

因为标准规定sizeof的操作数不可以是不完整类型(还有函数类型及位字段)。

所以sizeof (struct s)或sizeof (test),不算上柔性数组str占的空间,也是情理之中了。(如果在GCC中,单独测试array[0],则显示其占空间为0字节)

简而言之,柔性数组只是把符号(名字)放在结构体内(压根儿就没定义),方便使用.或->语法来操作柔性数组,其所占内存空间(定义时分配)并不算在结构体变量中。

C99标准的柔性数组 (Flexible Array)
#include <stdio.h>
#include <string.h>
#include <stdlib.h> int main(void)
{
struct s { int n; char str[]; };
char string[] = "ZhangHaiba";
struct s *ptos = malloc(sizeof (struct s) + sizeof (string));
strcpy(ptos->str, string);
//get the beginning address of str
char *p = ptos->str; printf("%s\n", p); struct s test; //test is static allocation,str didn't alloc memory
printf("%ld %ld\n", sizeof test, sizeof *ptos); // *ptos is dynamic allocation, str has been alloc memory
//printf("%ld\n", sizeof (test.str)); //error: invalid application of ‘sizeof’ to incomplete type ‘char[]’
//printf("%ld\n", sizeof (ptos->str)); //error: invalid application of ‘sizeof’ to incomplete type ‘char[]’
return ;
}
C99标准的柔性数组 (Flexible Array)

@Author: 张海拔

@Update: 2014-2-2

@Link: http://www.cnblogs.com/zhanghaiba/p/3537561.html

C99标准的柔性数组 (Flexible Array)的更多相关文章

  1. C语言struct中的长度可变数组&lpar;Flexible array member&rpar;

    C_struct中的长度可变数组(Flexible array member) Flexible array member is a feature introduced in the C99 sta ...

  2. flexible array柔性数组、不定长的数据结构Struct详解

    柔性数组,这个名词对我来说算是比较新颖的,在学习跳跃表的实现时看到的.这么好听的名字,的背后到底是如何的优雅. 柔性数组,其名称的独特和迷惑之处在于“柔性”这个词.在C/C++中定义数组,是一个定长的 ...

  3. 柔性数组-读《深度探索C&plus;&plus;对象模型》有感 &lpar;转载&rpar;

    最近在看<深度探索C++对象模型>,对于Struct的用法中,发现有一些地方值得我们借鉴的地方,特此和大家分享一下,此间内容包含了网上搜集的一些资料,同时感谢提供这些信息的作者. 原文如下 ...

  4. 柔性数组-读《深度探索C&plus;&plus;对象模型》有感

    最近在看<深度探索C++对象模型>,对于Struct的用法中,发现有一些地方值得我们借鉴的地方,特此和大家分享一下,此间内容包含了网上搜集的一些资料,同时感谢提供这些信息的作者. 原文如下 ...

  5. 深入浅出C语言中的柔性数组

    在日常的编程中,有时候需要在结构体中存放一个长度动态的字符串,一般的做法,是在结构体中定义一个指针成员,这个指针成员指向该字符串所在的动态内存空间,例如: typedef struct test { ...

  6. 柔性数组&lpar;Redis源码学习&rpar;

    柔性数组(Redis源码学习) 1. 问题背景 在阅读Redis源码中的字符串有如下结构,在sizeof(struct sdshdr)得到结果为8,在后续内存申请和计算中也用到.其实在工作中有遇到过这 ...

  7. 柔性数组成员 &lpar;flexible array member&rpar;-C99-ZZ

    学习flexible array member是因为阅读Redis源码遇到的,sds.h中一开始就用到了. ============================================== ...

  8. c99柔性数组

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

  9. 变长数组&lpar;variable-length array&comma;VLA&rpar;&lpar;C99)

    处理二维数组的函数有一处可能不太容易理解,数组的行可以在函数调用的时候传递,但是数组的列却只能被预置在函数内部.例如下面这样的定义: #define COLS 4 int sum3d(int ar[] ...

随机推荐

  1. MDK st-link下载STM32程序出现Internal command error和Error&colon;Flash download failed&period; Target DLL

    MDK st-link下载STM32程序出现Internal command error和Error:Flash download failed. Target DLL   是因为目标板的芯片处于休眠 ...

  2. BestCoder Round &num;83

    第一次做BC呀,本来以为会报零的,做了56分钟A了第一题 然后就没有然后了. 贴一下第一次A的代码. /* 0.组合数 1. 2016-05-14 19:56:49 */ #include <i ...

  3. 每一个程序员需要了解的10个Linux命令

    作为一个程序员,在软件开发职业生涯中或多或少会用到Linux系统,并且可能会使用Linux命令来检索需要的信息.本文将为各位开发者分享10个有用的Linux命令,希望对你会有所帮助. 以下就是今天我们 ...

  4. 说说通信设置方式之hostonly

    Vmnetcfg.exe是配置它的网络. 虚拟机,虚拟出来有两个.VMnet1和VMnet8. ************************若用hostonly,则需要将VMnet1给启用.*** ...

  5. java之方法覆盖的坑

    昨天写了个小例子,覆盖hashCode.equals进行集合set的一些特性测试,代码如下: class Test3 { public int c; public Test3(int c) {this ...

  6. android &period;9图片的制作

    android .9PNG图片制作 在android开发的过程中,我们经常因为没有好的美工图片失真,这样使界面看起来要逊色很多,有的时候可能我们会想在drawable-hdpi,ldpi,mdpi下放 ...

  7. VMware Workstation 虚拟机使用无线wifi上网配置

    VMware Workstation 虚拟机使用无线wifi上网配置 参考文档: 转载/VMware Workstation环境下的Linux网络设置/适用于无线网络 VMware Workstati ...

  8. jQuery&period;extend 函数使用

    JQuery的extend扩展方法:      Jquery的扩展方法extend是我们在写插件的过程中常用的方法,该方法有一些重载原型,在此,我们一起去了解了解.      一.Jquery的扩展方 ...

  9. javascript刷新父页面的各种方法汇总

    1.用iframe.弹出子页面刷新父页面iframe <script language=JavaScript> parent.location.reload(); </script& ...

  10. BOM下的属性和方法---下

    继续BOM下的属性和方法---上 代码示例(亲测)2:   <title>location对象的属性</title> <script> //服务器环境我再此次演示中 ...