(delphi11最新学习资料) Object Pascal 学习笔记---第6章第3节(传递字符串作为参数)
6.3 字符串数据类型
Object Pascal 中的字符串数据类型比简单的字符数组复杂得多,其功能远远超出了大多数编程语言为类似数据类型提供的功能。在本节中,我将介绍这种数据类型背后的关键概念;在接下来的章节中,我们将更详细地探讨其中的一些特性。
在以下要点中,我总结了理解语言中字符串工作原理的关键概念(请记住,即使不了解这些概念,您也可以使用字符串,因为字符串的内部行为是非常透明的):
- 字符串类型的数据在堆上动态分配。字符串变量只是对实际数据的引用。不必过多担心这一点,因为编译器会透明处理这个问题。与动态数组一样,当声明新字符串时,该字符串是空的。
- 尽管可以以多种方式向字符串分配数据,但还可以通过调用SetLength函数来分配特定数量的内存。参数是字符串应该能够容纳的字符数(每个2字节)。扩展字符串时,现有数据将被保留(但可能会被移动到新的物理内存位置)。而缩小字符串时,部分内容可能会丢失。很少有必要设置字符串的长度。唯一常见的情况是需要将字符串缓冲区传递给指定平台的操作系统函数。。
- 如果要增加字符串在内存中的大小(通过与另一个字符串连接),但相邻内存中有其他内容,则字符串不能在相同的内存位置中增长,因此必须在另一个位置制作字符串的完整副本。
- 要清除字符串,不要对引用本身进行操作,只需将其设置为空字符串,即’ ',或者可以使用相对应的Empty常量。
- 根据
Object Pascal的规则,字符串的长度(可以通过调用Length获得)是有效元素的数量,而不是分配的元素的数量。与C不同,C具有字符串终止符(#0)的概念,从早期开始,所有版本的 Pascal 都倾向于使用特定的内存区域(字符串的一部分)来存储实际的长度信息。不过,有时你会发现字符串也有结束符。 Object Pascal字符串使用引用计数机制,该机制会记录有多少个字符串变量在内存中引用给定的字符串。当字符串不再被使用时,即不再有字符串变量引用数据且引用计数为零时,引用计数将释放内存。- 字符串使用写时复制技术,非常高效。当将字符串赋值给另一个字符串或将其传递给例程的字符串参数时,不会复制数据,并且引用计数会增加。但是,如果更改其中一个引用的内容,系统将首先制作副本,然后仅修改该副本,其他引用保持不变。
- 使用字符串连接向现有字符串添加内容的速度通常非常快,而且没有明显的缺点。虽然还有其他方法,但字符串连接既快速又强大。这在当今许多编程语言中并非如此。
我想这样的描述可能会让人有点困惑,所以让我们来看看字符串在实际中的使用。稍后,我将通过一个演示来展示上述的一些操作,包括引用计数和写时复制。不过,在此之前,让我先回到字符串辅助操作和其他一些管理字符串的基本 RTL 函数上来。
首先,让我们根据实际代码测验一下前面列表中的结论。由于字符串操作非常完美,除非您开始查看字符串的内存结构(在本书的较晚部分我会这样做,因为这在目前的阶段过于高级),否则很难完全理解发生了什么。因此,让我们从 Strings101 示例中提取的一些简单字符串操作开始:
varString1, String2: string;
beginString1 := 'Hello world';String2 := String1;Show('1: ' + String1);Show('2: ' + String2);String2 := String2 + ', again';Show('1: ' + String1);Show('2: ' + String2);
end;
当执行此第一个代码段时,如果将两个字符串赋值相同的内容,修改其中一个不会影响另一个。也就是说,String1不受对String2的更改的影响:
1: Hello world
2: Hello world
1: Hello world
2: Hello world, again
不过,在后面的演示中我们会更好地了解到,初始赋值并不会导致字符串的完全复制,复制是延迟的,这种特性被称为写时复制(copy-on-write)。
另一个需要了解的重要特性是如何管理长度。如果询问字符串的长度,就会得到实际值(实际值存储在字符串元数据中,因此操作速度非常快)。但如果调用 SetLength,则需要分配内存,而内存通常不会被初始化。这通常用于将字符串作为缓冲区传递给外部系统函数。
如果需要一个空字符串,可以使用伪构造函数Create。最后,您可以使用SetLength修剪字符串。以下代码演示了所有这些情况:
varString1: string;
beginString1 := 'Hello world';Show(String1);Show('Length: ' + String1.Length.ToString);SetLength(String1, 100);Show(String1);Show('Length: ' + String1.Length.ToString);String1 := 'Hello world';Show(String1);Show('Length: ' + String1.Length.ToString);String1 := String1 + string.Create(' ', 100);SetLength(String1, 100);Show(String1);Show('Length: ' + String1.Length.ToString);
end;
输出大致如下:
Hello world
Length: 11
~ֳ~ו~~؛~ف~٦~ڋ~گ~ۓ~~Helloworld~̆~~̫ ͌~ʹ~Η~υ~ϧ~Ј~Щ~ы~ѭ~ҏ~ұ~Ә~Ӽ~ԟ~Շ~հ
~〈~⌇~۵~ܚ~ܼ~ݡ~~ރ~ޤ~ߊ~߰~~~~~ࢮ~ ~~ Length: 100
Hello world
Length: 11
Hello world
Length: 100
节要强调的第三个概念是空字符串。当字符串的内容是空字符串时,它就是空字符串。无论是赋值还是测试,都可以使用两个连续的引号或特定函数:
varString1: string;
beginString1 := 'Hello world';if String1 = '' thenShow('Empty')elseShow('Not empty');String1 := ''; // 或者 String1.Empty;if String1.IsEmpty thenShow('Empty')elseShow('Not empty');
end;
上述代码生成这个简单的输出:
Not empty
Empty
6.3.1 传递字符串作为参数
正如我已经解释过的,如果你将一个字符串赋值给另一个字符串,你只是复制了一个引用,而内存中的实际字符串并没有被复制。但是,如果你编写的代码改变了该字符串,那么字符串就会首先被复制(仅在该点),然后被修改。
将字符串作为参数传递给函数或过程时,也会发生类似的情况。默认情况下,你会获得一个新的引用,如果你在函数中修改了字符串,这并不会影响原始字符串。如果想获得不同的行为,即在函数中修改原始字符串,则需要使用 var 关键字通过引用传递字符串(就像大多数其他简单数据类型和托管数据类型一样)。
但如果不想修改作为参数传递的字符串呢?在这种情况下,可以对参数使用 const 修饰符进行优化。这样做意味着编译器不会让你在函数或过程中修改字符串,但也会因此优化参数传递操作。事实上,const 字符串不需要函数在开始时增加字符串引用计数,也不需要在结束时减少字符串引用计数,因为函数知道字符串不能被修改。
虽然字符串管理的例程非常快,但执行数千或数百万次也会给程序增加一点开销。这就是为什么在函数不需要修改字符串参数值的情况下,建议将字符串作为常量传递(尽管下面的注释中提到了潜在存在的问题)。
用编码术语来说,这是三个以不同方式传递字符串参数的过程的声明:
procedure ShowMsg1(Str: string);
procedure ShowMsg2(var Str: string);
procedure ShowMsg3(const Str: string);
注解:近年来,除非函数和方法需要对字符串进行修改,否则强烈所有字符串参数都应作为常量传递。但有一个非常重要的注意事项:对于常量字符串参数,编译器获取字符串引用后不会对其进行 “管理”(不进行引用计数等),而是将其视为指向内存位置的指针。编译器会正确检查例程的代码是否不会更改字符串参数。但是,编译器无法控制参数所指向的原始字符串会发生什么变化。
对该字符串的更改会影响其内存布局和位置,这一点普通字符串参数可以处理(具有多个引用的字符串会自动执行写时复制操作),而常量字符串参数则会受到这些更改的影响。换句话说,对原始字符串的更改会使引用它的常量参数失效,使用它很可能会导致内存访问错误。
相关文章:
(delphi11最新学习资料) Object Pascal 学习笔记---第6章第3节(传递字符串作为参数)
6.3 字符串数据类型 Object Pascal 中的字符串数据类型比简单的字符数组复杂得多,其功能远远超出了大多数编程语言为类似数据类型提供的功能。在本节中,我将介绍这种数据类型背后的关键概念;在接下来的章节中,我们将更详细地探…...
k8s节点负载使用情况分析命令kubectl describe node [node-name]
1.到任意安装了kubectl节点命令的节点上执行kubectl describe node [node-name] 上面的Requests最小分配 Limits最大分配是所有pod之和,最小分配之和不能超过服务器实际参数,否则新的pod会因为资源不够起不来,最大分配是预设之和࿰…...
自动驾驶加速落地,激光雷达放量可期(上)
1 激光雷达应用广泛,汽车有望成最大催化 激光雷达(LiDAR)是一种主动遥感技术,通过测定传感器发出的激光在传感器与目标物体之间的传播距离,来分析目标地物表面的反射能量大小、反射波谱的幅度、频率和相位等信息&#…...
变量的间接引用
场景: 如果第一个变量的值是第二个变量的名字,我们能够从第一个变量中取得第二个变量的值吗?例如,如果aztj且ztjz,那么我们能够通过引用变量a来获得值z吗?答案是可以,它被称为间接引用…...
学习JAVA的第六天(基础)
目录 集合 集合和数组的对比 ArrayList成员方法 ArrayList成员方法代码展示 练习 集合的遍历01之字符串 集合的遍历02之数字 集合的遍历03之学生对象 集合 集合和数组的对比 从长度维度来看 数组长度固定 集合长度可变从存储类型维度来看 数组可以存放基本数据类型和…...
LeetCode 2673.使二叉树所有路径值相等的最小代价:自顶向下的DFS 或 自底向上的递推
【LetMeFly】2673.使二叉树所有路径值相等的最小代价:自顶向下的DFS 或 自底向上的递推 力扣题目链接:https://leetcode.cn/problems/make-costs-of-paths-equal-in-a-binary-tree/ 给你一个整数 n 表示一棵 满二叉树 里面节点的数目,节点编…...
9、电源管理入门之CPU Idle
目录 1. CPU Idle有什么用? 2. CPU Idle整体框架 3. Idle状态判断 3. cpuidle core 4. 注册初始化 4.1 cpuidle governor注册 4.2 cpuidle driver注册 4.3 cpuidle device注册 5. cpuidle触发流程 关于Linux的很多知识其实网上的资料非常的多,但是也有些问题: 有时…...
uniapp的扩展组件uni-popup 弹出层自动打开
我的需求是在页面加载完之后自动打开弹窗,自动打开只能写在onReady 或 mounted 生命周期内,这是这个组件的规定: 如果想在页面渲染完毕后就打开 uni-popup ,请在 onReady 或 mounted 生命周期内调用,确保组件渲染完毕…...
二、mysql常用函数
目录 一、Mysql数值型函数 二、Mysql字符串函数 三、Mysql日期和时间函数 四、Mysql聚合函数 五、Mysql流程控制函数 六、其他函数 一、Mysql数值型函数 函数名称 作用 abc 求绝对值 sqrt 求二次方根 mod 求余数 ceil 和 ceiling 功能一样,都是返回不小…...
【Redis | 第一篇】快速了解Redis
文章目录 1.快速了解Redis1.1简介1.2与其他key-value存储的不同处1.3Redis安装——Windows环境1.3.1下载redis1.3.2启动redis1.3.3进入redis客户端1.3.4修改配置 1.4Redis安装——Linux环境1.4.1安装命令1.4.2启动redis1.4.3进入redis客户端 1.5配置修改1.6小结 1.快速了解Redi…...
Vim 模式切换 | 命令集
Vim 模式切换 | 命令集 vim 主要模式及切换一、正常/普通/命令模式1 光标相关操作命令集1.1 光标移动1.2 文字删除1.3 粘贴和复制1.4 撤销1.5 字符更改 二、插入模式2.1 插入模式和命令行模式相互切换 三、末行模式2.1 末行模式和命令行模式相互切换2.2 末行模式相关命令集 四、…...
广和通5G智能模组SC171支持Android、Linux和Windows系统,拓宽智能物联网应用
世界移动通信大会2024期间,广和通宣布:5G智能模组SC171除支持Android操作系统外,还兼容Linux和Windows系统,帮助更多智能终端客户快速迭代产品,拓宽智能化应用覆盖范围。 广和通SC171系列基于高通QCM6490物联网解决方案…...
【51单片机】红外遥控红外遥控电机调速(江科大)
1.红外遥控简介 红外遥控是利用红外光进行通信的设备,由红外LED将调制后的信号发出,由专用的红外接收头进行解调输出 通信方式:单工,异步 红外LED波长:940nm 通信协议标准:NEC标准 2.硬件电路 红外发送部分 IN高电平时,LED不亮,IN低电平时&…...
kubesphere jenkins 流水线 未运行(解决方案)
场景: 在kubesphere 中运行 流水线 devops 结果,显示未运行 但是用 admin 账户是可以运行成功的。 问题解决 1- 查日志: 然后 Caused: org.acegisecurity.userdetails.UsernameNotFoundException: org.springframework.security.core.…...
如何保护服务器的安全
互联网的迅速发展,让很多企业都很重视网络技术的使用,但是网络的传播速度比较快,同时容易造成数据、隐私方面的泄露现在每个企业基本有自己的服务器。有几点需要注意,可以参考: 1.基础密码安全 最基本的安全就是密码安…...
Python使用HDL 模拟器实现 FPGA 板卡的仿真验证
Python 结合 HDL 模拟器实现 FPGA 板卡的仿真验证,您可以借助一些开源工具和库来实现这一目的。下面我将为您介绍一种常用的方法,使用 Python 结合 Verilog 模拟器和 FPGA 开发工具进行仿真验证。 ### 步骤概述 1. **编写 Verilog 设计**:首…...
vue中 input disable后无法触发点击事件
问题:input标签为disabled后,点击事项无效;当点击文字**“请选择”**时无法触发点击事件,其父标签的其余位置均可触发 解决:只需要在input标签中添加 style“pointer-events:none” 即可 pointer-events: none 作用是…...
实战一个 Jenkins 构建 CI/CD流水线 的简单配置过程哈
引言:上一期我们讲述了gitlabCI/CD工具的介绍,工具之争,本期我们介绍Jenkins CI/CD 目录 一、Jenkins介绍 1、Jenkins概念 2、Jenkins目的 3、特性 4、产品发布流程 二、安装Jenkins 1、安装JDK 2、安装Jenkins 1、上传压缩包 2、…...
【InternLM 实战营笔记】大模型评测
随着人工智能技术的快速发展, 大规模预训练自然语言模型成为了研究热点和关注焦点。OpenAI于2018年提出了第一代GPT模型,开辟了自然语言模型生成式预训练的路线。沿着这条路线,随后又陆续发布了GPT-2和GPT-3模型。与此同时,谷歌也…...
数据卷(Data Volumes) 自定义镜像(dockerfile)
目录 一. 数据卷(Data Volumes) 1.1 什么是数据卷 1.2 为什么需要数据卷 1.3 数据卷的作用 1.4 数据卷的使用 二. 自定义镜像(dockerfile) 2.1 什么是dockerfile 2.2 自定义centos 2.3 自定义tomcat 一. 数据卷(Data…...
从不确定性到规律:随机信号的统计建模与工程应用
1. 随机信号:从噪声中寻找规律 第一次接触随机信号时,我盯着示波器上跳动的曲线发懵——这看起来就像一堆杂乱无章的毛线团。但导师告诉我:"这些看似混乱的波形里藏着宝藏,关键是要找到正确的解码方式。"十年后我才真正…...
AGI芯片架构迎来临界点:2026奇点大会公布的7nm类脑SoC实测数据首度解禁
第一章:2026奇点智能技术大会:AGI与硬件设计 2026奇点智能技术大会(https://ml-summit.org) AGI架构演进的关键拐点 2026年大会首次系统性披露了面向通用人工智能(AGI)的异构协同计算范式,其核心突破在于将认知推理层…...
别再只盯着AUC了!临床预测模型评估新宠NRI和IDI,手把手教你用R语言实战解读
临床预测模型评估进阶:NRI与IDI的实战解读与R语言实现 在临床预测模型的研究中,我们常常陷入一个思维定式——将AUC(曲线下面积)视为评估模型性能的黄金标准。然而,当两个模型的AUC差异仅为0.02或0.03时,我们真的能自信地说新模型…...
AD9361实战笔记:手把手教你配置Tx功率监控(TPM)与RSSI校准
AD9361实战笔记:手把手教你配置Tx功率监控(TPM)与RSSI校准 在射频系统设计中,精确的功率监控和信号强度测量是确保通信质量的关键环节。AD9361作为一款高度集成的射频收发器,其内置的发射功率监控(TPM&…...
Windows 11 LTSC微软商店安装终极指南:3步恢复完整应用生态
Windows 11 LTSC微软商店安装终极指南:3步恢复完整应用生态 【免费下载链接】LTSC-Add-MicrosoftStore Add Windows Store to Windows 11 24H2 LTSC 项目地址: https://gitcode.com/gh_mirrors/ltscad/LTSC-Add-MicrosoftStore 你是否在使用Windows 11 LTSC系…...
抖音无水印批量下载神器:douyin-downloader 完整使用指南
抖音无水印批量下载神器:douyin-downloader 完整使用指南 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback su…...
手把手教你用CVX和Mosek求解器搞定指数锥规划:从entr函数到投资组合优化实战
从理论到实践:基于CVX与Mosek的指数锥优化全流程解析 在金融工程与机器学习领域,许多核心问题最终都归结为包含指数、对数或熵函数的凸优化问题。传统求解器在处理这类问题时往往面临效率瓶颈,而指数锥(Exponential Coneÿ…...
Z-Image-Turbo-rinaiqiao-huiyewunv部署教程:模型路径校验+transformer模块异常捕获机制
Z-Image-Turbo-rinaiqiao-huiyewunv部署教程:模型路径校验transformer模块异常捕获机制 1. 项目概述 Z-Image-Turbo-rinaiqiao-huiyewunv是基于Tongyi-MAI Z-Image底座模型开发的专属二次元人物绘图工具。该工具通过注入辉夜大小姐(日奈娇)…...
手把手教你搞定DSP C6747与FPGA的EMIF通信:从寄存器配置到地址映射实战
手把手教你搞定DSP C6747与FPGA的EMIF通信:从寄存器配置到地址映射实战 在嵌入式系统开发中,DSP与FPGA的协同设计已经成为高性能信号处理、通信系统等领域的标配方案。而EMIF(External Memory Interface)作为两者之间的桥梁&#…...
ngosang/trackerslist项目:如何通过地理优化Tracker提升亚洲用户P2P体验
ngosang/trackerslist项目:如何通过地理优化Tracker提升亚洲用户P2P体验 【免费下载链接】trackerslist Updated list of public BitTorrent trackers 项目地址: https://gitcode.com/GitHub_Trending/tr/trackerslist 如果你在亚洲地区使用BitTorrent下载&a…...
