突破编程_C++_面试(数组(1))
面试题1:详细说明一下数组名是什么?
在 C++ 中,数组名代表数组首元素的地址。更具体地说,数组名是一个指向数组第一个元素的常量指针。这意味着,当使用数组名时,实际上是在使用指向数组第一个元素的指针。
例如,如果你有一个整数数组 int vals[5]; ,那么 vals 就是一个指向 int 类型的指针,它指向 vals[0] 的地址。因此, vals 和 &vals[0] 是等价的。
虽然数组名可以像指针一样使用,但它并不是真正的指针。它不能被重新赋值指向数组的其他位置,也不能被递增或递减。尝试这样做会导致编译错误。
这里有一些重要的点需要注意:
(1)数组名不是指针:尽管数组名可以像指针一样使用,但它本身不是一个指针变量。数组名是一个常量表达式,它不能被修改。
(2)数组名转换为指针:当数组名作为函数参数传递时,或者当它被用在需要指针的上下文中时,它会被隐式地转换为指向数组第一个元素的指针。
(3)数组名和指针的不同:可以改变一个指针变量的值让它指向不同的内存位置,但不能改变数组名让它指向数组中的其他元素或不同的数组。
下面是一个简单的示例,展示了数组名如何被用作指针:
#include <iostream>int main()
{int vals[5] = { 1, 2, 3, 4, 5 };// 使用数组名作为指针int* ptr = vals; // ptr 指向 vals[0] 的地址// 输出数组的第一个元素std::cout << "vals[0] = " << *vals << std::endl; // 输出 1std::cout << "ptr[0] = " << *ptr << std::endl; // 输出 1std::cout << "vals == &vals[0] = " << (vals == &vals[0]) << std::endl; // 输出 1(true)// 数组名不能被修改// vals = &vals[1]; // 这是非法的,会导致编译错误return 0;
}
在上面代码中,vals、 &vals[0] 和 ptr 都指向相同的内存地址,即数组的第一个元素的地址。然而,只有 ptr 可以被重新赋值指向其他位置,而 vals 则始终保持不变,指向数组的第一个元素。
面试题2:数组是一块连续的内存么?
是的, C++ 中的数组是一块连续的内存区域。当声明一个数组时, C++ 会在内存中为数组分配一块连续的空间,这块空间的大小是数组元素类型的大小乘以数组的大小(元素个数)。
数组元素在内存中是紧密排列的,这意味着每个元素都紧挨着前一个元素存储。这种连续的内存布局有几个重要的特点:
高效访问
由于数组元素是连续存储的,所以可以通过简单的偏移量快速访问任何元素。例如,如果有一个整数数组 int vals[10]; ,那么 vals[2] 就是 vals[0] 之后的第 2 个整数,可以直接通过 vals + 2 或者 &vals[0] + 2 * sizeof(int) 来访问。
快速遍历
连续的内存布局使得遍历数组变得非常高效。可以使用指针或迭代器轻松地遍历数组的所有元素。
空间局部性
由于数组元素是连续存储的,它们通常会被加载到缓存中,这有助于减少 CPU 访问内存的次数,从而提高程序的性能。
限制
数组的大小在编译时确定,并且一旦分配了内存,就不能改变数组的大小。这种连续内存分配方式要求数组的大小是固定的。
自动管理
在 C++ 中,当你声明一个局部变量数组时,数组的内存会在进入作用域时自动分配,并在离开作用域时自动释放。这种自动内存管理可以避免内存泄漏和其他与手动内存管理相关的问题。
需要注意的是,如果动态地分配数组(例如使用 new 关键字),那么你需要自己负责在不再需要数组时释放内存(使用 delete[] )。否则,可能会导致内存泄漏。
面试题3:多维数组如何声明和初始化?
在 C++ 中,多维数组可以通过在数组类型后面跟随多个方括号和大小来声明。多维数组的初始化可以通过在声明时提供初始化列表来完成,其中每个内部列表对应数组的一个维度。
下面是一个二维数组(也称为矩阵)的声明和初始化的例子:
// 声明一个3x3的二维数组
int matrix[3][3];// 初始化一个3x3的二维数组
int matrix[3][3] =
{{1, 2, 3},{4, 5, 6},{7, 8, 9}
};
在这个例子中, matrix 是一个 3x3 的整数数组,每个元素都被初始化为 0 (如果没有显式初始化)。初始化列表为数组的每个元素提供了具体的值。
对于更高维度的数组,可以继续添加更多的方括号和大小。例如,一个三维数组可以这样声明和初始化:
// 声明一个2x3x4的三维数组
int cube[2][3][4];// 初始化一个2x3x4的三维数组
int cube[2][3][4] =
{{{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12}},{{13, 14, 15, 16},{17, 18, 19, 20},{21, 22, 23, 24}}
};
在多维数组的初始化中,可以省略内部维度的大小,让编译器自动计算它们。但是,第一个维度的大小必须明确指定。例如:
// 声明并初始化一个3x自动计算大小的二维数组
int arr[3][] =
{{1, 2, 3},{4, 5, 6},{7, 8, 9}
};// 编译器会自动计算内部维度的大小,这里是3
面试题4:如何比较两个数组是否相等?
在C++中,比较两个数组是否相等通常涉及检查两个数组的每个元素是否都相同。这可以通过编写一个函数或使用标准库算法来完成。以下是几种比较两个数组是否相等的方法:
方法1:使用循环遍历数组
可以通过编写一个函数来遍历两个数组,并逐个比较它们的元素。
#include <iostream>bool isArraysEqual(const int* arr1, const int* arr2, size_t size)
{for (size_t i = 0; i < size; ++i) {if (arr1[i] != arr2[i]) {return false;}}return true;
}int main()
{int arr1[3] = {1, 2, 3};int arr2[3] = {1, 2, 3};bool equalFlag = isArraysEqual(arr1, arr2, 3);return 0;
}
方法2:使用 std::equal 算法
C++标准库提供了 std::equal 算法,它可以比较两个范围是否相等。要使用它,需要包含 <algorithm> 头文件,并确保数组是 C 风格的数组或者是可以通过迭代器访问的容器(如 std::vector )。
#include <iostream>
#include <algorithm>int main()
{int arr1[3] = {1, 2, 3};int arr2[3] = {1, 2, 3};bool equalFlag = std::equal(std::begin(arr1), std::end(arr1), std::begin(arr2));return 0;
}
在这个例子中, std::begin 和 std::end 分别用于获取数组的开始和结束迭代器。如果两个数组相等, std::equal 将返回 true ;否则返回 false 。
注意事项
(1)当使用 std::equal 时,确保两个数组的大小相同,否则比较可能会产生未定义的行为。
(2)如果数组中的元素是对象而不是基本类型,可能需要自定义比较函数或操作符来比较对象。
(3)上述示例中的数组大小是硬编码的。在实际应用中,你可能需要传递数组的大小作为参数,或者使用容器(如 std::vector )来动态管理数组的大小。
(4)如果数组元素是基本类型,且数组大小已知,可以直接使用 memcmp 函数进行比较,但这通常只适用于 C 风格的数组。
面试题5:数组和指针有什么区别?
数组和指针的区别如下:
定义和存储
数组是一个用于存储多个相同类型数据的有序集合,它在内存中占据一块连续的空间。数组的大小在编译时确定,并且在整个生命周期内保持不变。而指针是一个变量,它存储的是另一个变量在内存中的地址。指针可以随时指向任意内存地址,因此它的特征是可变。
赋值和访问
数组的元素赋值或拷贝需要逐个进行。例如, arr[0] = value; 将会把 value 赋值给数组 arr 的第一个元素。而指针变量可以相互赋值,如 ptr1 = ptr2; 。在访问数据时,数组名使用下标来引用元素,如 arr[i] 。指针则需要通过解引用操作符 * 来访问它所指向的值,如 *ptr 。
表示范围
数组的有效范围就是其空间的范围,数组名使用下标引用元素,不能指向别的数组。指针可以指向任何地址,但是不能随意访问,必须依附在变量的有效范围之内。
内存大小
数组所占的存储空间大小可以通过 sizeof(数组名) 得到,而数组的大小(即元素个数)可以通过 sizeof(数组名) / sizeof(数据类型) 计算。指针的大小则是由指针类型决定的,例如,在 32 位系统中,指针的大小通常为 4 字节;在 64 位系统中,指针的大小通常为8字节。
函数参数传递
当数组作为函数的参数进行传递时,数组将自动退化为同类型的指针。因此,传入数组做参数时一般需要将其长度也作为参数传入,因为函数内部无法直接获取数组的长度。
相关文章:
突破编程_C++_面试(数组(1))
面试题1:详细说明一下数组名是什么? 在 C 中,数组名代表数组首元素的地址。更具体地说,数组名是一个指向数组第一个元素的常量指针。这意味着,当使用数组名时,实际上是在使用指向数组第一个元素的指针。 例…...
基于springboot+vue的靓车汽车销售网站(前后端分离)
博主主页:猫头鹰源码 博主简介:Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战,欢迎高校老师\讲师\同行交流合作 主要内容:毕业设计(Javaweb项目|小程序|Pyt…...
【知识整理】Git Commit Message 规范
一. 概述 前面咱们整理过 Code Review 一文,提到了 Review 的重要性,已经同过gitlab进行CodeReview 的方式,那么本文详细说明一下对CodeReivew非常重要的Git Commit Message 规范。 我们在每次提交代码时,都需要编写 Commit Mes…...
HarmonyOS学习--三方库
文章目录 一、三方库获取二、常用的三方库1. UI库:2. 网络库:3. 动画库: 三、使用开源三方库1. 安装与卸载2. 使用 四、问题解决1. zsh: command not found: ohpm 一、三方库获取 在Gitee网站中获取 搜索OpenHarmony-TPC仓库,在t…...
【服务器数据恢复】FreeNAS+ESXi虚拟机数据恢复案例
服务器数据恢复环境: 一台服务器通过FreeNAS(本案例使用的是UFS2文件系统)实现iSCSI存储,整个UFS2文件系统作为一个文件挂载到ESXi虚拟化系统(安装在另外2台服务器上)上。该虚拟化系统一共有5台虚拟机&…...
【GPT-2】论文解读:Language Models are Unsupervised Multitask Learners
文章目录 介绍zero-shot learning 零样本学习 方法数据Input Representation 结果 论文:Language Models are Unsupervised Multitask Learners 作者:Alec Radford, Jeff Wu, Rewon Child, D. Luan, Dario Amodei, I. Sutskever 时间:2019 介…...
基于机器学习、遥感和Penman-Monteith方程的农田蒸散发混合模型研究_刘燕_2022
基于机器学习、遥感和Penman-Monteith方程的农田蒸散发混合模型研究_刘燕_2022 摘要关键词 1 绪论2 数据与方法2.1 数据2.2 机器学习算法2.3 Penman-Monteith方程2.4 Medlyn公式2.5 模型性能评估 3 基于机器学习算法的混合模型估算农田蒸散量的评价与比较4 利用人工神经网络算法…...
博客 cn 站搭建 v3 v3.1
1. 架构设计 v3.1 版本 2. v2.x 存在的痛点 在v2.x版本中,围绕 服务器 遇到了两个主要的问题: 服务器成本高:博客以静态页面为主,理论上可以实现无服务器部署,但是为了防止恶意攻击,不得不使用服务器进…...
2024全国水科技大会暨流域水环境治理与水生态修复论坛(六)
论坛召集人 冯慧娟 中国环境科学研究院流域中心研究员 刘 春 河北科技大学环境与工程学院院长、教授 一、会议背景 为深入贯彻“山水林田湖是一个生命共同体”的重要指示精神,大力实施生态优先绿色发展战略,积极践行人、水、自然和谐共生理念&…...
Python实战:读取MATLAB文件数据(.mat文件)
Python实战:读取MATLAB文件数据(.mat文件) 🌈 个人主页:高斯小哥 🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程 👈 希望得到您的订阅…...
spring boot3登录开发-3(账密登录逻辑实现)
⛰️个人主页: 蒾酒 🔥系列专栏:《spring boot实战》 🌊山高路远,行路漫漫,终有归途。 目录 前置条件 内容简介 用户登录逻辑实现 创建交互对象 1.创建用户登录DTO 2.创建用户登录VO 创建自定义登录业务异…...
Django后端开发——ORM
文章目录 参考资料ORM-基础字段及选项字段类型练习——添加模型类应用bookstore下的models.py数据库迁移——同步至mysqlmysql中查看效果字段选项Meta类定义示例:改表名应用bookstore下的models.py终端效果练习——改表名+字段选项修改应用bookstore下的models.py终端效果ORM基…...
AI模型训练的初步整理
明天会有人来给我们讲AI方面的课,我也一直想整理一下这方面的知识,今天也趁着这个机会做一下功课,算是预习。 首先,AI的模型训练可以分为: 增量学习(Incremental Learning) 增量学习允许模型在…...
【Java从入门到精通】Java Number Math 类
Java Number & Math 类 一般地,当需要使用数字的时候,我们通常使用内置数据类型,如:byte、int、long、double 等。 实例 int a 5000; float b 13.65f; byte c 0x4a; 然而,在实际开发过程中,我们…...
SQL字符集
目标:了解字符集的概念,掌握MySQL数据库存储数据的字符集逻辑以及设置方式 字符集概念 MySQL字符集关系 解决乱码问题 字符集设置原理 1、字符集概念 目标:了解字符集概念,掌握字符集存储和读取的实现原理 概念 字符集:charset或者character set&am…...
openssl 生成nginx自签名的证书
1、命令介绍 openssl req命令主要的功能有,生成证书请求文件, 查看验证证书请求文件,还有就是生成自签名证书。 主要参数 主要命令选项: -new :说明生成证书请求文件 -x509 :说明生成自签名证书 -key :指定已…...
adb push 使用
adb push命令用于将文件从本地计算机推送到Android设备。要使用adb push命令,需要先连接Android设备并启动ADB调试模式。以下是使用adb push命令的基本步骤: 打开终端(命令提示符)。 使用cd命令导航到存储要推送文件的文件夹。 …...
【Docker】构建pytest-playwright镜像并验证
Dockerfile FROM ubuntu LABEL maintainer "langhuang521l63.com" ENV TZAsia/Shanghai #设置时区 #安装python3依赖与下载安装包 RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone \&& apt update \&&…...
算法沉淀——穷举、暴搜、深搜、回溯、剪枝综合练习四(leetcode真题剖析)
算法沉淀——穷举、暴搜、深搜、回溯、剪枝综合练习四 01.解数独02.单词搜索03.黄金矿工04.不同路径 III 01.解数独 题目链接:https://leetcode.cn/problems/sudoku-solver/ 编写一个程序,通过填充空格来解决数独问题。 数独的解法需 遵循如下规则&am…...
如何在java中使用 Excel 动态函数生成依赖列表
前言 在Excel 中,依赖列表或级联下拉列表表示两个或多个列表,其中一个列表的项根据另一个列表而变化。依赖列表通常用于Excel的业务报告,例如学术记分卡中的【班级-学生】列表、区域销售报告中的【区域-国家/地区】列表、人口仪表板中的【年…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...
