今天复习数据结构,写代码时,遇到一个string比较的问题,查阅了大佬们的博客后,在这里做个总结记录(并附上对应链接)。
本文,先阐述C++中char[],char*和string三者的区别和联系,然后说明C++中的字符串比较的问题。
先说区别与联系。
首先明确一个点,C语言中,并无string数据类型(C++也没有)。在C语言中,字符串一般是通过 char[] 数组来存储的, 而<string.h>这个头文件里声明的函数原型也全是针对char数组的种种操作。直到C++中才出现了string这个类(注意是类,不是类型)。这里引用一个较为严谨的说法:
"C语言中有string类型变量吗"
这里的string有二义性。
(1)如果string是普通词汇,“C语言中有字符类型变量吗”,答,有。字符类型用char声明。
char str[] = "This is a string";
(2)如果string是专用词汇,“C语言中有string类型变量吗”,答,没有。string是类,是class;不是类型,不是type。
类的声明用构造函数初始化,或new声明。
一、char [] 类型
#include <iostream> using namespace std; int main() { char a[10] = "123"; cout << a; return 0; } // 输出:123,此程序在a[3]的位置自动写入了'\0',终止符
又如:
#include <iostream> using namespace std; int main() { char a[10]; a[0] = 'A'; a[2] = 'C'; cout << a; return 0; } // 输出:A
注意:这里的char [] 数组,
如果是全局变量,静态变量,一般编译器(具体要依赖于具体所使用的编译器和系统)会采用默认原则将内部的所有位置设置为0;
如果是局部变量,由于局部变量的内存分配是在栈上,如果未对char数组进行初始化的话,数组内的数据取决于此处原来的数据。同理,动态变量在堆上,同样数据为任意值。
一般来说 全局变量、静态变量处于数据区,默认初始化为0 (如果指定初始值,则为指定的值)
而局部变量处于堆栈区,其数值是随机的,即当时内存中的值。
建议:不要利用编译器的这种默认原则,而是应当显示的指定,必要的初始化不是笨拙,而是规范。
二、char [] 和char*
1、字符串char*
char *str1="abcde"; //这是一个字符串常量,存储在静态存储区,是只读的。
const char *str1 = "abcde";
char const *str1 = "abcde"; //注意,这两种写法等价
//其中,str1是一个变量,代表的意思就是字符串的第一个字符的值
此处参照此博客:
关于字符串常量&字符数组&字符常量:https://blog.csdn.net/wuwuku123/article/details/103575620
const char * 、char const * 、 char * const 三者的区别:https://blog.csdn.net/qq_40244176/article/details/80765975
*(str1++);//可行 *(str1+2)='f';//不可行
如:
char *str2=str1;
"abcde"存储的区域没有改变,只是将str1的地址复制给str2;
2、字符串数组:
char str3[]="abcde"; //str3是数组名,一个常量 str3++; //不可行 str3[2]='f';//可行
如:
char *str4=&str3;
上面语句是将"abcde"复制一遍,然后再复制给是str4;
三、char* 和 string
char是一个字符类型 C++的内置类型,char *是字符指针;
而string是一个字符容器,是一个扩展的模版类。
(一)、先解释char*字符串和string对象的区别。
1、定义
string:string是C++STL当中的一个容器,对其进行了封装,所以操作起来非常方便。
char*:char*是一个指针,可以指向一个字符串数组,至于这个数组可以在栈上分配,也可以在堆上分配,堆得话就要你手动释放了。
2、区别:
string的内存管理是由系统处理,除非系统内存池用完,不然不会出现这种内存问题。
char*的内存管理由用户自己处理,很容易出现内存不足的问题。
当我们要存一个串,但是不知道其他需要多少内存时,用string来处理就最好不过了。
当你知道了存储的内存的时候,可以用char*,但是不如用string的好,用指针总会有隐患。
用string还可以使用各种成员函数来处理串的每一个字符,方便处理。
用char*处理串,就不如string的方便了,没有相应的函数来直接调用,而是要自己编写函数来完成串的处理,而且处理过程中用指针还很容易出现内存问题。
char* s = "string"; 的内容是不可以改的;chars[10] = "string" 的内容是可以改的。
3、注意:
当我们定义了一个string,就不能用scanf("%s",s)和printf("%s",s)输入输出。主要是因为%s要求后面是对象的首地址。