精华内容
下载资源
问答
  • C语言变长数组

    2019-10-06 01:50:44
    C语言变长数组 http://www.cnblogs.com/pangyujie/archive/2011/09/28/2194730.htmlC语言变长数组变长数组是C99标准里面的内容,支持C99标准的编译器都能正确的编译含变长数组的C程序。以前一直用VC,...

    http://www.cnblogs.com/pangyujie/archive/2011/09/28/2194730.html

    C语言变长数组

    变长数组是C99标准里面的内容,支持C99标准的编译器都能正确的编译含变长数组的C程序。以前一直用VC,只能使用定长数组。当时也用过指针来模拟变长数组,但是比较麻烦,且使用指针的话是在堆中开辟内存空间,效率上会有影响。

    测试代码

     1 #include <stdio.h>
    2 #include <stdlib.h>
    3 #include <string.h>
    4
    5 int main(int argc, char *argv[])
    6 {
    7 const char *head = "headstr-";
    8 const char *tail = "tailstr";
    9 char vla[strlen(head) + strlen(tail) + 1];
    10 strcpy(vla, head);
    11 strcat(vla, tail);
    12 printf("%s\n", vla);
    13
    14 int i;
    15 for(i = 0; i < 5; ++i)
    16 {
    17 char foo[i + 2];
    18 strncpy(foo, "xxxxxxxxxxx", i + 1);
    19 foo[i + 1] = '\0';
    20 printf("%s\n", foo);
    21 }
    22
    23 return 0;
    24 }

     

    使用GCC(Windows下MinGW32环境)可正常编译:

     

    使用VC的编译器cl.exe,报错(VS2008下同样报错):



    分类: C
    标签: 变长数组
    0
    0
    (请您对文章做出评价)
    » 博主后一篇:CSS实现图片按比例缩放

    posted on 2011-09-28 18:58 Pang Yujie 阅读(185) 评论(8) 编辑 收藏

    评论

    #1楼 2011-09-28 20:21 garbageMan      

     

    引用int i;
    for(i = 0; i < 5; ++i)
    既然是C99
    写成
    for(int i = 0; i < 5; ++i ) 
    岂不更好  回复 引用 查看   

     

    #2楼[楼主2011-09-28 20:26 Pang Yujie      

    @garbageMan
    呵呵,我当时只是不想加上-std=c99这个参数才这么写的。
    不过说起来,变长数组这东西确实是到了C99才有的,for(int i = 0;......)也是C99才有的。我用GCC编译的时候没加-std=c99,还是能编译变长数组,但是不能编译for(int i = 0; .....)。这是怎么回事我就搞不懂了…… 
    回复 引用 查看   

    #3楼 2011-09-28 22:21 garbageMan      

    @Pang Yujie
    C99新内容的绝大部分都是在各个编译器中已经实现了的
    只是实现程度不同
    比如\\注释,VC6就有
    C99有些东西来自GCC原有的一些扩展
      回复 引用 查看   

    #4楼 2011-09-28 22:34 egmkang      

     

    引用garbageMan:
    @Pang Yujie
    C99新内容的绝大部分都是在各个编译器中已经实现了的
    只是实现程度不同
    比如\\注释,VC6就有
    C99有些东西来自GCC原有的一些扩展
    好像除了VC不支持C99,其他编译器都支持了吧  回复 引用 查看   

     

    #5楼[楼主2011-09-28 22:37 Pang Yujie      

    @egmkang
    应该说,现在的编译器基本上都支持了,只不过是支持程度的问题而已。
    但是microsoft的编译器对C99的支持非常差。wikipedia上有个列表http://en.wikipedia.org/wiki/C99
      回复 引用 查看   

    #6楼 2011-09-28 22:46 egmkang      

     

    引用Pang Yujie:
    @egmkang
    应该说,现在的编译器基本上都支持了,只不过是支持程度的问题而已。
    但是microsoft的编译器对C99的支持非常差。wikipedia上有个列表http://en.wikipedia.org/wiki/C99
    下面,自己看
    Microsoft Visual Studio No As of Visual Studio 2010, there are no plans to support C99.[11][12]  回复 引用 查看   

     

    #7楼[楼主2011-09-28 22:48 Pang Yujie      

    @egmkang
    所以说啊,人家MS就是牛气冲天,不把标准当回事。
      回复 引用 查看   

    #8楼 2011-09-29 07:31 garbageMan      

     

    引用egmkang:
    引用garbageMan:
    @Pang Yujie
    C99新内容的绝大部分都是在各个编译器中已经实现了的
    只是实现程度不同
    比如\\注释,VC6就有
    C99有些东西来自GCC原有的一些扩展
    好像除了VC不支持C99,其他编译器都支持了吧
    VC支持的确实很差
    但单行注释// (前面写错了) 是C99的  回复 引用 查看  
    posted on 2011-11-19 02:45 lexus 阅读(...) 评论(...) 编辑 收藏

    转载于:https://www.cnblogs.com/lexus/archive/2011/11/19/2254811.html

    展开全文
  • c语言变长数组

    千次阅读 2013-07-18 00:10:48
    C语言变长数组之剖析 (陈云川 ybc2084@163.comUESTC,CD) 1、引言 我们知道,与C++等现代编程语言不同,传统上的C语言是不支持变长数组功能的,也就是说数组的长度是在编译期就确定下来的,不能在运行期改变。...

    C语言变长数组之剖析

    (陈云川 ybc2084@163.comUESTC,CD)

    1、引言

    我们知道,与C++等现代编程语言不同,传统上的C语言是不支持变长数组功能的,也就是说数组的长度是在编译期就确定下来的,不能在运行期改变。不过,在C99标准中,新增的一项功能就是允许在C语言中使用变长数组。然而,C99定义的这种变长数组的使用是有限制的,不能像在C++等语言中一样自由使用。

    2、说明

    参考文献[1]中对变长数组的说明如下:

    C99gives C programmers the ability to use variable length arrays, which are arrayswhose sizes are not known until run time. A variable length array declarationis like a fixed array declaration except that the array size is specified by anon-constant expression. When the declaration is encountered, the sizeexpression is evaluated and the array is created with the indicated length,which must be a positive integer. Once created, variable length array cannotchange in length. Elements in the array can be accessed up to the allocatedlength; accessing elements beyond that length results in undefined behavior.There is no check required for such out-of-range accesses. The array isdestroyed when the block containing the declaration completes. Each time the blockis started, a new array is allocated.

    以上就是对变长数组的说明,此外,在文献[1]中作者还说明,变长数组有以下限制:

    1、变长数组必须在程序块的范围内定义,不能在文件范围内定义变长数组;

    2、变长数组不能用static或者extern修饰;

    3、变长数组不能作为结构体或者联合的成员,只能以独立的数组形式存在;

    4、变长数组的作用域为块的范围,对应地,变长数组的生存时间为当函数执行流退出变长数组所在块的时候;

    上述限制是最常见的一些限制因素,此外,当通过typedef定义变长数组类型时,如何确定变长数组的长度,以及当变长数组作为函数参数时如何处理,作者也做了一一说明。详细的细节情况请参阅文献[1]。由于变长数组的长度在程序编译时未知,因此变长数组的内存空间实际上是在栈中分配的。

    gcc虽然被认为是最遵守C语言标准的编译器之一,但是它并不是严格按照ISO C标准规定的方式来实现的。gcc的实现方式采取了这样的策略:最大限度地遵守标准的规定,同时从实用的角度做自己的扩展。当然,gcc提供了编译选项给使用者以决定是否使用这些扩展功能。gcc的功能扩展分为两种,一种是gnu自己定义的语言扩展;另外一种扩展是在C89模式中引入由C99标准定义的C语言特性。在参考文献[2]中,有关gcc的C语言扩展占据了将近120页的篇幅,扩展的语言功能多达几十个,由此可看出gcc的灵活程度。

    在参考文献[2]中,对变长数组的描述如下:

    Variable-lengthautomatic arrays are allowed in ISO C99, and as an extension GCC accepts themin C89 mode and in C++. (However, GCC’s implementation of variable-length arraysdoes not yet conform in detail to the ISO C99 standard.) These arrays aredeclared like any other automatic arrays, but with a length that is not aconstant expression. The storage is allocated at the point of declaration anddeallocated when the brace-level is exited.

    以上这段话并没有详细的说明gcc的变长数组实现和ISO C99的差异究竟体现在什么地方,但是从描述来看,基本上和文献[1]中的描述是一致的。文献[2]中没有说明而在文献[1]中给予了说明的几点是:变长数组是否能用static或者extern修饰;能否作为复合类型的成员;能否在文件域起作用。

    另外,在文献[2]中提到,采用alloca()函数可以获得和变长数组相同的效果。在作者所用的Red Hat 9.0(Linux 2.4.20-8)上,这个函数被定义为一个库函数:

    #include <alloca.h>

    void *alloca(size_t size);

    这个函数在调用它的函数的栈空间中分配一个size字节大小的空间,当调用alloca()的函数返回或退出的时候,alloca()在栈中分配的空间被自动释放。当alloca()函数执行成功时,它将返回一个指向所分配的栈空间的起始地址的指针;然而,非常特别的一点是,当alloca()函数执行失败时,它不会像常见的库函数那样返回一个NULL指针,之所以会出现这样的状况,是由于alloca()函数中的栈调整通常是通过一条汇编指令来完成的,而这样一条汇编指令是无法判断是否发生溢出或者是否分配失败的。alloca()函数通常被实现为内联函数,因此它是与特定机器以及特定编译器相关联的,可移植性因此而大打折扣,实际上是不推荐使用的。

    作者之所以会关注变长数组的问题是出于一次偶然的因素,在调试的时候发现gdb给出的变长数组的类型很怪异,由此引发作者对gcc中的变长数组进行了测试。本文中给出的就是对测试结果的说明和分析。

    3、实例

    第一个测试所用的源代码很简单,如下所示:

     1 int

     2 main(int argc, char*argv[])

     3 {

     4  int i, n;

     5

     6  n = atoi(argv[1]);

     7  char arr[n+1];

     8  bzero(arr, (n+1) * sizeof(char));

     9  for (i = 0; i < n; i++) {

    10      arr[i] = (char)('A' +i);

    11  }

    12  arr[n] = '\0';

    13  printf("%s\n",arr);

    14

    15  return (0);

    16 }

    上述程序名为dynarray.c,其工作是把参数argv[1]的值n加上1作为变长数组arr的长度,变长数组arr的类型为char。然后向数组中写入一些字符,并将写入的字符串输出。

    像下面这样编译这个程序:

    [root@cyc test]# gcc -g -odynarray dynarray.c

    然后,用gdb观察dynarray的执行情况:

    [root@cyc test]#gdb dynarray

    (gdb) break main

    Breakpoint 1 at 0x80483a3:file dynarray.c, line 6.

    (gdb) set args 6

    (gdb) run

    Starting program: /root/source/test/a.out 6

     

    Breakpoint 1, main (argc=2, argv=0xbfffe224) at dynarray.c:6

    6               n =atoi(argv[1]);

    (gdb) next

    7               char arr[n+1];

    (gdb) next

    8               bzero(arr,(n+1) * sizeof(char));

    (gdb) print/x arr

    $2 = {0xb0, 0xe5}

    (gdb) ptype arr

    type = char [2]

    (gdb) print &arr

    $3 = (char (*)[2]) 0xbfffe1c8

    这里,当程序执行流通过了为变长数组分配空间的第7行之后,用print/x命令打印出arr的值,结果居然是两个字节;而如果尝试用ptype打印出arr的类型,得到的结果居然是arr是一个长度为2的字符数组。很明显,在本例中,因为提供给main()函数的参数argv[1]是6,因此按常理可知arr应该是一个长度为7的字符数组,但很遗憾,gdb给出的却并不是这样的结果。用print &arr打印出arr的地址为0xbfffe1c8。继续上面的调试过程:

    (gdb) x/4x&arr

    0xbfffe5c8:     0xbfffe5b0     0xbfffe5c0      0x00000006      0x40015360

    (gdb) x/8x $esp

    0xbfffe5b0:     0xbffffad8      0x42130a14      0xbfffe5c8     0x0804828d

    0xbfffe5c0:     0x42130a14      0x4000c660      0xbfffe5b0      0xbfffe5c0

    可以看到,在&arr(即地址0xbfffe5c8)处的第一个32位值是0xbfffe5b0,而通过x/8x $esp可以发现,栈顶指针esp恰好就指向的是0xbfffe5b0这个位置。于是,可以猜想,如果arr是一个指针的话,那么它指向的就恰好是当前栈顶的指针。继续上面的调试:

    (gdb) next

    9               for (i = 0; i< n; i++) {

    (gdb) next

    10                      arr[i]= (char)('A' + i);

    (gdb) next

    9               for (i = 0; i< n; i++) {

    (gdb) until

    12              arr[n] = '\0';

    (gdb) next

    13             printf("%s\n", arr);

    (gdb) x/8x $esp

    0xbfffe5b0:     0x44434241     0x42004645      0xbfffe5c8     0x0804828d

    0xbfffe5c0:     0x42130a14      0x4000c660      0xbfffe5b0      0xbfffe5c0

    注意上面表示为蓝色的部分,由于Intel平台采用的是小端字节序,因此蓝色的部分实际上就是’ABCDEF’的十六进制表示。而红色的32位字则暗示着arr就是指向栈顶的指针。为了确认我们的这一想法,下面通过修改arr的值来观察程序的执行情况(需要注意的是:每一次运行时堆栈的地址是变化的):

    (gdb) run

    The program being debugged has been started already.

    Start it from the beginning? (y or n) y

    Starting program: /root/source/test/dynarray 6

     

    Breakpoint 1, main (argc=2, argv=0xbfffde24) at dynarray.c:6

    6               n =atoi(argv[1]);

    (gdb) next

    7               char arr[n+1];

    (gdb) next

    8                                                    bzero(arr, (n+1) *sizeof(char));

    (gdb) print/x &arr

    $3 = 0xbfffddc8

    (gdb) x/8x $esp

    0xbfffddb0:     0xbffffad8      0x42130a14      0xbfffddc8      0x0804828d

    0xbfffddc0:     0x42130a14      0x4000c660      0xbfffddb0      0xbfffddc0

    (gdb) set *(unsignedint*)&arr=0xbfffddc0

    (gdb) x/8x $esp

    0xbfffddb0:    0xbffffad8      0x42130a14      0xbfffddc8      0x0804828d

    0xbfffddc0:     0x42130a14      0x4000c660      0xbfffddc0      0xbfffddc0

    (gdb) next

    9               for (i = 0; i< n; i++) {

    (gdb) next

    10                      arr[i]= (char)('A' + i);

    (gdb) next

    9               for (i = 0; i< n; i++) {

    (gdb) until

    12              arr[n] = '\0';

    (gdb) next

    13             printf("%s\n", arr);

    (gdb) x/8x $esp

    0xbfffddb0:    0xbffffad8      0x42130a14      0xbfffddc8      0x0804828d

    0xbfffddc0:     0x44434241      0x40004645      0xbfffddc0      0xbfffddc0

    地址0xbfffddc8(也就是arr的地址)处的值本来为0xbfffddb0,我们把它改成了0xbfffddc0,于是,当程序运行到向变长数组输入数据完成之后,我们发现这次修改的地址的确是从0xbfffddc0开始的。这就表明arr的确像我们通常所理解的一样,数组名即指针。只不过这个指针指向的位置在它的下方(堆栈向下生长),而不是像大多数时候一样指向上方的某个位置。

    4、分析

    上面的测试结果表明:变长数组的确是在栈空间中分配的;变长数组的数组名实际上就是一个地址指针,指向数组所在的栈顶位置;而GDB无法判断出变长数组的数组名实际上是一个地址指针。

    GDB为什么无法准确判断出变长数组的类型的原因尚不清楚,但是作者猜测这和变长数组的动态特性有关,由于变长数组是在程序动态执行的过程生成的,GDB无法向对待常规数组一样从目标文件包含的.stabs节中获得长度信息,于是给出了错误的类型信息。

    另外,作者对变长数组的作用域进行了测试,测试代码根据上例修改得到,如下所示:

     1 int n;

     2 char arr[n+1];

     3

     4 int

     5 main(int argc, char*argv[])

     6 {

     7      int i;

     8

     9      n = atoi(argv[1]);

    10      bzero(arr, (n+1) *sizeof(char));

    11      for (i = 0; i < n;i++) {

    12              arr[i] =(char)('A' + i);

    13      }

    14      arr[n] = '\0';

    15     printf("%s\n", arr);

    16

    17      return (0);

    18 }

    当如下编译的时候,gcc会提示出错:

    [root@cyc test]#gcc -g dynarray.c

    dynarray.c:2: variable-size type declared outside of anyfunction

    可见gcc不允许在文件域定义变长数组。

    对于gcc中的变长数组能否用static修饰则使用如下代码进行测试:

     1 int

     2 main(int argc, char*argv[])

     3 {

     4      int i, n;

     5

     6      n = atoi(argv[1]);

     7      static char arr[n+1];

     8      bzero(arr, (n+1) * sizeof(char));

     9      for (i = 0; i < n; i++) {

    10              arr[i] =(char)('A' + i);

    11      }

    12      arr[n] = '\0';

    13      printf("%s\n", arr);

    14

    15      return (0);

    16 }

    当编译此源文件的时候,gcc给出如下错误提示:

    [root@cyc test]#gcc -g dynarray.c

    dynarray.c: In function `main':

    dynarray.c:7: storage size of `arr' isn't constant

    dynarray.c:7: size of variable `arr' is too large

    根据提示,可知当数组用static修饰的时候,不能将其声明为变长数组。至于这里的提示说arr太大,作者猜测可能的原因是这样的:对于整数,gcc在编译期赋予了一个非常大的值,于是导致编译报错,不过这仅仅是猜测而已。

    最后需要说明的是,作者是出于对gcc如何实现变长数组的方式感兴趣才进行上面的这些测试的。对于编程者来说,不用做这样的测试,也不需要知道变长数组是位于栈中还是其它地方,只要知道变长数组有上面这样一些限制就行了。另外,本文中有很多地方充斥着作者的推断和猜测。不过这并没有太大的关系,又不是写论文,谁在乎呢?

    另外,上面的测试也说明了:尽管文献[2]没有像文献[1]中那样仔细说明变长数组的限制条件,但实际上它就是那样工作的。再一次体现出gcc的确很好地遵守了C标准的规定。

    参考文献

    [1] Samuel P. Harbison III, Guy L. Steele Jr.; C: A Reference ManualFifth Edition; Prentice Hall, Pearson Education, Inc.; 2002

    [2] Richard M. Stallman and the GCC Developer Community; Using the GNUCompiler Collection; FSF; May 2004


    展开全文
  • 此时,我们可以使用结构体的方法实现C语言变长数组。 struct MyData { int nLen; char data[0];}; 在结构中,data是一个数组名;但该数组没有元素;该数组的真实地址紧随结构体MyData之后,而这个地址就是结构体...
  • C语言变长数组讲解

    万次阅读 2018-05-08 21:10:31
    C语言柔性数组讲解 看如下代码: #include&amp;amp;amp;amp;amp;amp;amp;lt;stdio.h&amp;amp;amp;amp;amp;amp;amp;gt; typedef struct _SoftArray{ int len; int array[]; }SoftArray; int main() { ...

    C语言变长数组讲解

    参考资料:
    1、https://www.cnblogs.com/Anker/p/3744127.html
    2、https://www.cnblogs.com/veis/p/7073076.html
    3、https://blog.csdn.net/dalerkd/article/details/69666716

    看如下代码:

    #include<stdio.h>
    typedef struct {
        int len;
        int array[];
    }SoftArray;
    
    int main() {
        int len = 10;
        printf("The struct's size is %d\n",sizeof(SoftArray));
        return 0;
    }
    

    运行结果:

    [root@VM-0-7-centos mydoc]# ./a.out 
    The struct's size is 4
    

    我们可以看出,_SoftArray结构体的大小是4,显然,在32位操作系统下一个int型变量大小刚好为4,也就说结构体中的数组没有占用内存。为什么会没有占用内

    存,我们平时用数组时不时都要明确指明数组大小的吗?但这里却可以编译通过呢?这就是我们常说的动态数组,也就是变长数组。

    先不要乱,让我们再看一段代码

    #include<stdio.h>
    #include<malloc.h>
    
    typedef struct {
        int len;
        int array[];
    }SoftArray;
    
    int main() {
        int len = 10;
        SoftArray *p=(SoftArray*)malloc(sizeof(SoftArray) + sizeof(int)*len);
        printf("SoftArray size is %d\n", sizeof(SoftArray));
        free(p);
    
        return 0;
    }
    
    

    运行结果:

    [root@VM-0-7-centos mydoc]# ./a.out 
    SoftArray size is 4
    

    是不是有点奇怪,为什么申请了内存后结构体大小还是4呢?原因是动态申请的内存只是申请给数组拓展所用,从上个程序我们可以看出结构体的大小在创建时已经

    确定了,array明确来说不算是结构体成员,只是挂羊头卖狗肉而已。

    下面我们来看看关于变长数组的资料:

    1、什么是变长数组?

    变长数组既数组大小待定的数组, C语言中结构体的最后一个元素可以是大小未知的数组,也就是所谓的0长度,所以我们可以用结构体来创建变长数组。

    2、变长数组有什么用途 ?

    它的主要用途是为了满足需要变长度的结构体,为了解决使用数组时内存的冗余和数组的越界问题。

    3、用法 :在一个结构体的最后 ,申明一个长度为空的数组,就可以使得这个结构体是可变长的。对于编译器来说,此时长度为0的数组并不占用空间,因为数组名

    本身不占空间,它只是一个偏移量, 数组名这个符号本身代 表了一个不可修改的地址常量 (注意:数组名永远都不会是指针! ),但对于这个数组的大小,我们

    可以进行动态分配,对于编译器而言,数组名仅仅是一个符号,它不会占用任何空间,它在结构体中,只是代表了一个偏移量,代表一个不可修改的地址常量!

    对于变长数组的这个特点,很容易构造出变成结构体,如缓冲区,数据包等等

    typedef struct {
        int len;
        int array[];
    }SoftArray;
    

    这样的变长数组常用于网络通信中构造不定长数据包,不会浪费空间浪费网络流量,比如我要发送1024字节的数据,如果用定长包,假设定长包的长度为2048,就

    会浪费1024个字节的空间,也会造成不必要的流量浪费。

    举个简单例子。

    #include<stdio.h>
    #include<malloc.h>
    
    typedef struct {
        int len;
        int array[];
    }SoftArray;
    
    int main() {
        int len=10, i=0;
        SoftArray *p=(SoftArray*)malloc(sizeof(SoftArray)+sizeof(int)*len);
        p->len=len;
        for(i = 0;i < p->len;i++) {
            p->array[i] = i+1;
        }
        for(i = 0;i < p->len;i++) {
            printf("%d\n", p->array[i]);
        }
        free(p);
    
        return 0;
    }
    

    运行结果:

    [root@VM-0-7-centos mydoc]# ./a.out 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    

    注意,内存对齐字节偏移
    解决:资料【3】

    #pragma pack(1)
    struct node {
        int  xxx;//4字节
        char yyy;//1字节
        char data[0];//零字节数组
    }
    #pragma pack()
    
    展开全文
  • } 根据结果可以得出的信息 结构体的地址和结构体中第一个元素的地址是相同的 Array在结构体中“不占空间” 实现的前提: 数组必须在结构体的最后,因为malloc的是整个结构体,如果数组不在最后,申请的空间会覆盖...

    #include

    #include

    #include

    typedef struct Variable_length_array

    {

    size_t len;

    char Arrary[0];

    }CString;

    int main(void)

    {

    printf("In stack\n");

    CString arr;

    printf("&a : %p\n", &arr);

    printf("&a.len : %p\n", &(arr.len));

    printf("&aArrary : %p\n", &(arr.Arrary));

    printf("sizeof(arr) : %lu\n", sizeof(arr));

    printf("sizeof(CString) : %lu\n", sizeof(CString));

    char pStr[] = "Variable_length_array";

    size_t len = strlen(pStr);

    CString *p = (CString*)malloc(sizeof(CString) + len);

    p->len = len;

    strcpy(p->Arrary,pStr);

    printf("\nIn heap\n");

    printf("&p : %p\n",p);

    printf("&p->len : %p\n",&(p->len));

    printf("&p->Array : %p\n", &(p->Arrary));

    printf("sizeof(*p) : %lu\n", sizeof(*p));

    printf("sizeof(CString) : %lu\n", sizeof(CString));

    printf("\nTest p + sizeof(CString)\n");

    printf("sizeof(CString*) : %lu\n", sizeof(CString*));

    printf("p+sizeof(CString) : %p\n", p+sizeof(CString));

    printf("(char*)p+sizeof(CString) : %p\n", ((char*)p+sizeof(CString)));

    printf("\nTest Get the struct data\n");

    char szBuffer[64] = {0};

    // memcpy(szBuffer, p->Arrary, p->len); //ok

    // memcpy(szBuffer, p+sizeof(CString), p->len); //未到达要求

    memcpy(szBuffer, (const void*)p+sizeof(CString), p->len); //ok

    // memcpy(szBuffer, (const void*)p+sizeof(CString), strlen((const void*)p+sizeof(CString))); //ok

    printf("szBuffer : %s\n",szBuffer);

    free(p);

    return 0;

    }

    根据结果可以得出的信息

    结构体的地址和结构体中第一个元素的地址是相同的

    Array在结构体中“不占空间”

    实现的前提:

    数组必须在结构体的最后,因为malloc的是整个结构体,如果数组不在最后,申请的空间会覆盖后面元素的空间

    展开全文
  • //零字节数组 } #pragma pack() 参考资料: 到此这篇关于C语言变长数组使用详解的文章就介绍到这了,更多相关C语言变长数组内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
  • C语言变长数组data[0] 1、前言  今天在看代码中遇到一个结构中包含char data[0],第一次见到时感觉很奇怪,数组的长度怎么可以为零呢?于是上网搜索一下这样的用法的目的,发现在linux内核中,结构体中经常用到...
  • 在《C语言的三套标准:C89、C99和C11》一节中我们讲到,目前经常使用的C语言有三个版本,分别是 C89、C99 和 C11。C89(也称 ANSI C)是较早的版本,也是最经典的版本,国内大学几乎都是以该版本为基础进行授课。C99 ...
  • 今天在看一段代码时出现了用结构体实现变长数组的写法,一开始因为忘记了这种技术,所以老觉得作者的源码有误,最后经过我深思之后,终于想起以前...此时,我们可以使用结构体的方法实现C语言变长数组。 struct MyData
  • C语言变长数组data[0]【总结】 1、前言    今天在看代码中遇到一个结构中包含char data[0],第一次见到时感觉很奇怪,数组的长度怎么可以为零呢?于是上网搜索一下这样的用法的目的,发现在linux内核中,...
  • C语言变长数组之剖析

    2009-01-21 10:17:51
    我们知道,与C++等现代编程语言不同,传统上的C语言是不支持变长数组功能的,也就是说数组的长度是在编译期就确定下来的,不能在运行期改变。不过,在C99标准中,新增的一项功能就是允许在C语言中使用变长数组。然而...
  • 摘要:在实际的编程中,我们经常需要...此时,我们可以使用结构体的方法实现C语言变长数组。 struct MyData { int nLen; char data[0]; }; PS:必须将指针定义在struct的末尾,指针的类型也可以不
  • 初次接触变长数组时我很不明白引入变长数组的意义,因为变长数组虽然是使用变量来指定数组的维度,但是这样操作与声明一个常量再应用似乎没什么区别。 例如:1.使用普通数组 2.使用变长数组  #include #include #...
  • C语言变长数组(zz)

    万次阅读 2008-02-25 15:34:00
    C语言变长数组之剖析1、引言我们知道,与C++等现代编程语言不同,传统上的C语言是不支持变长数组功能的,也就是说数组的长度是在编译期就确定下来的,不能在运行期改变。不过,在C99标准中,新增的一项功能就是允许...
  • C99定义的这种变长数组的使用是有限制的,不能像在C++等语言中一样自由使用 变长数组有以下限制: 1、变长数组必须在程序块的范围内定义,不能在文件范围内定义变长数组; 2、变长数组不能用static或者extern修饰...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 603
精华内容 241
关键字:

c语言变长数组

c语言 订阅