当前位置: 首页 > news >正文

突破编程_C++_面试(基础知识(13))

面试题45:C++中的字符串如何存储

在C++中,字符串可以通过多种方式存储,但最常见和推荐使用的方式是通过 std::string 类,该类位于 <string> 头文件中。std::string 是一个类模板的实例,通常用于存储字符数组,特别是char类型的数组。
std::string 内部使用动态分配的内存来存储字符数据,这样可以灵活地处理不同长度的字符串。这种动态分配的内存管理使得 std::string 能够自动处理字符串的创建、复制、赋值、拼接和销毁,而无需手动管理内存。
std::string的内部结构包含以下几个部分:
(1)字符数组:存储实际的字符数据,包括字符串的字符内容。
(2)长度信息:通常是一个整数,记录字符串中字符的数量(不包括终止字符’\0’)。
(3)容量信息:指示已分配内存的大小,这通常大于或等于字符串的实际长度,以便在添加更多字符时不需要频繁重新分配内存。
当创建一个 std::string 对象时,它会根据需要自动分配足够的内存来存储字符串。例如:

std::string str = "abc123";

在这个例子中, str 是一个 std::string 对象,它包含字符串 “abc123” 。str 内部会自动分配足够的内存来存储这 7 个字符(包括结束字符’\0’),以及使用成员变量存储的字符串信息(如长度和容量)。
使用 std::string 的好处之一是它自动处理内存管理,减少了内存管理错误(如内存泄漏或越界访问)的风险。此外,std::string 还提供了丰富的成员函数,用于执行常见的字符串操作,如拼接、查找、替换等。
除了 std::string ,C++还提供了 std::wstring 用于存储宽字符( wchar_t 类型)的字符串,可以用于处于多种字符集(如 utf-8 、 gb2312 等)。

面试题46:std::string 如何管理内存

std::string 在 C++ 中管理内存的方式是通过其内部实现的自动内存管理机制。这通常涉及到动态内存分配和释放,以及对内存使用的优化。以下是 std::string 如何管理内存的一些关键点:
(1)动态内存分配:当创建 std::string 对象或向现有字符串添加内容时,如果需要更多空间来存储字符, std::string 会动态地分配内存。这通常涉及到调用 new (或相应的内存分配函数)来分配足够大小的内存块。
(2)内存增长策略:当 std::string 需要扩展其内部缓冲区以容纳更多字符时,它通常会分配比当前需要更大的内存块。这是为了减少频繁的内存重新分配和复制操作,从而提高性能。这种策略称为内存预留( memory reservation )。
(3)内存释放:当 std::string 对象被销毁或缩小其大小时,它会释放不再需要的内存。这通常是通过调用 delete[](或相应的内存释放函数)来完成的。然而,值得注意的是,std::string通常不会立即释放所有内存回到系统,而是保留一些内存以便将来使用,这被称为内存池( memory pooling )。
(4)字符串拷贝和赋值:当 std::string 对象被拷贝或赋值时, std::string 会创建一个新的内存块来存储字符串内容,而不是共享内存。这是为了避免对原始字符串的修改影响到副本。
(5)内存效率: std::string 的设计通常旨在提供合理的内存使用效率。例如,当缩小字符串大小时,std::string 可能不会立即释放所有额外内存,而是保留一部分以便未来增长。这减少了频繁的内存分配和释放操作,从而提高了性能。
(6)异常安全性: std::string 的内存管理实现通常是异常安全的,这意味着即使在内存分配失败的情况下,它也不会导致程序崩溃或数据损坏。
(7)RAII原则: std::string 遵循资源获取即初始化( Resource Acquisition Is Initialization , RAII )原则,这意味着其内存管理与其生命周期紧密相关。当std::string对象超出其作用域或被销毁时,其内存也会被自动释放。
总的来说,std::string通过动态内存分配、内存增长策略、内存释放和其他优化技术来管理其内存。这使得 std::string 成为处理字符串时高效且安全的选择。

面试题47:如何处理大量的字符串拼接操作

如果处理大量的字符串拼接操作,或者每次拼接的字符串都非常大,那么性能可能会成为一个问题。在这种情况下,可以考虑以下优化策略:
使用 std::stringstream :
std::stringstream 允许像使用流一样的方式拼接字符串。它内部使用优化过的缓冲区来存储字符串,从而减少内存分配和复制的次数。

std::stringstream ss;  
ss << "abc" << "123" << "def" << std::endl;  
std::string str = ss.str();

预先分配内存:
如果知道最终字符串的大致大小,可以使用 std::string 的 reserve 成员函数预先分配足够的内存。这可以避免在拼接过程中频繁地重新分配内存。
注意拼接需要使用 append() 方法,使用该方法时,字符串的拼接是在现有 std::string 对象的内存块中进行的,这意味着不需要分配新的内存块来存储结果。因此,在需要频繁拼接字符串的情况下,使用 append() 函数通常比使用 + 运算符更高效。

std::string result;  
result.reserve(estimated_final_size);  
// 然后使用 append() 进行拼接操作

避免小字符串拼接:
如果需要拼接大量的小字符串,可以考虑将它们先存储在一个容器中(如std::vectorstd::string),然后再一次性拼接起来。这样可以减少内存分配和复制的次数。
自定义字符串处理:
对于特定的应用场景,可以考虑实现自定义的字符串处理函数,例如使用特定的算法或数据结构来优化拼接操作。

面试题48:描述 std::string 与其他类型的相互转换

std::string 可以与其他数据类型进行相互转换。以下是一些常见的转换示例:
转换为整数类型
使用 std::stoi、std::stol、std::stoul 等函数可以将 std::string 转换为整数类型(如 int、long、unsigned long 等)。如下为样例代码:

std::string str = "12345";  
int val = std::stoi(str); // 将字符串转换为整数

如果字符串不能被解析为有效的整数,std::stoi 等函数将抛出 std::invalid_argument 异常,或者如果转换结果超出了目标类型的表示范围,将抛出 std::out_of_range 异常。
转换为浮点数类型
使用 std::stof、std::stod 等函数可以将 std::string 转换为浮点数类型(如 float、double)。如下为样例代码:

std::string str = "3.14159";  
float val1 = std::stof(str); // 将字符串转换为单精度浮点数
double val2 = std::stod(str); // 将字符串转换为双精度浮点数

同样,如果字符串不能被解析为有效的浮点数,这些函数将抛出异常。
从整数或浮点数转换为 std::string
使用 std::to_string 函数可以将整数或浮点数转换为 std::string 。如下为样例代码:

int val1 = 12345;  
std::string str1 = std::to_string(val1); // 将整数转换为字符串  double val2 = 3.14159;  
std::string str2 = std::to_string(val2); // 将双精度浮点数转换为字符串

从 std::string 转换为字符数组(C字符串)
使用 c_str() 方法可以将 std::string 转换为字符数组(C字符串)。如下为样例代码:

std::string str = "abc123";  
const char* chStr = str.c_str(); // 获取指向字符串内容的指针

注意:c_str() 返回的是一个指向 std::string 内部数据的常量指针,该数据在 std::string 对象生命周期内有效。如果需要在 std::string 对象之外保留这个字符串,则需要使用 memcpy 做字符串复制。
从字符数组(C字符串)转换为 std::string
可以直接将C风格的字符串(字符数组)赋值给 std::string。如下为样例代码:

const char* chStr = "abc123";  
std::string str(chStr); // 使用C字符串初始化 std::string
std::string str2;  
str2.assign(chStr); // 也可以使用 assign() 方法

面试题49:std::string 的 swap 方法为什么比传统的字符串交换更快

std::string 的 swap 成员函数比传统的字符串交换更快,主要原因是它通常只交换两个字符串对象的内部指针,而不是实际复制字符串内容。这种操作通常被称为无开销交换或无拷贝交换。
传统的字符串交换通常涉及以下步骤:
(1)分配足够的内存来存储其中一个字符串的内容。
(2)将第一个字符串的内容复制到新分配的内存中。
(3)释放第一个字符串原本占用的内存。
(4)将第二个字符串的内容复制到第一个字符串原本占用的内存中。
(5)释放第二个字符串原本占用的内存。
(6)将新分配的内存地址赋给第二个字符串。
这个过程涉及多次内存分配和释放,以及字符串内容的复制,因此效率较低。
相比之下,std::string 的 swap 成员函数只是交换了两个字符串对象内部的指针,不涉及任何内存分配、释放或内容复制。这种操作的开销非常小,因此通常比传统的字符串交换更快。

面试题50:编程实例题:替换所有子字符串(replace() 方法)

std::string 类没有内置的直接替换所有子字符串的方法。可以在一个循环中多次调用 find() 和 replace() 方法,直到 find () 方法返回 std::string::npos ,表示没有更多的匹配项。如下为实现代码:

#include <iostream>  
#include <string>  void replaceAll(std::string& str, const std::string& strFrom, const std::string& strTo) 
{size_t pos = 0;while ((pos = str.find(strFrom, pos)) != std::string::npos){str.replace(pos, strFrom.length(), strTo);pos += strTo.length(); // 更新搜索起始位置  }
}int main() 
{std::string str = "abcdefabcdef";replaceAll(str, "abc", "123");// str 现在为 "123def123def"  return 0;
}

面试题51:编程实例题:分割子字符串(split() 方法)

std::string 没有内置的 split 方法来分割字符串。可以使用 std::istringstream 以及 std::getline 函数来分割字符串。如下为实现代码:

#include <iostream>  
#include <sstream>  
#include <vector>  
#include <string>  std::vector<std::string> split(const std::string& str, char delimiter) 
{std::vector<std::string> tokens;std::istringstream tokenStream(str);std::string token;while (std::getline(tokenStream, token, delimiter)) {tokens.push_back(token);}return tokens;
}int main() {std::string str = "abc,123,def";char delimiter = ',';std::vector<std::string> tokens = split(str, delimiter);// tokens 现在为 {"abc","123","def"}return 0;
}

相关文章:

突破编程_C++_面试(基础知识(13))

面试题45&#xff1a;C中的字符串如何存储 在C中&#xff0c;字符串可以通过多种方式存储&#xff0c;但最常见和推荐使用的方式是通过 std::string 类&#xff0c;该类位于 <string> 头文件中。std::string 是一个类模板的实例&#xff0c;通常用于存储字符数组&#x…...

掌握C语言文件操作:从入门到精通的完整指南!

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C语言学习 贝蒂的主页&#xff1a;Betty‘s blog 1. 什么是文件 文件其实是指一组相关数据的有序集合。这个数据集有一个名称&a…...

JavaEE作业-实验二

目录 1 实验内容 2 实验要求 3 思路 4 核心代码 5 实验结果 1 实验内容 实现两个整数求和的WEB程序 2 实验要求 ①采用SpringMVC框架实现 ②数据传送到WEB界面采用JSON方式 3 思路 ①创建一个SpringMVC项目&#xff0c;配置好相关的依赖和配置文件。 ②创建一个Con…...

2月8号作业

Sqlite3系统命令 .quit 退出数据库 .exit 退出数据库 .help 显示帮助信息&#xff0c;获取所有系统命令 .table 查看当前数据库下的所有表格 .schema 查看表的结构 Sqlite3语句 创建表格&#xff1a; create table 表名 (字段名 数据类型, 字段名 数据类型); create table if…...

08:K8S资源对象管理|服务与负载均衡|Ingress

K8S资源对象管理&#xff5c;服务与负载均衡&#xff5c;Ingress DaemonSet控制器污点策略容忍容忍污点 其他资源对象Job资源对象 有限生命周期CronJob资源对象 集群服务服务自动发现headless服务 实现服务定位与查找 服务类型 Ingress插件 发布服务的方式 DaemonSet控制器 Da…...

HarmonyOS 横屏调试与真机横屏运行

我们有些程序 需要横屏才能执行出效果 我们在预览器上 点击如下图指向出 就进入一个横屏调试了 但 我们真机运行 依旧是竖着的 我们如下图 找到 module.json5 在 abilities 下面 第一个对象 最下面 加上 "orientation": "landscape"然后 我们再真机运…...

Javaweb基础-tomcat,servlet

一.配置文件基础&#xff1a; properties配置文件&#xff1a; 由键值对组成 键和值之间的符号是等号 每一行都必须顶格写&#xff0c;前面不能有空格之类的其他符号 xml配置文件&#xff1a;&#xff08;xml语法HTML语法HTML约束&#xff09;xml约束-DTD / Schema DOM4…...

HCIA-HarmonyOS设备开发认证V2.0-3.2.轻量系统内核基础-中断管理

目录 一、中断基础概念二、中断管理使用说明三、中断管理模块接口四、代码分析&#xff08;待续...&#xff09;坚持就有收获 一、中断基础概念 在程序运行过程中&#xff0c;出现需要由 CPU 立即处理的事务时&#xff0c;CPU 暂时中止当前程序的执行转而处理这个事务&#xf…...

【开源】JAVA+Vue+SpringBoot实现就医保险管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 科室档案模块2.2 医生档案模块2.3 预约挂号模块2.4 我的挂号模块 三、系统展示四、核心代码4.1 用户查询全部医生4.2 新增医生4.3 查询科室4.4 新增号源4.5 预约号源 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVue…...

Stable Diffusion 模型下载:DreamShaper XL(梦想塑造者 XL)

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十 下载地址 模型介绍 DreamShaper 是一个分格多样的大模型&#xff0c;可以生成写实、原画、2.5D 等…...

【机器学习】数据清洗之处理异常点

&#x1f388;个人主页&#xff1a;甜美的江 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;机器学习 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步…...

JavaScript学习之旅10------掌握jQuery:实用应用案例深度解析

目录 写在开头1. jQuery基础知识回顾1.1. 选择器1.2. 事件1.3. 效果1.4. DOM操作1.5. AJAX 2. 实用应用案例分析2.1. 动态内容加载2.2. 表单验证2.3. 图像滑动门效果2.4. 创建动态导航菜单 3. 高级技巧与最佳实践3.1. 优化jQuery代码的性能3.2. jQuery插件的使用和自定义3.3. j…...

017_逆向工程搭建和使用

文章目录 启动代码生成器然后访问第一步处理:前端代码删除逆向生成的代码中有好多东西要引入创建gulimall-common插曲:修改模块名dao层entity层service层controllerRQuery文件当中的报错☆ 调整renren-generator的逆向工程逆向生成代码当中有什么总结...

位运算+leetcode(1)

基础 1.基础知识 以下都是针对数字的二进制进行操作 >> 右移操作符<< 左移操作符~ 取反操作符 & 有0就是0&#xff0c;全一才一 | 有一才一 &#xff0c;全0才0^ 相同为0&#xff0c;相异为1 异或( ^ )运算的规律 a ^ 0 a a ^ a 0a ^ b ^ c a ^ (b …...

如何在 JavaScript 中比较两个日期 – 技术、方法和最佳实践

在 JavaScript 中&#xff0c;您可以使用 date 对象有效地处理应用程序中的日期、时间和时区。 Date 对象可帮助您有效地操作数据、处理各种与日期相关的任务&#xff0c;并在创建实际应用程序时执行一些计算。 &#xff08;本文内容参考&#xff1a;java567.com&#xff09;…...

【More Effective C++】条款17:考虑使用lazy evaluation

含义&#xff1a;将计算拖延到必须计算的时候&#xff0c;以下为4个场景 优点&#xff1a;避免不必要的计算&#xff0c;节省成本 缺点&#xff1a; 管理复杂性&#xff1a;可能会增加代码复杂性&#xff0c;特别是在多线程环境中需要正确处理同步和并发问题。性能开销&…...

深入探索Pandas读写XML文件的完整指南与实战read_xml、to_xml【第79篇—读写XML文件】

深入探索Pandas读写XML文件的完整指南与实战read_xml、to_xml XML&#xff08;eXtensible Markup Language&#xff09;是一种常见的数据交换格式&#xff0c;广泛应用于各种应用程序和领域。在数据处理中&#xff0c;Pandas是一个强大的工具&#xff0c;它提供了read_xml和to…...

如何在我们的模型中使用Beam search

在上一篇文章中我们具体探讨了Beam search的思想以及Beam search的大致工作流程。根据对Beam search的大致流程我们已经清楚了&#xff0c;在这我们来具体实现一下Beam search并应用在我们的seq2seq任务中。 1. python中的堆&#xff08;heapq&#xff09; 堆是一种特殊的树形…...

PKI - 借助Nginx 实现Https 服务端单向认证、服务端客户端双向认证

文章目录 Openssl操系统默认的CA证书的公钥位置Nginx Https 自签证书1. 生成自签名证书和私钥2. 配置 Nginx 使用 HTTPS3. 重启 Nginx 服务4. 直接访问5. 不验证证书直接访问6. 使用server.crt作为ca证书验证服务端解决方法1&#xff1a;使用 --resolve 参数进行请求域名解析解…...

WebSocket原理详解

目录 1.引言 1.1.使用HTTP不断轮询 1.2.长轮询 2.websocket 2.1.概述 2.2.websocket建立过程 2.3.抓包分析 2.4.websocket的消息格式 3.使用场景 4.总结 1.引言 平时我们打开网页&#xff0c;比如购物网站某宝。都是点一下列表商品&#xff0c;跳转一下网页就到了商品…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

解析两阶段提交与三阶段提交的核心差异及MySQL实现方案

引言 在分布式系统的事务处理中&#xff0c;如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议&#xff08;2PC&#xff09;通过准备阶段与提交阶段的协调机制&#xff0c;以同步决策模式确保事务原子性。其改进版本三阶段提交协议&#xff08;3PC&#xf…...

PydanticAI快速入门示例

参考链接&#xff1a;https://ai.pydantic.dev/#why-use-pydanticai 示例代码 from pydantic_ai import Agent from pydantic_ai.models.openai import OpenAIModel from pydantic_ai.providers.openai import OpenAIProvider# 配置使用阿里云通义千问模型 model OpenAIMode…...

Win系统权限提升篇UAC绕过DLL劫持未引号路径可控服务全检项目

应用场景&#xff1a; 1、常规某个机器被钓鱼后门攻击后&#xff0c;我们需要做更高权限操作或权限维持等。 2、内网域中某个机器被钓鱼后门攻击后&#xff0c;我们需要对后续内网域做安全测试。 #Win10&11-BypassUAC自动提权-MSF&UACME 为了远程执行目标的exe或者b…...

StarRocks 全面向量化执行引擎深度解析

StarRocks 全面向量化执行引擎深度解析 StarRocks 的向量化执行引擎是其高性能的核心设计&#xff0c;相比传统行式处理引擎&#xff08;如MySQL&#xff09;&#xff0c;性能可提升 5-10倍。以下是分层拆解&#xff1a; 1. 向量化 vs 传统行式处理 维度行式处理向量化处理数…...

21-Oracle 23 ai-Automatic SQL Plan Management(SPM)

小伙伴们&#xff0c;有没有迁移数据库完毕后或是突然某一天在同一个实例上同样的SQL&#xff0c; 性能不一样了、业务反馈卡顿、业务超时等各种匪夷所思的现状。 于是SPM定位开始&#xff0c;OCM考试中SPM必考。 其他的AWR、ASH、SQLHC、SQLT、SQL profile等换作下一个话题…...