二维数组及其指针基础
编程学习-二维字符串数组的初始化-动态内存分配
动态内存分配
1.堆内存分配 :
C/C++定义了4个内存区间:代码区,全局变量与静态变量区,局部变量区即栈区,动态存储区,即堆
(heap)区或自由存储区(free store)。
堆的概念:
通常定义变量(或对象),编译器在编译时都可以根据该变量(或对象)的类型知道所需内存空间的
大小,从而系统在适当的时候为他们分配确定的存储空间。这种内存分配称为静态存储分配;
有些操作对象只在程序运行时才能确定,这样编译时就无法为他们预定存储空间,只能在程序运
行时,系统根据运行时的要求进行内存分配,这种方法称为动态存储分配。所有动态存储分配都在堆
区中进行。
当程序运行到需要一个动态分配的变量或对象时,必须向系统申请取得堆中的一块所需大小的存贮空
间,用于存贮该变量或对象。当不再使用该变量或对象时,也就是它的生命结束时,要显式释放它所
占用的存贮空间,这样系统就能对该堆空间进行再次分配,做到重复使用有限的资源。
2.堆内存的分配与释放
堆空间申请、释放的方法:
在C++中,申请和释放堆中分配的存贮空间,分别使用new和delete的两个运算符来完成, 指针变量名
=new 类型名(初始化式); delete 指针名;
例如:1、 int *pi=new int(0);
它与下列代码序列大体等价:
2、int ival=0, *pi=&ival;
区别:pi所指向的变量是由库操作符new()分配的,位于程序的堆区中,并且该对象未命名。
堆空间申请、释放说明:
⑴.new运算符返回的是一个指向所分配类型变量(对象)的指针。对所创建的变量或对象,都是通过
该指针来间接操作的,而且动态创建的对象本身没有名字。
⑵.一般定义变量和对象时要用标识符命名,称命名对象,而动态的称无名对象(请注意与栈区中的临
时对象的区别,两者完全不同:生命期不同,操作方法不同,临时变量对程序员是透明的)。
⑶.堆区是不会在分配时做自动初始化的(包括清零),所以必须用初始化式(initializer)来显式初
始化。new表达式的操作序列如下:从堆区分配对象,然后用括号中的值初始化该对象。
3.堆空间申请、释放演示:
⑴.用初始化式(initializer)来显式初始化
int *pi=new int(0);
⑵.当pi生命周期结束时,必须释放pi所指向的目标:
delete pi;
注意这时释放了pi所指的目标的内存空间,也就是撤销了该目标,称动态内存释放(dynamic memory
deallocation),但指针pi本身并没有撤销,它自己仍然存在,该指针所占内存空间并未释放。
4. 在堆中建立动态一维数组
①申请数组空间:
指针变量名=new 类型名[下标表达式];
注意:“下标表达式”不是常量表达式,即它的值不必在编译时确定,可以在运行时确定。
②释放数组空间:
delete [ ]指向该数组的指针变量名;
注意:方括号非常重要的,如果delete语句中少了方括号,因编译器认为该指针是指向数组第一个元
素的,会产生回收不彻底的问题(只回收了第一个元素所占空间),加了方括号后就转化为指向数组
的指针,回收整个数组。delete [ ]的方括号中不需要填数组元素数,系统自知。即使写了,编译器
也忽略。
#include <iostream.h>
#include <string.h>
void main(){
int n;
char *pc;
cout<<"请输入动态数组的元素个数"<<endl;
cin>>n; //n在运行时确定,可输入17
pc=new char[n]; //申请17个字符(可装8个汉字和一个结束符)的内存空间
strcpy(pc,“堆内存的动态分配”);//
cout<<pc<<endl;
delete []pc;//释放pc所指向的n个字符的内存空间
return ; }
5. 动态一维数组的说明
① 变量n在编译时没有确定的值,而是在运行中输入,按运行时所需分配堆空间,这一点是动态分配
的优点,可克服数组“大开小用”的弊端,在表、排序与查找中的算法,若用动态数组,通用性更佳
。一定注意:delete []pc是将n个字符的空间释放,而用delete pc则只释放了一个字符的空间;
② 如果有一个char *pc1,令pc1=p,同样可用delete [] pc1来释放该空间。尽管C++不对数组作边
界检查,但在堆空间分配时,对数组分配空间大小是纪录在案的。
③ 没有初始化式(initializer),不可对数组初始化。
6.指针数组和数组指针
指针类型:
(1)int *ptr;//指针所指向的类型是int
(2)char *ptr;//指针所指向的的类型是char
(3)int **ptr;//指针所指向的的类型是int* (也就是一个int * 型指针)
(4)int (*ptr)[3];//指针所指向的的类型是int()[3] //二维指针的声明
指针数组:
一个数组里存放的都是同一个类型的指针,通常我们把他叫做指针数组。
比如 int * a[2];它里边放了2个int * 型变量 .(指针数组)
int * a[2];
a[0]= new int[3];
a[1]=new int[3];
delete a[0];
delete a[1];
注意这里 是一个数组,不能delete [] ;
数组指针:
一个指向一维或者多维数组的指针.
int * b=new int[10]; 指向一维数组的指针b ;
注意,这个时候释放空间一定要delete [] ,否则会造成内存泄露, b 就成为了空悬指针
int (*b2)[10]=new int[10][10]; 注意,这里的b2指向了一个二维int型数组的首地址.
注意:在这里,b2等效于二维数组名,但没有指出其边界,即最高维的元素数量,但是它的最低维数
的元素数量必须要指定!就像指向字符的指针,即等效一个字符串,不要把指向字符的指针说成指向
字符串的指针。
int(*b3) [30] [20]; //三级指针――>指向三维数组的指针;
int (*b2) [20]; //二级指针;――>指向二维数组的指针;
b3=new int [1] [20] [30];
b2=new int [30] [20];
删除这两个动态数组可用下式:
delete [] b3; //删除(释放)三维数组;
delete [] b2; //删除(释放)二维数组; 在堆中建立动态多维数组
new 类型名[下标表达式1] [下标表达式2]……;
例如:建立loat (*cp)[30][20] ; //指向一个30行20列数组的指针,指向二维数组的指针
cp=new float [15] [30] [20]; //建立由15个30*20数组组成的数组;
注意:cp等效于三维数组名,但没有指出其边界,即最高维的元素数量,就像指向字符的指针即等效
一个字符串,不要把指向字符的指针,说成指向字符串的指针。这与数组的嵌套定义相一致。
总结如下方法:
指针对应关系为
char *a[6]<=>char **a //在函数传递参数时候很容易出错
char a[5][6]<=>char (*a)[6]
int a[50][100];
int *p=&a[0][0];
a[i][j]<=>*(p+100*i+j);
或:
int (*p)[100];
p=a;
a[i][i]<=>*(*(p+i)+j);
char *a[10]; //指针数组
for (i=0;i<10;i++)
a[i]=new char[10];
for(i=0;i<10;i++)
delete [] a[i];
#include <iostream.h>
#include <stdlib.h>
int main()
{
int (*p)[3];
p= new int [2][3];
int i,j;
for(i=0;i<2;i++)
for(j=0;j<3;j++)
p[i][j]=rand()%100;
for(i=0;i<2;i++)
{
cout<<endl;
for(j=0;j<3;j++)
cout<<p[i][j]<<ends;
}
delete [] p;
return 0;
}
#include<iostream.h>
#include<stdlib.h>
int main()
{
char **a; //或者用上面的指针数组的方法也可以
a=new char *[2];
for(int i=0;i<2;i++)
a[i]=new char [10];
for(i=0;i<2;i++)
cin.getline(a[i],9);
for(i=0;i<2;i++)
cout<<a[i]<<endl;
for(i=0;i<2;i++)
delete [] a[i];
delete [] a; //不要忘了
a=NULL;
return 0;
}
二维数组及其指针基础相关推荐
- C++ 二维数组和指针数组
C++ 二维数组和指针数组 开发工具与关键技术:C++.VisualStudio 作者:何任贤 撰写时间:2019年04月10日 二维数组大家都很清楚,就是该数组包含的元素是一个数组,那么和指针数组又 ...
- c++17(26)-数组、二维数组的指针、指向数组的指针、指向数组的指针的指针
#include <iostream> #include <string.h> using namespace std;void setC1(int a[],int size) ...
- c++如何打印一维数组首地址_C语言之二维数组和指针的结合
最近在练习 C 语言计算机二级的程序设计题,碰到了二维数组和指针的结合,当时怎么调试都不对,自己也记不清楚该怎么用了就跑去看书翻资料重新复习.自己纠结的问题是二维数组 int a[3][4]的数组名是 ...
- c语言二维数组 ppt,C语言二维数组与指针.ppt
C语言二维数组与指针.ppt 好好考,全国计算机等级考试 二级C语言,第12讲 二维数组与指针,二维数组的定义 数组元素的引用及初始化 二维数组和指针 二维数组名和指针数组作为实参 二维数组程序举例 ...
- C语言-二维数组与指针
目录 1 指针和二维数组 2 二维数组做函数的参数 2.1 方法一 2.2 方法二 2.3 方法三 1 指针和二维数组 #include <stdio.h>int main() {int ...
- C语言二维数组的指针写法
C语言中二维数组要用Int** 来表示,在分配空间后,int**加一会移动到下一行.而m行n列的二维数组的寻址方式是首地址a+in+j,因此先对a+i找到相应的行,也就是一维数组,并且取得到一个int ...
- C语言高级编程:二维数组、指针的指针、数组指针、指针数组
1. 定义 int **p; 指针的指针 int (*p2)[5]; 数组指针,指向一个数组 int *array[5]; 指针数组,是一个int *类型数组 int array2[3][5]; ...
- 指向二维数组的指针测试
定义a为二维数组后,有三种成份:数组本身.3个一维数组(a的每一行对应一个一维数组).12个数组元素, 由此就有三种指针及对应的指针变量, &a和int (*p1)[3][4](没有实用意义) ...
- 二级指针、数组指针、二维数组、指针数组作为函数形参时可传入的实参
1.传参规则: a.当二级指针作为函数形参时,能作为函数实参的是二级指针,指针数组,一级指针的地址 b.当数组指针作为函数形参时,能作为函数实参的是二维数组,数组指针 c.当二维数组作为函数形参时,能 ...
最新文章
- VirtualBox下安装RHEL5.5+Oracle 11g手记
- android源码出现的@字符意义总结
- 前端浏览器兼容知识点整理
- [scrum]2011/9/24-----第四天
- 将网址url中的参数转化为JSON格式的两种方法
- LeetCode 208. Implement Trie (Prefix Tree)
- mysql 5.6.23 免安装_MYSQL 免安装版的环境配置
- CPU,内存, 硬盘,指令之间的关系
- lisp 设计盘形齿轮铣刀_钨钢铣刀制造厂
- Linux 系统性能分析工具图解读
- B站又出事了,遭几大平台联合谴责
- sublime插件CSS转rem配置
- vsftp乱码问题解决
- android 电源管理 和 Doze 模式
- Linux 克隆虚拟机以及克隆之后引起的“Device eth0 does not seem to be present, delaying initialization”问题解决...
- python中利用ARIMA模型对时间序列问题进行预测(以洗发水销售预测为例)
- kafka中的消息(topic)和日志(log)
- TestCenter测试管理工具功能详解一(F)
- QQ空间g_tk、bkn加密参数算法
- Linux WiFi使用
热门文章
- 模糊数学笔记:七、模糊综合评判决策
- 机器人视觉——使用numpy进行像素的处理 || 获取图像的属性 || 感兴趣区域ROI || 通道的拆分与合并
- pageX,clientX,offsetX,layerX的区别
- Spring-data-redis 反序列化异常
- Java 技术篇 - ServerSocket接收http的url请求中包含中文的处理方法,URLDecode与URLEncode,url解码与编码
- CTFshow php特性 web123
- CTFshow 命令执行 web33
- windows的键盘输入重定向
- linux硬件设备操作函数 open
- Python爬虫,通过特定的函数来筛选标签