小白C++入坑学废之旅(一)

现在学c++貌似很有点离经叛道的嫌疑。也许很多人会问为什么不学Go或者Rust这些大热,而去学习c++这样的老古董。其实心里也没有什么特定的理由,学过Net,学过Java,用过Javascript,现在用React做前端开发,用Spring Boot做后端服务,之所以学习c++,可能是随着工作学习的深入,慢慢发现会接触计算机底层世界一些边缘,然后好奇那边有一个什么样的世界,所有以C++为切口,开始自己的自由之旅。总而言之,言而总之,兴趣使然。

说实话,身为没有任何c++基础的一枚小白,刚开始学习c++确实很茫然,和C#,Java相似但是有截然不同的原理确实造成了很大困惑。回顾一下最近学习c++的一段历程吧。首先找了一本经典的c++学习教程《C++程序设计语言.pdf》读完。说实话,这本书对于没有基础的小白还是太深了点,建议读前面基础之后,先实践一下再去读剩下的部分。然后侥幸网上发现了Cherno的C++教程视频,随便锻炼了一下英语。感觉视频确实不错,也看过国内很多大学讲堂的一些C++教程视频。觉得Cherno的更适合小白的我。

然后前几天开始正式进入c++的编程练习阶段,通过https://techstudy.org/CplusplusLanguage/cpp-programming-example-and-solutions/的练习250开始实践各种实践应用。

其中有一个练习是字符串的大小写转换。

首先我定义了一个名为StringUtils的namespace用于放置字符串处理的函数。并且定义字符串大小写的两个方法:

std::string toUpperCase(std::string source);
std::string toLowerCase(std::string source);

当然练习里面使用的是char*而我这里使用的是c++里面的标准库字符串类,具体的实现如下:

std::string StringUtils::toUpperCase(std::string source){
    char *buffer = new char[source.size() +2];
    char *begin = buffer;
    for(auto c = source.begin(); c != source.end(); c++){
        *buffer = toupper(*c);
        buffer++;
    }
    
    return std::string(begin, source.size());;
}

std::string StringUtils::toLowerCase(std::string source){
    char *buffer = new char[source.size() +2];
    char *begin = buffer;
    for(auto c = source.begin(); c != source.end(); c++){
        *buffer = tolower(*c);
        buffer++;
    }
    
    return std::string(begin, source.size());
}

上面的函数经过测试可以工作。当然上面的代码真的就可以了么?如果是C#或者Java上面的代码可能没有问题。但是这是c++。因为自己后面几天有空思索了一下就有下面这样的问题:

作为函数的参数source是不是不应该被修改?

是的,个人觉得函数的参数source不应该再函数里被修改,所以修改了定义:

std::string toUpperCase(const std::string source);
std::string toLowerCase(const std::string source);

但是这样就对了么?那几天我还是心里有疑问,上面的代码真的没有问题么?尤其是new char[source.size() +2] 会不会造成内存溢出?而这个时候我遇到的最大的麻烦是我第一次使用xcode调试c++代码的时候不知道如何查看内存是否有被释放(如果有知道xcode如何知道内存是否被释放的请不吝赐教,感激不尽)。加上xcode实在太笨拙,思来想去还是迁移到visual studio code。主要因为visual studio code还是不错的代码提示功能。当然我依然不知道visual studio code上面如果查看内存是否释放。所以我曲线救国,修改了定义std::string toUpperCase(const std::string source, char *buffer)

通过外部传入buffer我发现buffer并没有得到释放。所以又修改了对应的实现:

std::string StringUtils::toUpperCase(const std::string source){
    char buffer[source.size() +2];
    char *begin = buffer;
    for(std::string::const_iterator c = source.begin(); c != source.end(); c++){
        *begin = toupper(*c);
        begin++;
    }
    
    return std::string(buffer, source.size());
}

std::string StringUtils::toLowerCase(const std::string source){
    char buffer[source.size() +2];
    char *begin = buffer;
    for(std::string::const_iterator c = source.begin(); c != source.end(); c++){
        *begin = tolower(*c);
        begin++;
    }
    
    return std::string(buffer, source.size());
}

修改测试后,可以工作。嗯,不错,又是进步的一天。然后的然后还有隐藏的问题,当调用大小写转换函数的时候,貌似会发生copy操作,这样虽然没有大问题,但是我们还能再进步一点点,所有我又该了定义:

std::string toUpperCase(const std::string& source);
std::string toLowerCase(const std::string& source);

发现学习c++,真的好难好心累,但确实是收获很多的日子,中间解决过visual studio code不能编译多文件的问题,还困扰于visual studio code调试std::cin不起左右的问题,都需要一一去解决。而上面的代码我在想是不是使用右值会更好,应该还是有进步的地方的。总之,学习c++使我快乐,希望那天我可以达到写一个数据库引擎的地方。

你可能感兴趣的:(C++,c++,开发语言)