【和春笋一起学C++】使用new创建动态数组

目录

1. 什么是动态数组

2. 怎么使用动态数组


1. 什么是动态数组

char name[20];

       上面这种方式创建的数组在程序编译时将为它分配内存空间,不管程序最终是否使用数组,数组都在那里,它占用了内存空间。在编译时给数组分配内存被称为静态联编,意味着数组是在编译时加入到程序中的。

但如果使用new创建数组,则不在编译阶段为数组分配内存空间,而是在运行阶段创建并分配内存空间。在运行阶段,如果用到了数组则创建,如果用不到数组则不创建,称为动态联编。数组在程序运行时创建,这种数组叫动态数组。如下:

char *name = new char[20]; 
...
...
delete [] name;

使用静态联编时,必须在编写程序时指定数组的长度,使用动态联编时,程序在运行时确定数组的长度。

语句delete [] name;表示释放动态数组,方括号告诉程序,应释放整个数组,而不仅仅是指针指向的元素。

使用new和delete时,应遵守以下规则:

  1. 不要使用delete来释放不是new分配的内存;
  2. 不要使用delete释放同一内存块两次;
  3. 释放动态数组的内存时,delete后面还要加上方括号;
  4. 使用new为一个实体分配内存,应使用delete释放,且delete后面没有方括号;
  5. 对空指针应用delete是安全的;

2. 怎么使用动态数组

int *psome = new int[10];

表示创建指针psome,它指向包含10个int值的内存块中的第一个元素。假设int占4个字节,将psome向后面移动4个字节,则psome将指向第2个元素。

访问第1个元素使用psome[0], 访问第2个元素使用psome[1]。在C和C++内部,数组和指针的处理原来是基本相同的,内部都是用指针来处理数组的。

借用一个小的实例来更好的说明:

#include <iostream>
#include <cstring>
using namespace std;

int main()
{
	double *p3 = new double[3];
	p3[0] = 0.2;
	p3[1] = 0.5;
	p3[2] = 0.8;
	p3 = p3 + 1;
	cout << (*p3) << endl;
	cout << (*p3 + 1) << endl;
	cout << *(p3 + 1) << endl;
	p3 = p3 - 1;
	delete[] p3;
	p3 = NULL;
	return 0;
}

请问上面的代码输出的值是多少?可以在自己电脑上跑一下。输出结果如下图:

下面开始逐条语句的分析输出结果。

首先在C++内部,C++将数组名解释为地址

程序第1行double *p3 = new double[3];定义了一个动态数组;

第2-4行分别对数组的几个元素赋值;

关键是第5行p3 = p3 + 1;这条语句中p3是一个地址,而且是指向数组第1个元素的地址,即p3[0]的地址,这没毛病,然后p3+1是什么意思呢,就是将p3的地址向后移动1个单位,将p3指向数组的第2个元素,这个单位是多少呢?如果p3是指向double类型的指针,这个单位是8个字节,如果是指向int类型的指针,则这个单位是2个字节。所以最后输出的值的是0.5。

第6行输出的值是1.5,这是因为在C++中解除引用操作符(*)的优先级高于算术运算符,程序先找到(*p3)的值,然后再加1;

而第7行,使用小括号强行使程序先计算p3+1的值,p3在第5行加1后已经指向了数组的第2个元素,现在再加1就指向了第3个元素,所以最后输出是0.8。

运算符"+"也能用于指针,称为指针算术,在C++内部,指针和数组基本等价的原因在于指针算术和C++内部处理数组的方式。

上面代码中,指针变量加1后,它增加的量等于它指向的数据类型占用的字节数。 

在C++内部对于数组的处理是这样的。对于表达式p3[1],C++编译器将该表达式看作是*(p3+1),这意味着先计算数组第二个元素的地址,然后找到存储在那里的值。同理,p3[2]和*(p3+2)是等价的。

不管是数组还是指针,C++内部处理的方式是基本一样的。

如果是数组,就进行如下转换:

arrayName[i] 转化为 *(arrayName+i)

如果是指针,就进行如下转换:

pointerName[i] 转换为 *(pointerName+i)

因此,在很多情况下,可以用相同的方式使用指针名和数组名,既可以使用数组的方括号表示法,也可以使用解除引用操作符(*),在多数表达式中,它们都表示地址。 但他们也有一些不同之处。其一,指针的值可以修改,但数组名是常量,其值不能修改。

char arrayName[20];
char *pointerName = new char[20];
arrayName = arrayName + 1;///错误,数组名是常量,其值不能改变
pointerName = pointerName + 1;///有效,指针变量的值可以改变
cout<<sizeof(arrayName)<<endl;
cout<<sizeof(pointerName)<<endl;

其二,对数组应用sizeof操作符得到的是数组的长度,而对指针应用sizeof操作符得到的是指针的长度,上面代码中输出的值分别是20和4(对指针应用sizeof操作符时输出的值要看你的编译器是32位还是64位的,如果是32位,指针的长度是4,如果是64位编译器,则长度是8)。在这种情况下,C++不会将数组名解释为地址。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/926203.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2-2-18-9 QNX系统架构之文件系统(一)

阅读前言 本文以QNX系统官方的文档英文原版资料为参考&#xff0c;翻译和逐句校对后&#xff0c;对QNX操作系统的相关概念进行了深度整理&#xff0c;旨在帮助想要了解QNX的读者及开发者可以快速阅读&#xff0c;而不必查看晦涩难懂的英文原文&#xff0c;这些文章将会作为一个…

ECharts柱状图-极坐标系下的堆叠柱状图,附视频讲解与代码下载

引言&#xff1a; 在数据可视化的世界里&#xff0c;ECharts凭借其丰富的图表类型和强大的配置能力&#xff0c;成为了众多开发者的首选。今天&#xff0c;我将带大家一起实现一个柱状图图表&#xff0c;通过该图表我们可以直观地展示和分析数据。此外&#xff0c;我还将提供…

Android复习简答题

一、基础入门 Android程序架构 &#xff08;1&#xff09;app:用于存放程序的代码和资源等内容。包含很多子目录 libs:存放第三方jar包 src/androidTest&#xff1a;存放调试的代码文件 src/main/androidMainfest.xml 整个程序的配置文件&#xff0c;可配置程序所需要的权…

PaddleOCR:一款高性能的OCR工具介绍

一、引言 随着人工智能技术的不断发展&#xff0c;光学字符识别&#xff08;OCR&#xff09;技术在各行各业得到了广泛应用。OCR技术能够将图片、扫描件等非结构化数据中的文字信息提取出来&#xff0c;转换为可编辑的文本格式。在我国&#xff0c;百度开源了一款优秀的OCR工具…

HTML5好看的音乐播放器多种风格(附源码)

文章目录 1.设计来源1.1 音乐播放器风格1效果1.2 音乐播放器风格2效果1.3 音乐播放器风格3效果1.4 音乐播放器风格4效果1.5 音乐播放器风格5效果 2.效果和源码2.1 动态效果2.2 源代码 源码下载万套模板&#xff0c;程序开发&#xff0c;在线开发&#xff0c;在线沟通 作者&…

11、数组

1、数组概念 数组就是存储多个相同数据类型的数据。 比如&#xff1a;存储26个字母&#xff0c;存储一个班级的学生成绩。 2、数组使用 数组要遵循先定义再使用 2.1、数组定义的格式 存储数据---空间 ---- 数据类型 多少个 --- 数据个数 >> 数据类型 数…

C底层 函数栈帧

文章目录 一&#xff0c;什么是寄存器 二&#xff0c;栈和帧 前言 我们在学习c语言程序的时候&#xff0c;是不是有很多的疑问&#xff0c;如 1&#xff0c;为什么形参不可以改变实参 2&#xff0c;为什么我们编写程序的时候会出现烫烫烫......这个乱码 3&#xff0c;那些局…

MATLAB期末复习笔记(二)

三、MATLAB函数和程序结构 1.MATLAB文件 两种类型的M文件&#xff1a; • 脚本 &#xff0c;不接受输入参数或返回输出参数。它们处理工作区中的数据。 • 函数 &#xff0c;可接受输入参数&#xff0c;并返回输出参数。内部变量是函数的局部变量。 ① 函数文件是另一类 m 文…

redis的应用----缓存

redis的应用----缓存 一、缓存的概念二、使用redis作为缓存2.1使用redis作为缓存的原因2.2缓存机制的访问步骤 三、缓存的更新策略3.1定期更新3.2实时更新3.3淘汰策略 四、缓存常见的问题4.1缓存预热(Cache preheating)4.2缓存穿透(Cache penetration)4.3缓存雪崩(Cache avalan…

2025年Java面试八股文大全

很多人会问Java面试八股文有必要背吗&#xff1f; 我的回答是&#xff1a;很有必要。你可以讨厌这模式&#xff0c;但你一定要去背&#xff0c;因为不背你就进不了大厂。 国内的互联网面试&#xff0c;恐怕是现存的、最接近科举考试的制度。 而且&#xff0c;我国的八股文确…

JiaJia-CP-1,2,3的WP(2)

一.JiaJia-CP-2 一看题目&#xff0c;聊天软件&#xff0c;用的什么聊天软件直接userassist看运行过什么程序 vol -f JiaJia_Co.raw --profileWin7SP1x64 userassist 发现Telegram.exe(小飞机) 可能性很大啊(真是个摸鱼大神) 除此之外&#xff0c;filescan也能看到&#xff0…

小F的矩阵值调整

问题描述 小F得到了一个矩阵。如果矩阵中某一个格子的值是偶数&#xff0c;则该值变为它的三倍&#xff1b;如果是奇数&#xff0c;则保持不变。小F想知道调整后的矩阵是什么样子的。 测试样例 样例1&#xff1a; 输入&#xff1a;a [[1, 2, 3], [4, 5, 6]] 输出&#xff1a…

Docker Buildx 与 CNB 多平台构建实践

一、Docker Buildx 功能介绍 docker buildx 是 Docker 提供的一个增强版构建工具&#xff0c;支持更强大的构建功能&#xff0c;特别是在构建多平台镜像和高效处理复杂 Docker 镜像方面。 1.1 主要功能 多平台构建支持 使用 docker buildx&#xff0c;可以在单台设备上构建…

uni-app 使用笔记

1.缓存用法 &#xff08;1&#xff09;uni-app 存值取值删除 官网&#xff1a;https://uniapp.dcloud.net.cn/api/storage/storage.html#setstorage 存值 uni.setStorageSync(storage_key, hello);取值 uni.getStorageSync(storage_key)删除 uni.removeStorageSync(storag…

Unity的GPU Instancing技术

首先新建一个场景&#xff0c;添加一个相机&#xff0c;并创建一个Render Texture给相机。 然后在相机上挂载以下脚本TestBatches &#xff0c;同时脚本的Inspector面板的Mesh中选择Cube&#xff0c;另外创建一个新的材质拖动给mat&#xff1a; public class TestBatches : M…

你真的会用饼图吗?JVS-智能BI饼图组件深度解析

在数据可视化的世界里&#xff0c;饼图是我们常见的一种可视化图形。在JVS-智能BI中提供了数据可视化饼图组件&#xff0c;接下来我通过这篇文章详细介绍&#xff0c;从配色方案到图形配置&#xff0c;从显示数据到提示信息&#xff0c;饼图的每一个细节配置。 饼图类图表概述…

IOS ARKit进行图像识别

先讲一下基础控涧&#xff0c;资源的话可以留言&#xff0c;抽空我把它传到GitHub上&#xff0c;这里没写收积分&#xff0c;竟然充值才能下载&#xff0c;我下载也要充值&#xff0c;牛&#xff01; ARSCNView 可以理解画布或者场景 1 配置 ARWorldTrackingConfiguration AR追…

golang debug调试

1. 本地调试 1&#xff1a;Add Configurations 添加配置文件&#xff08;Run kind &#xff1a;Directory&#xff09; 2&#xff1a;进入run运行窗口 3&#xff1a;debug断点调试模式 1. Resume Program (继续运行) 图标: ▶️ 或 ► 快捷键: F9&#xff08;Windows/Linux&a…

联想YOGA Pro 14s至尊版电脑找不到独立显卡(N卡)问题,也无法安装驱动的问题

问题描述 电脑是联想YOGA Pro 14s至尊版&#xff0c;电脑上装的独立显卡是4060&#xff0c;一直是能够使用独立显卡的。然而有两次突然就找不到显卡了&#xff0c;NVIDIA CONTROL PANEL也消失了&#xff0c;而且也无法安装驱动。具体表现如下&#xff1a; 无法连接外接显示器…

Python酷库之旅-第三方库Pandas(250)

目录 一、用法精讲 1181、pandas.tseries.offsets.BusinessMonthEnd.is_on_offset方法 1181-1、语法 1181-2、参数 1181-3、功能 1181-4、返回值 1181-5、说明 1181-6、用法 1181-6-1、数据准备 1181-6-2、代码示例 1181-6-3、结果输出 1182、pandas.tseries.offse…