麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

5.1數(shù)組的定義&5.2數(shù)組的順序表示和實(shí)現(xiàn)

2019-11-10 19:16:20
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

5.1數(shù)組的定義:

數(shù)組一旦被定義,它的維數(shù)和維界就不再改變。因此,除了結(jié)構(gòu)的初始化和銷毀之外,數(shù)組只有存取元素和修改元素值的操作。

5.2數(shù)組的順序表示和實(shí)現(xiàn)

下面我們先來(lái)看下數(shù)組順序存儲(chǔ)的表示:

代碼如下:

#include <stdarg.h>	//提供宏va_start、va_arg、va_end					//用于存取可變長(zhǎng)參數(shù)表#define MAX_ARRAY_DIM 8//假設(shè)數(shù)組最大值為8typedef struct{	ElemType* base;	//數(shù)組元素基址,由InitArray分配	int dim;	//數(shù)組維數(shù)	int* bounds;	//數(shù)組維界基址,由InitArray分配	int* constants;	//數(shù)組映像函數(shù)常量基址,由InitArray分配}Array;

我們先分析下:

這個(gè)va_start,va_arg,va_end我們遇到相關(guān)代碼再說(shuō)。

這個(gè)*base是數(shù)組元素基址,所謂的元素基址,我們知道一維數(shù)組,二維數(shù)組,三維數(shù)組在邏輯上我們可以把他形象化,比如一維數(shù)組是線,二維是平面,三維是空間,但在內(nèi)存中,他還是處于線性排列的,所以得有那么一個(gè)數(shù)組的元素基址,才能確定元素的位置。

這個(gè)dim,指的是數(shù)組的維度,比如剛剛所說(shuō)的一維,二維,三維。

這個(gè)*bounds是存儲(chǔ)了每個(gè)維度所在的地址。

這個(gè)*constants這個(gè)是數(shù)組映像函數(shù)常量基址,可能有人會(huì)問(wèn),什么是映像函數(shù)。所謂的映像函數(shù)就是用以根據(jù)數(shù)組下標(biāo)快速計(jì)算其存儲(chǔ)位置,有人說(shuō)聽不懂!那舉個(gè)例子。假定每個(gè)元素之占用1個(gè)存儲(chǔ)單元.其實(shí)這就是:(b2*...*bn)*j1+(b3*...*bn)*j2+(b4*...*bn)*j3+...+[b(n-1)*bn]*j(n-2)+bn*j(n-1)+1*jn上面式子的變體.constants[0]*j1+constants[1]*j2+...+constants[n-2]*j(n-1)+constants[n-1]*jnbounds[]中存儲(chǔ)的每一維的多少

懂了吧。

下面是基本操作的函數(shù)原型說(shuō)明:

首先來(lái)看InitArray函數(shù):

代碼如下:

Status InitArray(Array& A, int dim, ...){	//若維度dim和各維度長(zhǎng)度合法,則構(gòu)造相應(yīng)的數(shù)組A,并返回OK	if (dim<1 || dim>MAX_ARRAY_DIM)		return ERROR;	A.dim = dim;	A.bounds = (int *)malloc(dim*sizeof(int));	if (!A.bounds)		exit(OVERFLOW);	//若各維長(zhǎng)度合法,則存入A.bounds,并求出A的元素總數(shù)elemtotl	int elemtotal = 1;	// elemtotal是數(shù)組元素總數(shù),初值為1(累乘器)	va_list ap;	va_start(ap, dim);	//讀取可變參數(shù)的過(guò)程其實(shí)就是在堆棧中,使用指針,遍歷堆棧段中的參數(shù)列表,從低地址到高地址一個(gè)一個(gè)地把參數(shù)內(nèi)容讀出來(lái)的過(guò)程	for (int i = 0; i < dim; i++)	{		A.bounds[i] = va_arg(ap, int);		if (A.bounds[i] < 0)			return UNDERFLOW;	// 在math.h中定義為4		elemtotal *= A.bounds[i];	}	va_end(ap);	A.base = (ElemType*)malloc(elemtotal*sizeof(ElemType));	if (!A.base)		exit(OVERFLOW);	//求映像函數(shù)的常數(shù)Ci,并存入A.constant[i-1],i=1,...,dim	A.constants = (int*)malloc(dim*sizeof(int));	if (!A.constants)		exit(OVERFLOW);	A.constants[dim - 1] = 1;	//L=1,指針的增減以元素的大小為單位	for (int i = dim - 2; i >= 0; --i)		A.constants[i] = A.bounds[i + 1] * A.constants[i + 1];	return Ok;}下面來(lái)分析下:

這個(gè)MAX_ARRAY_DIM,是剛剛定義的宏,也就是最大只有8維。

這里的參數(shù)里面有"..."這個(gè)可能有人問(wèn)。在此說(shuō)明下。大家都懂PRintf這個(gè)也就是這樣,可變參數(shù)。那么如何讀取到底有多少個(gè)可變參數(shù)。那就是va_start,va_list,va_end,va_arg的事,下面來(lái)講解下va_start,va_list,va_end,va_arg。

va_list 是一個(gè)字符指針,可以理解為指向當(dāng)前參數(shù)的一個(gè)指針,取參必須通過(guò)這個(gè)指針進(jìn)行。<Step 1> 在調(diào)用參數(shù)表之前,定義一個(gè) va_list 類型的變量,(假設(shè)va_list 類型變量被定義為ap);<Step 2> 然后應(yīng)該對(duì)ap 進(jìn)行初始化,讓它指向可變參數(shù)表里面的第一個(gè)參數(shù),這是通過(guò) va_start 來(lái)實(shí)現(xiàn)的,第一個(gè)參數(shù)是 ap 本身,第二個(gè)參數(shù)是在變參表前面緊挨著的一個(gè)變量,即“...”之前的那個(gè)參數(shù);<Step 3> 然后是獲取參數(shù),調(diào)用va_arg,它的第一個(gè)參數(shù)是ap,第二個(gè)參數(shù)是要獲取的參數(shù)的指定類型,然后返回這個(gè)指定類型的值,并且把 ap 的位置指向變參表的下一個(gè)變量位置;<Step 4> 獲取所有的參數(shù)之后,我們有必要將這個(gè) ap 指針關(guān)掉,以免發(fā)生危險(xiǎn),方法是調(diào)用 va_end,他是輸入的參數(shù) ap 置為 NULL,應(yīng)該養(yǎng)成獲取完參數(shù)表之后關(guān)閉指針的習(xí)慣。說(shuō)白了,就是讓我們的程序具有健壯性。通常va_start和va_end是成對(duì)出現(xiàn)。

這里面沒(méi)有用到va_arg,在下面的程序里面會(huì)用到。

函數(shù)都講解完了,下面講解下這程序的思路。

這個(gè)程序的思路是先把有多少維度的Array初始了,這個(gè)可變參數(shù)里面放的是根據(jù)dim的數(shù)來(lái)判斷的,比如dim為2,那么就是二維的,那么還要兩個(gè)可變參數(shù),一個(gè)是第一維的元素個(gè)數(shù),一個(gè)是第二維的元素個(gè)數(shù)。

這里elemotal*=A.bounds[i],就把維度里面的所有元素都讀取了出來(lái)

然后A.base就是第一個(gè)元素的地址。

開辟了A.base的空間后,現(xiàn)在弄映像函數(shù)。

下面是銷毀數(shù)組A

代碼如下:

Status DestroyArray(Array& A){	//銷毀數(shù)組A	if (!A.base)		return ERROR;	free(A.base);	A.base=NULL:	if (!A.bounds)		return ERROR;	free(A.bounds);	A.bounds = NULL;	if (!A.constants)		return ERROR;	free(A.constants);	A.constants = NULL;	return Ok;}分析:

這個(gè)就是當(dāng)那個(gè)指針地址不為空就free,然后把指針指向安全的地帶,也就是NULL。

下面是求元素在A中的相對(duì)位置。

代碼如下:

Status Locate(Array A, va_list ap, int& off){	//若ap指示的各下標(biāo)值合法,則求出該元素在A中相對(duì)地址off	int ind;	off = 0;	for (int i = 0; i < A.dim; i++)	{		ind = va_arg(ap, int);		if (ind < 0 || ind >= A.bounds[i])			return OVERFLOW;		off += A.constants[i] * ind;	}	return Ok;}

分析:

這個(gè)函數(shù)是要結(jié)合下面這個(gè)函數(shù)看的。調(diào)用va_arg,它的第一個(gè)參數(shù)是ap,第二個(gè)參數(shù)是要獲取的參數(shù)的指定類型,然后返回這個(gè)指定類型的值,并且把 ap 的位置指向變參表的下一個(gè)變量位置。這個(gè)ap是下面這個(gè)Value函數(shù)的可變參數(shù)。

下面兩個(gè)函數(shù)代碼為:

Status Value(Array A, ElemType& e, ...){	//A是n維數(shù)組,e為元素變量,隨后是n個(gè)下標(biāo)值。	//若各下標(biāo)不超界,則e賦值為所指定的A的元素值,并返回OK。	va_list ap;	int result;	int off;	va_start(ap, e);	if ((result = Locate(A, ap, off)) <= 0)		return result;	e = *(A.base + off);	return Ok;}Status Assign(Array& A, ElemType e, ...){	//A是n維數(shù)組,e為元素變量,隨后是n個(gè)下標(biāo)值。	//若下標(biāo)不越界,則將e的值賦值給所指定的A的元素,并返回OK	va_list ap;	va_start(ap, e);	int off;	int result;	//這里的Statues被定義為int型	if (result = Locate(A, ap, off) <= 0)		return result;	*(A.base + off) = e;	return Ok;}


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 91短视频版高清在线观看www | 毛片免费大全短视频 | 亚洲成人在线免费观看 | 精品久久久久久亚洲精品 | 中文字幕欧美专区 | 久久国产精品久久久久久电车 | 中文字幕在线播放不卡 | 免费a级毛片大学生免费观看 | 天天黄色片| 亚洲欧美在线视频免费 | 操你啦免费视频 | 色七七久久影院 | 亚洲免费视频大全 | 91短视频网页版 | 激情亚洲一区二区 | 国产精品亚洲三区 | 黄视频在线网站 | 欧美毛片 | 92自拍视频| 日韩欧美激情视频 | 国产成人精品一区二区三区电影 | 欧美在线观看视频网站 | asian裸体佳人pics | 黄色网址在线免费播放 | 国产一区二区在线免费观看 | 亚洲成人第一页 | 羞羞视频免费视频欧美 | 国产精品av久久久久久网址 | 精品在线一区二区三区 | 国产成年人网站 | 毛片大全免费看 | 欧美成人黄色小视频 | 免费午夜视频 | 国产一区二区视频在线播放 | 999精品国产 | 大学生一级毛片在线视频 | 精品久久久久久国产 | 国产免费一区二区三区最新不卡 | 国产午夜免费不卡精品理论片 | 中文字幕在线观看91 | 欧美一级毛片免费观看视频 |