亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C > 正文

C語言柔性數組實例詳解

2020-01-26 15:20:30
字體:
來源:轉載
供稿:網友

本文實例分析了C語言柔性數組的概念及用法,對于進一步學習C程序設計有一定的借鑒價值。分享給大家供大家參考。具體如下:

一般來說,結構中最后一個元素允許是未知大小的數組,這個數組就是柔性數組。結構中的柔性數組前面必須至少一個其他成員,柔性數組成員允許結構中包含一個大小可變的數組,sizeof返回的這種結構大小不包括柔性數組的內存。包含柔數組成員的結構用malloc函數進行內存的動態分配,且分配的內存應該大于結構的大小以適應柔性數組的預期大小。柔性數組到底如何使用?

不完整類型

C和C++對于不完整類型的定義是一樣的,不完整類型是這樣一種類型,它缺乏足夠的信息例如長度去描述一個完整的對象。

不完整類型舉例:
前向聲明就是一種常用的不完整類型

struct test; //test 只給出了聲明,沒有給出定義

不完整數據類型必須通過某種方式補充完整,才能使它們進行實例化。否則只能用于定義指針或引用,因為此時實例化的是指針或引用本身,不是base和test對象

一個未知長度的數組也屬于不完整類型:

extern int a[];

extern 關鍵字不能去掉,因為數組的長度未知,不能作為定義出現。不完整類型的數組需要補充完整才能使用。不完整類型的數組可以通過幾種方式補充完整,大括號形式的初始化就是其中的一種方式:

int a[] = { 10,20 };

結構體

首先,我們需要知道――所謂變量,其實是內存地址的一個抽像名字罷了。在靜態編譯的程序中,所有的變量名都會在編譯時被轉成內存地址。機器是不知道我們取的名字的,只知道地址。

所以有了――棧內存區,堆內存區,靜態內存區,常量內存區,我們代碼中的所有變量都會被編譯器預先放到這些內存區中。

有了上面這個基礎,我們來看一下結構體中的成員的地址是什么?我們先簡單化一下代碼:

struct test{  int i;  char *p;};

上面代碼中,test結構中i和p指針,在C的編譯器中保存的是相對地址――也就是說,他們的地址是相對于struct test的實例的。如果我們有這樣的代碼:

struct test t;

下面做個實驗:

#include<stdio.h>struct test{  int i;  char *p;};int main(void){  struct test t;  printf("%p/n", &t);  printf("%p/n", &(t.i));  printf("%p/n", &(t.p));  return 0;}

運行結果:

我們可以看到,t.i的地址和t的地址是一樣的,t.p的址址相對于t的地址多了個8。說白了,t.i 其實就是(&t + 0×0), t.p 的其實就是 (&t + 0×8)。0×0和0×8這個偏移地址就是成員i和p在編譯時就被編譯器給hard code了的地址。于是,你就知道,不管結構體的實例是什么――訪問其成員其實就是加成員的偏移量。

下面再來做個實驗:

#include<stdio.h>struct test{  int i;  short c;  char *p;};int main(void){  struct test *pt=NULL;  printf("%p/n", &(pt->i));  printf("%p/n", &(pt->c));  printf("%p/n", &(pt->p));  return 0;}

運行結果:

注意:上面的pt->p的偏移之所以是0×8而不是0×6,是因為內存對齊了(我在64位系統上)。關于內存對齊,具體可以參看本站C語言內存對齊實例詳解一文。

柔性數組

柔性數組成員(flexible array member)也叫伸縮性數組成員,這種代碼結構產生于對動態結構體的需求。在日常的編程中,有時候需要在結構體中存放一個長度動態的字符串,一般的做法,是在結構體中定義一個指針成員,這個指針成員指向該字符串所在的動態內存空間,例如:

struct s_test{  int a;  double b;  char* p;};

p指向字符串,這種方法造成字符串與結構體是分離的,不利于操作。把字符串和結構體連在一起的話,效果會更好,可以修改如下:

char a[] = "Hello world";struct s_test *ptest = (struct s_test*)malloc(sizeof(s_test)+streln(a)+1);strcpy(ptest+1,a);

這樣一來,(char*)(ptestt + 1)就是字符串“hello world”的地址。這時候p成了多余的東西,可以去掉。但是,又產生了另外一個問題:老是使用(char*)(ptestt + 1)不方便。如果能夠找出一種方法,既能直接引用該字符串,又不占用結構體的空間,就完美了,符合這種條件的代碼結構應該是一個非對象的符號地址,在結構體的尾部放置一個0長度的數組是一個絕妙的解決方案。不過,C/C++標準規定不能定義長度為0的數組,因此,有些編譯器就把0長度的數組成員作為自己的非標準擴展,例如:

struct s_test2{  int a;  double b;  char c[0];};

c就叫柔性數組成員,如果把ptest指向的動態分配內存看作一個整體,c就是一個長度可以動態變化的結構體成員,柔性一詞來源于此。c的長度為0,因此它不占用test的空間,同時ptest->c就是“hello world”的首地址,不需要再使用(char*)(ptestt + 1)這么丑陋的語法了。

鑒于這種代碼結構所產生的重要作用,C99甚至把它收入了標準中:

As a special case, the last element of a structure with more than one named member may have an incomplete array type; this is called a flexible array member.
C99使用不完整類型實現柔性數組成員,標準形式是這樣的:

struct s_test{ int a; double b; char c[];};

c同樣不占用test的空間,只作為一個符號地址存在,而且必須是結構體的最后一個成員。柔性數組成員不僅可以用于字符數組,還可以是元素為其它類型的數組,例如:

struct s_test{  int a;  double b;  float[];};

首先,我們要知道,0長度的數組在ISO C和C++的規格說明書中是不允許的。這也就是為什么在VC++2012下編譯你會得到一個警告:“arning C4200: 使用了非標準擴展 : 結構/聯合中的零大小數組”。

那么為什么gcc可以通過而連一個警告都沒有?那是因為gcc 為了預先支持C99的這種玩法,所以,讓“零長度數組”這種玩法合法了。關于GCC對于這個事的文檔在這里:“Arrays of Length Zero”,文檔中給了一個例子,完整代碼如下:

#include <stdlib.h>#include <string.h>struct line {  int length;  char contents[0]; // C99的玩法是:char contents[]; 沒有指定數組長度};int main(){  int this_length=10;  struct line *thisline = (struct line *)           malloc (sizeof (struct line) + this_length);  thisline->length = this_length;  memset(thisline->contents, 'a', this_length);  return 0;}

上面這段代碼的意思是:我想分配一個不定長的數組,于是我有一個結構體,其中有兩個成員,一個是length,代表數組的長度,一個是contents,代碼數組的內容。后面代碼里的 this_length(長度是10)代表是想分配的數據的長度。

相信本文所述對大家C程序設計的學習有一定的借鑒價值。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲一区www| 成人欧美一区二区三区在线| 亚洲一区二区三区乱码aⅴ| 亚洲bt天天射| 一个人www欧美| 美日韩精品视频免费看| 久久精品视频免费播放| 亚洲欧美日韩一区二区三区在线| 国产免费观看久久黄| 亚洲电影免费观看高清完整版在线观看| 国产一区二区久久精品| 日韩视频―中文字幕| 91在线视频精品| 最近2019中文免费高清视频观看www99| 2020欧美日韩在线视频| 国产成人精品免高潮费视频| 日韩欧美成人精品| 日本一区二区三区四区视频| 成人国产亚洲精品a区天堂华泰| 国产在线999| 精品久久国产精品| 国产成人aa精品一区在线播放| 中文字幕综合一区| 亚洲香蕉成视频在线观看| 国产精品视频免费观看www| 成人欧美一区二区三区黑人| 欧美丰满少妇xxxxx| 青草热久免费精品视频| 欧美国产欧美亚洲国产日韩mv天天看完整| 国内精品伊人久久| 亚洲国产高清高潮精品美女| 日韩美女免费观看| 国产精品老牛影院在线观看| 中文字幕日韩在线观看| 性色av一区二区三区红粉影视| 日本人成精品视频在线| 黄色成人在线播放| 亚洲va欧美va国产综合剧情| 最近中文字幕mv在线一区二区三区四区| 欧美电影免费观看| 九九久久久久99精品| 欧美成人精品影院| 亚洲国产精品yw在线观看| 成人免费网站在线看| 日韩av电影在线播放| 精品欧美激情精品一区| 91av在线影院| 亚洲欧美成人一区二区在线电影| 久久久亚洲影院| 插插插亚洲综合网| 伊人伊人伊人久久| 久久久国产精彩视频美女艺术照福利| 69影院欧美专区视频| 91免费人成网站在线观看18| 欧美日韩一区二区三区在线免费观看| 亚洲国产精品小视频| 久久久久久国产免费| 国产a∨精品一区二区三区不卡| 欧美日韩在线看| 色老头一区二区三区| 日韩在线观看av| 日韩av123| 国产有码在线一区二区视频| 国产成人精品亚洲精品| 韩国v欧美v日本v亚洲| 国产精品久久久久久久久久99| 国产成人综合精品| 91精品在线一区| 成人写真福利网| 久久久亚洲福利精品午夜| 欧美在线观看网站| 国产精品久久久久久久久影视| 66m—66摸成人免费视频| 亚洲精品国产欧美| 亚洲精品v天堂中文字幕| 久久精品久久久久久| 久久91亚洲人成电影网站| 日韩av片永久免费网站| 色樱桃影院亚洲精品影院| 97**国产露脸精品国产| 在线看日韩av| 日韩av手机在线观看| 欧美一级高清免费播放| 乱亲女秽乱长久久久| 精品福利在线观看| 精品福利在线观看| 亚洲大胆人体av| 国产一区二区免费| 亚洲国产成人精品电影| 色妞欧美日韩在线| 国产精品入口夜色视频大尺度| 91精品国产色综合久久不卡98口| 国产91精品久久久久| 欧美俄罗斯性视频| 91在线高清免费观看| 日韩美女av在线免费观看| 日韩精品中文字幕有码专区| 欧美高清电影在线看| 青青在线视频一区二区三区| 播播国产欧美激情| 亚洲自拍偷拍色图| 亚洲精品在线看| 国产剧情日韩欧美| 92裸体在线视频网站| 日韩性生活视频| 亚洲欧美色图片| 久久精品久久久久久国产 免费| 日韩精品视频在线免费观看| 久久理论片午夜琪琪电影网| 中文欧美日本在线资源| 国产在线精品一区免费香蕉| 欧美一区二区.| 国产一区二区三区视频在线观看| 日韩精品在线免费观看视频| 久久好看免费视频| 97精品一区二区三区| 国产91免费看片| 国产日韩精品电影| 亚洲精品国产精品自产a区红杏吧| 精品久久久久久久中文字幕| 97国产精品久久| 欧美成人在线免费| 69精品小视频| 欧美国产亚洲视频| 久久久人成影片一区二区三区| 国产精品久久久久久av福利软件| 欧美激情成人在线视频| 国模吧一区二区三区| 亚洲电影免费观看| 久久精品中文字幕一区| 亚洲天堂视频在线观看| 亚洲最新av网址| 亚洲精品不卡在线| 欧美激情一区二区三区在线视频观看| 亚洲一区二区三区四区在线播放| 亚洲最大中文字幕| 超碰91人人草人人干| 日韩成人在线视频观看| 欧美成人激情在线| 精品动漫一区二区三区| 夜夜嗨av一区二区三区四区| 久久久久久久久久国产| 欧美亚洲成人精品| 久久精品一偷一偷国产| 91精品视频在线播放| 8x拔播拔播x8国产精品| 日韩少妇与小伙激情| 国产亚洲精品久久久优势| 欧美在线一区二区三区四| 国产精品女视频| 精品亚洲精品福利线在观看| 91在线看www| 国产精品白丝av嫩草影院| 精品亚洲一区二区三区在线观看| 在线日韩中文字幕| 久色乳综合思思在线视频| 色爱精品视频一区| 日韩中文娱乐网| 少妇av一区二区三区| 成人在线激情视频| 亚洲高清福利视频| 在线看日韩欧美| 伊人久久免费视频| 91国产精品91|