String小结
String
C#
1.判断数据类型
int i = 5;
Console.WriteLine( "i is an int? {0}",i.GetType()==typeof(int));
Console.WriteLine( "i is an int? {0}",typeof(int).IsInstanceOfType(i));
首先得到变量的类型,使用:变量.GetType()
得到要比较的类型:typeof(类型名),比如typeof(string)
最后做比较:
if(变量.GetType()==typeof(string))
...
else
...
如果要判断是不是某个类的继承类的时候可以使用is
例如:
class Var{}
class IntVar : Var {}
object o = new IntVar();
if ( o is Var )...
2.string与char[]
//string 转换成 Char[]
string s = "abcdefg";
char[] c = ss.ToCharArray();
//Char[] 转换成string
string s = new string(c);
3.string转int
string s = "123";
int result;
if(int.TryParse(s,out result))
{
Console.WriteLine(result);
}
else
{
Console.WriteLine("fail change "+s);
}
try
{
result = int.Parse(s);
Console.WriteLine(result);
}
catch
{
Console.WriteLine("fail change " + s);
}
4.CopyTo
static void Main(string[] args)
{
char[] copy = new char[10];
string s = "123456789";
s.CopyTo(0, copy, 0, 8); //12345678
Console.WriteLine(copy);
s.CopyTo(1, copy, 0, 8); //23456789
Console.WriteLine(copy);
//for (int i = 0; i < 10; i++) //清零操作
//{
// copy[i] = '\0';
//}
s.CopyTo(2, copy, 0, 4); //3456
Console.WriteLine(copy);
}
结果输出是:
12345678
23456789
34566789
说明如果同一个char[]类型CopyTo时,除第一次外,它仍然会保留之前的数据
除非把注释那行复原,也就是在中间加一个覆写'\0'(类似清空操作)
C++
C++中char*与string的转换
C++中的char*相当于char[],只能指向字符数组,若要指向字符串常量需在前面添加const
string一般情况下没必要转换为char**,因为它也能像char*通过下标法进行访问字符
int main()
{
//from char* to string
char p[]= "char* has become string";
char* ch = p;
string s1 = ch; //char*可直接转换为string
cout << s1 << endl;
//from string to char*
string str = string("string1 has become char*");
const char* ch1 = str.c_str(); //第一种:c_str()
cout << ch1 << endl;
string str1 = "string2 has become char*";
char* ch2= (char*)str1.data(); //第二种:data()+强制转换
cout << ch2 << endl;
system("pause");
}
//Output:
//char* has become string
//string1 has become char*
//string2 has become char*
C++与C#的比较
类型 | C++的string | C#的string |
---|---|---|
定义变量 | string name | string name |
长度获取 | 1.size()和length() 2.max_size() 3.capacity() | length() |
复制替换 | str1=str2,replace() | Copy() ,Copy To(),Replace() |
比较 | 1.比较操作符(>,>=,<,<=,==,!=) 2.compare() | Compare(),CompareTo() CompareOrdinal(),Equals() |
插入 | push_back() , insert() | Insert |
查找 | find(),rfind() | Contains(),IndexOf(),LastIndexOf() |
截取 | substr() | SubString() |
分割 | strtok() | Split() |
合并 | append() & + 操作符 | + 操作符,Concat(), Join() |
删除 | erase() | Trim(),Remove() |
大小写转换 | 1.tolower()和toupper() 2.STL中的transform算法 | ToLower(),ToUpper() |
关于C++String详细讲解:https://blog.csdn.net/qq_37941471/article/details/82107077
关于C#String详细讲解:https://blog.csdn.net/Dandelion_gong/article/details/77994193
从C,C++,JAVA和C#看String库的发展(一)----C语言和C++篇:https://www.cnblogs.com/wenjiang/p/3266305.html
从C,C++,JAVA和C#来看String库的发展(二)---JAVA和C#篇:https://www.cnblogs.com/wenjiang/p/3272859.html
C /C++中的char*,char[],string与Java中String,StringBuilder,StringBuffer对比
类型 | 实现方法 | 读取单个字符 | 修改 | 获取长度 | 安全性 | 特点 |
---|---|---|---|---|---|---|
C 中的char* | 指针,可指向字符串常量,也可指向字符串数组 | 1.*(name+i) 2.name[i] | 1.指向字符串常时不可改 2.指向字符串数组用1)*(name+i) 2)name[i] | 1.strlen(name)不包括空字符 2.sizeof(name) 包括空字符 | 不安全 ,会越界 | 可进行底层操作 |
C++中的char* | 指针,只能指向字符串数组,若要指向字符串常量需加const | 1.*(name+i) 2.name[i] | 1.*(name+i) 2.name[i] | 1.strlen(name)不包括空字符 2.sizeof(name) 包括空字符 | 不安全,会越界 | 可进行底层操作 |
C/C++中char[] | 存放多个字符 | 1.*(name+i) 2.name[i] | 1.*(name+i) 2.name[i] | 1.strlen(name)不包括空字符 2.sizeof(name) 包括空字符 | 不安全,会越界 | 可进行底层操作 |
C++中的String | STL中的封装类 | 1.name[i] 2.name.begin(); 3.name.rbegin(); | 1.push_back() 2.insert() 3.append() & + 操作符 4.erase() 5.replace | 1.name.size() 2.name.length() | 安全 | 具有丰富的接口可以使用 |
Java中的String | 字符串常量 | charAt(index) | 不可变 | name.length() | 安全 | 在单线程环境下使用 |
Java中的StringBuilder | 字符串变量 | charAt(index) | 1.append() & + 操作符 2.insert() 3.setCharAt() 4.delete() 5.reverse() | name.length() | 线程不安全 | 在单线程环境下使用 |
Java中的StringBuffer | 字符串变量 | charAt(index) | 1.append() & + 操作符 2.insert() 3.setCharAt() 4.delete() 5.reverse() | name.length() | 线程安全 | 在多线程环境下使用,可以保证线程同步; |
C++中的char[]与C中的char[]不同,C中的既可以指向字符串常量,也可以指向字符串数组,而C++中的只能指向字符串数组,如果想指向字符串常量需在前面加上const以确保你不会修改所指向的字符串常量
C++的String库和C的String库相比,最大的区别就是C++帮我们用户封装了底层操作并且提供了更好的接口,使得这些函数的调用更加方便和符合人的习惯,当然,C++还保留了之前C语言的String库,也就是cstring这个库,但是它本身也提供了一个全新的String库:string。
Java中的String在修改方面不可变,但为啥实际好像可以使用+进行修改呢?其实实际上是在字符串常量池重新创建个对象,为其赋值为""原来str+你修改的部分",然后将原来的str通过垃圾回收机制回收,所以在频繁使用+修改字符串值的Java代码处应该使用StringBuilder或StringBuffer
Java中的StringBuffer其方法大都采用了 synchronized 关键字进行修饰,因此是线程安全的
Java的String等三者进行+操作速度测试
1.当对某一字符串少量重复+操作时:
三者速度基本相近,推荐使用string
2.当需要对某一字符串大量重复+操作时:
StringBuilder 最快,不需要考虑线程同步;
StringBuffer次之;
String最慢,因为每次都要重新开辟内存,产生很多匿名对象,影响系统性能。
测试代码
public class AppendStringTest
{
public static void main(String[] args)
{
String str = "" ;
StringBuilder sbd = new StringBuilder ( "" );
StringBuffer sbf = new StringBuffer ( "" );
int test,i,tests[]= {100,1000,10000,100000};
long beginTime,endTime;
for(int n=0;n<4;n++)
{
test=tests[n];
beginTime = System.currentTimeMillis(); //String
for ( i= 0 ;i< test ;i++)
{
str = str + i;
}
endTime = System.currentTimeMillis();
System.out.println("String执行"+test+"个'+'操作所用时间:" +(endTime-beginTime)+"ms");
beginTime = System.currentTimeMillis(); //StringBuilder
for ( i= 0 ;i< test ;i++)
{
sbd.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println("StringBuilder执行"+test+"个'+'操作所用时间:" +(endTime-beginTime)+"ms");
beginTime = System.currentTimeMillis(); //String
for ( i= 0 ;i< test ;i++)
{
sbf.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println("StringBuffer执行"+test+"个'+'操作所用时间:" +(endTime-beginTime)+"ms"+"\n");
}
}
}
测试结果
PS:实际测试时,StringBuilder和StringBuffer速度明显比较在100w次后才开始显示出来
C++中的char[]与string速度测试
测试代码:
int main()
{
clock_t start, end;
double endtime;
char name[] = "Mike";
string str1(5, '1');
char* p = name;
char temp;
//测试char*/char[]
start = clock();
for (int i = 1; i <= 1e8; i++)
{
p[2] = 'x';
}
end = clock();
endtime = (double)(end - start) / CLOCKS_PER_SEC;
cout << "C++中的char*进行1e8次修改单字符Total time:" << endtime * 1000 << "ms" << endl;
start = clock();
for (int i = 1; i <= 1e8; i++)
{
temp=p[1];
}
end = clock();
endtime = (double)(end - start) / CLOCKS_PER_SEC;
cout << "C++中的char*进行1e8次获取单字符Total time:" << endtime * 1000 << "ms" << endl;
//测试string
start = clock();
for (int i = 1; i <= 1e8; i++)
{
str1[1] = 'x';
}
end = clock();
endtime = (double)(end - start) / CLOCKS_PER_SEC;
cout << "C++中的string进行1e8次修改单字符Total time:" << endtime * 1000 << "ms" << endl;
start = clock();
for (int i = 1; i <= 1e8; i++)
{
temp = str1[1];
}
end = clock();
endtime = (double)(end - start) / CLOCKS_PER_SEC;
cout << "C++中的string进行1e8次获取单字符Total time:" << endtime * 1000 << "ms" << endl;
start = clock();
for (int i = 1; i <= 1e8; i++)
{
str1.append(1, temp);
}
end = clock();
endtime = (double)(end - start) / CLOCKS_PER_SEC;
cout << "C++中的string进行1e8次获取单字符Total time:" << endtime * 1000 << "ms" << endl;
system("pause");
}
测试总结:
C/C++中char*无法修改其字符串长度,但其进行修改和获取等操作时速度很快
C/C++中的string可以修改其字符串长度,但其进行修改,获取,和增加字符串长度等操作速度较慢