网站首页 > 技术文章 正文
对字符串的操作到目前为止还只是対字符串数据的连接(+)转换和输出这些基础应用
字符串是一个特殊的引用类型,字符串类型还有非常多的其他操作,如查找文本文件中某些文字,统计特定字符/字符串等等
字符串可以看做是一个只读的字符数组,因此可以通过下标循环遍历
string str1 = "我爱北京天安门";
//使用下标访问字符串,就可以得到一个字符类型的数据
char a = str1[0];//我
//str1.Length 获取字符串的字符个数
for (int i = 0; i < str1.Length; i++)
{
Console.WriteLine(str1[i]);
}
Console.ReadKey();
因为是只读字符数组所以不可更改,因为它是只读属性的
说过字符串方法可以将其变为可写的字符数组,还可以用来统计指定(或用户输入)的字符串中各个字符的个数
字符串特性
1 字符串具有不可变性(也有的叫做恒定性)
int[] num = { 8 };
num[0] = 80;
string str = "我爱";
Console.WriteLine(str);
str += "北京";
Console.WriteLine(str);
str += "天安门";
Console.WriteLine(str);
Console.WriteLine("num={0} str={1}", num[0], str);
Console.ReadKey();
通过复合运算符的赋值操作发现更改了字符串变量的值,貌似被"打脸"了,但是赋值操作并不能推翻“字符串不可变性”中的不可变
可以为变量赋一个全新的值,但出于性能方面考虑,没有提供修改字符串内容的机制
不可变性是指字符串对象的内容不可改变,改变的是栈中对应堆的引用的地址,因此导致赋值结果在改变;
所以说字符串是变量的是从赋值结果来说;说字符串是常量的是从字符串内容
只是上面51,53,55 3行代码在内存堆中就产生了5个字符串对象在内存栈,堆中的变化
数组num[0]都是对同一对象的内容进行修改
str每次+=操作
在栈中str栈的地址不变,改变的是指向堆的地址,因此str赋值才会显现改变
在堆中并不会在原有字符串str上进行操作而是产生一个新的对象并将str指向新对象的地址,旧的对象没有被引用了就成了堆中待GC进行垃圾回收的资源,至于什么时候回收,说到垃圾回收时再细说
这里的"垃圾"指的是程序运行时堆中没有被引用的变量,对象等
因此在有大量字符串拼接时,短时间内会产生大量垃圾,影响性能有内存溢出危险,
2 字符串池(或字符串留用池)主要针对字符串常量
string str1 = "字符串池";
string str2 = "字符串池";
str1 = str1 + str2;
Console.WriteLine("{0} {1}");
Console.ReadKey();
当程序中有多个相同字符内容的字符串常量时,不是立马创建新对象存储其值而是先在字符串池中查找是否有相同字符的字符串常量,如果有就会指向对中已有的字符串常量,如果没有才会创建新的字符串常量
不会因此产生程序混乱的原因就是因为字符串具有的不可变的特性(由查看str1=str1+str2的堆地址可知)
上面操作不会留有程序垃圾,因为两个字符串常量都有被引用
3 字符串拘留池 常量变量皆可使用,主要针对变量(了解即可)
没有使用字符串拘留池的特性,即使字符串变量的字符相同也会创建新的字符串常量,基于此类状况,.Net为字符串类型又提供了一个字符串拘留的机制
字符串Intern()方法作用相当于将拼接的字符串变为字符串常量留在了字符串池中,下次再有拼接相同字符的字符串,不会创建新的字符串常量,直接指向字符串池中的字符串常量,因为每次创建新的对象会消耗大量的内存
////没有使用字符串拘留池
//string str1 = "我爱";
//string str2 = "北京";
//string str3 = "天安门";
//string str5 =str1 + str2 + str3;
//string str6 = str1 + str2 + str3;
////使用快捷键进行断点调试
////将光标放在将要调试暂停的行按下面快捷键即可
//使用字符串拘留池
string str1 = "我爱";
string str2 = "北京";
string str3 = "天安门";
//拘留拼接的字符串
string str5 = string.Intern(str1 + str2 + str3);
string s1 = "我爱北京";
string s2 = "天安门";
//判断堆中是否有相同字符的字符串常量
string str6 = string.IsInterned(s1 + s2);
Console.ReadKey();
小结
1)了解字符串具有不可变性的特殊性;了解字符串常量在栈堆的变化,理解其底层逻辑,
2)理解掌握前两个特性,了解第三个特性(一般**必有的面试题...)
3)小量的字符串拼接还可以使用,大量的拼接操作会有专门的类与方法解决
如声明变量,一次声明一个或者多个同类型变量太麻烦,推出了枚举,结构,枚举与结构不能使用循环,推出了数组,数组不能添加,删除元素推出集合类型等,总有新方法来解决
猜你喜欢
- 2024-09-15 C#内插字符串(c# 字符串)
- 2024-09-15 C#中动态编译并执行字符串代码,类似javascript中的eval方法
- 2024-09-15 精通C#整数转字符串:多种方法解密填充零的奥秘
- 2024-09-15 一个超实用随机字符串生成方法,超经典!
- 2024-09-15 C# Win Form 字符串函数与正则表达式取子串
- 2024-09-15 c#正则判断字符串是否为mac地址(c# 正则表达式判断字符串是否全是数字)
- 2024-09-15 C# 判断字符串是否为手机号的函数
- 2024-09-15 C# 基础知识系列- 13 常见类库介绍(二)日期时间类
- 2024-09-15 揭秘:带引号的字符串字面量的魅力与用途!
- 2024-09-15 C#中的转义符与原始字符串(c# &转义)
- 1512℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 556℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 504℃MySQL service启动脚本浅析(r12笔记第59天)
- 482℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 481℃启用MySQL查询缓存(mysql8.0查询缓存)
- 461℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 441℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 438℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- c语言min函数头文件 (68)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)