前言:
指针、常量、字符串和等号,这四个东西可以说贯穿你写的每一个Cpp文件,我大约记得我刚学的时候可是在这些东西中载了大跟头,前车之鉴啊,必须用笔记和文章形式好好理一理。
让我们先从最简单一句开始,声明并初始化一个字符串常量。
const char* s1="HelloWorld";
就这一句话就把这四个概念都用上了。让我梳理一下这句话是要告诉计算机干什么。
第一步:在计算机中找一块可用空间(所有的字符窜常量都被放在全局静态内存区)放"HelloWorld"这个字符串。
第二步:产生一个char*的指针s1指向这个字符串的首地址。
第三步:把这个char*标记为const。
(一旦标记了const就说明*s1=这个语法就不能使用了,也就是说已经不能用*s1=这种语法来改变这个空间中放的"HelloWorld"这个字符串,简单说这个s1就是只能看不能动,实际上即使没有const ,HelloWorld本身也处在全
局静态内存区,你懂的这里编译好就不能改的)
疑点1:
const char *s1="HelloWorld";//是不是就可以保证print("%s",s1);永远输出"HelloWorld"呢,
答案是否定的(想想就知道s1只能看不能改,这样s1肯定不高兴啊,不高兴就很可能不看她了是不是,s1很可能
考虑来个s1="HelloChina";看不了世界我看中国还不行吗)所以print("%s",s1);指不定输出啥呢。
疑点2:
那这次来个狠点的 const char *const s1="HelloWorld";(我还就不让看别处呢)初想想这可是传说中的指向常量的常量指针,听起来就NB劲十足的,这时候有人想了是不是print("%s",s1);就永远输出"HelloWorld"了。关于这点请接着看下去
注意:const char *const s1="HelloWorld";
//这句话写上实际上HelloWorld无法被变的原因是因为他本身是字符串常量处在全局静态区域,和第一个const关键字的功劳挂不上钩
但是如下情况呢,当s1指向一个new出来的内容时候呢,情况会大大不同
std::string initVal="HelloWorld";
const char*const s1=initVal.c_str();
initVal="HelloChina";
printf("%s",s1);
这4行代码输出结果为:HelloChina
可以很明显发现s1,在执行完initVal="HelloChina";这行之后,s1指向空间内容确实变成了"HelloChina"。
就是这么神奇,呵呵。
我们最后再说一说字符串比较和等号的误区。
如果是char*和char*之间的比较那么比较实际是他们的指向的地址的大小
如果是std::string和char*或则std::string和std::string比较那么实际上都是转换成std::string来比较他们指向内容的ASCCII码值的大小如:"abc">"zxc"
如果char* s="HelloWorld",这里的等于是把地址给了s
如果std::string s="HelloWorld";这里的等于是把内容拷贝了一份给了s里面New出来的空间。