1. 程式人生 > >C語言柔性數組和動態數組

C語言柔性數組和動態數組

了解 方法 功能 lock 使用數組 內容 n) 長度 用法

【前言】經常看到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[]來訪問每一個值;

  


C語言柔性數組和動態數組