電子商務(wù)網(wǎng)站建設(shè)專業(yè)主修課程關(guān)鍵詞挖掘排名
👦個人主頁:@Weraphael
?🏻作者簡介:目前是C語言學(xué)習(xí)者
??專欄:C語言航路
🐋 希望大家多多支持,咱一起進步!😁
如果文章對你有幫助的話
歡迎 評論💬 點贊👍🏻 收藏 📂 加關(guān)注
前言
說起數(shù)組,一維數(shù)組、二維數(shù)組、字符數(shù)組、整型數(shù)組和浮點型數(shù)組,我相信大家并不陌生吧,今天我們一起看看柔性數(shù)組!
目錄
- 前言
- 一、柔性數(shù)組的概念和定義
- 二、柔性數(shù)組的特點
- 三、柔性數(shù)組的使用
- 四、柔性數(shù)組的優(yōu)勢
一、柔性數(shù)組的概念和定義
在C99中,結(jié)構(gòu)中的最后一個元素允許是未知大小的數(shù)組,我們把這樣的數(shù)組稱為柔性數(shù)組成員。
【定義】
struct S
{int i;int a[]; //柔性數(shù)組
};
若有些編譯器無法編譯,可以改成以下這種:
struct S
{int i;int a[0];//柔性數(shù)組成員
};
二、柔性數(shù)組的特點
- 結(jié)構(gòu)中的柔性數(shù)組前必須至少有一個其他成員
sizeof
返回的這種結(jié)構(gòu)大小不包括柔性數(shù)組的內(nèi)存
- 包含柔性數(shù)組成員的結(jié)構(gòu)用
malloc
函數(shù)進行動態(tài)內(nèi)存分配,并且分配的內(nèi)存應(yīng)該大于結(jié)構(gòu)體大小,以適應(yīng)柔性數(shù)組的預(yù)期大小
三、柔性數(shù)組的使用
動態(tài)內(nèi)存開辟函數(shù)講解:傳送門
#include <stdio.h>
#include <stdlib.h>
struct S
{int i;char a[];
};
int main()
{//包含柔性數(shù)組成員的結(jié)構(gòu)用`malloc`函數(shù)進行動態(tài)內(nèi)存分配//并且分配的內(nèi)存應(yīng)該大于結(jié)構(gòu)體大小struct S* sp = (struct S*)malloc(sizeof(struct S) + 10 * sizeof(char));//若sp為空指針,說明開辟動態(tài)內(nèi)存失敗if (sp == NULL){return 1;}//否則開辟成功//使用sp->i = 100;for (int i = 0; i < 10; i++){sp->a[i] = 'x';}//打印for (int i = 0; i < 10; i++){printf("%c ", sp->a[i]);}//釋放free(sp);sp = NULL;return 0;
}
甚至還能擴容
realloc
#include <stdio.h>
#include <stdlib.h>
struct S
{int i;char a[];
};
int main()
{//包含柔性數(shù)組成員的結(jié)構(gòu)用`malloc`函數(shù)進行動態(tài)內(nèi)存分配//并且分配的內(nèi)存應(yīng)該大于結(jié)構(gòu)體大小struct S* sp = (struct S*)malloc(sizeof(struct S) + 10 * sizeof(char));//若sp為空指針,說明開辟動態(tài)內(nèi)存失敗if (sp == NULL){return 1;}//否則開辟成功//使用sp->i = 100;for (int i = 0; i < 10; i++){sp->a[i] = 'x';}//擴容(多加10字節(jié)的空間)struct S* p = (struct S *)realloc(sp, sizeof(struct S) + sizeof(char) * 20);//如果p為空指針說明擴容失敗if (p == NULL){return 1;}else{sp = p;p = NULL;}for (int i = 10; i < 20; i++){sp->a[i] = 'w';}//打印printf("%d\n", sp->i);for (int i = 0; i < 20; i++){printf("%c ", sp->a[i]);}return 0;
}
所以柔性數(shù)組在內(nèi)存其實是這樣的
它在內(nèi)存是連續(xù)的
四、柔性數(shù)組的優(yōu)勢
除【柔性數(shù)組的使用】樣例以外,也可以設(shè)計成下面這樣:
#include <stdio.h>
#include <stdlib.h>struct S
{int i;char* a;
};int main()
{//為結(jié)構(gòu)體開辟空間struct S* sp = (struct S*)malloc(sizeof(struct S));//若sp = NULL,說明開辟失敗if (sp == NULL){return 1;}//否則開辟成功//使用內(nèi)存空間sp->i = 100;//為char* a開辟10個字節(jié)空間sp->a = (char*)malloc(sizeof(char) * 10);//使用for (int i = 0; i < 10; i++){sp->a[i] = 'w';}//或者還能為char* a擴容char* p = (char*)realloc(sp->a, 20 * sizeof(char));if (p == NULL){return 1;}else{sp->a = p;p = NULL;}//使用擴容的空間for (int i = 10; i < 20; i++){sp->a[i] = 'J';}//打印printf("int i = %d\n", sp->i);for (int i = 0; i < 20; i++){printf("%c ", sp->a[i]);}//釋放空間free(sp->a);sp->a = NULL;free(sp);sp = NULL;return 0;
}
一個常見的問題:為什么要先釋放
sp->a
的內(nèi)存空間
- 首先程序是先為結(jié)構(gòu)體開辟空間
- 接著又為
char*
開辟空間
所以,若先對sp
釋放空間,到后面就不能通過sp
找到char* c
開辟的空間
柔性數(shù)組好處的總結(jié):
- 對于柔性數(shù)組來說,開辟空間(malloc)只需要一個,釋放空間(free)也只需要一次,且內(nèi)存空間是連續(xù)的,而對于上面的代碼來說,開辟空間需要二次,釋放空間也同樣需要二次,且內(nèi)存空間是不連續(xù)的。所以它第一個好處是方便內(nèi)存釋放
- 連續(xù)的內(nèi)存有益于提高訪問速度