C++中如何定义动态数组

C++中如何定义动态数组

http://blog.youkuaiyun.com/bzhxuexi/article/details/17230073

标签: C++动态数组
  3145人阅读  评论(0)  收藏  举报
  分类:

首先:为什么需要动态定义数组呢?
  这是因为,很多情况下,在预编译过程阶段,数组的长度是不能预先知道的,必须在程序运行时动态的给出
  但是问题是,c++要求定义数组时,必须明确给定数组的大小,要不然编译通不过 
 
  如: int Array[5];正确

       int i=5;
       int Array[i]; 错误 因为在编译阶段,编译器并不知道 i 的值是多少

   那么,我们该如何解决定义长度未知的数组呢?
   答案是:new 动态定义数组 

   因为new 就是用来动态开辟空间的,所以当然可以用来开辟一个数组空间
   
   这样,下面的语句:
    int size=50;
    int *p=new int[size]; 是正确的
 
   但是二维动态数组能不能也这样定义呢
   
  int size=50,Column=50;
  int (*p)[Column]=new int [size][Column]

  这样的语句,编译器通不过,为什么呢?
  首先 new int[size][Column] 就是动态生成时确定的,所以它没有错
  那么就是 int(*p)[Column],这句有问题了,这句为什么不对呢, 那是因为,这是一个定义语句,而定义语句先经过编译器进行编译,当编译器运行到此处时,发现Column 不是常数,因此不能通过编译。 而之所以编译器认为Column 不是常数,是因为编译阶段,编译器起的作用是查语法错误,和预分配空间,它并不执行程序,因此,没有执行那个赋值语句(只是对这个语句检查错误,和分配空间),因此编译阶段,它将认为column 是个变量。所以上面的二维数组定义是错误的, 它不能通过编译。

  改成这样:
  int size=50
  int (*p)[50]=new int [size][50]
  便正确了。

   由此可见,这种动态分配数组,仅对一维数组空间是真正动态分配的。
   但是如何真正的动态分配二维数组呢,即如果Column 也不能预先知道的话,该如何处理呢?
   
   上面的动态分配已经不能满足我们的要求,因为上面动态分配只对一维数组是真正动态的,对二维数组的话,必须编译之前预先知道二维数组每一列的长度,而这个长度在很多情况下是不能预先知道的,所以我们得结合其他方法来解决这个问题。
   
   既然一维是真正的动态分配的话,那我们利用这一特性定义一个指针数组。
   
   int **p= new int*[size];//定义指针数组 
   int *p[5];//  假若知道二维数组的行数为5

   然后对指针数组中的每一个指针分配一个一维数组空间,这样便动态定义了二维数组
  
   事实上,我认为指针数组的主要用途,就在于动态定义多维数组
    
    for(int i=0;i<size;i++)
   {
     p[i]=new int[Column];
   }
   
   运行完毕后,一个二维数组便被动态的成功建立

-----------------------------------

 

例子:

 

   size =6;

 

   column =5

 

   int **p=new int*[size];

 

    for(int i=0;i<size;i++)
   {
     p[i]=new int[Column];
   }

 

 

 

所生成的动态数组如下图所示:

 

 

 
   

  最后 ,因为调用了new, 千万千万别忘记在用完之后,将其所占资源 delete 掉

 

  下面是delete方法:

    for(int i=0;i<size;i++)
   {

           delete []  p[i];   // 要在指针前加[] , 否则的话 只释放p[i]所指的第一个单元所占的空间
   }

 

   delete [] p;     //最后不要忘掉 释放掉开辟的指针数组  :》


// ArrayTest.cpp : 定义控制台应用程序的入口点。
//


#include "stdafx.h"
#include "ArrayTest.h"
#include <afxstr.h>


#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 唯一的应用程序对象


CWinApp theApp;


using namespace std;


// ArrayTest.cpp : 定义控制台应用程序的入口点。
//


CString** CreateCStringArray(UINT colcount, UINT rowcount){
	CString** strMsg = new CString*[colcount];
	for (UINT i = 0; i < colcount; i++)
	{
		strMsg[i] = new CString[rowcount];
	}
	return strMsg;
}
POINT** CreatePOINTArray(UINT colcount, UINT rowcount)
{
	POINT** Point = new POINT*[colcount];
	for (UINT i = 0; i < colcount; i++)
	{
		Point[i] = new POINT[rowcount];
	}
	return Point;
}


void DeleteCStringArray(UINT size, CString** pstr)
{
	for (unsigned int i = 0; i < size; i++)
	{
		delete[]  pstr[i];   // 要在指针前加[] , 否则的话 只释放p[i]所指的第一个单元所占的空间
	}
}


void DeletePOintArray(UINT size, POINT** pPoint)
{
	for (UINT i = 0; i < size; i++)
	{
		delete[]  pPoint[i];   // 要在指针前加[] , 否则的话 只释放p[i]所指的第一个单元所占的空间
	}
}


int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;


	HMODULE hModule = ::GetModuleHandle(NULL);

	if (hModule != NULL)
	{
		// 初始化 MFC 并在失败时显示错误
		if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
		{
			// TODO:  更改错误代码以符合您的需要
			_tprintf(_T("错误:  MFC 初始化失败\n"));
			nRetCode = 1;
		}
		else
		{
			// TODO:  在此处为应用程序的行为编写代码。


			// 定义字符串数组--动态数组
			CString** strMsg = CreateCStringArray(8, 16);
			strMsg[0][0] = L"AddressWidth";
			strMsg[0][1] = L"Architecture";
			strMsg[0][2] = L"Availability";
			strMsg[0][3] = L"Caption";
			strMsg[0][4] = L"ConfigManagerErrorCode";
			strMsg[0][5] = L"ConfigManagerUserConfig";
			strMsg[0][6] = L"CpuStatus";
			strMsg[0][7] = L"CreationClassName";
			strMsg[0][8] = L"CurrentClockSpeed";


			strMsg[2][0] = L"InstallDate";
			strMsg[2][1] = L"L2CacheSize";
			strMsg[2][2] = L"L2CacheSpeed";
			strMsg[2][3] = L"L3CacheSize";
			strMsg[2][4] = L"L3CacheSpeed";
			strMsg[2][5] = L"LastErrorCod";
			strMsg[2][6] = L"Level";
			strMsg[2][7] = L"LoadPercentage";
			strMsg[2][8] = L"Manufacturer";
			strMsg[2][9] = L"MaxClockSpeed";
			strMsg[2][10] = L"Name";
			strMsg[2][11] = L"NumberOfCores";
			strMsg[2][12] = L"NumberOfLogicalProcessors";
			strMsg[2][13] = L"OtherFamilyDescription";
			strMsg[2][14] = L"PNPDeviceID";
			strMsg[2][15] = L"PowerManagementCapabilities";


			strMsg[4][0] = L"ProcessorId";
			strMsg[4][1] = L"ProcessorType";
			strMsg[4][2] = L"Revision";
			strMsg[4][3] = L"Role";
			strMsg[4][4] = L"SocketDesignation";
			strMsg[4][5] = L"Status";
			strMsg[4][6] = L"StatusInfo";
			strMsg[4][7] = L"Stepping";
			strMsg[4][8] = L"SystemCreationClassName";
			strMsg[4][9] = L"SystemName";
			strMsg[4][10] = L"UniqueId";
			strMsg[4][11] = L"UpgradeMethod";
			strMsg[4][12] = L"VoltageCaps";
			////////////////////////////////////////////////////////////////////////////
			strMsg[4][13] = L"ErrorCleared";
			strMsg[4][14] = L"ErrorDescription";
			strMsg[4][15] = L"ExtClock";


			strMsg[6][0] = L"InstallDate";
			strMsg[6][1] = L"L2CacheSize";
			strMsg[6][2] = L"L2CacheSpeed";
			strMsg[6][3] = L"L3CacheSize";
			strMsg[6][4] = L"L3CacheSpeed";
			strMsg[6][5] = L"LastErrorCod";
			strMsg[6][6] = L"Level";
			strMsg[6][7] = L"LoadPercentage";
			strMsg[6][8] = L"Manufacturer";
			strMsg[6][9] = L"MaxClockSpeed";
			strMsg[6][10] = L"Name";
			strMsg[6][11] = L"NumberOfCores";
			strMsg[6][12] = L"NumberOfLogicalProcessors";
			strMsg[6][13] = L"OtherFamilyDescription";
			strMsg[6][14] = L"PNPDeviceID";
			strMsg[6][15] = L"PowerManagementCapabilities";


			for (UINT i = 0; i < 8; i++)
			{
				for (UINT j = 0; j < 16; j++)
				{
					printf("%ls\n", strMsg[i][j]);
				}
				printf("--------------i = %d\n", i);
			}


			DeleteCStringArray(8, strMsg);
			//// 定义坐标数组
			POINT** Point = CreatePOINTArray(8, 16);
			POINT p1;
			p1.x = 1.0;
			p1.y = 2.0;


			Point[0][0] = p1;
			Point[0][1] = p1;
			Point[0][2] = p1;
			Point[0][3] = p1;
			Point[0][4] = p1;
			Point[0][5] = p1;
			Point[0][6] = p1;
			Point[0][7] = p1;
			Point[0][8] = p1;


			Point[1][0] = p1;
			Point[1][1] = p1;
			Point[1][2] = p1;
			Point[1][3] = p1;
			Point[1][4] = p1;
			Point[1][5] = p1;
			Point[1][6] = p1;
			Point[1][7] = p1;
			Point[1][8] = p1;


			for (UINT i = 0; i < 8; i++)
			{
				for (UINT j = 0; j < 16; j++)
				{
					printf("%d\n", Point[i][j]);
				}
				printf("--------------i = %d\n", i);
			}
			DeletePOintArray(8, Point);
		}
	}
	else
	{
		// TODO:  更改错误代码以符合您的需要
		_tprintf(_T("错误:  GetModuleHandle 失败\n"));
		nRetCode = 1;
	}
	return nRetCode;
}




<think> 我们正在讨论C++定义动态数组的方法。根据引用内容,C++中静态数组的大小是固定的,而动态数组可以在运行时改变大小。引用中提供了几种定义动态数组的方法,包括一维和二维动态数组。 对于一维动态数组,我们可以使用`new`运算符来动态分配内存,并在使用完毕后使用`delete[]`释放内存。例如: int *arr = new int[size]; // 动态分配大小为size的整型数组 // 使用arr delete[] arr; // 释放内存 对于二维动态数组,我们可以通过先分配一个指针数组,然后为每一行分配空间来实现。同样,释放内存时需要先释放每一行的空间,再释放指针数组。例如: int **arr2d = new int*[rows]; // 分配rows个int*指针 for (int i = 0; i < rows; i++) { arr2d[i] = new int[cols]; // 为每一行分配cols个整数的空间 } // 使用arr2d for (int i = 0; i < rows; i++) { delete[] arr2d[i]; // 先释放每一行的空间 } delete[] arr2d; // 再释放指针数组 此外,引用[2]还提到可以使用malloc和calloc等函数(C语言风格)来分配内存,但在C++中更推荐使用new和delete。 另外,需要注意的是,在现代C++中,我们通常使用标准库提供的容器(如std::vector)来实现动态数组,因为它们更安全、更方便。但是用户的问题是关于如何用原始方式定义动态数组,因此我们将重点放在new和delete上。 下面我将详细描述一维和二维动态数组定义和释放过程。 </think> 在C++定义动态数组主要有以下两种方法,可根据维度需求选择: ### 🔹 一维动态数组 ```cpp // 分配动态数组 int size = 10; int* arr = new int[size]; // 创建容量为size的整型数组 // 使用数组(示例赋值) for(int i = 0; i < size; i++) { arr[i] = i * 2; } // 必须手动释放内存 delete[] arr; // 释放整个数组[^1][^3] ``` ### 🔹 二维动态数组 ```cpp // 分配动态二维数组 int rows = 5, cols = 3; int** matrix = new int*[rows]; // 分配行指针数组 for(int i = 0; i < rows; i++) { matrix[i] = new int[cols]; // 为每行分配列空间[^2][^3] } // 使用示例(矩阵初始化) for(int i = 0; i < rows; i++) { for(int j = 0; j < cols; j++) { matrix[i][j] = i + j; } } // 释放内存(按行释放) for(int i = 0; i < rows; i++) { delete[] matrix[i]; // 释放每行的列空间 } delete[] matrix; // 释放行指针数组[^3] ``` ### 📌 关键注意事项 1. **内存管理**:动态数组必须手动释放,否则会导致内存泄漏 2. **维度扩展原理**: - 二维数组本质是"指针的数组"(行指针) - 每个行指针指向独立的一维数组(列数据)[^2] 3. **现代替代方案**:推荐使用`std::vector`容器(自动内存管理): ```cpp #include <vector> std::vector<int> dynArray; // 一维动态数组 std::vector<std::vector<int>> mat; // 二维动态数组 ``` > ⚠️ 重要提示:使用`new/delete`管理内存时,必须严格配对使用`new[]`和`delete[]`,否则会导致未定义行为[^1][^3]。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值