c++动态数组模板库
C语言中动态数组的实现
![C语言中动态数组的实现](https://img.taocdn.com/s3/m/48dc927b590216fc700abb68a98271fe910eafce.png)
C语言中动态数组的实现在C语言中,动态数组的实现主要依靠指针和内存分配函数。
动态数组是在程序执行过程中根据需要动态分配内存空间的数组。
相比于静态数组,在编写代码时不需要提前指定数组的大小,可以更加灵活地适应不同数据量的需求。
C语言中的动态数组实现主要分为两个步骤:内存分配和内存释放。
1.内存分配:C语言提供了几种内存分配函数来动态分配内存空间,包括malloc、calloc、realloc等。
a) malloc函数:malloc函数用于从堆中分配指定大小的内存块,并返回该内存块的首地址。
其函数原型为:```cvoid* malloc(size_t size);```这里的size是以字节为单位的分配内存的大小。
分配成功时,返回分配内存的首地址;分配失败时,返回NULL。
b) calloc函数:calloc函数用于从堆中分配指定数量、指定大小的连续内存空间,并将该内存空间初始化为0。
其函数原型为:```cvoid* calloc(size_t num, size_t size);```这里的num是要分配的元素个数,size是每个元素的大小。
分配成功时,返回分配内存的首地址;分配失败时,返回NULL。
c) realloc函数:realloc函数用于重新调整之前分配的内存大小,并返回调整后的内存地址。
其函数原型为:```cvoid* realloc(void* ptr, size_t size);```这里的ptr是之前分配的内存地址,size是调整后的内存大小。
如果调整成功,返回调整后的内存地址;如果调整失败,返回NULL。
2.内存释放:动态数组使用完毕后,需要手动释放分配的内存空间,避免内存泄漏。
C语言中使用free函数来释放动态分配的内存空间,函数原型为:```cvoid free(void* ptr);```这里的ptr为之前分配的内存地址。
释放成功后,内存空间可以被重新分配使用;如果指针为空指针,则不进行任何操作。
C++自定义动态数组模板的方法介绍
![C++自定义动态数组模板的方法介绍](https://img.taocdn.com/s3/m/6244b937964bcf84b9d57b3d.png)
{ MyArray a; a.push(11); a.push(22); a.push(33); a.push(55); a[0]=44; coutreturn 0; } 好了,C++自定义动态数组模板的方法内容就给大家介绍到这里了。希望 大家学业有成,工作顺利 Байду номын сангаас
T& MyArray::operator [](int index) { if(index;(len-1)) { coutexit(1); } return data[index]; } template void MyArray::push(T d) { T *pdata = data;
data = new T[len + 1]; if(pdata != NULL) { for(int i = 0 ; i { data[i] = pdata[i]; } delete[] pdata; } data[len] = d; len++; } //测试代码 int main(int argc, char* argv[])
MyArray() { data = NULL; len = 0; } ~MyArray() { delete[] data; } T& operator [](int index); void push(T d); }; template
C++自定义动态数组模板的方法介绍
欢迎大家在这里学习 C++自定义动态数组模板的方法!这里是我们给大家 整理出来的精彩内容。我相信,这些问题也肯定是很多朋友在关心的,所以 我就给大家谈谈这个! #include “stdafx.h” #include using namespace std; template class MyArray { int len; public: T *data;
CArray百度百科
![CArray百度百科](https://img.taocdn.com/s3/m/795d14abd1f34693daef3eb1.png)
CArrayCArray需要包含的头文件 <afxtempl.h>CArray类支持与C arrays相似的数组,但是必要时可以动态压缩并扩展。
数组索引从0开始。
可以决定是固定数组上界还是允许当添加元素时扩展当前的边界。
内存对上界是连续地分配空间,甚至一些元素可为空。
和CArray一样,CArray索引元素的访问时间是不变的,与数组大小无关。
提示:在使用一个数组之前,使用SetSize建立它的大小和为它分配内存。
如果不使用SetSize,则为数组添加元素就会引起频繁地重新分配和拷贝。
频繁地重新分配和拷贝不但没有效率,而且导致内存碎片。
如果需要一堆数组中的个别数据,必须设置CDumpContext对象的深度为1或更大。
此类的某成员函数调用全局帮助函数,它必须为CArray的大多数使用而定制。
请参阅宏和全局量部分中的“类收集帮助器”。
当从一个CArray对象中移去元素时,帮助函数DestructElements被调用。
当添加元素时,帮助函数ConstructElements被调用。
数组类的派生与列表的派生相似。
MFC提供了一套模板库,来实现一些比较常见的数据结构如Array,List,Map。
CArray即为其中的一个,用来实现动态数组的功能。
CArray是从CObject派生,有两个模板参数,第一个参数就是CArray类数组元素的变量类型,后一个是函数调用时的参数类型。
有一个类 class Object,要定义一个Object的动态数组,那么可以用以下两种方法:CArray<Object,Object> Var1;CArray<Object,Object&> Var2;Var2的效率要高。
先了解一下CArray中的成员变量及作用。
TYPE* m_pData; // 数据保存地址的指针int m_nSize; // 用户当前定义的数组的大小int m_nMaxSize; // 当前实际分配的数组的大小int m_nGrowBy; // 分配内存时增长的元素个数构造函数,对成员变量进行了初始化。
STL标准模板库向量容器(vector)
![STL标准模板库向量容器(vector)](https://img.taocdn.com/s3/m/4b61a1185e0e7cd184254b35eefdc8d376ee14d1.png)
STL标准模板库向量容器(vector)向量容器使⽤动态数组存储、管理对象。
因为数组是⼀个随机访问数据结构,所以可以随机访问向量中的元素。
在数组中间或是开始处插⼊⼀个元素是费时的,特别是在数组⾮常⼤的时候更是如此。
然⽽在数组末端插⼊元素却很快。
实现向量容器的类名是vector(容器是类模板)。
包含vector类的头⽂件名是vector。
所以,如果要在程序⾥使⽤向量容器,就要在程序中包含下⾯语句:#include <vector>此外,在定义向量类型对象时,必须指定该对象的类型,因为vector类是⼀个类模板。
例如,语句:vector<int> intList;将intList声明为⼀个元素类型为int的向量容器对象。
类似地,语句:vector<string> stringList;将stringList声明为⼀个元素类型为string的向量容器对象。
声明向量对象vector类包含了多个构造函数,其中包括默认构造函数。
因此,可以通过多种⽅式来声明和初始化向量容器。
表⼀描述了怎样声明和初始化指定类型的向量容器。
表⼀各种声明和初始向量容器的⽅法语句作⽤vector<elementType> vecList; 创建⼀个没有任何元素的空向量vecList(使⽤默认构造函数)vector<elementType> vecList(otherVecList)创建⼀个向量vecList,并使⽤向量otherVecList中的元素初始化该向量。
向量vecList与向量otherVecList的类型相同vector<elementType> vecLIst(size);创建⼀个⼤⼩为size的向量vecList,并使⽤默认构造函数初始化该向量 vector<elementType>vecList(n,elem);创建⼀个⼤⼩为n的向量vecList,该向量中所有的n个元素都初始化为elemvector<elementType> vecList(begin,end);创建⼀个向量vecList,并初始化该向量(begin,end)中的元素。
C语言利用动态数组实现顺序表(不限数据类型)
![C语言利用动态数组实现顺序表(不限数据类型)](https://img.taocdn.com/s3/m/09099902bb1aa8114431b90d6c85ec3a87c28bba.png)
C语⾔利⽤动态数组实现顺序表(不限数据类型)实现任意数据类型的顺序表的初始化,插⼊,删除(按值删除;按位置删除),销毁功能。
、顺序表结构体 实现顺序表结构体的三个要素:(1)数组⾸地址;(2)数组的⼤⼩;(3)当前数组元素的个数。
1//顺序表结构体2struct DynamicArray{3void **addr; //指向数组的⾸地址(指向数组的指针)4int capacity; //数组的⼤⼩5int size; //当前数组元素的个数6 }; 注意事项:void **addr为⼆级指针,即数组的元素也为指针,因为我们并不知道⽤户的输⼊数据是什么类型,操作数据的地址是最安全的⽅法。
初始化 对顺序表进⾏初始化,实际上为初始化顺序表内的各个成员,另外对输⼊的参数做边界处理。
1//初始化数组,初始化结构体和⾥⾯的元素。
初始化之后返回该数组,写为void*2void *Init(int capacity_){3if (capacity_ <= 0){4return NULL;5 }67struct DynamicArray *arr = malloc(sizeof(struct DynamicArray));//开辟⼀个结构体就可以了8if (NULL == arr){9return NULL;10 }1112 arr->capacity = capacity_;13 arr->addr = malloc(sizeof(void*)*arr->capacity);//对数组开辟内存14 arr->size = 0;1516return arr;17 }插⼊操作 对于顺序表的插⼊操作,需要在pos位置处开始的元素统⼀往后移动⼀个位置,处理⽅式为:从后往前挨个移动,从前往后会覆盖。
注意:(1)考虑顺序表的顺序插⼊和乱序插⼊,12⾏的代码;(2)若顺序表被填满,则需要对现有数组进⾏扩⼤空间,这⾥涉及到四步操作:开辟内存、拷贝数据(尽量使⽤memcpy)、释放原内存、修改指针指向。
C#静态与动态数组
![C#静态与动态数组](https://img.taocdn.com/s3/m/55fdc0dc77a20029bd64783e0912a21614797fdb.png)
C#静态与动态数组C#中的数组是由System.Array类衍⽣出来的引⽤对象,因此可以使⽤Array类中的各种⽅法对数组进⾏各种操作。
⼀维数组:using System;using System.Collections.Generic;using System.Text;using System.Collections;namespace ConsoleApplication1{class Program{static void Main(string[] args){// 定义⼀维数组int[] IntArray = new int[10] {1,2,3,4,5,6,7,8,9,10};// 定义⼀维字符串数组string[] StrArray = new string[3];StrArray[0] = "abc" ;StrArray[1] = "abc";Console.ReadKey();}}}删除元素(⼀维数组):using System;using System.Collections.Generic;using System.Text;using System.Collections;namespace ConsoleApplication1{class Program{static void Main(string[] args){// 定义⼀维数组int[] IntArray = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };// 遍历数组foreach (int num in IntArray)Console.WriteLine(num);Console.ReadLine();// 通过循环删除第三个元素int Del_Num = 2;for (int x = Del_Num; x < IntArray.Length - Del_Num; x++){IntArray[x] = IntArray[x - 1];}Console.ReadKey();}}}寻找最⼤最⼩值:using System;using System.Collections.Generic;using System.Text;using System.Collections;namespace ConsoleApplication1{class Program{static void Main(string[] args){// 定义⼀维数组int[] Array = new int[10] { 57, 32, 78, 96, 33, 11, 78, 3, 78, 2 };// 声明两个变量⽤来存储最⼤值和最⼩值int min = int.MaxValue;int max = int.MinValue;int sum = 0;for (int i = 0; i < Array.Length; i++){if (Array[i] > max)max = Array[i];if (Array[i] < min)min = Array[i];sum += Array[i];}Console.WriteLine("最⼤值: {0} 最⼩值: {1} 总和: {2} 平均值: {3}", max, min, sum, sum / Array.Length); Console.ReadKey();}}}数组组合为字符串:using System;using System.Collections.Generic;using System.Text;using System.Collections;namespace ConsoleApplication1{class Program{static void Main(string[] args){String[] name = { "⽼杨", "⽼苏", "⽼邹", "⽼虎", "⽼⽜", "⽼马" };string str = null;for (int x = 0; x < name.Length - 1; x++)str += name[x] + "|";Console.WriteLine(str + name[name.Length - 1]);Console.ReadKey();}}}数组元素反转:using System;using System.Collections.Generic;using System.Text;using System.Collections;namespace ConsoleApplication1{class Program{static void Main(string[] args){String[] name = { "⽼杨", "⽼苏", "⽼邹", "⽼虎", "⽼⽜", "⽼马" };string tmp;for (int x = 0; x < name.Length / 2; x++){tmp = name[name.Length - 1 - x];name[x] = name[name.Length - 1 - x];name[name.Length - 1 - x] = tmp;}for (int x = 0; x < name.Length - 1; x++)Console.Write(name[x] + " |" );Console.ReadKey();}}}冒泡排序:using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace ConsoleApplication1{class Program{// 执⾏排序static void Sort(int[] Array){for (int x = 0; x < Array.Length - 1; x++){for (int y = 0; y < Array.Length - 1 - x; y++){if (Array[y] > Array[y + 1]){int tmp = Array[y];Array[y] = Array[y + 1];Array[y+1] = tmp;}}}}// 输出结果static void Display(int[] Array){for (int x = 0; x < Array.Length; x++){Console.Write(Array[x] + " ");}}static void Main(string[] args){int[] MyArray = new int[10] { 57, 32, 4, 96, 33, 11, 78, 3, 78, 2 }; Sort(MyArray);Display(MyArray);// 使⽤系统提供的⽅法排序Array.Sort(MyArray);// 执⾏⼀次反向排序Array.Reverse(MyArray);Console.ReadKey();}}}直接插⼊排序:using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace ConsoleApplication1{class Program{// 执⾏排序static void Sort(int[] Array){for (int x = 0; x < Array.Length; x++){int tmp = Array[x];int y = x;while ((y > 0) && (Array[y - 1] > tmp)){Array[y] = Array[y-1];--y;}Array[y] = tmp;}}static void Main(string[] args){int[] MyArray = new int[10] { 57, 32, 4, 96, 33, 11, 78, 3, 78, 2 }; Sort(MyArray);foreach (int x in MyArray)Console.Write(x + " ");Console.ReadKey();}}}选择排序:using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace ConsoleApplication1{class Program{// 执⾏排序static void Sort(int[] Array){int min = 0;for (int x = 0; x < Array.Length; x++){min = x;for (int y = x + 1; y < Array.Length; y++){if (Array[y] < Array[min])min = y;}int tmp = Array[min];Array[min] = Array[x];Array[x] = tmp;}}static void Main(string[] args){int[] MyArray = new int[10] { 57, 32, 4, 96, 33, 11, 78, 3, 78, 2 };Sort(MyArray);foreach (int x in MyArray)Console.Write(x + " ");Console.ReadKey();}}}定义⼆维数组using System;using System.Collections.Generic;using System.Text;using System.Collections;namespace ConsoleApplication1{class Program{static void Main(string[] args){// 定义⼆维数组int[,] Array = new int[2,3]{{1,2,4},{4,5,6}};Console.WriteLine("数组⾏数为: {0}", Array.Rank);Console.WriteLine("数组列数为: {0}", Array.GetUpperBound(Array.Rank - 1) + 1); for (int x = 0; x < Array.Rank;x++ ){string str = "";for(int y=0;y< Array.GetUpperBound(Array.Rank-1)+1;y++){str = str + Convert.ToString(Array[x, y]) + " ";}Console.Write(str);}Console.ReadKey();}}}定义动态⼆维数组:using System;using System.Collections.Generic;using System.Text;using System.Collections;namespace ConsoleApplication1{class Program{static void Main(string[] args){int Row = Convert.ToInt32(Console.ReadLine()); int Col = Convert.ToInt32(Console.ReadLine()); int[,] Array = new int[Row, Col];for (int x = 0; x < Row; x++){for (int y = 0; y < Col; y++){Console.Write(x + "-->" + y.ToString() + " "); }Console.WriteLine();}Console.ReadKey();}}}⼀维数组的合并:using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace ConsoleApplication1{class Program{static void Main(string[] args){int[] Array1 = new int[] { 1, 2, 3, 4, 5 };int[] Array2 = new int[] { 6, 7, 8, 9, 10 };// 将Array1 与 Array2 合并成 Array3int Count = Array1.Length + Array2.Length;int[] Array3 = new int[Count];for (int x = 0; x < Array3.Length; x++){if (x < Array1.Length)Array3[x] = Array1[x];elseArray3[x] = Array2[x - Array1.Length];}foreach (int each in Array3)Console.Write(each + " ");Console.ReadKey();}}}⼆维数组的合并:using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace ConsoleApplication1{class Program{static void Main(string[] args){int[] Array1 = new int[] { 1, 2, 3, 4, 5 };int[] Array2 = new int[] { 6, 7, 8, 9, 10 };// 将两个⼀维数组,合并到⼀个⼆维数组中int[,] Array3 = new int[2, 5];// Rank = ⼆维数组中的2for (int x = 0; x < Array3.Rank; x++){switch (x){case 0:{for (int y = 0; y < Array1.Length; y++)Array3[x, y] = Array1[y];break;}case 1:{for (int z = 0; z < Array2.Length; z++)Array3[x, z] = Array2[z];break;}}}// 输出⼆维数组中的数据for (int x = 0; x < Array3.Rank;x++ ){for(int y=0;y<Array3.GetUpperBound(Array3.Rank-1)+1;y++)Console.Write(Array3[x, y] + " ");Console.WriteLine();}Console.ReadKey();}}}⼆维数组的拆分:using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace ConsoleApplication1{class Program{static void Main(string[] args){int[,] Array = new int[2, 3] { { 1, 3, 5 }, { 3, 4, 6 } };int[] ArrayOne = new int[3];int[] ArrayTwo = new int[4];for (int x = 0; x < 2; x++){for(int y= 0; y<3; y++){switch(x){case 0: ArrayOne[y] = Array[x, y]; break;case 1: ArrayTwo[y] = Array[x, y]; break;}}}foreach (int each in ArrayOne)Console.WriteLine(each);Console.ReadKey();}}}ArrayList 类位于System.Collections命名空间下,它可以动态添加和删除元素,可以将该数组类看作扩充了功能的数组。
C语言建立动态数组
![C语言建立动态数组](https://img.taocdn.com/s3/m/dccfa0d25122aaea998fcc22bcd126fff7055ddc.png)
C语⾔建⽴动态数组C语⾔建⽴动态数组数组的有点在于随机存取,然⽽其不⾜也是明显的,就是⼀旦建⽴其⼤⼩就不能改变。
若⽤数组存储数据,则必须创建⼀个可能存放的最⼤空间的数组,这⽆疑浪费了空间。
动态数组解决了这个问题。
动态数组的思路是:先建⽴⼀定⼤⼩的数组,向这个数组中存放数据,如果数组已满,则重新申请⼀个更⼤的空间来存放。
每次重新申请时可以指定增量(inc)的⼤⼩,也可以固定⼤⼩。
这样做的好处是空间浪费不多,最多浪费(inc-1)个元素空间,其不⾜是重新申请空间浪费时间,每次重新申请空间时须将原来的数据拷贝到新申请的空间,当数组很⼤时,这种浪费还是相当可观的。
稍后将⽤链表和数组结合解决这⼀问题。
先建⽴动态数组的存储结构:typedef unsigned char BOOL;typedef int elem_t; //存放数据类型typedef struct{int iCount; //数据个数(数组中实际存放元素的个数)int iCapacity; //容量(数组中能够容纳元素的最⼤个数)elem_t * pData; //数据指针(该指针指向存放数据空间的⾸地址)}Array_t;下⾯定义数组的基本操作,包括:1、初始化;2、设置元素的值;3、取得元素的引⽤(C语⾔中指地址);4、取得元素的值;5、销毁数组以下是上⾯五个操作的函数声明:BOOL initArray( Array_t * array, int size ); //初始化,size为指定初始化数组容量BOOL setValue( Array_t * array, int index, elem_t val ); //设置指定位置元素的值elem_t * getRef( Array_t * array, int index ); //得到指定位置元素的引⽤(地址)elem_t getValue( Array_t * array, int index ); //得到指定位置元素的值BOOL destroyArray( Array_t * array ); //销毁该数组以下是函数实现:#define INIT_DATA_NUM 10 //数组初始化⼤⼩,增量⼤⼩BOOL initArray( Array_t * array, int size ) //初始化,若size <= 0,则采⽤默认⼤⼩{BOOL bRet = FALSE;int initSize = (size > 0) ? size:INIT_DATA_NUM;array->pData = ( elem_t * )malloc( initSize * sizeof( elem_t) );if ( array->pData != NULL ){array->iCapacity = initSize;array->iCount = 0;bRet = TRUE;}return bRet;}BOOL setValue( Array_t * array, int index, elem_t val ) //设置指定位置元素的值{BOOL bRet = FALSE;if( index > 0 && index < array->iCount ){array->pData[index] = val;bRet = TRUE;}return bRet;}elem_t * getRef( Array_t * array, int index ) //得到指定位置元素的引⽤(地址){elem_t * eRet = NULL;if( index > 0 && index < array->iCount ){eRet = array->pData + index;}return eRet;}elem_t getValue( Array_t * array, int index ) //得到指定位置元素的值(不检查数组越界){return array->pData[index];}BOOL destroyArray( Array_t * array ) //销毁该数组{free( array->pData );array->pData = NULL;return TRUE;}这样关于动态数组的基本操作就完成了。
C++技巧:二维动态数组类模板
![C++技巧:二维动态数组类模板](https://img.taocdn.com/s3/m/b66a5716cc7931b765ce151f.png)
C++技巧:二维动态数组类模板
学习各种外挂制作技术,马上去百度搜索"魔鬼作坊"点击第一个站进入、快速成为做挂达人。
C++提供了许多强大的机制来实现代码的高度复用、来使我们使用我们自已的类就像使用内置类型那样方便快捷。
比如模板,运算符重载等等。
模板好比如是一个大批量生产函数和类的工厂,使我们不用再去关心与数据类型相关的繁琐编程细节,把我们精力留给那些真正值得我们去认真思考的地方。
而运算符重载则使我们的程序更直观更简洁,这不仅使我们更容易读懂我们的程序,而且使我们能以一种更为流畅的方式来表达我们的想法。
就像上篇文章说到的,如果我们把动态分配的二维数组用类模板实现,并重载相应的操作符,我们就能十分方便的使用我们自己定义的数组类型了。
今天我正好把以往的程序整理了一下,就一并贴了出来,看下面的程序。
下面的两个类模板在vc++6.0上编译运行良好,测试程序也都得到正确的结果,如果在其他编译环境下有什么问题,欢迎给我留言。
第一个头文件Array.h是一维动态数组类模板:。
C语言动态创建二维数组
![C语言动态创建二维数组](https://img.taocdn.com/s3/m/6d3002280622192e453610661ed9ad51f01d5467.png)
C语 言 动 态 创 建 二 维 数 组
/*C语言 如何动态创建二维数组 转化为一维数组申请数组,创建和释放都比较简单 */ #include <stdlib.h> #include <stdio.h> #include <malloc.h>
for(i=0;i<RANK;i++) for(j=0;j<COLUMN;j++) p[i][j]=i*j;
for(i=0;i<RANK;i++) { for(j=0;j<COLUMN;j++) printf("%d,",p[i][j]);
printf("\n"); } free(p);
system("pause"); return 0; }
当然,还有第二种方法,这里就不测试了,只是为了工程实用性,哈哈
#define RANK 10 #define COLUMN 7 int main() {
int i,j;
int (*p)[COLUMN];
//动态生成二维数组,指定列数为COLUMN,如果想改,自己该里面 //的参数,如果想定义n行2列就为: p=(int (*)[2])malloc(n*2*sizeof(int)); p=(int (*)[COLUMN])malloc(RANK*COLUMN*sizeof(int)); //动态申请n行COLUMN列的二维数组
C语言动态数组
![C语言动态数组](https://img.taocdn.com/s3/m/7cd8f04db307e87100f69604.png)
动态内存分配
第四章例题:数组处理“通讯录”
2013年1月12日星期六
问题:人数不确定,数组长度无法确定,怎么办? 如果定义足够大的空间,可能造成浪费! 解决:使用动态存储分配,在程序执行期间分配内存
单元
动态内存分配
根据需要开辟或释放存储单元 相关函数 malloc函数
2013年1月12日星期六
if(p == NULL) { puts(“存储空间分配失败!”); exit(0); }
malloc()与calloc()的主要区别
2013年1月12日星期六
函数calloc()会将所分配的内存空间中的每一位都 初始化为零,即:如果是为字符类型或整数类型的 元素分配内存,那么这些元素将保证会被初始化为 0;如果是为指针类型的元素分配内存,那么这些
每个元素a[i]又是一个包 含4个元素的一维数组
a[0] 0 1 2 3 a[1] 4 5 6 7 a[2] 8 9 10 11
a[0][0] a[0][1] a[0][2] a[0][3] a[1][0]
a[1][1] a[1][2] a[1][3] a[2][0] a[2][1] a[2][2] a[2][3]
元素通常会被初始化为空指针;如果你为实型数据
分配内存,则这些元素会被初始化为浮点型的零。 函数malloc()不能初始化所分配的内存空间。
realloc函数
函数原型
2013年1月12日星期六
void *realloc(void *p,unsigned size);
功能
将p所指的已分配内存区的大小改为size字节, size可以比原来分配的空间大或小 返回值 若成功,返回指向新分配内存区的指针(与原
使用C语言实现vector动态数组的实例分享
![使用C语言实现vector动态数组的实例分享](https://img.taocdn.com/s3/m/43e1bd03f08583d049649b6648d7c1c708a10bb9.png)
使⽤C语⾔实现vector动态数组的实例分享下⾯是做项⽬时实现的⼀个动态数组,先后加⼊了好⼏个之后的项⽬,下⾯晒下代码。
头⽂件:# ifndef __CVECTOR_H__# define __CVECTOR_H__# define MIN_LEN 256# define CVEFAILED -1# define CVESUCCESS 0# define CVEPUSHBACK 1# define CVEPOPBACK 2# define CVEINSERT 3# define CVERM 4# define EXPANED_VAL 1# define REDUSED_VAL 2typedef void *citerator;typedef struct _cvector *cvector;# ifdef _cplusplus# define EXTERN_ extern "C"# else# define EXTERN_ extern# endifEXTERN_ cvector cvector_create (const size_t size );EXTERN_ void cvector_destroy (const cvector cv );EXTERN_ size_t cvector_length (const cvector cv );EXTERN_ int cvector_pushback (const cvector cv, void *memb );EXTERN_ int cvector_popback (const cvector cv, void *memb );EXTERN_ size_t cvector_iter_at (const cvector cv, citerator iter );EXTERN_ int cvector_iter_val (const cvector cv, citerator iter, void *memb);EXTERN_ citerator cvector_begin (const cvector cv );EXTERN_ citerator cvector_end (const cvector cv );EXTERN_ citerator cvector_next (const cvector cv, citerator iter );EXTERN_ int cvector_val_at (const cvector cv, size_t index, void *memb );EXTERN_ int cvector_insert (const cvector cv, citerator iter, void *memb);EXTERN_ int cvector_insert_at(const cvector cv, size_t index, void *memb );EXTERN_ int cvector_rm (const cvector cv, citerator iter );EXTERN_ int cvector_rm_at (const cvector cv, size_t index );/* for test */EXTERN_ void cv_info (const cvector cv );EXTERN_ void cv_print (const cvector cv );#endif /* EOF file cvector.h */C⽂件:# include <stdio.h># include <stdlib.h># include <string.h># include <unistd.h># define MIN_LEN 256# define CVEFAILED -1# define CVESUCCESS 0# define CVEPUSHBACK 1# define CVEPOPBACK 2# define CVEINSERT 3# define CVERM 4# define EXPANED_VAL 1# define REDUSED_VAL 2typedef void *citerator;typedef struct _cvector{void *cv_pdata;size_t cv_len, cv_tot_len, cv_size;if ((cvector_begin(cv) > iter) || (cvector_end(cv) <= iter)) {\fprintf(stderr, "var(" #iter ") warng out of range, "\"at file:%s func:%s line:%d!!/n", file, func, line);\return CVEFAILED;\}\} while (0)# ifdef _cplusplus# define EXTERN_ extern "C"# else# define EXTERN_ extern# endifEXTERN_ cvector cvector_create (const size_t size );EXTERN_ void cvector_destroy (const cvector cv );EXTERN_ size_t cvector_length (const cvector cv );EXTERN_ int cvector_pushback (const cvector cv, void *memb ); EXTERN_ int cvector_popback (const cvector cv, void *memb ); EXTERN_ size_t cvector_iter_at (const cvector cv, citerator iter ); EXTERN_ int cvector_iter_val (const cvector cv, citerator iter, void *memb); EXTERN_ citerator cvector_begin (const cvector cv );EXTERN_ citerator cvector_end (const cvector cv );EXTERN_ citerator cvector_next (const cvector cv, citerator iter ); EXTERN_ int cvector_val_at (const cvector cv, size_t index, void *memb ); EXTERN_ int cvector_insert (const cvector cv, citerator iter, void *memb); EXTERN_ int cvector_insert_at(const cvector cv, size_t index, void *memb ); EXTERN_ int cvector_rm (const cvector cv, citerator iter );EXTERN_ int cvector_rm_at (const cvector cv, size_t index );/* for test */EXTERN_ void cv_info (const cvector cv );EXTERN_ void cv_print (const cvector cv );cvector cvector_create(const size_t size){cvector cv = (cvector)malloc(sizeof (struct _cvector));if (!cv) return NULL;cv->cv_pdata = malloc(MIN_LEN * size);if (!cv->cv_pdata){free(cv);return NULL;}cv->cv_size = size;cv->cv_tot_len = MIN_LEN;cv->cv_len = 0;return cv;}void cvector_destroy(const cvector cv){free(cv->cv_pdata);free(cv);return;}size_t cvector_length(const cvector cv){return cv->cv_len;}int cvector_pushback(const cvector cv, void *memb){if (cv->cv_len >= cv->cv_tot_len){void *pd_sav = cv->cv_pdata;cv->cv_tot_len <<= EXPANED_VAL;cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size);cv->cv_pdata = pd_sav;cv->cv_tot_len >>= EXPANED_VAL;return CVEPUSHBACK;}}memcpy(cv->cv_pdata + cv->cv_len * cv->cv_size, memb, cv->cv_size); cv->cv_len++;return CVESUCCESS;}int cvector_popback(const cvector cv, void *memb){if (cv->cv_len <= 0) return CVEPOPBACK;cv->cv_len--;memcpy(memb, cv->cv_pdata + cv->cv_len * cv->cv_size, cv->cv_size); if ((cv->cv_tot_len >= (MIN_LEN << REDUSED_VAL))&& (cv->cv_len <= (cv->cv_tot_len >> REDUSED_VAL))){void *pd_sav = cv->cv_pdata;cv->cv_tot_len >>= EXPANED_VAL;cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size);if (!cv->cv_pdata){cv->cv_tot_len <<= EXPANED_VAL;cv->cv_pdata = pd_sav;return CVEPOPBACK;}}return CVESUCCESS;}size_t cvector_iter_at(const cvector cv, citerator iter){CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__);return (iter - cv->cv_pdata) / cv->cv_size;}int cvector_iter_val(const cvector cv, citerator iter, void *memb){CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__);memcpy(memb, iter, cv->cv_size);return 0;}citerator cvector_begin(const cvector cv){return cv->cv_pdata;}citerator cvector_end(const cvector cv){return cv->cv_pdata + (cv->cv_size * cv->cv_len);}static inline void cvmemove_foreward(const cvector cv, void *from, void *to) {size_t size = cv->cv_size;void *p;for (p = to; p >= from; p -= size) memcpy(p + size, p, size);return;}static inline void cvmemove_backward(const cvector cv, void *from, void *to) {memcpy(from, from + cv->cv_size, to - from);return;}CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__);if (cv->cv_len >= cv->cv_tot_len){void *pd_sav = cv->cv_pdata;cv->cv_tot_len <<= EXPANED_VAL;cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size);if (!cv->cv_pdata){cv->cv_pdata = pd_sav;cv->cv_tot_len >>= EXPANED_VAL;return CVEINSERT;}}cvmemove_foreward(cv, iter, cv->cv_pdata + cv->cv_len * cv->cv_size);memcpy(iter, memb, cv->cv_size);cv->cv_len++;return CVESUCCESS;}int cvector_insert_at(const cvector cv, size_t index, void *memb){citerator iter;if (index >= cv->cv_tot_len){cv->cv_len = index + 1;while (cv->cv_len >= cv->cv_tot_len) cv->cv_tot_len <<= EXPANED_VAL; cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size);iter = cv->cv_pdata + cv->cv_size * index;memcpy(iter, memb, cv->cv_size);}else{iter = cv->cv_pdata + cv->cv_size * index;cvector_insert(cv, iter, memb);}return 0;}citerator cvector_next(const cvector cv, citerator iter){return iter + cv->cv_size;}int cvector_val(const cvector cv, citerator iter, void *memb){memcpy(memb, iter, cv->cv_size);return 0;}int cvector_val_at(const cvector cv, size_t index, void *memb){memcpy(memb, cv->cv_pdata + index * cv->cv_size, cv->cv_size);return 0;}int cvector_rm(const cvector cv, citerator iter){citerator from;citerator end;CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__);from = iter;end = cvector_end(cv);memcpy(from, from + cv->cv_size, end - from);cv->cv_len--;if ((cv->cv_tot_len >= (MIN_LEN << REDUSED_VAL))&& (cv->cv_len <= (cv->cv_tot_len >> REDUSED_VAL)))cv->cv_tot_len >>= EXPANED_VAL;cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size);if (!cv->cv_pdata){cv->cv_tot_len <<= EXPANED_VAL;cv->cv_pdata = pd_sav;return CVERM;}}return CVESUCCESS;}int cvector_rm_at(const cvector cv, size_t index){citerator iter;iter = cv->cv_pdata + cv->cv_size * index;CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__);return cvector_rm(cv, iter);}void cv_info(const cvector cv){printf("/n/ntot :%s : %d/n", __func__, cv->cv_tot_len);printf("len :%s : %d/n", __func__, cv->cv_len);printf("size:%s : %d/n/n", __func__, cv->cv_size);return;}void cv_print(const cvector cv){int num;citerator iter;if (cvector_length(cv) == 0)fprintf(stderr, "file:%s func:%s line:%d error, null length cvector!!/n", __FILE__, __func__, __LINE__);for (iter = cvector_begin(cv);iter != cvector_end(cv);iter = cvector_next(cv, iter)){cvector_iter_val(cv, iter, &num);printf("var:%d at:%d/n", num, cvector_iter_at(cv, iter));}return;}改进版上⾯那份代码是在Linux下写的,如果是在Windows的Visul C++环境下编译似乎会出些问题,所以特别做了个改进版:下⾯是更新后的代码:cvector.h# ifndef __CVECTOR_H__# define __CVECTOR_H__# include <stdio.h># include <stdlib.h># include <string.h># define MIN_LEN 256# define CVEFAILED -1# define CVESUCCESS 0# define CVEPUSHBACK 1# define CVEPOPBACK 2# define CVEINSERT 3# define CVERM 4# define EXPANED_VAL 1# define REDUSED_VAL 2# ifdef __cplusplusextern "C" {# endifcvector cvector_create (const size_t size );void cvector_destroy (const cvector cv );size_t cvector_length (const cvector cv );int cvector_pushback (const cvector cv, void *memb );int cvector_popback (const cvector cv, void *memb );size_t cvector_iter_at (const cvector cv, citerator iter );int cvector_iter_val (const cvector cv, citerator iter, void *memb); citerator cvector_begin (const cvector cv );citerator cvector_end (const cvector cv );citerator cvector_next (const cvector cv, citerator iter );int cvector_val_at (const cvector cv, size_t index, void *memb ); int cvector_insert (const cvector cv, citerator iter, void *memb); int cvector_insert_at(const cvector cv, size_t index, void *memb ); int cvector_rm (const cvector cv, citerator iter );int cvector_rm_at (const cvector cv, size_t index );/* for test */void cv_info (const cvector cv );void cv_print (const cvector cv );# ifdef __cplusplus}# endif#endif /* EOF file cvector.h */cvector.c#include "cvector.h"#ifndef __gnu_linux__#define __func__ "unknown"#define inline __forceinline#endif# define CWARNING_ITER(cv, iter, file, func, line) \do {\if ((cvector_begin(cv) > iter) || (cvector_end(cv) <= iter)) {\fprintf(stderr, "var(" #iter ") warng out of range, "\"at file:%s func:%s line:%d!!\n", file, func, line);\return CVEFAILED;\}\} while (0)struct _cvector{void *cv_pdata;size_t cv_len, cv_tot_len, cv_size;};cvector cvector_create(const size_t size){cvector cv = (cvector)malloc(sizeof (struct _cvector));if (!cv) return NULL;cv->cv_pdata = malloc(MIN_LEN * size);if (!cv->cv_pdata){free(cv);return NULL;}cv->cv_size = size;cv->cv_tot_len = MIN_LEN;cv->cv_len = 0;void cvector_destroy(const cvector cv){free(cv->cv_pdata);free(cv);return;}size_t cvector_length(const cvector cv){return cv->cv_len;}int cvector_pushback(const cvector cv, void *memb){if (cv->cv_len >= cv->cv_tot_len){void *pd_sav = cv->cv_pdata;cv->cv_tot_len <<= EXPANED_VAL;cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size);if (!cv->cv_pdata){cv->cv_pdata = pd_sav;cv->cv_tot_len >>= EXPANED_VAL;return CVEPUSHBACK;}}memcpy((char *)cv->cv_pdata + cv->cv_len * cv->cv_size, memb, cv->cv_size); cv->cv_len++;return CVESUCCESS;}int cvector_popback(const cvector cv, void *memb){if (cv->cv_len <= 0) return CVEPOPBACK;cv->cv_len--;memcpy(memb, (char *)cv->cv_pdata + cv->cv_len * cv->cv_size, cv->cv_size); if ((cv->cv_tot_len >= (MIN_LEN << REDUSED_VAL))&& (cv->cv_len <= (cv->cv_tot_len >> REDUSED_VAL))){void *pd_sav = cv->cv_pdata;cv->cv_tot_len >>= EXPANED_VAL;cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size);if (!cv->cv_pdata){cv->cv_tot_len <<= EXPANED_VAL;cv->cv_pdata = pd_sav;return CVEPOPBACK;}}return CVESUCCESS;}size_t cvector_iter_at(const cvector cv, citerator iter){CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__);return ((char *)iter - (char *)cv->cv_pdata) / cv->cv_size;}int cvector_iter_val(const cvector cv, citerator iter, void *memb){CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__);memcpy(memb, iter, cv->cv_size);return 0;}citerator cvector_begin(const cvector cv){citerator cvector_end(const cvector cv){return (char *)cv->cv_pdata + (cv->cv_size * cv->cv_len);}static inline void cvmemove_foreward(const cvector cv, void *from, void *to) {size_t size = cv->cv_size;char *p;for (p = (char *)to; p >= (char *)from; p -= size) memcpy(p + size, p, size);return;}static inline void cvmemove_backward(const cvector cv, void *from, void *to) {memcpy(from, (char *)from + cv->cv_size, (char *)to - (char *)from);return;}int cvector_insert(const cvector cv, citerator iter, void *memb){CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__);if (cv->cv_len >= cv->cv_tot_len){void *pd_sav = cv->cv_pdata;cv->cv_tot_len <<= EXPANED_VAL;cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size);if (!cv->cv_pdata){cv->cv_pdata = pd_sav;cv->cv_tot_len >>= EXPANED_VAL;return CVEINSERT;}}cvmemove_foreward(cv, iter, (char *)cv->cv_pdata + cv->cv_len * cv->cv_size); memcpy(iter, memb, cv->cv_size);cv->cv_len++;return CVESUCCESS;}int cvector_insert_at(const cvector cv, size_t index, void *memb){citerator iter;if (index >= cv->cv_tot_len){cv->cv_len = index + 1;while (cv->cv_len >= cv->cv_tot_len) cv->cv_tot_len <<= EXPANED_VAL;cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size);iter = (char *)cv->cv_pdata + cv->cv_size * index;memcpy(iter, memb, cv->cv_size);}else{iter = (char *)cv->cv_pdata + cv->cv_size * index;cvector_insert(cv, iter, memb);}return 0;}citerator cvector_next(const cvector cv, citerator iter){return (char *)iter + cv->cv_size;}int cvector_val(const cvector cv, citerator iter, void *memb){memcpy(memb, iter, cv->cv_size);int cvector_val_at(const cvector cv, size_t index, void *memb){memcpy(memb, (char *)cv->cv_pdata + index * cv->cv_size, cv->cv_size);return 0;}int cvector_rm(const cvector cv, citerator iter){citerator from;citerator end;CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__);from = iter;end = cvector_end(cv);memcpy(from, (char *)from + cv->cv_size, (char *)end - (char *)from);cv->cv_len--;if ((cv->cv_tot_len >= (MIN_LEN << REDUSED_VAL))&& (cv->cv_len <= (cv->cv_tot_len >> REDUSED_VAL))){void *pd_sav = cv->cv_pdata;cv->cv_tot_len >>= EXPANED_VAL;cv->cv_pdata = realloc(cv->cv_pdata, cv->cv_tot_len * cv->cv_size);if (!cv->cv_pdata){cv->cv_tot_len <<= EXPANED_VAL;cv->cv_pdata = pd_sav;return CVERM;}}return CVESUCCESS;}int cvector_rm_at(const cvector cv, size_t index){citerator iter;iter = (char *)cv->cv_pdata + cv->cv_size * index;CWARNING_ITER(cv, iter, __FILE__, __func__, __LINE__);return cvector_rm(cv, iter);}void cv_info(const cvector cv){printf("\n\ntot :%s : %d\n", __func__, cv->cv_tot_len);printf("len :%s : %d\n", __func__, cv->cv_len);printf("size:%s : %d\n\n", __func__, cv->cv_size);return;}void cv_print(const cvector cv){int num;citerator iter;if (cvector_length(cv) == 0)fprintf(stderr, "file:%s func:%s line:%d error, null length cvector!!\n", __FILE__, __func__, __LINE__); for (iter = cvector_begin(cv);iter != cvector_end(cv);iter = cvector_next(cv, iter)){cvector_iter_val(cv, iter, &num);printf("var:%d at:%d\n", num, cvector_iter_at(cv, iter));}return;}main.cppint i = 1;cvector cv = cvector_create(sizeof(int)); cvector_pushback(cv, &i);cvector_pushback(cv, &i);cvector_pushback(cv, &i);cvector_pushback(cv, &i);cv_print(cv);cvector_destroy(cv);return 0;}。
C++动态数组类
![C++动态数组类](https://img.taocdn.com/s3/m/c385c5d2360cba1aa811daf9.png)
C++编写动态数组类变长数组用C++实现的方法如下,为了简单起见,使用的int类型作为内部元素,其实可以根据需要把它升级为任意元素,可以自定义数据类型,也可以把其写成模板类。
//Dynamicarray.h#ifndef DYNAMICARRAY_H#define DYNAMICARRAY_Hclass DynamicArray{public:DynamicArray(int aSize = 10);DynamicArray(const DynamicArray &aArray);~DynamicArray();DynamicArray &operator=(const DynamicArray &aArray);bool push(int aElement);bool pop(int &aElement);int getElement(int aIndex) const;int operator[](int aIndex) const;int &operator[](int aIndex);int getCount() const;private:int *m_pArray; //用于存储内部数组int m_iCount; //用于记录元素数int m_iSize; //用于记录占用的内存数const int KStep; //每次分配的步长};#endif// Dynamicarray.cpp#include "Dynamicarray.h"//构造函数DynamicArray::DynamicArray(int aSize):KStep(10){m_iSize = aSize;m_iCount = 0;m_pArray = new int[m_iSize];}//拷贝构造函数DynamicArray::DynamicArray(const DynamicArray &aArray):KStep(10) {m_iSize = aArray.m_iSize;m_iCount = aArray.m_iCount;m_pArray = new int[m_iSize];for(int i = 0 ; i < m_iCount ; i++){m_pArray[i] = aArray.m_pArray[i];}}//析构函数DynamicArray::~DynamicArray(){delete []m_pArray;}//重载赋值运算符DynamicArray &DynamicArray::operator =(const DynamicArray &aArray) {if(this == &aArray){return *this;}m_iSize = aArray.m_iSize;m_iCount = aArray.m_iCount;delete []m_pArray;m_pArray = new int[m_iSize];for(int i = 0 ; i < m_iCount ; i++){m_pArray[i] = aArray.m_pArray[i];}return *this;}//尾部添加元素bool DynamicArray::push(int aElement){//检查m_iCount == m_iSizeif(m_iCount == m_iSize){//分配内存m_iSize = m_iSize + KStep;int *p = new int[m_iSize];if(0 == p){return false;}//拷贝for(int i = 0 ; i < m_iCount ; i++){p[i] = m_pArray[i];}//删delete []m_pArray;m_pArray = p;}m_pArray[m_iCount] = aElement;m_iCount++;return true;}//尾部弹出元素bool DynamicArray::pop(int &aElement) {m_iCount--;if(m_iCount < 0){return false;}aElement = m_pArray[m_iCount];//释放过多的内存if(m_iSize - m_iCount > KStep){//分配内存m_iSize = m_iSize - KStep;int *p = new int[m_iSize];if(0 == p){return false;}//拷贝for(int i = 0 ; i < m_iCount ; i++){p[i] = m_pArray[i];}//删delete []m_pArray;m_pArray = p;}return true;}//获取指定索引的元素int DynamicArray::getElement(int aIndex) const {if(aIndex < 0 || aIndex >= m_iCount){throw 0;}return m_pArray[aIndex];}//重载【】运算符int DynamicArray::operator[](int aIndex) const {if(aIndex < 0 || aIndex >= m_iCount){throw 0;}return m_pArray[aIndex];}//重载[]运算符int &DynamicArray::operator[](int aIndex) {if(aIndex < 0){throw 0;}if(aIndex >= m_iSize){m_iSize = aIndex + KStep;int *p = new int[m_iSize];for(int i = 0 ; i < m_iCount; i++){p[i] = m_pArray[i];}delete []m_pArray;m_pArray = p;}return m_pArray[aIndex];}//获取元素个数int DynamicArray::getCount() const{return m_iCount;}。
c语言 结构体动态数组
![c语言 结构体动态数组](https://img.taocdn.com/s3/m/0399dee4a48da0116c175f0e7cd184254b351ba5.png)
c语言结构体动态数组结构体是C语言中一种非常重要的数据类型,它允许我们将不同类型的数据组织在一起,形成一个“结构体”。
而动态数组则是在程序运行时动态分配内存的一种数据结构。
本文将讲解如何使用C语言中的结构体动态数组。
一、结构体在C语言中,结构体可以定义为一种用户自定义的数据类型,它由多个不同类型的数据成员组成。
定义一个结构体的语法如下:```struct 结构体名{数据类型成员1;数据类型成员2;// ...};```例如,定义一个表示学生信息的结构体可以如下所示:```struct Student{char name[20];int age;char gender;float score;};```这里我们定义了一个名为“Student”的结构体,它由一个字符串类型的“name”成员、一个整型的“age”成员、一个字符型的“gender”成员和一个浮点型的“score”成员组成。
我们可以通过以下方式来访问结构体成员:```struct Student stu;strcpy(, "Tom");stu.age = 18;stu.gender = 'M';stu.score = 87.5;```这里我们定义了一个名为“stu”的结构体变量,并通过“.”操作符来访问它的不同成员。
例如,通过“”可以访问它的“name”成员,通过“stu.age”可以访问它的“age”成员,以此类推。
二、动态数组在C语言中,数组是一种固定长度的数据结构,其长度在定义时就已经确定了。
而动态数组则是在程序运行时动态分配内存的一种数据结构,其长度可以在运行时动态改变。
使用动态数组需要用到“malloc”函数,它可以在运行时申请一块指定大小的内存,返回该内存块的首地址。
例如,以下代码可以申请一块大小为“n”个整型变量的内存,并将其首地址存储在“ptr”指针变量中:```int *ptr;int n = 10;ptr = (int*)malloc(n * sizeof(int));```这里我们先定义了一个名为“ptr”的指针变量,并使用“malloc”函数申请了一块大小为“n”的内存块,并将其首地址存储在“ptr”中。
vc++6.0中动态数组实现(例如string类对象数组等)
![vc++6.0中动态数组实现(例如string类对象数组等)](https://img.taocdn.com/s3/m/da3a234d2e3f5727a5e96208.png)
VC动态数组实现数组类型的变量有三个重要的限制:数组长度固定不变,在编译时必须知道其长度,数组只在定义它的块语句内存在.实际的程序往往不能忍受这样的限制-------它们需要在运行时动态地分配数组.虽然数组长度是固定的,但动态分配的数组不必在编译时知道其长度,可以(通常也是)在运行时才确定数组长度.与数组变量不同,动态分配的数组将一直存在,知道程序显式释放它为止.每一个程序在执行时都占用一款可用的内存空间,用于存放动态分配的对象,此内存空间称为程序的自由存储区(free store)或堆(heap).C语言程序使用一对标准库函数malloc和free在自由存储区中分配存储空间,而C++语言则使用new 和delete表达式实现相同的功能。
1.动态数组的定义数组变量通过指定类型、数组名和维数来定义.而动态分配数组时,只需指定类型和数组长度,不必为数组对象命名,new表达式返回指向新分配数组的第一个元素的指针:int *pia=new int[10]; //array of 10 uninitialized ints此new表达式分配了一个含有10个int型元素的数组,并返回指向该数组第一个元素的指针,此返回值初始化了之怎pia.new表达式需要指定指针类型以及在方括号中给出的数组维数,该维数可以是任意的复杂表达式.创建数组后,new将返回指向数组第一个元素的指针.在自由存储区中创建的数组对象是没有名字的,程序员只能通过其地址间接地访问堆中的对象.2.初始化动态分配的数组动态分配数组时,如果数组元素具有类类型,将使用该类的默认构造函数实现初始化;如果数组元素是内置类型,则无初始化:string *psa=new string[10]; //array of 10 empty stringsint *pia=new int[10]; //array of 10 ninitialized ints这两个new表达式都分配了含有10个对象的数组.其中第一个数组是string类型,分配了保存对象的内存空间后,将调用string类型的默认构造函数依次初始化数组中的每个元素(实际上string对象都是空串,结尾无‘\0’).第二个数组则具有内置类型的元素,分配了存储10个int对象的内存空间,但这些元素没有初始化.也可使用跟在数组长度后面的一对空圆括号,对数组元素做值初始化:int *pia2=new int[10](); //array of 10 uninitialized ints圆括号要求编译器对数组做值初始化,在本例中即把数组元素都设置为0.注解:对于动态分配的数组,其元素只能初始化为元素类型的默认值,而不能像数组变量一样,用初始化列表为数组元素提供各不相同的初值.3.const对象的动态数组如果我们在自由存储区中创建的数组存储了内置类型的const对象,则必须为这个数组提供初始化:因为数组元素都是const对象,无法赋值.实现这个要求的唯一方法是对数组做值的初始化://error:uninitialized const arrayconst int *pci_bad=new const int[100];//ok:value-initialized const arrayconst int *pci_ok=new const int[100]();C++允许定义类类型的const数组,但该类类型必须提供默认构造函数://ok:array of 100 empty stringsconst string *pcs=new const string[100];在这里,将使用string类的默认构造函数初始化数组元素.当然,已创建的常量元素不允许修改------因此这样的数组实际上用处不大.4.允许动态分配空数组之所以要动态分配数组,往往是由于编译时并不知道数组的长度.我们可以编写如下代码size_t n=get_size(); //get_size returns number of elements needed int *p=new int[n];for(int *q=p;q!=p+n;++q)/* process the array */;计算数组长度,然后创建和处理该数组.有趣的是,如果get_size返回0会怎么样?答案是:代码仍然正确执行.C++虽然不允许定义长度为0的数组变量,但明确指出,调用new动态创建长度为0的数组是合法的:char arr[0]; //error:cannot define zero-length arraychar *cp=new char[0]; //ok:but cp can't be dereferenced用new动态创建长度为0的数组时,new返回有效的非零指针.该指针与new返回的其他指针不同,不能进行解引用操作,因为它毕竟没有指向任何元素.而允许的操作包括:比较运算,因此该指针能在循环中使用;在该指针上加(减)0,或者减去本身值,得0值.在上述例题中,如果get_size返回0,则仍然可以成功调用new,但是p并没有指向任何对象,数组是空的.因为n为0,所以for循环实际比较的是p和q,而q是用p初始化的,两者具有相等的值,因此for循环条件不成立,循环体一次都没有执行5.动态空间的释放动态分配的内存最后必须进行释放,否则,内存最终将会逐渐耗尽.如果不再需要使用动态创建的数组,程序员必须显式地将其占用的存储空间返还给程序的自由存储区.C++语言为指针提供delete[]表达式释放指针所指向的数组空间:delete[] pia;该语句回收了pia所指向的数组,把相应的内存返还给自由存储区.在关键字delete和指针之间的空方括号对是必不可少的:它告诉编译器该指针指向的是自由存储区中的数组,而并非单个对象.小心:如果遗漏了空方括号对,这是一个编译器无法发现的错误,将导致程序在运行时出错.理论上,回收数组时缺少空方括号对,至少会导致运行时少释放了内存空间,从而产生内存泄漏(memory leak).对于某些系统和/或元素类型,有可能会带来更严重的运行时错误.因此,在释放动态数组时千万别忘了方括号对.C风格字符串与C++的标准库类型string的比较:以下两段程序反映了使用C风格字符串与C++的标准库类型string的不同之处.使用string类型的版本更短、更容易理解,而且出错的可能性更小://C-style character string implementationconst char *pc="a very long literal string";const size_t len=strlen(pc +1); //space to allocate//performance test on string allocation and copyfor(size_t ix=0;ix!=1000000;++ix){char *pc2=new char[len+1]; //allocate the spacestrcpy(pc2,pc); //do the copyif(strcmp(pc2,pc)) //use the nuw string; //do nothingdelete[] pc2; //free the memory}//string implementationstring str("a very long literal string");//performance test on string allocation and copyfor(int ix=0;ix!=1000000;++ix){string str2=str; //do the copy,automatically allocatedif(str!=str2) //use the new string; //do nothing} //str2 is automatically freed6.动态数组的使用通常是因为在编译时无法知道数组的维数,所以才需要动态创建该数组.例如,在程序执行过程中,常常使用char*指针指向多个C风格字符串,于是必须根据每个字符串的长度实时地动态分配存储空间.采用这种技术要比建立固定大小的数组安全.如果程序员能够准确计算出运行时需要的数组长度,就不必再担心因数组变量具有固定的长度而造成的溢出问题.假设有以下C风格字符串:const char *noerr="success";//...const char *err189="Error: a function declaration must ""specify a function return type!";我们想在运行时把这两个字符串中的一个复制给新的字符数组,于是可以用以下程序在运行时计算维数:const char *errorTxt;if(errorFound)errorTxt=err189;elseerrorTxt=noerr;//remember the 1 for the terminating nullint dimension=strlen(errorTxt)+1;char *errMsg=new char[dimension];//copy the text for the error into errMsgstrncpy (errMsg,errorTxt,dimension);别忘记标准库函数strlen返回的是字符串的长度,并不包括字符串结束符,在获得的字符串长度上必须加1以便在动态分配时预留结束符的存储空间.。
MFC中动态数组CArray的使用
![MFC中动态数组CArray的使用](https://img.taocdn.com/s3/m/ecc297eb172ded630b1cb600.png)
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。
c++ vector的resize函数
![c++ vector的resize函数](https://img.taocdn.com/s3/m/55964090370cba1aa8114431b90d6c85ed3a887c.png)
c++ vector的resize函数1. 引言1.1 概述在C++编程语言中,vector是一个动态数组容器,提供了灵活的内存管理和使用方便的操作函数。
其中,resize函数作为vector类的一员,用于调整容器大小。
本文将详细介绍C++ vector的resize函数及其相关知识。
1.2 文章结构本篇文章将分为五个部分进行介绍和讨论。
首先,在引言部分简要概述了整篇文章的内容安排。
接下来讲解C++ vector的基本特点、使用场景以及与静态数组的比较。
随后介绍C++ vector中resize函数的概念、用法以及对内存管理的影响。
在第四部分中,我们将考量resize函数的性能,并提供优化技巧和注意事项。
最后,在结论与总结部分对文章进行小结,并重点总结C++ vector 的resize函数特点与用法,并归纳了相关性能考量以及优化技巧。
1.3 目的随着软件开发项目越来越复杂和庞大,对于内存管理和性能方面的需求也日益增加。
因此,深入理解和掌握C++ vector类以及其成员函数resize的使用方法、底层原理和优化技巧可以帮助我们更好地应对实际开发中的挑战。
本文的目的是为读者提供一份全面而详细的关于C++ vector的resize函数的指南,以便于读者在实际项目中能够灵活运用和优化该函数,达到更高效的编程效果。
2. C++ vector介绍:2.1 定义和特点:C++中的vector是一种动态数组容器,可以根据需要动态调整大小。
它是标准模板库(STL)中的一部分,使用vector可以方便地管理元素的插入、删除和访问。
和静态数组相比,vector具有以下几个特点:- 动态长度:vector可以根据需要自动扩展或缩小大小,无需手动调整。
- 内存管理:vector负责内部元素的内存分配和释放,无需手动操作。
- 随机访问:可以通过下标直接访问vector中的元素。
- 尾部插入和删除效率高:在尾部进行插入和删除操作时,效率非常高。
C语言宏定义技巧和实现动态数组
![C语言宏定义技巧和实现动态数组](https://img.taocdn.com/s3/m/3d3c7e300b4c2e3f5727632f.png)
#define STR(s) #s #define CONS(a,b) int(a##e##b)
int main()
{
printf(STR(vck));
// 输出字符串"vck"
printf("%d\n", CONS(2,3)); // 2e3 输出:2000
return 0;
}
二、当宏参数是另一个宏的时候 需要注意的是凡宏定义里有用'#'或'##'的地方宏参数是不会再展开.
#define A
(2)
#define _STR(s) #s
#define STR(s)
_STR(s)
#define _CONS(a,b) int(a##e##b)
#define CONS(a,b) _CONS(a,b)
// 转换宏 // 转换宏
printf("int max: %s\n", STR(INT_MAX));
1, 非'#'和'##'的情况
#define TOW
(2)
#define MUL(a,b) (a*b)
printf("%d*%d=%d\n", TOW, TOW, MUL(TOW,TOW)); 这行的宏会被展开为:
printf("%d*%d=%d\n", (2), (2), ((2)*(2))); MUL 里的参数 TOW 会被展开为(2).
写好 C 语言,漂亮的宏定义很重要,使用宏定义可以防止出错,提高可移植性,可读性,方便性 等 等。下面列举一些成熟软件中常用得宏定义。。。。。。
1,防止一个头文件被重复包含
C语言中动态数组的构建
![C语言中动态数组的构建](https://img.taocdn.com/s3/m/f3ba1dfe9a89680203d8ce2f0066f5335a81676d.png)
C语言中动态数组的构建
刘洪霞
【期刊名称】《科技信息》
【年(卷),期】2010(000)024
【摘要】在C语言中,数组在使用前必须进行定义,一旦定义了一个数组,系统将为它分配一个所申请大小的空间,该大小固定,以后不能改变,称为静态数组.但在编程过程中,有时我们所需的内存空间无法预先确定,对于这个问题,用静态数组的办法很难解决.为了解决这个问题,C语言提供了一些内存管理函数,这些内存管理函数结合指针可以按需要动态地分配内存空间,来构建动态数组.本文就从动态数组的定义,使用两个方面介绍一下动态数组是如何构建的.
【总页数】2页(P394,396)
【作者】刘洪霞
【作者单位】菏泽学院计算机与信息工程系
【正文语种】中文
【中图分类】TP3
【相关文献】
1.C语言多维动态数组在图象处理与矩阵运算中的应用 [J], 何昱;童卫兵
2.基于C语言的指针构造动态数组的方法研究 [J], 张欢枝
3.C语言中动态数组的实现 [J], 陈衍祥;王军
4.在C语言中用指针实现科学计算的动态数组 [J], 肖小英
5.利用指针在C语言中构造动态数组 [J], 岳晓红
因版权原因,仅展示原文概要,查看原文内容请购买。
C++自定义动态数组模板简介
![C++自定义动态数组模板简介](https://img.taocdn.com/s3/m/a94cef28e87101f69e31953d.png)
C++自定义动态数组模板简介欢迎大家在这里学习C++自定义动态数组模板!这里是我们给大家整理出来的精彩内容。
我相信,这些问题也肯定是很多朋友在关心的,所以我就给大家谈谈这个! #include “stdafx.h” #include using namespace std; template class MyArray { int len; public: T *data; MyArray() { data = NULL; len = 0; } ~MyArray() { delete[] data; } T& operator [](int index); void push(T d); }; template T& MyArray::operator [](int index) { if(index;(len-1)) { coutexit(1); } return data[index]; } template void MyArray::push(T d) { T *pdata = data; data = new T[len + 1]; if(pdata != NULL) { for(int i = 0 ; i { data[i] = pdata[i]; } delete[] pdata; } data[len] = d; len++; } //测试代码 int main(int argc, char* argv[]) { MyArray a; a.push(11); a.push(22); a.push(33); a.push(55); a[0]=44; coutreturn 0; } 好了,C++自定义动态数组模板内容就给大家介绍到这里了。
希望大家学业有成,工作顺利。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
if (array == NULL)
throw MEMFAIL;
}
template <class el>
AeDynArray<el>::~AeDynArray()
{
if (array)
{
free(array); // Freeing memory
Clear(); // than we clear it, since it will be deleted
else
{
// otherwise, shift array elements
for(unsigned int i=pos; i<size-1; i++)
// or new size is less then half of the current
if ((size > realsize) || (size < realsize/2))
{
realsize = size;
array = (el *)realloc(array, sizeof(el)*size);
void AeDynArray<el>::SetSize(unsigned int newsize)
{
size = newsize;
if (size != 0)
{
// change array memory size
// if new size is larger than current
return *this;
}
template <class el>
unsigned int AeDynArray<el>::GetSize()
{
return size; // simply return size
}
template <class el>
compatible
# Any modern C++ compiler
AeDynArray class interface is quite simple. There are two
constructors(default constructor and copy constructor), assignment
C++ dynamic array template class
abstract
This article provides example of dynamic array implementation using *C++
templates*. It uses standard *malloc*/realloc memory allocation
void* AeDynArray<el>::getptr()
{
return array; // return void* pointer
}
template <class el>
el& AeDynArray<el>::operator [] (unsigned int index)
if (array == NULL)
throw MEMFAIL;
memcpy(array, a.array, sizeof(el)*a.realsize);
// memcpy call -- coping memory contents
realsize = a.realsize;
array = (el *)realloc(array, sizeof(el)*dyn_array_step);
// set initial memory size again
realsize = dyn_array_step;
}
template <class el>
array = NULL;
}
}
template <class el>
AeDynArray<el>::AeDynArray(const AeDynArray &a)
{
array = (el *)malloc(sizeof(el)*a.realsize);
* GetSize() — returns current size of an array
* SetSize(unsigned int size) — sets array size
* Fill(int c) — fills all array's memory with a given integer
// dyn_array_mult times )
};
//////////////////////////////////////////////////////////////////////
template <class el>
AeDynArray<el>::AeDynArray()
return *this;
if (a.size == 0) // is other array is empty -- clear this array
Clear();
SetSize(a.size); // set size
memcpy(array, a.array, sizeof(el)*a.size);
is a type parameter — it can be any type. Functions Add() and operator
[] uses type /el/ specified while instantiating a class.
source code: C++
#include <cstdlib>
Free, tested & ready to use examples!
</>
Web
Programming </programming/> / C++ </programming/cplusplus/>
void Delete(unsigned int pos); // delete array item
void* getptr(); // get void* pointer to array data
enum exception { MEMFAIL }; // exception enum
AeDynArray& operator = (const AeDynArray &a); // assignment operator
el& operator [] (unsigned int index); // get array item
void Add(const el &item); // Add item to the end of array
size = a.size;
}
template <class el>
AeDynArray<el>& AeDynArray<el>::operator = (const AeDynArray &a)
{
if (this == &a) // in case somebody tries assign array to itself
const static int dyn_array_step = 128; // initial size of array memory (elements)
const static int dyn_array_mult = 2; // multiplier (enlarge array memory
{
return array[index]; // return array element
if (array == NULL)
throw MEMFAIL;
}
}
else
Clear();
}
template <class el>
void AeDynArray<el>::Delete(unsigned int pos)
{
if (size == 1) // If array has only one element
template<class el>
class AeDynArray
{
public:
AeDynArray(); // constructor
AeDynArray(const AeDynArray &a); // copy constructor
~AeDynArray(); // distructor
* Clear() — removes all elemets from the array, resets memory alocation
* Delete(unsigned int pos) — deletes specified element from the array
AeDynArray class difinition is prefixed by the keyword *template*: /el/
unsigned int GetSize(); // get size of array (elements)