C语言柔性数组和动态数组

【前言】经常看到C语言里的两个数组,总结一下。

一、柔性数组

  参考:https://www.cnblogs.com/veis/p/7073076.html

#include<stdio.h>
typedef struct _SoftArray{
    int len;
    int array[];
}SoftArray;

int main()
{
    int len = 10;

    printf("The struct‘s size is %d\n",sizeof(SoftArray));
}

  

  我们可以看出,_SoftArray结构体的大小是4,显然,在32位操作系统下一个int型变量大小刚好为4,也就说结构体中的数组没有占用内存。为什么会没有占用内存,我们平时用数组时不时都要明确指明数组大小的吗?但这里却可以编译通过呢?这就是我们常说的动态数组,也就是柔性数组。

1、什么是柔性数组?

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

2、柔性数组有什么用途 ?

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

3、用法 :

  在一个结构体的最后 ,申明一个长度为空的数组,就可以使得这个结构体是可变长的。对于编译器来说,此时长度为0的数组并不占用空间,因为数组名本身不占空间,它只是一个偏移量, 数组名这个符号本身代 表了一个不可修改的地址常量 (注意:数组名永远都不会是指针! ),但对于这个数组的大小,我们可以进行动态分配,对于编译器而言,数组名仅仅是一个符号,它不会占用任何空间,它在结构体中,只是代表了一个偏移量,代表一个不可修改的地址常量!

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

    typedef struct _SoftArray

    {

        Int len;

      int array[];

    }SoftArray;

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

4、举例

#include<stdio.h>
#include<malloc.h>
typedef struct _SoftArray{
int len;
int array[];
}SoftArray;
int main()
{
    int len=10,i=0;
    //分配空间的格式。此时softarray大小仍然为4
    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;
}

  

  这代码的作用是用柔性数组动态创建数组并输出数组内容,这里我就直接解释解释这两句代码:

SoftArray* p = (SoftArray*)malloc(sizeof(SoftArray) + sizeof(int) *10);

 p->len = 10;

 第一句,主要是根据你要定义的数组长度和数据类型以及柔性数组本身的大小来开辟一块内存空间给柔性数组p,第二个是定义len的长度,便于确定循环打印输出是循环的次数。

5、柔性数组在“不确定数组大小”中的应用 

 对不确定len值大小的数组,使用了数组的方法。若不定义柔性数组,定义普通数组len需要确定的值!如10,11...
#include<stdio.h>
#include<malloc.h>
typedef struct _SoftArray{
    int len;
    int array[];
}SoftArray;

//打印输出斐波那契数列
void printfln(SoftArray *p,int len)
{
    int i;
    for(i=0;i<len;i++)        //循环进行打印输出
    {
        printf("%d\n",p->array[i]);
    }
}

//动态生成斐波那契数列
void create(int len)
{
    int i;

    SoftArray * p=(SoftArray*)malloc(sizeof(SoftArray)+sizeof(int)*len);    //声明结构体指针p,动态申请内存,大小为结构体大小+10个int型大小
    //对不确定len值大小,使用了数组的方法。若不定义柔性数组,定义普通数组len需要确定的值!如10,11...
    for(i=0;i<len;i++)        //循环进行数组赋值
    {
        if( i <= 1 )
        {
            p->array[i] = 1;
        }else if( i >= 2 )
        {
            p->array[i] = p->array[i-1] + p->array[i-2];
        }else
        {
            printf("DAMAGE: before Normal block or after Normal block");
            return (-1);
        }

    }
    printfln(p,len);
    free(p);
}

//主函数
int main()
{
    int i=0;
    int len;
    printf("请输入生成斐波那契数列的行数:");
    scanf("%d",&len);
    //将一个不确定值传入了函数
    create(len);

    return 0;
} 

二、动态数组

  动态数组,即根据实时变化,可以扩大数组大小。而这个功能的实现需要用到指针和malloc和realloc函数
    int *a = (int*)malloc(10*sizeof(int));那么 a就相当于一个有10个元素的数组。当数据量超过10个放不下的时候,利用
    a = (int*)realloc(a, 20*sizeof(int));//意思是把a的大小增加到20,而保持原来已有的数据不变。
  上面的函数要包含:#include<stdlib.h> #include<malloc.h> 或#include<alloc.h>

举例说明:

#include<stdio.h>
#include<stdlib.h>
void DimensionalVector(){
    int n, i;
    int *arr;
    //输入不定的值,体现了数组与指针的关系
    scanf("%d",&n);
    arr = (int*)malloc(sizeof(int)*n);

    for (i = 0; i < n; i++)
        arr[i] = i;
    for (i = 0; i < n; i++)
        printf("%d\t",arr[i]);
}

int main(){
    DimensionalVector();

    return 0;
}

  体现了数组与指针的关系,可具体参考数组与指针的转换关系。

三、二者的区别

  柔性数组是利用结构体,动态数组使用了指针与数组的关系;

  前者在创建之后,利用p->array[]来访问每一个值,后者直接利用p[]来访问每一个值;

  

原文地址:https://www.cnblogs.com/huangfuyuan/p/9557435.html

时间: 2024-10-13 16:13:29

C语言柔性数组和动态数组的相关文章

C语言中怎么求动态数组大小

先来个简单的例子 int a[] = {1,2,3}; int arr_len = 0; arr_len = sizeof(a)/sizeof(int); 解释:sizeof() 关键字是求出对象所占用的内存空间的大小,so, sizeof(a)是算出整个数组占用的空间的大小. 因为是整数数组,一个整数在32位系统上占用4个字节,不同的系统数值可能不同, 用sizeof(int)可以计算出 一个整数占用的内存空间大小.所以用sizeof(a)/sizeof(int)数组中有几个整数,也即算出了数

c语言结构体中动态数组的使用

[背景] c语言结构体中动态数组使得用户能够根据需要来申请空间,相比静态数组,更能有效利用存储空间. [正文] 1. 动态数组在结构体中间 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct { int a; char buf[0]; // 或者char buf[]; int b; }Node; int main() { printf("%d\n", si

[C] 在 C 语言编程中实现动态数组对象

对于习惯使用高级语言编程的人来说,使用 C 语言编程最头痛的问题之一就是在使用数组需要事先确定数组长度. C 语言本身不提供动态数组这种数据结构,本文将演示如何在 C 语言编程中实现一种对象来作为动态数组. /* Author: [email protected] */ 基本的 C 数组 C 语言编程中声明一个基本数组如下: int main() { // 声明一个容纳 3000 个整数的数组 int my_array[3000]; } 以上代码做了两件事: ● 在栈区开辟内存空间.准确说来是在

JS 索引数组、关联数组和静态数组、动态数组

1 JS 索引数组.关联数组和静态数组.动态数组 2 3 数组分类: 4 5 1.从数组的下标分为索引数组.关联数组 6 7 var ary1 = [1,3,5,8]; 8 //按索引去取数组元素,从0开始(当然某些语言实现从1开始) 9 //索引实际上就是序数,一个整型数字 10 alert(ary1[0]); 11 alert(ary1[1]); 12 alert(ary1[2]); 13 alert(ary1[3]); 14 15 16 var ary2 = {}; 17 //存取时,以非

队列的三种实现(静态数组、动态数组及指针)

本文有关栈的介绍部分参考自网站数据结构. 1. 队列  1.1 队列的定义 队列(Queue)是只允许在一端进行插入,而在另一端进行删除的运算受限的线性表. (1)允许删除的一端称为队头(Front). (2)允许插入的一端称为队尾(Rear). (3)当队列中没有元素时称为空队列. (4)队列亦称作先进先出(First In First Out)的线性表,简称为FIFO表.    队列的修改是依先进先出的原则进行的.新来的成员总是加入队尾(即不允许"加塞"),每次离开的成员总是队列头

静态数组和动态数组

概念 数组在程序设计中应用十分广泛,可以用不同类型的数组来存储大量相同类型的数据.创建数组的方式一般有三种: 全局/静态范围的数组.局部变量数组.申请堆空间创建的数组.其中,全局/静态范围的数组以及局部变量数组都属于静态数组,从堆中申请空间建立的数组为动态数组. 静态数组和动态数组的区别 1.静态数组的大小是在编译期间就确定,并且分配的,其内存在使用结束后由计算机自动释放,效率高:动态数组是在程序运行时,由程序员根据实际需要从堆内存中动态申请的,使用结束后由程序员进行释放,效率低. 2.对静态数

WEB开发教程--ASP中静态数组与动态数组的用法

在ASP中,数组是具有相同名字的一组变量,数组中包含多个元素,由不同的下标值区分数组的各个元素.在VBScript中,数组有两种类型:静态数组和动态数组. 1.静态数组 静态数组在编译时开辟内存区,数组大小在运行时不可改变. 定义一个一维数组mmArray(3) Dim mmArray(3) mmArray(0)=1 mmArray(1)=3 mmArray(2)=5 mmArray(3)=7 其中mmArray是数组名,数组的下界为0,上界为3,数组元素从mmArray(0)到mmArray(

C语言数组:C语言数组定义、二维数组、动态数组、字符串数组

1.C语言数组的概念 在<更加优美的C语言输出>一节中我们举了一个例子,是输出一个 4×4 的整数矩阵,代码如下: #include <stdio.h> #include <stdlib.h> int main() { int a1=20, a2=345, a3=700, a4=22; int b1=56720, b2=9999, b3=20098, b4=2; int c1=233, c2=205, c3=1, c4=6666; int d1=34, d2=0, d3

Java程序猿学习C++之数组和动态数组

数组: #include <iostream> using namespace std; //模板函数 template <class T> void dump(T val) { cout << ">>>>" << __FUNCTION__ << endl;//内置的宏,打印当前函数的名字 cout << sizeof(val) << ":" <<