【c++】STL--string_c+(1),2024年最新专题解析

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新大数据全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip204888 (备注大数据)
img

正文

}

int main()
{
TestPushBack();

return 0;

}


![](https://img-blog.csdnimg.cn/6874daa0c31e469cb833421750e34edf.png)


**我们发现在vs2013环境下,它是以1.5倍扩容的**


linux下--同样的代码


![](https://img-blog.csdnimg.cn/0bd746807420405db7af1601bd76cabf.png)


**那么在linux下我们发现,它是以2倍扩容的**



> 
> 我们知道要插入多少数据,提前用reserve开好空间,避免扩容,提高效率
> 
> 
> 


**resize**



> 
> void resize (size\_t n);
> 
> 
> void resize (size\_t n, char c);
> 
> 
> 


Resize string----调整字符串大小



> 
> Resizes the string to a [length]( ) of *n* characters.  
>   
>  If *n* is smaller than the current [string length]( ), the current value is shortened to its first *n* character, removing the characters beyond the *n*th.  
>   
>  If *n* is greater than the current [string length]( ), the current content is extended by inserting at the end as many characters as needed to reach a size of *n*. If *c* is specified, the new elements are initialized as copies of *c*, otherwise, they are *value-initialized characters* (null characters).
> 
> 
> -----将字符串的长度调整为n个字符。如果n小于当前字符串长度,则将当前值缩短为其第一个n个字符,删除第n个字符以外的字符。如果n大于当前字符串长度,则通过在末尾插入尽可能多的字符来扩展当前内容,以达到n的大小。如果指定了c,则将新元素初始化为c的副本,否则,它们是值初始化字符(空字符)。
> 
> 
> 



#include
#include

int main()
{
std::string str(“I like to code in C”);
std::cout << str << ‘\n’;

unsigned sz = str.size();
std::cout << sz << '\n';

str.resize(sz + 2, '+');//增加两个字符‘++’
std::cout << str << '\n';

str.resize(14);//减少5个字符
std::cout << str << '\n';
return 0;

}


![](https://img-blog.csdnimg.cn/6380b4de94ec4198a733defeb22668bf.png)


####  string类对象的访问及遍历操作


**operator[]**



> 
> char& operator[] (size\_t pos);
> 
> 
> const char& operator[] (size\_t pos) const;
> 
> 
> 


Returns a reference to the character at position *pos* in the [string]( ).


----返回pos位置的字符,const string类对象调用



#include
#include

int main()
{
std::string str(“Test string”);
for (int i = 0; i<str.length(); ++i)
{
std::cout << str[i];
}
return 0;
}


**begin /end**



> 
> iterator begin();
> 
> 
> const\_iterator begin() const;
> 
> 
> 


Returns an iterator pointing to the first character of the string


----返回指向字符串第一个字符的迭代器 



> 
> iterator end();
> 
> 
> const\_iterator end() const;
> 
> 
> 


Returns an iterator pointing to the *past-the-end* character of the string.


----返回一个迭代器,该迭代器指向字符串的结束字符。



#include
#include

int main()
{
std::string str(“Test string”);
for (std::string::iterator it = str.begin(); it != str.end(); ++it)
std::cout << *it;
std::cout << ‘\n’;

return 0;

}


![](https://img-blog.csdnimg.cn/56db37c8f2e24c6a8888a3983607a783.png)


**rend/rbegin**


reverse\_iterator rbegin();  
 const\_reverse\_iterator rbegin() const;


Return reverse iterator to reverse beginning


----返回反向迭代器以反向开始


reverse\_iterator rend();  
 const\_reverse\_iterator rend() const;


Return reverse iterator to reverse end


----将反向迭代器返回到反向端



#include
#include

int main ()
{
std::string str (“now step live…”);
for (std::string::reverse_iterator rit=str.rbegin(); rit!=str.rend(); ++rit)
std::cout << *rit;
return 0;
}


![](https://img-blog.csdnimg.cn/eb497481ab834aa39f9f9c43bf598eab.png)


C++中,迭代器就是一个类似于指针的对象,它能够用来[遍历]( )C++标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。


这里需要注意的是,,对于string类来说,无论是正向遍历,还是反向遍历,下标+[]都足够好用,但是对于其他容器,对于那些以链表形式连接的数据结构,如list,map/set等,就不能使用下标+[]的方式去访问容器里的元素,所以就需要采用**迭代器来访问这些容器里的元素**。


vector--容器



vector<int> v;
vector<int>::iterator vit = v.begin();
while (vit != v.end())
{
	cout << *vit << " ";
	vit++;
}
cout << endl;

#### string类对象的修改操作


**push\_back**



> 
> void push\_back (char c);
> 
> 
> 


ppends character *c* to the end of the [string]( ), increasing its [length]( ) by one.


----将字符c追加到字符串的末尾,将其长度增加1



#include
#include
#include
using namespace std;

int main()
{
string str;
str.push_back(‘h’);
str.push_back(‘e’);
str.push_back(‘l’);
str.push_back(‘l’);
str.push_back(‘o’);

std::cout << str << '\n';
return 0;

}


**append**




|  |  |
| --- | --- |
| string (1) | 

string& append (const string& str);

 |
| substring (2) | 

string& append (const string& str, size_t subpos, size_t sublen);

 |
| c-string (3) | 

string& append (const char* s);

 |
| buffer (4) | 

string& append (const char* s, size_t n);

 |
| fill (5) | 

string& append (size_t n, char c);

 |
| range (6) | 

template
string& append (InputIterator first, InputIterator last);

 |




> 
> (1) string
> 
> 
> Appends a copy of *str*.----追加str的副本
> 
> 
> (2) substring
> 
> 
> Appends a copy of a substring of *str*. The substring is the portion of *str* that begins at the character position *subpos* and spans *sublen* characters (or until the end of *str*, if either *str* is too short or if *sublen* is [string::npos]( )).
> 
> 
> ----追加str的子字符串的副本。该子字符串是str的一部分,从字符位置子字符串开始,跨越子字符串字符(或直到str结尾,如果str太短或子字符串为string::npos)
> 
> 
> (3) c-string
> 
> 
> Appends a copy of the string formed by the null-terminated character sequence (C-string) pointed by *s*.
> 
> 
> ----追加由s指向的以空结尾的字符序列(C字符串)形成的字符串的副本
> 
> 
> (4) buffer
> 
> 
> Appends a copy of the first *n* characters in the array of characters pointed by *s*.
> 
> 
> ----追加由s指向的字符数组中前n个字符的副本
> 
> 
> (5) fill
> 
> 
> Appends *n* consecutive copies of character *c*.
> 
> 
> ----追加n个字符c的连续副本。
> 
> 
> (6) range
> 
> 
> Appends a copy of the sequence of characters in the range [first,last), in the same order.
> 
> 
> ----以相同的顺序追加范围[first,last]中字符序列的副本。
> 
> 
> 



#include
#include

int main()
{
std::string str;
std::string str2 = "Writing ";
std::string str3 = “print 10 and then 5 more”;

str.append(str2);                       // 情况1
std::cout << str << '\n';

str.append(str3, 6, 3);                   // 情况2
std::cout << str << '\n';

str.append("dots are cool", 5);          // 情况3
std::cout << str << '\n';

str.append("here: ");                   // 情况4
std::cout << str << '\n';

str.append(10u, '.');                    // 情况5
std::cout << str << '\n';

str.append(str3.begin() + 8, str3.end());  // 情况6
std::cout << str << '\n';

return 0;

}


![](https://img-blog.csdnimg.cn/77f1d84bf5ef4a6792aebf7d1cb95f68.png)


**operator+=**


Append to string----附加到字符串




|  |  |
| --- | --- |
| string (1) | 

string& operator+= (const string& str);

 |
| c-string (2) | 

string& operator+= (const char* s);

 |
| character (3) | 

string& operator+= (char c);

 |



#include
#include

int main()
{
std::string name(“John”);
std::string family(“Smith”);
name += " K. "; // c-string
name += family; // string
name += ‘\n’; // character

std::cout << name;
return 0;

}



> 
> 运行结果:John K. Smith
> 
> 
> 


**c\_str**



> 
> const char\* c\_str() const;
> 
> 
> 


Get C string equivalent----获取等效的C字符串



> 
> Returns a pointer to an array that contains a null-terminated sequence of characters (i.e., a C-string) representing the current value of the string object.
> 
> 
> This array includes the same sequence of characters that make up the value of the string object plus an additional terminating null-character ('\0') at the end.
> 
> 
> ----返回指向数组的指针,该数组包含表示字符串对象当前值的以空结尾的字符序列(即C字符串)。
> 
> 
> 此数组包含构成字符串对象值的相同字符序列,加上末尾的附加终止空字符(“\0”)。
> 
> 
> 



#include
#include
#include

int main()
{
std::string str(“Please split this sentence into tokens”);//str是一个类

char * cstr = new char[str.length() + 1];
std::strcpy(cstr, str.c_str());				//将字符串返回成char *,然后进行拷贝
											//char *strcpy(char *dest, const char *src)
											//  str现在包含str的c字符串副本

char * p = std::strtok(cstr, " ");			//char *strtok( char *strToken, const char *strDelimit );
											//分解字符串为一组字符串

while (p != 0)
{
	std::cout << p << '\n';
	p = std::strtok(NULL, " ");
}

delete[] cstr;
return 0;

}


![](https://img-blog.csdnimg.cn/25c1000f40c5416ba6d201dfb4e3493c.png)


**find + npos**




|  |  |
| --- | --- |
| string (1) | 

size_t find (const string& str, size_t pos = 0) const;

 |
| c-string (2) | 

size_t find (const char* s, size_t pos = 0) const;

 |
| buffer (3) | 

size_t find (const char* s, size_t pos, size_t n) const;

 |
| character (4) | 

size_t find (char c, size_t pos = 0) const;

 |


Find content in string----在字符串中查找内容



> 
> static const size\_t npos = -1;
> 
> 
> 


npos:Maximum value for size\_t----size\_t的最大值



#include
#include
using namespace std;

int main()
{
string str(“There are two needles in this haystack with needles.”);
string str2(“needle”);

// different member versions of find in the same order as above:
size_t found = str.find(str2);
if (found != string::npos)
	cout << "first 'needle' found at: " << found << '\n';

found = str.find("needles are small", found + 1, 6);
if (found != string::npos)
	cout << "second 'needle' found at: " << found << '\n';

found = str.find("haystack");
if (found != string::npos)
	cout << "'haystack' also found at: " << found << '\n';

found = str.find('.');
if (found != string::npos)
	cout << "Period found at: " << found << '\n';

// let's replace the first needle:
str.replace(str.find(str2), str2.length(), "preposition");
cout << str << '\n';

return 0;

}


![](https://img-blog.csdnimg.cn/31d105e5b3304185a4c75f833530c46a.png)


**rfind**




|  |  |
| --- | --- |
| string (1) | 

size_t rfind (const string& str, size_t pos = npos) const;

 |
| c-string (2) | 

size_t rfind (const char* s, size_t pos = npos) const;

 |
| buffer (3) | 

size_t rfind (const char* s, size_t pos, size_t n) const;

 |
| character (4) | 

size_t rfind (char c, size_t pos = npos) const;

 |


Find last occurrence of content in string----查找字符串中内容的最后一次出现



#include
#include
#include

int main()
{
std::string str(“The sixth sick sheik’s sixth sheep’s sick.”);
std::string key(“sixth”);

std::size_t found = str.rfind(key);//找到sixth第二次出现的位置

if (found != std::string::npos)
	str.replace(found, key.length(), "seventh");//seventh替换掉二次出现的sixth

std::cout << str << '\n';

return 0;

}



> 
> 输出结果:The sixth sick sheik's seventh sheep's sick.
> 
> 
> 


**substr**



> 
> string substr (size\_t pos = 0, size\_t len = npos) const;
> 
> 
> 


Returns a newly constructed [string]( ) object with its value initialized to a copy of a substring of this object-----返回一个新构造的字符串对象,其值初始化为此对象的子字符串的副本。



#include
#include

int main ()
{
std::string str=“We think in generalities, but we live in details.”;
// (quoting Alfred N. Whitehead)

std::string str2 = str.substr (3,5); // “think”

std::size_t pos = str.find(“live”); // position of “live” in str

std::string str3 = str.substr (pos); // get from “live” to the end

std::cout << str2 << ’ ’ << str3 << ‘\n’;

return 0;
}


**注意:**


1. 在string尾部追加字符时,s.push\_back(c) / s.append(1, c) / s += 'c'三种的实现方式差不多,一般 情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。


2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好


#### string类非成员函数


**operator+ (string)**




|  |  |
| --- | --- |
| string (1) | 

string operator+ (const string& lhs, const string& rhs);

 |
| c-string (2) | 

string operator+ (const string& lhs, const char* rhs);
string operator+ (const char* lhs, const string& rhs);

 |
| character (3) | 

string operator+ (const string& lhs, char rhs);
string operator+ (char lhs, const string& rhs);

 |


Concatenate strings ----连接字符串



#include
#include

int main()
{
std::string firstlevel(“com”);
std::string secondlevel(“cplusplus”);
std::string scheme(“http://”);
std::string hostname;
std::string url;

hostname = "www. " + secondlevel + '.' + firstlevel;
url = scheme + hostname;

std::cout << url << '\n';

return 0;

}


运行结果:http://www. cplusplus.com


**operator>> (string)**


istream& operator>> (istream& is, string& str);


Extract string from stream----从流中提取字符串



#include
#include

int main()
{
std::string name;

std::cout << "Please, enter your name: ";
std::cin >> name;
std::cout << "Hello, " << name << "!\n";

return 0;

}


![](https://img-blog.csdnimg.cn/ca9bd87f525043e598a98949db13e9fa.png)


**operator<< (string)**



> 
>  ostream& operator<< (ostream& os, const string& str);
> 
> 
> 


Insert string into stream----将字符串插入流 



#include
#include

int main()
{
std::string str = “Hello world!”;
std::cout << str << ‘\n’;
return 0;
}


**getline (string)**




|  |  |
| --- | --- |
| (1) | 

istream& getline (istream& is, string& str, char delim);

 |
| (2) | 

istream& getline (istream& is, string& str);

 |


Get line from stream into string----从流获取线到字符串 



#include
#include

int main()
{
std::string name;

std::cout << "Please, enter your full name: ";
std::getline(std::cin, name);
std::cout << "Hello, " << name << "!\n";

return 0;

}


![](https://img-blog.csdnimg.cn/c1426a4f2ce7433e8696f8e379ee3ca9.png)


 relational operators (string)




|  |  |
| --- | --- |
| (1) | 

bool operator== (const string& lhs, const string& rhs);
bool operator== (const char* lhs, const string& rhs);
bool operator== (const string& lhs, const char* rhs);

 |
| (2) | 

bool operator!= (const string& lhs, const string& rhs);
bool operator!= (const char* lhs, const string& rhs);
bool operator!= (const string& lhs, const char* rhs);

 |
| (3) | 

bool operator< (const string& lhs, const string& rhs);
bool operator< (const char* lhs, const string& rhs);
bool operator< (const string& lhs, const char* rhs);

 |
| (4) | 

bool operator<= (const string& lhs, const string& rhs);
bool operator<= (const char* lhs, const string& rhs);
bool operator<= (const string& lhs, const char* rhs);

 |
| (5) | 

bool operator> (const string& lhs, const string& rhs);
bool operator> (const char* lhs, const string& rhs);
bool operator> (const string& lhs, const char* rhs);

 |
| (6) | 

bool operator>= (const string& lhs, const string& rhs);
bool operator>= (const char* lhs, const string& rhs);
bool operator>= (const string& lhs, const char* rhs);

 |


Relational operators for string----字符串的关系运算符



#include
#include

int main()
{
std::string foo = “alpha”;
std::string bar = “beta”;

if (foo == bar) std::cout << "foo and bar are equal\n";
if (foo != bar) std::cout << "foo and bar are not equal\n";
if (foo< bar) std::cout << "foo is less than bar\n";
if (foo> bar) std::cout << "foo is greater than bar\n";
if (foo <= bar) std::cout << "foo is less than or equal to bar\n";
if (foo >= bar) std::cout << "foo is greater than or equal to bar\n";

return 0;

}


![](https://img-blog.csdnimg.cn/62fad67e55f1456a88140ac843d51f6e.png)


### string类的模拟实现


#### 经典的string类问题


我们在模拟实现string的时候,可以先看看string类的经典问题。在实现string类的构造、拷贝构造、赋值运算符重载以及析构函数时,经常会出现深浅拷贝的问题。


**构造String类对象的错误:**



> 
> String(const char\* str = "\0") ----错误示范,"\0"是需要内存存放的
> 
> 
> String(const char\* str = nullptr) ----错误示范,String是类,地址是不会指向nullptr
> 
> 
> Sring(const char\* str = "")----正确示范
> 
> 
> 


构造String类对象时,如果传递nullptr指针,可以认为程序非法。


**浅拷贝的问题:**



#include
#include <assert.h>
using namespace std;
class String
{
public:
String(const char* str = “”)
{

if (nullptr == str)
{
	assert(false);
	return;
}

_str = new char[strlen(str) + 1];
strcpy(_str, str);

}

~String()
{
if (_str)
{
delete[] _str;
_str = nullptr;
}
}

private:
char* _str;
};
// 测试
void TestString()
{
String s1(“hello bit!!!”);
String s2(s1);
}

int main()
{
TestString();

return 0;

}


在这段代码中,我们发现测试的时候,开始s1传入字符串是没有问题的,但是将s1的地址传入s2时,就会出现错误。因为在s2调用构造函数的时候,s2中的\_str存放的地址也是s1的地址。那么在调用析构函数的时候,我们就会发现调用了两次析构函数,第一将\_str清除后,s2再调用析构函数的时候,此时\_str已经是随机值,再对\_str进行删除的时候就会报错。


![](https://img-blog.csdnimg.cn/6ab0fc9be2894d9cafb56865850e1148.png)


**运行结果:**![](https://img-blog.csdnimg.cn/fa9f25dcbee142b8bda45f774dd0fc80.png)


**说明:**上述String类没有显式定义其拷贝构造函数与赋值运算符重载,此时编译器会合成默认的,当用s1构造s2时,编译器会调用默认的拷贝构造。**最终导致的问题是,s1、s2共用同一块内存空间,在释放时同一块 空间被释放多次而引起程序崩溃,这种拷贝方式,称为浅拷贝**。


那么什么是深拷贝?什么是浅拷贝呢?


#### 浅拷贝/深拷贝


**浅拷贝:**也称位拷贝,编译器只是将对象中的值拷贝过来。如果对象中管理资源,最后就会导致多个对象共享同一份资源,当一个对象销毁时就会将该资源释放掉,而此时另一些对象不知道该资源已经被释放,以为还有效,所以当继续对资源进项操作时,就会发生发生了访问违规。


可以采用深拷贝解决浅拷贝问题,即:**每个对象都有一份独立的资源,不要和其他对象共享**。


**深拷贝:**如果一个类中涉及到资源的管理,其拷贝构造函数、赋值运算符重载以及析构函数必须要显式给出。一般情况都是按照深拷贝方式提供。


![](https://img-blog.csdnimg.cn/b00fcab5be0947ddb5736675a005f1fd.png)


#### string类的模拟实现



#define _CRT_SECURE_NO_WARNINGS

#include
using namespace std;
#include <assert.h>

#define npos -1

namespace bit
{
class string
{
public:
typedef char* iterator;

public:
	string(const char* str = "")//构造空的string类对象,即空字符串
	{
		// 构造String类对象时,如果传递nullptr指针,可以认为程序非法
		if (nullptr == str)
		{
			assert(false);
			return;
		}

		_str = new char[strlen(str) + 1];//扩容要加'/0'
		strcpy(_str, str);
	}

	string(const string& s) //拷贝构造函数
		: _str(new char[strlen(s._str) + 1])//初始化列表
	{
		strcpy(_str, s._str);
	}

	string& operator=(const string& s)//字符串赋值
	{
		if (this != &s)
		{
			char* pStr = new char[strlen(s._str) + 1];
			strcpy(pStr, s._str);
			delete[] _str;
			_str = pStr;
		}
		return *this;
	}

	~string()//析构函数
	{
		if (_str)
		{
			delete[] _str;
			_str=nullptr;
		}
	}
	/
	// iterator--迭代器
	iterator begin()//返回到开始
	{
		return _str;
	}

	iterator end()//返回到结束
	{
		return _str + _size;
	}

	/
	// modify--修改

	void push_back(char c)//将字符附加到字符串
	{
		if (_size == _capacity)
			reserve(_capacity * 2);//2倍扩容

		_str[_size++] = c;
		_str[_size] = '\0';//++后添加上‘\0’
	}

	string& operator+=(char c)
	{
		push_back(c);
		return *this;
	}

	
	void append(const char* str)
	{
		size_t n = strlen(str);
		if (_size + n > _capacity )
		{
			reserve(_size + n);
		}

		strcpy(_str + _size, str);
		_size += n;

	}
	string& operator+=(const char* str)
	{
		append(str);
		return *this;
	}

	void clear()
	{
		_str[0] = '\0';

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

pStr = new char[strlen(s._str) + 1];
strcpy(pStr, s._str);
delete[] _str;
_str = pStr;
}
return *this;
}

	~string()//析构函数
	{
		if (_str)
		{
			delete[] _str;
			_str=nullptr;
		}
	}
	/
	// iterator--迭代器
	iterator begin()//返回到开始
	{
		return _str;
	}

	iterator end()//返回到结束
	{
		return _str + _size;
	}

	/
	// modify--修改

	void push_back(char c)//将字符附加到字符串
	{
		if (_size == _capacity)
			reserve(_capacity * 2);//2倍扩容

		_str[_size++] = c;
		_str[_size] = '\0';//++后添加上‘\0’
	}

	string& operator+=(char c)
	{
		push_back(c);
		return *this;
	}

	
	void append(const char* str)
	{
		size_t n = strlen(str);
		if (_size + n > _capacity )
		{
			reserve(_size + n);
		}

		strcpy(_str + _size, str);
		_size += n;

	}
	string& operator+=(const char* str)
	{
		append(str);
		return *this;
	}

	void clear()
	{
		_str[0] = '\0';

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)
[外链图片转存中…(img-EbVfmtrV-1713338251344)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 12
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值