欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【C++深度剖析教程15】经典问题解析之关于string的疑问

程序员文章站 2024-01-01 20:05:04
...

今天来看一下在面试笔试中经常会出错的地方。
我们先来看一个代码:

#include <iostream>
#include <string>

using namespace std;

int main()
{
    string s = "12345";
    const char* p = s.c_str();

    cout << p << endl;     

    s.append("abced");  

    cout << p << endl;     


    return 0;
}

看一下这个代码,第一感觉是没有什么问题的,指针p指向了S这个字符串,那么当执行 s.append(“abced”);这句话之后,字符串S会增加“abced”这借个字符,那么打印输出的结果应该为:12345和12345abced。但是我们运行程序发现,两条打印语句都是12345.这是为什么呢?下面我们看图详细分析一下:
【C++深度剖析教程15】经典问题解析之关于string的疑问
一开始只是字符串S指向0xFF112233这个内存空间,然后让P指向这个空间,执行这句话后:s.append(“abced”);S这个字符串变成了0x12345abced,同时这个字符串所对应的地址空间却变成了:0xFF445566,但是此时指针P依然指向之前的0xFF112233,里面的值是没有变化的,为什么出现这种情况呢?

因为:string对象维护了一个指向数据的char*指针,这个指针在程序运行阶段,有可能会发生突变。
所以那个P指针还是指向原来的0xFF112233这个地址,打印输出的内容就还是12345了。

下面再看一个程序:

#include <iostream>
#include <string>

using namespace std;

int main()
{
    const char* p = "12345";
    string s = "";

    s.reserve(10);  //分配内存大小为10

    // 不要使用 C 语言中的方式操作 C++ 中的字符串
    for(int i=0; i<5; i++)
    {
        s[i] = p[i];
    }

    cout << s << endl;

    return 0;
}

这个程序运行结果为:空!!!
为什么呢?难道对S的赋值没有成功么?我们给出分析,用C语言描述C++中的字符串,会出现一些异常,看图:
【C++深度剖析教程15】经典问题解析之关于string的疑问

这里可以看出,m_cstr是指向字符串的内容,m_length是string类的成员变量,它指向字符串的长度,经过for循环后,我们操作的不是对象的整体,m_cstr所指向的字符串确实有了,但是m_length却依然为0,所以最后打印出来的是空,我们应该直接操作这个对象,才能让m_length随着赋值而出生存在。

我们把程序改成这样:

#include <iostream>
#include <string>

using namespace std;

int main()
{
    const char* p = "12345";
    string s = "";

    s.reserve(10);

    s = p;    //直接操作对象,不要像C语言那样进行for循环赋值。
    // 不要使用 C 语言中的方式操作 C++ 中的字符串
    /*
    for(int i=0; i<5; i++)
    {
        s[i] = p[i];
    }
    */    
    cout << s << endl;

    return 0;
}

打印结果为:
【C++深度剖析教程15】经典问题解析之关于string的疑问
这下就是我们期待的结果了。

总结一下:
-string类通过一个数据空间保存字符串数据
-string类通过一个成员变量保存当前字符串的长度
-C++开发时,尽量避免C语言的一些惯用的编程思想

想一起探讨以及获得各种学习资源加我(有我博客中写的代码的原稿):
qq:1126137994
微信:liu1126137994
可以共同交流关于嵌入式,操作系统,C++语言,C语言,数据结构等技术问题。

上一篇:

下一篇: