【c++丨STL】string类的使用

简介: 本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。

string类的介绍--为什么学习string类

       之前我们对STL已经有了一些初步的了解,本篇文章我们正式开始学习STL。我们都知道,在C语言当中,有一些库函数:strlen、strcpy、strcmp、strstr......它们都是处理字符串的函数。但是这些函数的定义与字符串是分离的,并不符合面向对象编程的思想。c++标准库当中,定义了一个类用于表示字符串及其操作,叫做string。string类最开始并不属于STL,但是它在c++标准库中的作用与STL紧密相连,于是成为了STL的一员。与C语言的字符数组和头文件string.h相比,string类具有更丰富的功能、更高的安全性和更便捷的操作方式。本篇文章,我们一起学习探讨string类的一些常用接口及使用方法。


      小贴士:在我们使用string类时,要引头文件<string>,并且该类定义在命名空间std当中。


       string类相关接口查阅:


https://legacy.cplusplus.com/reference/string/string/?kw=string


一、string类的默认成员函数

       string类显示实现的默认成员函数有三种:



构造函数(constructor)


在c++11中,string有九个构造函数,但最常用的构造函数有四个

image.png


使用举例:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str1;//无参构造
    string str2("hello world");//用字符数组构造
    string str3(10, 'c');//用10个字符c构造
    string str4(str2);//用另一个string类构造
 
    //打印
    cout << "str1:" << str1 << endl;
    cout << "str2:" << str2 << endl;
    cout << "str3:" << str3 << endl;
    cout << "str4:" << str4 << endl;
    return 0;
}



注:由于标准库已经实现了string类流插入与流提取的相关重载函数,所以我们可以直接配合cin和cout对string类进行输入和输出。


析构函数(destructor)


string中字符串的内存是动态申请的,所以需要显示写析构释放相应空间。 析构函数已经被显示实现,我们无需多虑。


赋值运算符重载operator=


c++11实现了五个赋值重载函数,其中最常用的当属前三种:

image.png

我们可以看到,这些重载函数的返回值都是引用类型,不仅可以减少拷贝提升效率,还能够支持连续赋值。


使用举例:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str1, str2, str3;
 
    str1 = "hello world";//字符串赋值
    str2 = str1;//string对象赋值
    str3 = 'c';//字符赋值
 
    //打印
    cout << "str1:" << str1 << endl;
    cout << "str2:" << str2 << endl;
    cout << "str3:" << str3 << endl;
    return 0;
}



二、string类的容量接口

string类有如下与容量相关的接口:


我们重点介绍一下较为常用的几个接口:


size和length



size和length的作用完全相同,都用于返回string对象中字符串的长度(不包括 '\0' ),单位是字节。


使用举例:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str = "hello world";
    cout << str.size() << endl;
    cout << str.length() << endl;
}


看到这里,我们不禁发出疑问:为什么会实现两个功能完全相同的接口呢?由于string类之前是不属于STL的,只有一个接口length用于求字符串长度。但由于STL的其他容器都是通过size来求元素个数,为了保持一致性,string也实现了一个相同功能的接口size。所以相比其他容器,string的某些实现上就显得比较杂乱。


capacity


capacity返回string对象为字符串开辟的空间大小,单位是字节。


使用举例:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str = "hello world";
    cout << str.capacity() << endl;
}

我们在实现顺序表时,其结构中也有一个成员叫capacity,如果要插入数据,则会判断空间大小,空间不足则会提前申请空间供数组使用。string这里申请空间的机制是类似的。


clear


clear的作用是删除对象中字符串的有效内容,使其成为空字符串。注意:clear只会将有效字符清空,而不会改变空间容量的大小。


使用举例:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str = "hello world";
 
    cout << "size:" << str.size() << endl;
    cout << "capacity:" << str.capacity() << endl << endl;
 
    str.clear();//清空字符串
 
    cout << "size:" << str.size() << endl;
    cout << "capacity:" << str.capacity() << endl;
}


empty


empty的作用是检测字符串是否是空串,如果是,则返回true;否则返回false。注意:该接口只是用于检查,不会修改字符串的任何内容。


使用举例:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str = "hello world";
 
    cout << str.empty() << endl;
 
    str.clear();//清空字符串
 
    cout << str.empty() << endl;
}


reserve


reserve的作用是为字符串预留空间,单位是字节。reserve不会改变字符串有效字符的个数。注意:当参数n的值小于已有空间的总大小时,该函数不会改变其大小。


使用举例:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str = "hello world";
 
    cout << str.capacity() << endl;
 
    str.reserve(20);//增容
 
    cout << str.capacity() << endl;
}


我们可以看到,传参是20,但是空间容量却被增至31。标准规定增容的结果会大于等于参数n,具体会增至多少,取决于编译器。


resize


resize的作用是将字符串中有效字符的个数修改为n个。当n大于原有的有效字符个数时,如果没有传第二个参数,则会用 '\0' 来填充元素,如果传入第二个参数c,则会用c来填充元素。注意:如果将元素个数增多,则空间大小可能改变;否则空间大小不会改变。


使用举例:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str = "hello world";
    str.resize(20, 'm');
 
    cout << "size:" << str.size() << endl;
    cout << "capacity:" << str.capacity() << endl;
    cout << str << endl;
}


三、string对象的访问及遍历操作

1. string类的元素访问接口

       首先,我们介绍一下string类的元素访问相关接口,它们便于我们访问和修改字符串中的元素:

operator[ ]


operator[]是一个运算符重载,它能够让我们像访问数组元素一样访问string类字符串中的字符,因此,它的使用方法和数组的访问是相同的。注意:如果 pos 等于字符串长度,该函数将返回指向字符串最后一个字符之后的空字符的引用(该字符不应被修改)。


使用举例:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str = "hello world";
 
    cout << str[0] << endl;
    cout << str[3] << endl;
    return 0;
}


at


at的使用方法与operator[ ]相同,传入的参数对应字符串的下标。与operator[ ]不同的是:如果越界访问,at会抛出异常,而operator[ ]会返回 '\0' 的引用。


使用举例:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str = "hello world";
 
    cout << str.at(0) << endl;
    cout << str.at(3) << endl;
    return 0;
}


front和back



顾名思义,front返回的是字符串的第一个字符,而back返回的是字符串中的最后一个字符(不是 '\0')。


使用举例:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str = "hello world";
 
    str.front() = 'w';
    str.back() = 'w';
 
    cout << str << endl;
    return 0;
}


2. 迭代器接口

       由于迭代器(Iterator)的组成比较复杂,现阶段我们可以将其理解为一种指针,指向容器内的数据元素。它可以执行与指针一样的操作,能够让我们用“指针”的方式访问元素。


string类的迭代器接口如下:



其中,比较常用的是前四种。

begin和end



begin返回一个指向字符串首字符的迭代器,而end返回指向字符串末尾 '\0' 的迭代器。它们返回的迭代器的类型是“iterator”或“const_iterator”(const对象)。对于一个容器而言,其迭代器接口都定义在类当中,所以我们定义迭代器时需要声明类域。



前面已经提到,我们可以像指针般地使用迭代器访问数据元素。接下来我们尝试使用它:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str = "hello world";
    string::iterator it = str.begin();//定义一个string类的迭代器
 
    cout << *it << endl;//"解引用"
    it++;//后移一位
    cout << *it << endl;
}


在上面的程序中,我们可以看到定义迭代器时需要标明的类型比较冗长,这里有一个c++11小语法可以为我们提供方便:


auto关键字


       在c语言当中,auto所修饰的变量叫做“自动变量”,是具有自动存储器的局部变量。后来这个关键字并不显得十分重要,于是c++11赋予了auto全新的含义:auto关键字修饰的变量,其类型由编译器在编译时根据初始化值的类型推导而得。什么意思呢?我们看一段代码:

int main()
{
    auto a = 1;
    auto b = 5.5f;
    auto c = 'w';
    return 0;
}

调试窗口:



我们可以看到,这些根据我们赋的初值,自动推导出了相应的类型。所以今后对于那些十分冗长的类型,我们想要创建变量或对象时,就可以使用auto做修饰,编译器就会自动推导出其类型。


       使用auto关键字的注意事项


1. auto变量在定义时必须赋初值,否则编译器会报错。


2. 同一行声明多个auto变量时,所有初值的类型都必须相同。


3. auto修饰指针类型时,使用auto或者suto*是没有区别的,但是修饰引用类型时必须加上 "&"。


4. auto不能直接用于声明数组。


5. auto不能用作函数形参,但可以用作返回值(谨慎使用)。


这样,我们就可以用一个auto变量来接收迭代器接口的返回值了,无需标明冗长的类型名。


rbegin和rend



rbegin和rend被成为“反向迭代器接口”,rbegin返回指向字符串最后一个字符的迭代器,rend返回指向字符串首元素“前一个位置”的迭代器。它们返回的迭代器类型是“reverse_iterator”或“const_reverse_iterator”(const对象)。



使用举例:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str = "hello world";
    auto it = str.rbegin();
 
    cout << *it << endl;
    it++;
    cout << *it << endl;
    return 0;
}


这里要注意:对于反向迭代器,它的加减操作与普通迭代器相反。


cbegin、cend、crbegin、crend

相比于前四种迭代器接口,这四种迭代器就是在之前的基础上修改为只能进行读操作,不可修改指向的值。这里就不多说了。


3. string类字符串的三种遍历方法

       了解了string类的元素访问接口和迭代器相关知识,我们学习string类字符串的三种遍历方法:


3.1 下标访问

代码如下:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str = "hello world";
    for (int i = 0; i < str.size(); i++)
    {
        cout << str[i] << ' ';
    }
    cout << endl;
    return 0;
}


可以看到,程序通过循环产生下标,配合operator[ ]来遍历元素。


3.2 迭代器访问

正向遍历:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str = "hello world";
    for (auto it = str.begin(); it != str.end(); it++)
    {
        cout << *it << ' ';
    }
    cout << endl;
    return 0;
}


反向遍历:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str = "hello world";
    for (auto it = str.rbegin(); it != str.rend(); it++)
    {
        cout << *it << ' ';
    }
    cout << endl;
    return 0;
}


3.3 范围for

       由于string类字符串是一个有范围的集合,我们可能会经常对其进行遍历操作,但是使用下标访问或者迭代器访问的方式,每次遍历都需要写明范围,并且有时还会出现错误。对于这种问题,c++11规定了一种新语法:范围for循环语句。它的使用方法是:


for((范围内用于迭代的变量) : (被迭代的范围))

{

       ...

}


范围for会自动判断遍历结束,每一次循环结束后,用于迭代的变量都会更新。


范围for底层就是由迭代器实现的。一个容器支持迭代器,那么就支持范围for。


接下来我们尝试使用范围for遍历字符串:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str = "hello world";
    for (auto e : str)//使用范围for遍历
    {
        cout << e << ' ';
    }
    cout << endl;
    return 0;
}


四、string类的修改操作接口

       string类中字符串内容修改相关的接口如下:



其中operator+=最为常用,我们重点介绍;其他接口作为了解即可。


operator+=


operator+=是一个运算符重载,它的作用是字符串追加,可以追加字符,也可以追加字符串。


它的常用重载函数有三个:

image.png

使用举例:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str1 = "hello ";
    string str2 = "world";
 
    cout << str1 << endl;
 
    str1 += str2;//追加一个对象中的字符串
    cout << str1 << endl;
 
    str1 += '!';//追加一个字符
    cout << str1 << endl;
 
    str1 += "!!!!";//追加一个字符数组
    cout << str1 << endl;
 
    return 0;
}



过一会我们了解push_back、append时,你会发现它们的一些接口与operator+=的效果是一样的。不过一般情况下,operator+=比较常用。


小技巧:我们在对字符串进行追加等操作时,如果能够大概预估到需要多大空间,可以先使用reserve将空间预留好,然后进行操作,可以提升运行效率。


append


append作用是追加字符串,它有七个重载函数:


(1)string

       追加一个str的副本。

(2)substring

       追加一个str的子字符串的副本。子字符串是str的一部分,从字符位置subpos开始,并跨越子字符(或者直到str的末尾,如果str太短或者sublen是string::npos)。

(3) c-string

       附加一个由s指向的以空结尾的字符序列(C-string)组成的字符串的副本。

(4)buffer

       在s所指向的字符数组中追加前n个字符的副本。

(5)fill

       追加n个字符c的连续副本。

(6)range

       以相同的顺序追加[first,last)范围内字符序列的副本。

(7)initializer list

       以相同的顺序追加il中每个字符的副本。


push_back和pop_back


push_back的作用是将一个字符追加到一个字符串末尾。



pop_back的作用是删除字符串末尾的字符。


assign

assign的作用是给一个字符串赋一个新值,舍弃原来的值。他有八个重载函数:


(1)string

       str副本。

(2)substring

       复制str中从字符位置subpos开始的部分,并跨出sublen字符(如果str太短或sublen为string::npos,则复制到str的末尾)。

(3) c-string

       复制以s为指向的以空结尾的字符序列(C - string)。

(4)buffer

       从s指向的字符数组中复制前n个字符。

(5)fill

       将当前值替换为字符c的连续n个副本。

(6)range

       以相同的顺序复制[first,last)范围内的字符序列。

(7)initializer list

       以相同的顺序复制il中的每个字符。

(8)move

       获取str的内容。STR保持在未指定但有效的状态。


insert


insert的作用是在字符串指定位置插入字符或者字符串。八个重载函数描述如下:


(1)string

       插入一个str的副本。

(2)substring

       插入str的子字符串的副本。子字符串是str的一部分,从字符位置subpos开始,并跨越子字符(或者直到str的末尾,如果str太短或sublen为npos)。

(3) c-string

       插入由以s为指向的以空结尾的字符序列(C-string)组成的字符串的副本。

(4)buffer

       在s所指向的字符数组中插入前n个字符的副本。

(5)fill

       插入n个字符c的连续副本。

(6)single character

       插入字符c。

(7)range

       以相同的顺序在[first,last)范围内插入字符序列的副本。

(8)initializer list

       以相同的顺序插入il中每个字符的副本。


erase


erase的作用是删除字符串的一部分,三个重载函数如下:


(1)sequence

       擦除字符串值中从字符位置pos开始并跨越len字符的部分(如果内容太短或len为string::npos,则擦除直到字符串末尾)。注意,默认实参会擦除字符串中的所有字符(类似于成员函数clear)。

(2)character

       擦除指向p的字符。

(3)range

       擦除[first,last)范围内的字符序列。


replace


replace可以将字符串的一部分替换为另一字符串或者字符。这个接口听着感觉比较实用,但是当需要替换的部分的长度比原部分大时,就需要将后面的字符全体后移,效率较低,实用性较差。


七个重载函数:


(1)string

       str副本。

(2)substring

       复制str中从字符位置subpos开始的部分,并跨出sublen字符(如果str太短或sublen为string::npos,则复制到str的末尾)。

(3) c-string

       复制以s为指向的以空结尾的字符序列(C-string)。

(4)buffer

       从s指向的字符数组中复制前n个字符。

(5)fill

       将字符串的一部分替换为字符c的连续n个副本。

(6)range

       以相同的顺序复制[first,last)范围内的字符序列。

(7)initializer list

       以相同的顺序复制il中的每个字符。


swap


顾名思义,swap的功能是交换两字符串的内容。使用举例:


#include <iostream>

#include <string>

using namespace std;

int main()

{

string str1 = "aaaaa";

string str2 = "bbbbbb";

str1.swap(str2);//交换两字符串

cout << "str1:" << str1 << endl;

cout << "str2:" << str2 << endl;

}



五、string类的字符串运算相关接口

       string类有以下字符串运算相关的接口(博主只介绍其中比较常用的几个,其他的可自行了解):



c_str


c_str可以将对象临时转换为一个字符数组(以 '\0' 结尾)。它的返回值是指向自己成员字符数组的指针。


该函数返回的指针指向内容被const修饰,我们只能读,不能通过该函数修改字符串内容。


使用举例:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str = "hello world";
 
    cout << str.c_str() << endl;//打印字符串
 
    return 0;
}

find和rfind


find用于查找一个字符串当中第一次出现的子串或者字符。 如果给定了参数pos,则函数会从字符串的pos位置开始向后查找;否则从起始处查找。


如果找到了,函数会返回第一个匹配的字符/字符串首字符的位置。如果找不到,则返回npos(第六点有介绍)。


这里解释一下第三个重载函数:从pos位置开始,查找对象字符串中的第一个匹配的子串,该子串由字符串s中前n个字符构成。



与find相反,rfind的作用是查找一个字符串当中最后一次出现的子串或者字符。如果给定了参数pos,则函数会从字符串的pos位置开始向前查找;否则从起始处查找。其余机制与find相同,不多做赘述。


substr


substr会产生一个新的string对象,该对象中的字符串是由原字符串中pos位置开始的len个字符组成。如果没有给定参数len,则一直截取到原字符串末尾。


使用举例:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str1 = "hello world";
    string str2 = str1.substr(2);//截取下标为2的位置开始的部分
    string str3 = str1.substr(2, 6);//截取下标为2的位置开始的六个字符
 
    cout << str2 << endl;
    cout << str3 << endl;
    return 0;
}


六、string类的常量成员

刚才我们在一些接口的缺省参数中看到了"npos",它便是string类的常量成员。



npos具有size_t类型元素的最大可能值。


当在string的成员函数中作为len(或sublen)参数的值时,该值表示“直到字符串结束”。


作为返回值,它通常用于表示没有匹配。


该常量定义为-1,由于size_t是无符号整型,因此它是该类型的最大可表示值。


七、string类的非成员函数

最后,我们介绍几个string类相关的非成员函数,它们在string的使用中有至关重要的作用。



relational operators(关系运算符重载)


string类重载了一系列关系运算符,用于比较对象之间的大小。它们的比较机制与c语言中的strcmp相同。我们使用这些运算符时,只需要将两对象放在运算符两边即可。


使用举例:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str1 = "abc";
    string str2 = "abd";
    
    //大小比较
    if (str1 > str2)
    {
        cout << "str1 > str2" << endl;
    }
    else if (str1 == str2)
    {
        cout << "str1 == str2" << endl;
    }
    else
    {
        cout << "str1 < str2" << endl;
    }
    return 0;
}


operator>>和operator<<



这两个运算符重载用于对string的输入和输出。使用方法与其他内置类型的输入输出相同。


对于输入操作,函数会以空格、回车等字符作为分隔符,它们将无法读入字符串当中。如果想要读取这些字符,就需要使用getline函数。


getline


getline的作用是从输入流中提取字符串并将其存储到str中,直到找到分隔字符delim(没有给定该参数时,分隔符默认是 '\n' )。如果到达文件的末尾,或者在输入操作期间发生其他错误,提取也会停止。如果找到分隔符,则提取并丢弃它(即不存储它,下一个输入操作将在它之后开始)。


注意:调用之前str中的任何内容都将被新提取的序列替换。


使用该函数输入时,每个提取的字符都被附加到字符串中,就像调用了其成员push_back一样。


使用举例:

#include <iostream>
#include <string>
using namespace std;
 
int main()
{
    string str1;
    getline(cin, str1);//使用getline输入整行
    cout << str1 << endl << endl;
 
    string str2;
    cin >> str2;//使用operator>>输入
    cout << str2 << endl;
    return 0;
}


可以看到,getline读取了一整行字符,而operator>>遇到空格就停止读取。

swap


成员函数当中也有一个swap接口,用于两个字符串的交换。这个非成员的swap作用于其相同,只是在调用方法上略有不同而已。


总结

       今天,我们正式进入了STL的大门,学习了第一个容器——string。string虽然接口较多,但是它的实用性很高,为我们处理字符串提供了很多便利。由于其中一些接口并不是很常用,博主就没有过多赘述,大家可以在cplusplus官网进一步了解它们。之后博主会和大家一起,在熟练运用的基础上,深入其底层,并尝试模拟实现string类。如果你觉得博主讲的还不错,就请留下一个小小的赞在走哦,感谢大家的支持❤❤❤

相关文章
|
14天前
|
C++ 芯片
【C++面向对象——类与对象】Computer类(头歌实践教学平台习题)【合集】
声明一个简单的Computer类,含有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等等,以及两个公有成员函数run、stop。只能在类的内部访问。这是一种数据隐藏的机制,用于保护类的数据不被外部随意修改。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。成员可以在派生类(继承该类的子类)中访问。成员,在类的外部不能直接访问。可以在类的外部直接访问。为了完成本关任务,你需要掌握。
55 19
|
14天前
|
存储 编译器 数据安全/隐私保护
【C++面向对象——类与对象】CPU类(头歌实践教学平台习题)【合集】
声明一个CPU类,包含等级(rank)、频率(frequency)、电压(voltage)等属性,以及两个公有成员函数run、stop。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。​ 相关知识 类的声明和使用。 类的声明和对象的声明。 构造函数和析构函数的执行。 一、类的声明和使用 1.类的声明基础 在C++中,类是创建对象的蓝图。类的声明定义了类的成员,包括数据成员(变量)和成员函数(方法)。一个简单的类声明示例如下: classMyClass{ public: int
39 13
|
14天前
|
编译器 数据安全/隐私保护 C++
【C++面向对象——继承与派生】派生类的应用(头歌实践教学平台习题)【合集】
本实验旨在学习类的继承关系、不同继承方式下的访问控制及利用虚基类解决二义性问题。主要内容包括: 1. **类的继承关系基础概念**:介绍继承的定义及声明派生类的语法。 2. **不同继承方式下对基类成员的访问控制**:详细说明`public`、`private`和`protected`继承方式对基类成员的访问权限影响。 3. **利用虚基类解决二义性问题**:解释多继承中可能出现的二义性及其解决方案——虚基类。 实验任务要求从`people`类派生出`student`、`teacher`、`graduate`和`TA`类,添加特定属性并测试这些类的功能。最终通过创建教师和助教实例,验证代码
37 5
|
14天前
|
存储 算法 搜索推荐
【C++面向对象——群体类和群体数据的组织】实现含排序功能的数组类(头歌实践教学平台习题)【合集】
1. **相关排序和查找算法的原理**:介绍直接插入排序、直接选择排序、冒泡排序和顺序查找的基本原理及其实现代码。 2. **C++ 类与成员函数的定义**:讲解如何定义`Array`类,包括类的声明和实现,以及成员函数的定义与调用。 3. **数组作为类的成员变量的处理**:探讨内存管理和正确访问数组元素的方法,确保在类中正确使用动态分配的数组。 4. **函数参数传递与返回值处理**:解释排序和查找函数的参数传递方式及返回值处理,确保函数功能正确实现。 通过掌握这些知识,可以顺利地将排序和查找算法封装到`Array`类中,并进行测试验证。编程要求是在右侧编辑器补充代码以实现三种排序算法
29 5
|
14天前
|
Serverless 编译器 C++
【C++面向对象——类的多态性与虚函数】计算图像面积(头歌实践教学平台习题)【合集】
本任务要求设计一个矩形类、圆形类和图形基类,计算并输出相应图形面积。相关知识点包括纯虚函数和抽象类的使用。 **目录:** - 任务描述 - 相关知识 - 纯虚函数 - 特点 - 使用场景 - 作用 - 注意事项 - 相关概念对比 - 抽象类的使用 - 定义与概念 - 使用场景 - 编程要求 - 测试说明 - 通关代码 - 测试结果 **任务概述:** 1. **图形基类(Shape)**:包含纯虚函数 `void PrintArea()`。 2. **矩形类(Rectangle)**:继承 Shape 类,重写 `Print
34 4
|
14天前
|
设计模式 IDE 编译器
【C++面向对象——类的多态性与虚函数】编写教学游戏:认识动物(头歌实践教学平台习题)【合集】
本项目旨在通过C++编程实现一个教学游戏,帮助小朋友认识动物。程序设计了一个动物园场景,包含Dog、Bird和Frog三种动物。每个动物都有move和shout行为,用于展示其特征。游戏随机挑选10个动物,前5个供学习,后5个用于测试。使用虚函数和多态实现不同动物的行为,确保代码灵活扩展。此外,通过typeid获取对象类型,并利用strstr辅助判断类型。相关头文件如&lt;string&gt;、&lt;cstdlib&gt;等确保程序正常运行。最终,根据小朋友的回答计算得分,提供互动学习体验。 - **任务描述**:编写教学游戏,随机挑选10个动物进行展示与测试。 - **类设计**:基类
26 3
|
24天前
|
编译器 C语言 C++
【c++丨STL】list模拟实现(附源码)
本文介绍了如何模拟实现C++中的`list`容器。`list`底层采用双向带头循环链表结构,相较于`vector`和`string`更为复杂。文章首先回顾了`list`的基本结构和常用接口,然后详细讲解了节点、迭代器及容器的实现过程。 最终,通过这些步骤,我们成功模拟实现了`list`容器的功能。文章最后提供了完整的代码实现,并简要总结了实现过程中的关键点。 如果你对双向链表或`list`的底层实现感兴趣,建议先掌握相关基础知识后再阅读本文,以便更好地理解内容。
30 1
|
4月前
|
Java 索引
java基础(13)String类
本文介绍了Java中String类的多种操作方法,包括字符串拼接、获取长度、去除空格、替换、截取、分割、比较和查找字符等。
54 0
java基础(13)String类
|
3月前
|
Java
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
本文深入探讨了Java中方法参数的传递机制,包括值传递和引用传递的区别,以及String类对象的不可变性。通过详细讲解和示例代码,帮助读者理解参数传递的内部原理,并掌握在实际编程中正确处理参数传递的方法。关键词:Java, 方法参数传递, 值传递, 引用传递, String不可变性。
81 1
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
|
3月前
|
安全 Java 测试技术
Java零基础-StringBuffer 类详解
【10月更文挑战第9天】Java零基础教学篇,手把手实践教学!
81 2

热门文章

最新文章