文档库 最新最全的文档下载
当前位置:文档库 › MFC中动态数组CArray的使用

MFC中动态数组CArray的使用

MFC中动态数组CArray的使用
MFC中动态数组CArray的使用

MFC中动态数组CArray的使用

数组——这个C语言中的怪物,自从被直接继承到C++中,便让无数有识之士们前赴后继、绞尽脑汁,试图寻找一种可以动态增长的替代数据类型。当然,最著名的,应该就是vector向量。但是,它的数据定义极其复杂,还有迭代的出现,几乎彻底摧毁了它仅存的一点优势。所以,引入MFC之后,微软斩钉截铁地抛弃了标准C++的模板库。

CArray是MFC中非常重要的几个类模板之一,其他的还有CList、CMap等,但它们的定义略微有点晦涩。以我自己的经验,在MFC中使用CArray定义动态数组是非常方便的。在MSDN中,CArray的声明如下:

template< class TYPE, class ARG_TYPE > class CArray : public CObject

参数

TYPE

模板参数,指定存储在数组中对象的类型。TYPE是CArray返回的参数类型。

ARG_TYPE

模板参数,指定用来访问存储在数组中对象的变量类型,通常是TYPE的引用。ARG_TYPE 是传递给CArray的参数类型。

备注

CArray类支持与C中相似的数组,但是必要时可以动态收缩和增长。数组索引总是从0开始。你可以决定是固定数组上界还是允许当添加元素超过当前边界时扩展数组。内存被连续地分配到上界,即使一些元素可能为空。和C中数组一样,CArray索引元素的访问时间是不变的,与数组大小无关。

提示在使用一个数组之前,使用SetSize建立它的大小和为它分配内存。如果不使用SetSize,则为数组添加元素就会引起频繁地重新分配和拷贝。频繁地重新分配和拷贝不但没有效率,而且会导致内存碎片。

如果需要一堆数组中的个别数据,必须设置CDumpContext对象的深度为1或更大。

此类的某些成员函数调用全局帮助函数,它必须为CArray的大多数使用而定制。请参阅宏和全局量章节中的Collection Class Helpers。

当从一个CArray对象中移去元素时,帮助函数DestructElements被调用。当添加元素时,帮助函数ConstructElements被调用。

数组类的派生与列表的派生类似。

有关使用CArray类的更多信息,请参考Visual C++ Programmer's Guide中的论文集。

#include

看到上面这么一大段文字是不是觉得有点头晕?MSDN就是这样的,不然怎么能体现出它的“权威”呢。其实不要觉得它很复杂,使用CArray类构造动态数组非常简单。首先,你需要包含头文件Afxtempl.h,然后就可以定义自己的动态数组了。例如定义一个int型和CPoint型的动态数组:

#include

CArray num;

CArray pt; // 也可以这样:CArray pt;

现在,我们构造了两个动态数组,按照MSDN的提示,我们要使用SetSize函数建立它的大小和分配内存。(但其实这一步可以省略,而且我自己就是这么做的,虽然这不符合一个规范程序员的风格。)SetSize的函数原型是:

void SetSize(int nNewSize,int nGrowBy=-1);

这个函数在MSDN中也有详细的说明,我就不再去翻译了。其中第一个参数指定数组大小,即数组中元素个数(必需大于或等于0)。对于第二个参数,MSDN中有这样一句话:如果使用了默认值,MFC以一种在大多数情况下能够避免内存碎片和最高效的方式去分配内存。既然人家MSDN都这么说了,那我们第二个参数就使用它的默认值了。如果要加上这一步的话,可以这么写(我们先不写):

num.SetSize(40); // 其实大小设为多少没有关系,只要是你认为最合适的就行了

pt.SetSize(10); // 一般地,设得大些可以避免内存碎片和提高效率,但所需空间越大

现在我们可以使用Add函数向数组中添加一个元素,也可以用GetAt函数来获得一个元素。它们的函数的原型分别是:

int Add(ARG_TYPE newElement );

TYPE GetAt( int nIndex ) const;

Add函数向数组末尾增加一个元素,必要的话会扩展数组,它返回增加元素的索引值。GetAt函数返回给定索引的元素值。例如,我们可以这样写:

for (int i=0; i<20; i++) num.Add(i); // 数组大小为20,数组中元素依次为0, 1, 2, … , 19 int n = num.GetAt(10); // 由于索引是从0开始,得到第11个元素,也就是10

CPoint point(100,100);

pt.Add(point); // 或者不用定义point,直接pt.Add(CPoint(100,100));

需要特别说明的是,如果使用了SetSize函数,上面介绍的Add函数会在数组原来的大小上扩展数组,数组前面的元素全为0。即这时候数组的大小变成了50,前30个元素为0,后面的元素依次为0, 1, 2, … , 19。为了避免这种情况,这时候就需要使用SetAt函数来向数组中添加元素,SetAt函数设置给定索引的元素值,不允许扩展数组。其函数原型为:void SetAt(int nIndex,ARG_TYPE newElement);

如果使用SetAt函数,那么前面的代码就要这么写:

for (int i=0; i<20; i++) num.SetAt(i, i);

如果要向数组中间插入或者删除一个或多个元素,可以使用InsertAt和RemoveAt函数。它们的函数原型分别是:

void InsertAt(int nIndex,ARG_TYPE newElement,int nCount=1);

void InsertAt(int nStartIndex,CArray*pNewArray);

void RemoveAt(int nIndex,int nCount=1);

接着上面的例子,我们可以这样写:

num.InsertAt(3, 100); // 在索引为3的位置插入元素100

// 那么数组中的元素是这样的:0, 1, 2, 100, 3, 4, 5, … , 19

// num.InsertAt(3, 100, 2); // 在索引为3的位置向后插入两个元素,均为100

// 则数组中元素是这样的:0, 1, 2, 100, 100, 3, 4, 5, … , 19

CArray numNew;

for (i=0; i<10; i++) numNew.Add(i); // 新建数组的元素为:0, 1, 2, … , 9

num.InsertAt(5, &numNew); // InsertAt的第二个版本,插入一个数组

// 现在数组中的元素是这样的:0, 1, 2, 100, 3, 0, 1, 2, … , 9, 4, 5, 6, … , 19

num.RemoveAt(2); // 移除索引为2的元素

// 数组中的元素变成这样:0, 1, 100, 3, 0, 1, 2, … , 9, 4, 5, 6, … , 19

// num.RemoveAt(2, 3); // 从索引为2的位置开始,移除3个元素

// 数组中的元素变成这样:0, 1, 0, 1, 2, … , 9, 4, 5, 6, … , 19

我们可以使用GetSize函数得到数组当前的大小(元素个数),可以使用GetUpperBound 函数得到数组的上界(最大索引值),可以使用RemoveAll函数清空数组。跟C中一样,我们还可以使用操作符[ ]来访问数组元素,例如接着上面的例子:

n = num.GetSize(); // n = 30

n = num.GetUpperBound(); // n = 29

n = num[2]; // n = 100

num.RemoveAll();

n = num.GetSize(); // n = 0

写到这里,对CArray类的介绍已经差不多了,使用上面的函数基本上可以满足动态数组的操作。该类中还有一些其他函数,需要进一步了解的可以查阅MSDN,在这里只是对CArray的常用函数作一个大概的介绍。

如何在VC中创建动态数组

如何在VC中创建动态数组 怎样给多维数组动态分配内存 //Allocate: int **p = new int* [m]; for(int i = 0 ; i < m ; i++) p[i] = new int[n]; //Use: for(int i = 0 ; i < m; i++) for(int j = 0 ; j < n ; j++) p[i][j] = i * j; //Free: for(int i = 0 ; i < m ; i++) delete[] p[i]; delete[] p; 1. 演示形为int[2][3]的二维动态数组 /////////////////////////////////////////////////////////////////// int n1, n2; const int DIM1 = 2; const int DIM2 = 3; // 构造数组 int **ppi = new int*[DIM1]; for(n1 = 0; n1 < DIM1; n1++) { ppi[n1] = new int[DIM2]; } // 填充数据 for(n1 = 0; n1 < DIM1; n1++) { for(n2 = 0; n2 < DIM2; n2++) { ppi[n1][n2] = n1 * 10 + n2; } } // 输出 for(n1 = 0; n1 < DIM1; n1++) { for(n2 = 0; n2 < DIM2; n2++) {

afxDump << "ppi[" << n1 << "][" << n2 << "] = " << ppi[n1][n2] << "\n"; } } // 释放数组 for(n1 = 0; n1 < DIM1; n1++) { delete [] ppi[n1]; } delete [] ppi; 2. 三维动态数组(int[2][3][4]) /////////////////////////////////////////////////////////////////// int n1, n2, n3; const int DIM1 = 2; const int DIM2 = 3; const int DIM3 = 4; // 构造数组 int ***ppi = new int**[DIM1]; for(n1 = 0; n1 < DIM1; n1++) { ppi[n1] = new int*[DIM2]; for(n2 = 0; n2 < DIM2; n2++) { ppi[n1][n2] = new int[DIM3]; } } // 填充数据 for(n1 = 0; n1 < DIM1; n1++) { for(n2 = 0; n2 < DIM2; n2++) { for(n3 = 0; n3 < DIM3; n3++) { ppi[n1][n2][n3] = n1 * 100 + n2 * 10 + n3; } } } // 输出 for(n1 = 0; n1 < DIM1; n1++) { for(n2 = 0; n2 < DIM2; n2++) { for(n3 = 0; n3 < DIM3; n3++)

最新C++二维动态数组的申请与_释放汇总

C++二维动态数组的申请与_释放

一维数组是指针,可将二维数组看作是指针的指针:每一行是一个一维数组,而列是指向行的指针。在动态创建时,先分配指向行的指针空间,再循环维每一行申请空间。 #include using namespace std; int main() { //[3]4] //三行四列的二维数组 int x,y; int i,n,k; x=3; y=4; int **p; p = new int*[x]; //行 //申请行的空间 //每行的列申请空间 for(i=0; i

//赋值, k=0; for(i=0;i

delete [] p[i]; } delete [] p; return 0; 今天归纳总结了一下,希望以后的朋友可以少走些弯路:) 一:关于指针和堆的内存分配 先来介绍一下指针:指针一种类型,理论上来说它包含其他变量的地址,因此有的书上也叫它:地址变量。既然指针是一个类型,是类型就有大小,在达内的服务器上或者普通的PC机上,都是4个字节大小,里边只是存储了一个变量的地址而已。不管什么类型的指针,char * ,int * ,int (*) ,string * ,float * ,都是说明了本指针所指向的地址空间是什么类型而已,了解了这个基本上所有的问题都好象都变的合理了。 在C++中,申请和释放堆中分配的存贮空间,分别使用new和delete的两个运算符来完成: 指针类型指针变量名=new 指针类型 (初始化); delete 指针名; 例如:1、 int *p=new int(0); 它与下列代码序列大体等价: 2、int tmp=0, *p=&tmp; 区别:p所指向的变量是由库操作符new()分配的,位于内存的堆区中,并且该对象未命名。 下面是关于new 操作的说明:部分引自<>

c#中动态数组的使用

在向大家详细介绍C#动态数组之前,首先让大家了解下C#动态数组的方法及属性,然后全面介绍C#动态数组。 下面的例子向你演示C#动态数组的方法及属性,这样通过实例的演示介绍能够更加深刻的理解C#动态数组的各项基本概念和应用,希望对你有所帮助。 C#动态数组的详解实例: 1.ArrayList AL = new ArrayList(); 2.AL.Add("Hello"); 3.AL.Add(" World"); 4.Console.WriteLine("给数组添加元素:"); 5.foreach (Object obj in AL) 6.{ Console.Write(obj); } 7.Console.WriteLine(); 8.Console.WriteLine("个数:" + AL.Count); 9.Console.WriteLine("容量: " + AL.Capacity); 10.AL.Insert(1, " c#"); 11.//C#动态数组的详解实例 12.Console.Write("在索引值为1的地方插入 "); 13.foreach (Object obj in AL) 14.{Console.Write(obj); } 15.Console.WriteLine(); 16.Console.WriteLine("个数:" + AL.Count); 17.Console.WriteLine("容量: "+AL.Capacity); 18.AL.Add("。");//给集合添加“。”,查看集合的容量 19.Console.WriteLine("容量。: " + AL.Capacity); 20.AL.Add("---");//给集合添加“---”,查看当集合的容量不够时,倍数变化 21.Console.WriteLine("容量---: " + AL.Capacity); 22.Console.WriteLine("3号索引的:"+AL[3]); 23.//用索引方式获取集合元素值 24.//C#动态数组的详解实例 25.Console.WriteLine("数组中是否包含?:"+AL.Contains ("?")); 26.//利用contains方法,查找集合中是否包含“?” 27.Console.WriteLine("经过之前操作后的数组元素:"); 28.foreach (Object obj in AL) 29.{ Console.Write(obj); } 30.Console.WriteLine(); 31.Console.WriteLine("个数:" + AL.Count);

c语言数组的动态分配

下面代码添加到头文件里面 #include #include struct data { int*p;//指针保存数组起始点 int length;//保存数组长度 int reallength;//实际分配内存长度 int state;//0代表无序,1代表有序从小到大,2代表有序从大到小 }; struct find { int**pp; int n; }; void init(struct data*pdata);//初始化 void reinit(struct data*pdata);//重新初始化 void addobject(struct data*pdata,int num);//增加一个元素 void addobjects(struct data*pdata,int*pnum,int n);//增加一个数组void printf1(struct data*pdata);//打印一个出来 void sort(struct data*pdata,int obj);//实现排序obj=0从小到大,否则从大到小 int*finddata(struct data*pdata,int num);//找到并返回第一次找到的地址void change(struct data*pdata,int oldnum,int newnum);//修改一个数据void insert(struct data*pdata,int num,int insertnum,int headback);//插入一个数据,0代表前插,1代表后插 void deleteone(struct data*pdata,int num);//删除第一个找到的数据 void deleteall(struct data*pdata,int num);//删除找到的全部数据 struct find findalldata(struct data*pdata,int num);//返回一片内存,包含所有找到的元素

C语言中动态数组的实现

C语言中动态数组的实现 (2009-05-10 10:19:30) 转载 分类:C语言学习 标签: c中动态数组 教育 近来编写几个程序,很多都用到了数组。但是对于数组的大小却是没有固定的,也就是说可以更改数组大小,其大小是可以变化的。并不像初学时的那样,告诉你一个范围,你就必须取最大值以满足要求。那样可能就会浪费很多不必要的内存单元!那么到底应该怎样定义一个动态数组列? 在数组一章中,曾介绍过数组的长度是预先定义好的,在整个程序中固定不变。C语言中不允许动态数组类型。例如: int n;scanf("%d",&n);int a[n]; 用变量表示长度,想对数组的大小作动态说明,这是错误的。但是在实际的编程中,往往会发生这种情况,即所需的内存空间取决于实际输入的数据,而无法预先确定。对于这种问题,用数组的办法很难解决。为了解决上述问题,C语言提供了一些内存管理函数,这些内存管理函数可以按需要动态地分配内存空间,也可把不再使用的空间回收待用,为有效地利用内存资源提供了手段。其它文献中所提到的"动态数组",指的就是利用内存的申请和释放函数,在程序的运行过程中,根据实际需要指定数组的大小.其本质是一个指向数组的指针变量.常用的内存管理函数有以下三个: 1.分配内存空间函数malloc 调用形式: (类型说明符*) malloc (size) 功能:在内存的动态存储区中分配一块长度为"size" 字节的连续区域。函数的返回值为该区域的首地址。“类型说明符”表示把该区域用于何种数据类型。(类型说明符*)表示把返回值强制转换为该类型指针。“size”是一个无符号数。例如: pc=(char *) malloc (100); 表示分配100个字节的内存空间,并强制转换为字符数组类型,函数的返回值为指向该字符数组的指针,把该指针赋予指针变量pc。 2.分配内存空间函数 calloc calloc 也用于分配内存空间。调用形式: (类型说明符*)calloc(n,size) 功能:在内存动态存储区中分配n块长度为“size”字节的连续区域。函数的返回值为该区域的首地址。(类型说明符*)用于强制类型转换。calloc函数与malloc 函数的区别仅在于一次可以分配n块区域。例如: ps=(struet stu*) calloc(2,sizeof (struct stu)); 其中的sizeof(struct stu)是求stu的结构长度。因此该语句的意思是:按stu的长度分配2块连续区域,强制转换为stu 类型,并把其首地址赋予指针变量ps。

Delphi之动态数组使用总结

Delphi之动态数组使用总结 传统的Pascal 语言其数组大小是预先确定的,当你用数组结构声明数据类型时,你必须指定数组元素的个数。专业程序员也许知道些许动态数组的实现技术,一般是采用指针,用手工分配并释放所需的内存。 Delphi 4中增加了非常简单的动态数组实现方法,实现过程效仿我前面讲过的动态长字符串。与长字符串一样,动态数组的内存动态分配并且引用记数,不过动态数组不支持copy-on-write 技术。这不是个大问题,因为你可以把变量值设置为nil释放数组内存。 这样你就可以声明一个不指定元素个数的数组,并用SetLength 过程给数组分配一个特定大小的内存,SetLength 过程还可以改变数组大小而不影响其内容,除此外还有一些字符串过程也可用于数组,如Copy 函数。 以下摘录的代码突出了一点,这就是:定义数组后必须先为它分配内存,然后才能开始使用: procedure TForm1.Button1Click(Sender: TObject);var Array1: array of Integer;begin Array1 [1] := 100; // error SetLength (Array1, 100); Array1 [99] := 100; // OK ...end; 如果你只定义一个数组元素个数,那么索引总是从0开始。Pascal 中的普通数组既能用不为零的下标,也能用非整数的下标,但动态数组均不支持这两种下标。象普通数组一样,你可以通过Length、High和Low 函数了解到动态数组的状况,不过对于动态数组,Low 函数返回值总是0,High函数返回数组大小减1,这意味着空的动态数组其函数High返回值是-1,这是一个很怪的值,因为它比Low的返回值还小。 图8.1:例DynArr 窗体 以上作了简短的介绍,现在举个简例,例名DynArr ,见图8.1。例子实在是很简单,其实动态数组没有什么特别复杂地方。我想通过该例说明几个程序员可能犯的错误。程序中声明了两个全程数组并在OnCreate 事件中初始化了第一个数组: var Array1, Array2: array of Integer;procedure TForm1.FormCreate(Sender: TObject);begin // allocate SetLength (Array1, 100);end; 这样就把数组所有值设置为0。完成这段代码你马上就能读写数组元素的值,而不用害怕内存出错,当然条件是你没有试图访问超过数组上界的元素。为了更好地初始化,程序中添加了一个按钮,执行数组元素赋值操作:

C语言动态数组

动态数组是指在声明时没有确定数组大小的数组,即忽略圆括号中的下标;当要用它时,可随时用ReDim语句(C语言中用malloc语句)重新指出数组的大小。使用动态数组的优点是可以根据用户需要,有效利用存储空间。 动态数组,是相对于静态数组而言。静态数组的长度是预先定义好的,在整个程序中,一旦给定大小后就无法改变。而动态数组则不然,它可以随程序需要而重新指定大小。动态数组的内存空间是从堆(heap)上分配(即动态分配)的。是通过执行代码而为其分配存储空间。当程序执行到这些语句时,才为其分配。程序员自己负责释放内存。(欲详细了解堆请见堆栈) 为什么要使用动态数组? 在实际的编程中,往往会发生这种情况,即所需的内存空间取决于实际输入的数据,而无法预先确定。对于这种问题,用静态数组的办法很难解决。为了解决上述问题,C语言提供了一些内存管理函数,这些内存管理函数结合指针可以按需要动态地分配内存空间,来构建动态数组,也可把不再使用的空间回收待用,为有效地利用内存资源提供了手段。 动态数组与静态数组的对比 对于静态数组,其创建非常方便,使用完也无需释放,要引用也简单,但是创建后无法改变其大小是其致命弱点! 对于动态数组,其创建麻烦,使用完必须由程序员自己释放,否则严重会引起内存泄露。但其使用非常灵活,能根据程序需要动态分配大小。 如何构建动态数组 遵循原则 申请的时候从外层往里层,逐层申请; 释放的时候从里层往外层,逐层释放。 构建所需指针 对于构建一维动态数组,需要一维指针;对于二维,则需要一维,二维指针;三维需要一,二,三维指针; 依此类推。 构建所需函数 函数原型返回 功能说明 void *malloc(unsigned int size); 成功:返回所开辟空间首地址失败:返回空指针向系统申请size字节的堆空间 void *calloc(unsigned int num, unsigned int size);成功:返回所开辟空间首地址失败:返回空指针按类型申请num个size字节的堆空间 void free(void *p); 无返回值 释放p指向的堆空间 void *realloc(void *p,unsigned int size); 成功:返回新开辟空间首地址失败:返回空指针将p指向的堆空间变为size 说明: (1)规定为void *类型,这并不是说该函数调用后无返回值,而是返回一个结点的地址,该地址的类型为void(无类型或类型不确定),即一段存储区的首址,其具体类型无法确定,只有使用时根据各个域值数据再确定。可以用强制转换的方法将其转换为别的类型。例

动态数组vector用法

Vector用法介绍 这篇文章的目的是为了介绍std::vector,如何恰当地使用它们的成员函数等操作。本文中还讨论了条件函数和函数指针在迭代算法中使用,如在remove_if()和for_each()中的使用。通过阅读这篇文章读者应该能够有效地使用vector容器,而且应该不会再去使用C类型的动态数组了。 Vector总览 vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库。vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。为了可以使用vector,必须在你的头文件中包含下面的代码: #include vector属于std命名域的,因此需要通过命名限定,如下完成你的代码: using std::vector; vector vInts; 或者连在一起,使用全名: std::vector vInts; 建议使用全局的命名域方式: using namespace std; 在后面的操作中全局的命名域方式会造成一些问题。vector容器提供了很多接口,在下面的表中列出vector的成员函数和操作。 Vector的函数 c.assign(beg,end) 将[beg; end)区间中的数据赋值给c。 c.assign(n,elem) 将n个elem的拷贝赋值给c。 c.at(idx) 传回索引idx所指的数据,如果idx越界,抛出out_of_range。

c.back() 传回最后一个数据,不检查这个数据是否存在。 c.begin() 传回迭代器中的一个数据。 c.capacity() 返回容器中数据个数。 c.clear() 移除容器中所有数据。 c.empty() 判断容器是否为空。 c.end() 指向迭代器中的最后一个数据地址。 c.erase(pos) 删除pos位置的数据,传回下一个数据的位置。 c.erase(beg,end) 删除[beg,end)区间的数据,传回下一个数据的位置。 c.front() 传回地一个数据。 get_allocator 使用构造函数返回一个拷贝。 c.insert(pos,elem) 在pos位置插入一个elem拷贝,传回新数据位置。 c.insert(pos,n,elem) 在pos位置插入n个elem数据。无返回值。 c.insert(pos,beg,end) 在pos位置插入在[beg,end)区间的数据。无返回值。

动态数组的创建

摘要的重要性是不言而喻的,每次发文章我都很纠结如何写出一个有特色的摘要来,能够以最为简短的文字向读者描述出我所要表达的东西。但是常常出现的问题是,摘要写得太简短了,读者看了不清楚文章究竟要讲啥;摘要写得稍微长点的话自然能够描述清楚所要表达的东西,但是却也出现了另外一个问题,就是读者看到大段的文字描述,觉得枯燥无味,直接二话不说给文章判了个“死刑”,导致这种情况下愿意真正的花时间看完摘要的读者屈指可数,更不用说文章的正文部分了,所以时长感慨写文章最头疼的莫过于摘要了。 很多人在编写C语言代码的时候很少使用动态数组,不管什么情况下通通使用静态数组的 方法来解决,在当初学习C语言的时候我就是一个典型的例子,但是现在发现这是一个相 当不好的习惯,甚至可能导致编写的程序出现一些致命的错误。尤其对于搞嵌入式的人来所,嵌入式系统的内存是宝贵的,内存是否高效率的使用往往意味着嵌入式设备是否高质量和高性能,所以高效的使用内存对我们来说是很重要的。那么我们在自己编写C语言代码的时 候就应该学会使用动态数组,这也就是我这篇博客要给大家讲的,我尽我所能的用一些简单的代码来讲解动态数组,希望我所讲的对你有所帮助。 那么我们首先来看看什么是动态数组,动态数组是相对于静态数组而言,从“动”字我们也可以看出它的灵活性,静态数组的长度是预先定义好的,在整个程序中,一旦给定大小后就无法改变。而动态数组则不然,它可以随程序需要而重新指定大小。动态数组的内存空间是从堆动态分配的。是通过执行代码而为其分配存储空间。当程序执行到我们编写的分配语句时,才为其分配。对于静态数组,其创建非常方便,使用完也无需释放,要引用也简单,但是创建后无法改变其大小是其致命弱点!对于动态数组,其创建麻烦,使用完必须由程序员自己释放,否则将会引起内存泄露。但其使用非常灵活,能根据程序需要动态分配大小。所以相对于静态数组的来说我们对于使用动态数组有很大的自由度。 在创建动态数组的过程中我们要遵循一个原则,那就是在创建的时候从外层往里层,逐层创建;而释放的时候从里层往外层,逐层释放。这个话你读了可能理解并不深刻,不过不要急,接下来我们看看两段代码。 一维动态数组的创建: #include #include int main() { int n1,i; int *array; printf("请输入所要创建的一维动态数组的长度:");

(一)C++动态二维数组的申请、赋值、使用、释放以及作参数示例

/***************************/ /* DYNAMIC ARRAY EXEMPLE */ /* 唐国峰2011年月日 */ /***************************/ //按照动态二维数组的申请、赋初值、使用、释放空间五个部分给出代码,以示参考。//同时,给出了动态二维数组用作形参和实参的实例,方便大家查询。 #include using namespace std; //动态二维数组作形参 void display(int ** &p,int row,int col) { int i,j; for(i = 0;i <= row-1;i++) { for(j = 0; j <= col-1;j++) { cout << p[i][j]+i+j << "\t"; } cout << endl; } } //主函数 void main() { //-------格式化输出模板信息内容------开始------ cout << "程序输出结果如下所示:" << endl << endl; cout << "/***************************/" << endl; cout << "/* DYNAMIC ARRAY EXEMPLE */" << endl; cout << "/* 唐国峰2011年月日 */" << endl; cout << "/***************************/" << endl << endl; //-------格式化输出模板信息内容------结束------ int **p; //这是指向指针的指针 int row,col; //此动态二维数组为“row”行、“col”列 int i,j; //循环用变量 //动态二维数组p的申请 cout << "请输入行数和列数:" << endl << endl; cin >> row >> col; cout << endl; p = new int *[row]; for(int i = 0;i <= row-1;i++) { p[i]=new int[col]; } //为动态二维数组p的元素赋初值 for(i = 0;i <= row-1;i++) { for(j = 0; j <= col-1;j++)

VB编程基础教程10–动态数组

VB编程基础教程10–动态数组 [ 程序乐园] 数组到底应该有多大才合适,有时可能不得而知。所以希望能够在运行时具有改变数组大小的能力。 动态数组就可以在任何时候改变大小。在visual basic 中,动态数组最灵活、最方便,有助于有效管理内存。例如,可短时间使用一个大数组,然后,在不使用这个数组时,将内存空间释放给系统。 如果不用动态数组,就要声明一个数组,它的大小尽可能达到最大,然后再抹去那些不必要的元素。但是,如果过度使用这种方法,会导致内存的操作环境变慢。 要创建动态数组,请按照以下步骤执行: (如果希望数组为公用数组,则)用public 语句声明数组,或者,(如果希望数组为模块级,则)在模块级用dim 语句声明数组,或者(如果希望数组为局部数组,则)在过程中用static 或dim 语句声明数组。给数组附以一个空维数表,这样就将数组声明为动态数组。 dim dynarray () 用redim 语句分配实际的元素个数。 redim dynarray (x + 1) redim 语句只能出现在过程中。与dim 语句、static 语句不同,redim 语句是一个可执行语句,由于这一语句,应用程序在运行时执行一个操作。 redim 语句支持这样的语法,它与固定数组中使用的语法相同。对于每一维数,每个redim 语句都能改变元素数目以及上下界。但是,数组的维数不能改变。 redim dynarray (4 to 12) 例如,用第一次声明在模块级所建立的动态数组matrix1: dim matrix1 () as integer 然后,在过程中给数组分配空间: sub calcvaluesnow () . . . redim matrix1 (19, 29) end sub 这里的redim 语句给matrix 分配一个20 ×30 的整数矩阵(元素总大小为600)。还有一个办法,用变量设置动态数组的边界: redim matrix1 (x, y) 注意您可以将字符串赋值给大小可变的字节数组。一个字节数组也可以被赋值给一个可变长的字符串。一定要注意字符串中的字节数会随平台而变化。同一个字符串在unicode 平台上的字节数是它在非unicode 平台上的两倍。 保留动态数组的内容 每次执行redim 语句时,当前存储在数组中的值都会全部丢失。visual basi 重新将数组元素的值置为empty(对variant 数组)、置为0(对numeric 数组)、置为零长度字符串(对string 数组)或者置为nothing(对于对象的数组)。 在为新数据准备数组,或者要缩减数组大小以节省内存时,这样做是非常有用的。有时希望改变数组大小又不丢失数组中的数据。使用具有preserve 关键字的redim 语句就可做到这点。例如,使用ubound 函数引用上界,使数组扩大、增加一个元素,而现有元素的值并

e_00005+Java动态数组的用法详解

?Java动态数组的用法详解 ? ? Java动态数组是一种可 以任意伸缩数组长度的对象,在 Java中比较常用的是ArrayLis t,ArrayList是javaAPI中自带 的java.util.ArrayList。下面 介绍一下ArrayList作为Java 动态数组的用法。 1.语法:add()是添加一个新 的元素,remove()删除一个元素, size()获得ArrayList的长度。A rrayList的下标是从0开始。 2.示例代码 package wang48.jiaocheng; import java.util.ArrayList; public class JavaArrayList { public static void main(String[]args) { //Java动态数组的初始化 ArrayList al=new ArrayList(); //向Java动态数组中添加数据 al.add("a"); al.add("b"); al.add("c"); //输出Java动态数组 for(int i=0;i

} //删除数组中的某个元素,删除第二个元素 al.remove(1); //修改Java动态数组,把新的元素放到第二个位置 al.add(1,"2"); ////输出Java动态数组 for(int i=0;i

动态二维数组的用法

1、动态创建二维数组 正确的做法: 方法一: void fun(int iRow, int iCol) { CString** ppData; ppData = new CString*[iRow]; for(int i=0;i< iRow;++i) { ppData[i] = new CString[iCol]; } } 方法二: void fun(int iRow, int iCol) { CString* pTemp; CString** ppData; pTemp =new CString[iRow*iCol]; ppData = new CString*[iRow]; for(int i=0;i< iRow;++i) { ppData[i] =&pTemp[i*iCol]; } } ppData就是我们创建的二维数组。 错误的做法: void fun(int iRow, int iCol) { CString** ppData; ppData = new CString[iRow][iCol]; } 错误提示:error C2540: non-constant expression as array bound 2、使用二维数组 (1)我们在应用中有时候会需要把一个二维数组作为参数传入一个函数中,这个函数的形式怎样才是正确的? void fun(CString** str, int iRow, int iCol); 正确 void fun(CString str[][], int iRow, int iCol); 错误,没有指定数组的列数! void fun(CString* str, int iRow, int iCol); 正确,可以在函数内部对str处理,变成一

动态数组的建立使用

1.动态数组的定义和实验 Option Base 1 Private Sub Command1_Click() Dim s() As Integer Dim n%, i%, ave! n = Val(Text1.Text) ReDims(n) For i = 1 To n s(i) = val(InputBox("输入数据")) Picture1.Print s(i); ave = ave + s(i) If i Mod 5 = 0 Then Picture1.Print Next i Text2.Text = Str(ave / n) End Sub 2.在动态数组重新定义中使用Preserve参数,保留数组原来的数据Dim a() as integer ˊ定义一个空数组 Private Sub Command1_Click() n = 5 ' 一开始第一维、第二维的大小是5 ReDima(n, n) For i = 0 To n For j = 0 To n a(i, j) = 5 Next j Next i Print "原始数据" For i = 0 To n For j = 0 To n Print a(i, j); Next j Print '换行 Next i m = 10 ReDim Preserve a(n, m) '只改变第二维值的上限第一维不能改 Print "重新设置后数据" For i = 0 To n For j = 0 To m Print a(i, j); Next j Print '换行 Next i

End Sub 3.用Array函数为一维数组赋初值。 Private Sub Command1_Click() Dim c As Variant c = Array(4, 5, 3, 7, 2, 9,10,12) For i = LBound(c) To UBound(c) Print c(i); Next i Print Print For i = 0 To 7 Print c(i); Next i End Sub 4.控件数组的设定和使用,先拖进一命令按钮,复制出3个同名的命令按钮,在窗体上作出如下的设计:“控件数组”在标签中。 4.控件数组的设定和使用,先拖进一命令按钮,复制出3个同名的命令按钮,在窗体上作出如下的设计:“控件数组”在标签中。 Private Sub Command1_Click(Index As Integer) Select Case Index Case 0 Text1.Text = "现在选定的序列号是" & Index Label1.BackColor = RGB(255, 0, 0) Case 1 Text1.Text = "现在选定的序列号是" & Index Label1.BackColor = RGB(0, 255, 0) Case 2 Text1.Text = "现在选定的序列号是" & Index Label1.BackColor = RGB(0, 0, 255) Case 3

在C++中实现变长数组动态创建数组

在C++中实现变长数组 1.变长一维数组 这里说的变长数组是指在编译时不能确定数组长度,程序在运行时需要动态分配内存空间的数组。实现变长数组最简单的是变长一维数组,你可以这样做: //文件名: array01.cpp #include using namespace std; int main() { int len; cin>>len; //用指针p指向new动态分配的长度为len*sizeof(int)的内存空间 int *p=new int[len]; ........... delete[] p; return 0; } 注意int *p=new int[len];这一句,你不能这样做: int p[len]; C++编译器会报错说len的大小不能确定,因为用这种形式声明数组,数组的大小需要在编译时确定。而且这样也不行: int p[]=new int[len]; 编译器会说不能把int*型转化为int[]型,因为用new开辟了一段内存空间后会返回这段内存的首地址,所以要把这个地址赋给一个指针,所以要用int *p=new int[len]; array01.cpp实现了一个变长的一维数组,但是要养成一个好习惯,就是注意要注销指针p,使程序释放用new开辟的内存空间,delete []p; 当然使用C++标准模版库(STL)中的vector(向量)也可以实现变长数组: #include #include using namespace std; int main(void) { vector a; int i; for (i=0;i<10;++i) a.push_back(i);//添加元素

【IT专家】为动态数组分配大空间

本文由我司收集整编,推荐下载,如有疑问,请与我司联系 为动态数组分配大空间 2016/11/14 83 we wrote a program that reads comma-separated integer-values into an array and tries processing them with a parallel structure. By doing so, we found out that there is a fixed limitation for the maximum size of the dynamic array, which usually gets allocated dynamically by doubling the size. Yet for a dataset with more than 5000 values, we can’t double it anymore. 我们编写了一个程序,它将逗号分隔的整数值读入数组,并尝试使用并行结构处 理它们。通过这样做,我们发现动态数组的最大大小存在固定限制,通常通过将大 小加倍来动态分配。然而,对于具有超过5000 个值的数据集,我们不能再将其加 倍。 I am a bit confused right now, since technically, we did everything the way other posts pointed out we should do (use realloc, don’t use stack but heap instead). 我现在有点困惑,因为从技术上讲,我们做了所有其他帖子指出我们应该做的事 情(使用realloc,不要使用堆栈而是使用堆)。 Note that it works fine for any file with less or equal than 5000 values. We also tried working with realloc, but to the same result. 请注意,它适用于任何小于或等于5000 值的文件。我们也尝试使用realloc,但结 果相同。 #include stdio.h #include stdlib.h #include math.h // compile with gcc filename - lpthread -lm -Wall -Wextra -o testint reader(int ** array, char * name) { FILE *fp; int data,row,col,count,inc; int capacity=10; char ch; fp=fopen(name,”r”);row=col=count=0; while(EOF!=(inc=fscanf(fp,”%d%c”,data, ch)) inc == 2){ if(capacity==count) // this is the alternative with realloc we tried. Still the same issue. //*array=malloc(sizeof(int)*(capacity*=2)); *array = realloc(*array, sizeof(int)*(capacity*=2)); (*array)[count++] = data; //printf(“%d“, data); if(ch == ‘\n’){ break; } else if(ch != ‘,’){ fprintf(stderr, “format error of different separator(%c) of Row at

动态数组的基本应用与实现实验报告

设计动态数组的基本应用与实现 1.1需求陈述 数组是应用程序中经常要用到的一种数据结构。虽然通过数组可以对大量的数据和对象进行有效的管理,但很多情况下,在程序运行之前,并不能够确切地知道数组中会有多少元素,这时候数组到底声明为多大,就是一个很麻烦的问题。在C++中,动态内存分配技术可以保证程序在运行过程中按照实际需要申请适量的内存,使用结束后还可以释放。这样就使得在运用数组时更加方便,有效。 1.2 需求分析 1.2.1功能分析 表1 函数库功能分析 1.2.2数据分析

数组最初默认为空,并且容量为10。由于使用动态内存分配,所以在存入数据时不必担心数组大小的影响,数组容量不够时可以自动分配新的内存存储数据。对数组进行不同的操作时,数组也会根据实际需要进行动态的内存分配。这样使得数组的应用更加方便、灵活,同时提高了效率。为提高函数的可靠性,我们对每个函数的测试准备了2-3套测试数据。 1.2.3技术约束 本函数库的测试系统已在code blocks下编译通过。 1.3 总体设计 1.3.1 数据结构 数组所采用的数据结构是类。声明一个数组类,在将对数组进行的各项操作声明为类的函数,通过调用各个函数来实现对数组的各项操作功能。具体定义形式为: class Array { int _size;//元素个数 int _capacity;//容量 int* items;//动态数组 public: Array(const int& capcity = 16);//构造函数 Array(const Array& other);//拷贝构造函数 Array& operator = (const Array& other);// ~Array();//析构函数 void insert(const int& index, const int& value);//插入函数 void remove(const int& index);//删除函数 void append(const int& value);//追加函数 void run();//运行函数 };

相关文档
相关文档 最新文档