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

article/2025/10/3 14:00:19

 

首先:为什么需要动态定义数组呢?
  这是因为,很多情况下,在预编译过程阶段,数组的长度是不能预先知道的,必须在程序运行时动态的给出
  但是问题是,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;
}

二, C、C++之动态数组的实现


http://chatgpt.dhexx.cn/article/Adca01VS.shtml

相关文章

c++ 动态数组

动态数组 相关数组知识连接 数组详解 多维数组 在之前的文章中&#xff0c;讲解了数组的相关知识&#xff0c;那一种数组&#xff08;数组相关连接&#xff1a;https://blog.csdn.net/m0_62870588/article/details/123787052&#xff09;又称是静态数组&#xff0c;因为它的大小…

C语言中动态分配数组

很多人在编写C语言代码的时候很少使用动态数组&#xff0c;不管什么情况下通通使用静态数组的方法来解决&#xff0c;在当初学习C语言的时候我就是一个典型的例子&#xff0c;但是现在发现这是一个相当不好的习惯&#xff0c;甚至可能导致编写的程序出现一些致命的错误。尤其对…

C语言学习笔记:动态数组

动态数组 数组是C语言中的很重要的一种构造类型&#xff0c;最初我们学习的都是静态数组&#xff0c;但是&#xff0c;静态数组有着自己难以改变的缺点——数组长度固定。 一般在静态数组定义后&#xff0c;系统就会为其分配对应长度的连续的专有内存空间&#xff0c;可是&am…

C语言如何实现动态数组?

提出问题 请问在c语言里如何实现动态大小的数组啊&#xff0c;比如说int a[N];&#xff0c;这里N的值可以在程序中定&#xff0c;或者有什么方法可以实现类似的功能&#xff1f;总之只要在编译时不用制定数组大小就行。 分析问题 嵌入式系统的内存是宝贵的&#xff0c;内存是否…

C的动态数组的详细知识(网上收集到的大量详细知识以及个人理解的汇总)

动态数组是指在声明时没有确定数组大小的数组&#xff0c;即忽略圆括号中的下标&#xff1b;当要用它时&#xff0c;可随时用ReDim语句重新指出数组的大小。使用动态数组的优点是可以根据用户需要&#xff0c;有效利用存储空间。 可以了解动态数组的详细定义 一.C版本动态数组…

动态数组C语言实现详解

目录 0、前言 一、动态数组数据结构 二、动态数组增删改查函数声明 三、数组创建 1、头部动态创建 2、头部静态创建 四、元素添加 五、元素删除 1、根据元素值删除 2、根据元素位置删除 六、元素修改 七、元素查找 八、数组清空 九、数组销毁 十、验证程序 0、前…

C语言实现 动态数组 处理任意类型数据

引言&#xff1a;动态数组在C/C、Java、Python等语言中应用广泛&#xff0c;高级语言一般通过调用类或接口等可以快捷使用&#xff0c;C语言实现动态数组需要手动构造&#xff0c;以下为实现过程。 1 结构体构造动态数组 typedef struct Array {void **p; //维护在堆区…

C语言创建动态数组

C语言创建动态数组 1.编写步骤 1. 添加所需头文件 stdlib.h 该头文件下包含的与分配存储区相关的函数如下&#xff1a; void* malloc (size_t size);//从堆中分配size字节的存储空间 void* calloc (size_t num, size_t size);//分配数组并将数组零初始化。为 num 个元素的数…

在OpenCV里实现开运算

前面学习腐蚀和膨胀算法,并且深刻地认识到它们的特性以及作用。如果由这两种组合出来的运算又有什么样的不同呢?比如一个图像先腐蚀后膨胀的操作,会有什么结果呢?因为腐蚀是把图片白色变小,膨胀又是把图片白色变大,是否会保持原图不变呢?带着这些问题来研究一下先腐蚀后…

OpenCV python 形态学 圆形开运算

处理流程 # -*- coding: utf-8 -*- # note : 形态学 开运算 圆形内核 处理 # --------------------------------import cv2 as cv import numpy as npdef opening_circle(img_bin, kernel_size10):# 形态学kernel np.zeros((kernel_size, kernel_size), np.uint8)center_…

腐蚀、膨胀、开运算、闭运算

一、腐蚀、膨胀、开运算、闭运算 腐蚀&#xff1a;图像中的高亮部分进行膨胀 膨胀&#xff1a;原图中的高亮部分被腐蚀&#xff0c;类似于领域被蚕食 开运算&#xff1a;先腐蚀再膨胀&#xff0c;可以去掉目标外孤立的点 闭运算&#xff1a;先膨胀再腐蚀&#xff0c;可以去掉目…

【youcans 的 OpenCV 例程200篇】137. 灰度开运算和灰度闭运算原理

欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列&#xff0c;持续更新中 欢迎关注 『youcans 的 OpenCV学习课』 系列&#xff0c;持续更新中 【youcans 的 OpenCV 例程200篇】137. 灰度开运算和灰度闭运算 5. 灰度级形态学 灰度级形态学将形态学操作从二值图像扩展到灰度图…

开闭运算

开运算和闭运算是将腐蚀和膨胀按照一定的次序进行处理。但这两者并不是可逆的&#xff0c;即先开后闭并不能得到原来的图像。 开运算 开运算是先腐蚀后膨胀&#xff0c;其作用是&#xff1a;分离物体&#xff0c;消除小区域。特点&#xff1a;消除噪点&#xff0c;去除小的干扰…

图像的形态学开操作(开运算)和闭操作(闭运算)的概念和作用,并用OpenCV的函数morphologyEx()实现对图像的开闭操作

大家看这篇博文前可以先看一看下面这篇博文&#xff0c;下面这篇博文是这篇博文的基础&#xff1a; 详解图像形态学操作之图形的腐蚀和膨胀的概念和运算过程,并利用OpenCV的函数erode()和函数dilate()对图像进行腐蚀和膨胀操作 图像形态学腐蚀可以将细小的噪声区域去除&#x…

OpenCV-Python图像运算变换处理:开运算和闭运算以及不同核矩阵的影响分析

☞ ░ 前往老猿Python博客 https://blog.csdn.net/LaoYuanPython ░ 一、引言 在《OpenCV-Python图像处理&#xff1a;腐蚀和膨胀原理及erode、dilate函数介绍 https://blog.csdn.net/LaoYuanPython/article/details/109441709》等系列博文中老猿详细介绍了腐蚀和膨胀的原理、…

灰度级形态学 - 灰度开运算和灰度闭运算

目录 1. 介绍 2. code 1. 介绍 灰度级的开运算和闭运算和二值图像的处理一样&#xff0c;只不过一个作用于灰度图&#xff0c;一个作用于二值图像 灰度级的开运算公式为&#xff1a; 先对图像做腐蚀&#xff0c;然后对腐蚀的结果做膨胀运算 灰度级的闭运算公式为&#xff…

OpenCV(七)形态学操作2--开运算与闭运算

目录 概述&#xff1a; morphologyEX()函数 一、开运算&#xff08;分开&#xff09; 1、基础理论 1、作用&#xff1a; 2、代码 3、效果 二、闭运算&#xff08;封闭&#xff09; 1、基础理论 1、作用 2、过程 2、代码 3、效果 总代码 参考资料&#xff1a; 概述…

开运算—闭运算

转载&#xff1a;https://blog.csdn.net/hanshanbuleng/article/details/80657148 如果不了解腐蚀与膨胀原理的同学那请看我前一期博客哦&#xff01;&#xff09; 1.开运算 开运算 先腐蚀运算&#xff0c;再膨胀运算&#xff08;看上去把细微连在一起的两块目标分开了&…

Halcon形态学处理-腐蚀、膨胀、开运算、闭运算、顶帽运算和底帽运算

提示&#xff1a;文章参考了网络上其他作者的文章&#xff0c;以及相关书籍&#xff0c;如有侵权&#xff0c;请联系作者。 文章目录 前言一、腐蚀和膨胀1.腐蚀2.膨胀 二、开运算和闭运算1.开运算2.闭运算 三、顶帽运算和底帽运算1.顶帽运算2.底帽运算 总结参考文献 前言 图像的…

Opencv中的开运算和闭运算操作讲解(python实现)

文章目录 1.首先了解腐蚀和膨胀原理2.开运算&#xff08;1&#xff09;为什么开运算可以去白噪点呢&#xff1f;&#xff08;2&#xff09;.函数讲解&#xff08;3&#xff09;代码实战 3.闭运算&#xff08;1&#xff09;函数讲解&#xff08;2&#xff09;代码实战 1.首先了解…