`

C语言长度为0的数组

    博客分类:
  • C++
 
阅读更多

前面在看Xen的源码时,遇到了一段代码,如下所示:

注意上面最后一行的代码,这里定义了一个长度为的数组,这种用法可以吗?为什么可以使用长度为0的数组?长度为的数组到底怎么使用?……这篇文章主要针对该问题进行简单的讲解。废话不多说了,现在就开始。

长度为的数组在标准cc++中是不允许的,如果使用长度为的数组,编译时会产生错误,提示数组长度不能为。但在GNUc中,这种用法却是合法的。它的最典型的用法就是位于数组中的最后一项,如上面所示,这样做主要是为了方便内存缓冲区的管理。如果你将上面的长度为的数组换为指针,那么在分配内存时,需采用两步:首先,需为结构体分配一块内存空间;其次再为结构体中的成员变量分配内存空间。这样两次分配的内存是不连续的,需要分别对其进行管理。当使用长度为的数组时,则是采用一次分配的原则,一次性将所需的内存全部分配给它。相反,释放时也是一样的。

对于长度为的数组,在gcc手册中,有如下一段代码片段:

structline{

intlength;

charcontents[0];

};

structline*thisline=(structline*)malloc(sizeof(structline)+this_length);

thisline->length=this_length;

这段代码的主要含义是定义了一个结构体,并对其进行初始化,上面结构体的第二个成员变量contents[0]事实上是不占内存空间的,因此整个结构体的长度sizeof(structline)4。当采用malloc为其申请内存空间时,如上所示,申请了一段长度为结构体长度加可变长度的内存空间给结构体类型的指针,这时contents就指向申请的可变长度的内存空间。由于是一次申请的,所以这段可变长度的内存空间和前面的结构体长度的内存空间是连续的。对于这段可变长度的内存空间,可以采用数组的方式对其进行访问。对于整个结构体,当不再使用时,可以使用free函数一次性对其进行释放,而不必像指针那样分别释放。

 

下面举例进行说明:

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

structtest1
{
inta;
int*b;
}__attribute((packed));

structtest2
{
inta;
intb[0];
}__attribute((packed));

structtest3
{
inta;
intb[1];
}__attribute((packed));

intmain()
{
structtest1*var1;
structtest2*var2;
structtest3*var3;
inti;

printf("thelengthofstructtest1:%d\n",sizeof(structtest1));
printf("thelengthofstructtest2:%d\n",sizeof(structtest2));
printf("thelengthofstructtest3:%d\n",sizeof(structtest3));

var1=(structtest1*)malloc(sizeof(structtest1));
var1->a=1;
var1->b=(int*)malloc(sizeof(int));
*var1->b=1;
printf("\nvar1->a=%d,*(var1->b)=%d\n",var1->a,*var1->b);

var2=(structtest2*)malloc(sizeof(structtest2)+sizeof(int)*LENGTH);
var2->a=2;
printf("\nvar2->a=%d\n",var2->a);
for(i=0;i<LENGTH;i++)
{
var2->b[i]=i;
printf("var2->b[i]=%d\t",var2->b[i]);
}
printf("\n\n");

var3=(structtest3*)malloc(sizeof(structtest3));
var3->a=3;
(var3->b)[0]=3;
printf("var3->a=%d,(var3->b)[0]=%d\n",var3->a,(var3->b)[0]);


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

}

这段程序的运行结果如下图所示:

从上面的结果可以看出:

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

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

l对于长度为的数组的访问可采用数组方式进行。

分享到:
评论

相关推荐

    c语言输入字符串数组.pdf

    在这个示例中,我们定义了一个二维字符数组 `strArray`,其中有5个字符串,每个字符串的最大长度为19。在 `main` 函数中,我们使用一个循环来输入每个字符串,然后再使用另一个循环来输出这些字符串。 当你运行这段...

    c语言输入字符串数组四组输入字符串数组

    c语言输入字符串数组 一、在C语言中,你可以通过几种不同的方式来输入字符串数组。以下是一个基本的示例,该...我们也可以为用户输入的字符串添加一个最大长度限制,以防止输入过长的字符串。以下是一个更新后的版本:

    不定长数组输入C语言版

    C语言 不定长数组输入 很简短。。。。。。。。。。。。。。。。。。。。

    c语言版本-求数组中第二大的元素

    这个 C 语言程序包括了一个 find_second_largest 函数,该函数接受一个整数数组和数组长度作为参数,并返回数组中第二大的元素。该函数使用一个 for 循环遍历数组中的每个元素,并根据算法中的步骤来更新最大元素和...

    C语言实验报告——数组

    1.编程实现:对任意一个一维数组,从中找出数组...6.编写函数catStr(char str1[],char str2[])用于进行两个字符串的连接,编写函数lenStr()用于统计一个字符串的长度。编写函数cmpStr()用于判断两个字符串的大小。

    C语言变长数组之剖析

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

    c语言 利用字符数组实现两个大整数的加减法.exe

    c语言 利用字符数组实现两个大整数的加减法.exe

    C语言可变长度数组(int型)实现

    gcc xxx.c vsArray.c array_t_s:可变大小的数组的类型 array_t:一个指针类型的别名,访问其内容时,遵循array_t_s的访问规则 函数的功能和使用方法都有注释 新手一个,代码写的不规范欢迎点评

    C语言不定长数组及初始化方法

    今天小编就为大家分享一篇C语言不定长数组及初始化方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

    C++实现不定长数组

    C++简单模拟实现不定长数组,简化操作

    C语言数组指针编程

    定义一个长度为10的int数组nArr,采用给定初始值或从键盘输入的方式给数组的10个元素赋值;定义一个int *型指针变量pInt,并将nArr的首地址存入pInt中

    二进制文件转C语言数组.rar

    任意文件转C语言数组,可以转换图片,exe,文本文件等等,可以选择所要转换的数据长度。 可以转换任意文件。

    结构体中最后一个数组长度为零

    在Linux系统里,/usr/include/linux/if_pppox.h里面有这样...使用起来非常方便,创建时,malloc一段结构体大小加上可变长数据长度的空间给它,可变长部分可按数组的方式访问,释放时,直接把整个结构体free掉就可以了。

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

    在实际的编程中,我们经常需要使用变长数组,但是C语言并不支持变长的数组。此时,我们可以使用结构体的方法实现C语言变长数组。 struct MyData { int nLen; char data[0];}; 在结构中,data是一个数组名;但该数组...

    输入一个任意长度的数组,再对数组排序程序

    输入一个数组,数组的长度有用户输入,然后再一次输出数组的元素。

    C语言安全之数组长度与指针实例解析

    1.C语言编码需要保证变长数组的长度参数位于合法范围之内 例如以下代码: void func(size_t s) { int vla[s]; /*...*/ } /*...*/ func(size); /*...*/ 解决方案如下: enum {MAX_ARRAY = 1024}; void func(size...

    c语言数组指定位置插入和删除-玩转C语言链表,单链表双向链表的建立遍历插入删除... 数组和链表.pdf

    c语言数组指定位置插入和删除-玩转C语言链表,单链表双向链表的建立遍历插入删除... 数组和链表.pdf

    C语言数组操作(长度、输出、拷贝、插入、删除、排序)

    有很详细的注释,可以作为一维数组操作函数进行参考。操作可供选择。 int length(int *array); 返回数组元素个数 int copyarray(int *src, int *dest); 成功返回0, 失败返回-1 int printarray(int *array); 打印 ...

    C语言构建动态数组完整实例

    本文以一个完整的实例代码简述了C语言构建动态数组的方法,供大家参考,完整实例如下: #include #include int main(void) { int len; int * arr; printf(请输入数组长度:); scanf(%d, &len); arr = (int *)...

Global site tag (gtag.js) - Google Analytics