C++面试基础篇(后续继续更新.....)

1.C++中的 struct 和 class 有什么区别?

  • 【参考答案】从语法上讲,class和struct做类型定义时只有两点区别: 
  • (一)默认继承权限。如果不明确指定,来自class的继承按照private继承处理,来自struct的继承按照public继承处理; 
  • (二)成员的默认访问权限。class的成员默认是private权限,struct默认是public权限。 除了这两点,class和struct基本就是一个东西。语法上没有任何其它区别

2.如何判断一段程序是由C 编译程序还是由C++编译程序编译的?(LZ曾经遇到过并不多,留个印象)

#ifdef __cplusplus  

        cout<<“c++";  

#else  

        printf("c");  

#endif  

3.c/c++引用和指针区别?(经常面试到)

  •   1.指针是指向内存地址的一个存储单元;而引用仅是个别名;
  •   2.引用使用时无需解引用(*),指针需要解引用;
  •   3.引用只能在定义时被初始化一次,之后不可变;指针可变;
  •   4.引用没有 const,指针有 const;
  •   5.引用不能为空,指针可以为空;
  •   6.“sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身的大小;

4. const  与 #define 的比较 ,const有什么优点?(出现概率也比较大)

1.编译器处理方式 
define – 在预处理阶段进行替换 
const – 在编译时确定其值

2.类型检查 
define – 无类型,不进行类型安全检查,可能会产生意想不到的错误 
const – 有数据类型,编译时会进行类型检查

3.内存空间 
define – 不分配内存,给出的是立即数,有多少次使用就进行多少次替换,在内存中会有多个拷贝,消耗内存大 
const – 在静态存储区中分配空间,在程序运行过程中内存中只有一个拷贝

4.其他 
在编译时, 编译器通常不为const常量分配存储空间,而是将它们保存在符号表中,这使得它成为一个编译期间的常量,没有了存储与读内存的操作,使得它的效率也很高。 
宏替换只作替换,不做计算,不做表达式求解。

// 拓展一下之前define没有的用法,有点类似与匿名函数

5.有了 malloc/free 为什么还要 new/delete ?(出现概率较大)

  • malloc 与 free 是 C++/C 语言的标准库函数,new/delete 是 C++的运算符。它们都可用于申请动态内存和释放内存
  • 对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数,而malloc/free没有

6.C++是不是类型安全的?(了解)

  • 不是。两个不同类型的指针之间可以强制转换(用reinterpret cast)

7.(1)const char *p       (2)char const *p      (3)char * const p       (4)const char *const p
说明上面三种描述的区别;(重点很多面试都会问到)

  • 1.p是一个指向const char的指针,p是可以改变指向的,但是p指向的值是不能改变的;      
  • 2.p指向的恰好是一个指向const的char的普通指针;
  • 3.p是一个指针,这个指针是指向char的const指针.p指向的不可改变,但可以改变指向的值
  • 4.p指向的不可改变,同时p指向的值是不能改变的;
  • (1)和(2)的定义是一样的。

 8.用C++写个程序,如何判断一个操作系统是16位还是32位的?(了解,面试过不多)

方法一:定义一个指针p,打印出sizeof(p),如果节后是4,则表示该操作系统是32位,打印结果是2,表示是16位。

方法二:

int a = ~0;

if(a > 65536) {

    cout<<"32 bit"<<endl;

} else {

    cout<<"16 bit"<<endl;

}

9.(1)void * ( * (*fp1)(int))[10];             (2)float (*(* fp2)(int,int,int))(int);                      (3)int (* ( * fp3)())[10](); 
分别表示什么意思? (函数指针,面试不多,但也是重点)

  • void * ( * (*fp1)(int))[10];  fp1是一个指针,指向一个函数,这个函数的参数为int型,函数的返回值是一个指针,这个指针指向一个数组,这个数组有10个元素,每个元素是一个void*型指针。
  • float (*(* fp2)(int,int,int))(int);  fp2是一个指针,指向一个函数,这个函数的参数为3个int型,函数的返回值是一个指针,这个指针指向一个函数,这个函数的参数为int型,函数的返回值是float型。
  • int (* ( * fp3)())[10]();  fp3是一个指针,指向一个函数,这个函数的参数为空,函数的返回值是一个指针,这个指针指向一个数组,这个数组有10个元素,每个元素是一个指针,指向一个函数,这个函数的参数为空,函数的返回值是int型

10.C/C++程序内存的分配

  • 栈区(stack):由编译器自动分配与释放,存放为运行时函数分配的局部变量、函数参数、返回数据、返回地址等。其操作类似于数据结构中的栈。
  • 堆区(heap):一般由程序员自动分配,如果程序员没有释放,程序结束时可能有OS回收。其分配类似于链表或者new/delete。
  • 全局区(静态区static):存放全局变量、静态数据、常量。程序结束后由系统释放。全局区分为已初始化全局区(data)和未初始化全局区(bss)。
  • 常量区(文字常量区):存放常量字符串,程序结束后有系统释放。
  • 代码区:存放函数体(类成员函数和全局区)的二进制代码。
     

11.为什么数组名作为参数,会改变数组的内容,而其它类型如int却不会改变变量的值?

  • 当数组名作为参数时,传递的实际上是地址。而其他类型如int作为参数时,由于函数参数值实质上是实参的一份拷贝,被调函数内部对形参的改变并不影响实参的值。

12.const关键字?有哪些作用?(重点)

  • (1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;
  • (2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;
  • (3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
  • (4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;
  • (5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。
  • 注: 这个题可以考查面试者对程序设计知识的掌握程度是初级、中级还是比较深入,没有一定的知识广度和深度,不可能对这个问题给出全面的解答。大多数人只能回答出 static 和 const 关键字的部分功能。

13.当一个类A 中没有声命任何成员变量与成员函数,这时sizeof(A)的值是多少,如果不是零,请解释一下编译器为什么没有让它为零

  • sizeof(A) = 1;最小存储为1,空类也可以继承等操作

14.用变量a给出下面的定义(这题后面几个很容易搞混)

a) 一个整型数(An integer)

b) 一个指向整型数的指针(A pointer to an integer)

c) 一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to a pointer to an integer)

d) 一个有10个整型数的数组(An array of 10 integers)

e) 一个有10个指针的数组,该指针是指向一个整型数的(An array of 10 pointers to integers)

f) 一个指向有10个整型数数组的指针(A pointer to an array of 10 integers)

g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer)

h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数( An array of ten pointers to functions that take an integer argument and return an integer )

  • a) int a; // An integer
  • b) int *a; // A pointer to an integer
  • c) int **a; // A pointer to a pointer to an integer
  • d) int a[10]; // An array of 10 integers
  • e) int *a[10]; // An array of 10 pointers to integers
  • f) int (*a)[10]; // A pointer to an array of 10 integers
  • g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integer
  • h) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer

15.如果 ClassA 中定义并实现虚函数 int func(void),ClassB 中也实现该函数,那么上述变量 a->func() 将调用哪个类里面的函数?如果 int func(void) 不是虚函数,情况又如何?为什么? 

  • 第一问调用的是B的。第二问调用A的。虚函数的一个典型应用,虚函数只能借助于指针或者引用来达到多态的效果。

16.字符串倒叙输出

方法1:

#include "stdafx.h"
#include <stdio.h>
#include <string.h>

int main()
{
    char ch1[10] = "abcde", ch2[10] = {0};
    int n=0, i=0, j=0;
    n = strlen(ch1);
    for(i = n-1; i>=0; i--)
    {
        ch2[j] = ch1[i];
        j++;
    }
    printf("%s\n%s\n", ch1, ch2);
    return 0;
}

方法2:

#include "stdafx.h"
#include <stdio.h>
#include <string.h>
using namespace std;
#include <vector>

int main()
{
    char ch1[10] = "abcde", ch2[10] = {0};
    int n=0, i=0, j=0;
    n = strlen(ch1);
    vector <char> cVec(ch1, ch1+n);
    for(i = cVec.size()-1; i>=0; i--)
    {
        ch2[j] = ch1[i];
        j++;
    }
    printf("%s\n%s\n", ch1, ch2);
    return 0;
}

方法3:

#include "stdafx.h"
#include <stdio.h>
#include <string.h>
using namespace std;
#include <vector>
#include <iterator>

int main()
{
    char ch1[10] = "abcde", ch2[10] = {0};
    int n=0, i=0, j=0;
    n = strlen(ch1);
    vector <char> cVec(ch1, ch1+n);
    vector <char>::reverse_iterator cRIter;

    for(cRIter=cVec.rbegin(); cRIter!=cVec.rend(); cRIter++)
    {
        ch2[j] = *cRIter;//同时也可更改*cRIter为cRIter[0];
        j++;
    }
    printf("%s\n%s\n", ch1, ch2);
    return 0;
}

方法4:

//使用双向链表list,list可以被视为一个双向链表,每个元素都具有前后元素的链接
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
using namespace std;
#include <list>
#include <iterator>

int main()
{
    char ch1[10] = "abcde", ch2[10] = {0};
    int n=0, i=0, j=0;
    n = strlen(ch1);
    list<char> cList(ch1, ch1+n);
    list<char>::reverse_iterator cRIter;

    for(cRIter=cList.rbegin(); cRIter!=cList.rend(); cRIter++)
    {
        ch2[j] = *cRIter;
        j++;
    }
    printf("%s\n%s\n", ch1, ch2);
    return 0;
}

17.基类为什么需要虚析构函数? 

防止内存泄漏。想去借助父类指针去销毁子类对象的时候,不能去销毁子类对象。假如没有虚析构函数,释放一个由基类指针指向的派生类对象时,不会触发动态绑定,则只会调用基类的析构函数,不会调用派生类的。派生类中申请的空间则得不到释放导致内存泄漏。(扩展一下什么时候需要虚析构呢?当使用到多态的时候,基类指针指向派生类对象。这时候析构对象,希望调用的是派生类的析构函数,如果没有定义虚析构函数的话,析构时只能调基类的析构函数)

18.32位,64位系统中,各种常用内置数据类型占用的字节数?

char :1个字节(固定)

*(即指针变量): 4个字节(32位机的寻址空间是4个字节。同理64位编译器)(变化*)

short int : 2个字节(固定)

int: 4个字节(固定)

unsigned int : 4个字节(固定)

float: 4个字节(固定)

double: 8个字节(固定)

long: 4个字节

unsigned long: 4个字节(变化*,其实就是寻址控件的地址长度数值)

long long: 8个字节(固定)


64位操作系统

char :1个字节(固定)

*(即指针变量): 8个字节

short int : 2个字节(固定)

int: 4个字节(固定)

unsigned int : 4个字节(固定)

float: 4个字节(固定)

double: 8个字节(固定)

long: 8个字节

unsigned long: 8个字节(变化*其实就是寻址控件的地址长度数值)

long long: 8个字节(固定)

除*与long 不同其余均相同。

19.深拷贝与浅拷贝的区别?

1.什么时候用到拷贝函数?

  a.一个对象以值传递的方式传入函数体; 
  b.一个对象以值传递的方式从函数返回;

  c.一个对象需要通过另外一个对象进行初始化。

  如果在类中没有显式地声明一个拷贝构造函数,那么,编译器将会自动生成一个默认的拷贝构造函数,该构造函数完成对象之间的位拷贝。位拷贝又称浅拷贝;

2.是否应该自定义拷贝函数?

 自定义拷贝构造函数是一种良好的编程风格,它可以阻止编译器形成默认的拷贝构造函数,提高源码效率。

3.什么叫深拷贝?什么是浅拷贝?两者异同?

  如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。

4.深拷贝好还是浅拷贝好?

如果实行位拷贝,也就是把对象里的值完全复制给另一个对象,如A=B。这时,如果B中有一个成员变量指针已经申请了内存,那A中的那个成员变量也指向同一块内存。这就出现了问题:当B把内存释放了(如:析构),这时A内的指针就是野指针了,出现运行错误。

20.C++类中数据成员初始化顺序?

1.成员变量在使用初始化列表初始化时,与构造函数中初始化成员列表的顺序无关,只与定义成员变量的顺序有关。

2.如果不使用初始化列表初始化,在构造函数内初始化时,此时与成员变量在构造函数中的位置有关。

3.类中const成员常量必须在构造函数初始化列表中初始化。

4.类中static成员变量,只能在类内外初始化(同一类的所有实例共享静态成员变量)。

初始化顺序:

  • 1) 基类的静态变量或全局变量
  • 2) 派生类的静态变量或全局变量
  • 3) 基类的成员变量
  • 4) 派生类的成员变量

21.指针常量与常量指针(其实就是const*和*const)

常量指针(被指向的对象是常量)

定义:又叫常指针,可以理解为常量的指针,指向的是个常量

关键点:

  1. 常量指针指向的对象不能通过这个指针来修改,可是仍然可以通过原来的声明修改;
  2. 常量指针可以被赋值为变量的地址,之所以叫常量指针,是限制了通过这个指针修改变量的值;
  3. 指针还可以指向别处,因为指针本身只是个变量,可以指向任意地址;

const int *p或int const *p

指针常量(指针本身是常量)

定义:

本质是一个常量,而用指针修饰它。指针常量的值是指针,这个值因为是常量,所以不能被赋值。

关键点

  1. 它是个常量!
  2. 指针所保存的地址可以改变,然而指针所指向的值却不可以改变;
  3. 指针本身是常量,指向的地址不可以变化,但是指向的地址所对应的内容可以变化;
int* const p;

22.编写一个有构造函数,析构函数,赋值函数,和拷贝构造函数的String类

//.h
class String{
    public:
        String(const char* str);
        String(const String &other);
        ~String();
        String & operate=(const String &other);
    private:
         char* m_data;
}; 

//.cpp
String::String(const char*str){
    if(str==NULL){
        m_data=new char[1];
        *m_data='\0';
    }
    else{
        int length=strlen(str);
        m_data=new char[length+1];
        strcpy(m_data,str);
    }
}

String::String(const String &other){
    int length=strlen(other.m_data);
    m_data=new char[length+1];
    strcpy(m_data,other.m_data);
}

String::~String(){
    delete [] m_data;
}

String::String& operate=(const String & other){
    if(&other==*this)return *this;//检查自赋值
    delete[]m_data;//释放原有的内存资源
    int length=strlen(other.m_data);
    m_data=new char[length+1];
    strcpy(m_data,other.m_data);
    return *this;//返回本对象的引用

23.strcpy(字符拷贝)和memcpy(内存拷贝)区别

1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy
 

char* mystrcpy(char* des,char* src)
{
    assert(des!=NULL && src!=NULL);
    
    char* str=src;
    while((*des++=*str++)!='\0');
    
    return des;
}
void *memcpy(void *dest , const void *src , size_t count)
{
	assert( (dest != NULL) && (src != NULL));     //安全检查
	assert( count > 0 );
 
	char *psrc = (char *) src;  //可以保持src里面的值不变,否则后面的自增会改变里面存放的值
	char *pdest = (char *) dest;
	//检查是否有重叠问题
	if( pdest < psrc )        //无内容重叠
	{
		//正向拷贝
		while( count-- )
			*pdest++ = *psrc++;
	}
	else if( psrc < pdest )
	{
		//反向拷贝
		psrc = psrc + count - 1;
		pdest = pdest + count - 1;
		while( count-- )
			*pdest-- = *psrc--;
	}
	return dest;
}

引用:博客字符串拷贝和内存拷贝的区别_qq_40395404的博客-CSDN博客。这里还有个函数memmove可以了解一下

24.函数指针和指针函数用法和区别 

简单理解:

函数指针:返回值是指针的函数,简单举例定义 void * add(int a){ return a};

typedef struct _Data{
    int a;
    int b;
}Data;

//指针函数
Data* f(int a,int b){
    Data * data = new Data;
    data->a = a;
    data->b = b;
    return data;
}
//注释Qt框架  后面//可以认为空语句也可以
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);//

    //调用指针函数
    Data * myData = f(4,5);
    qDebug() << "f(4,5) = " << myData->a << myData->b;

    return a.exec();//
}

指针函数:指向函数的指针,简单举例定义 void (* add)(int a){ return a};

int add(int x,int y){
    return x+y;
}
int sub(int x,int y){
    return x-y;
}
//函数指针
int (*fun)(int x,int y);

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //第一种写法
    fun = add;
    qDebug() << "(*fun)(1,2) = " << (*fun)(1,2) ;
	//第二种写法
    fun = &sub;
    qDebug() << "(*fun)(5,3) = " << (*fun)(5,3)  << fun(5,3);

    return a.exec();
}

引用Qt大佬博客 :函数指针和指针函数用法和区别_luoyayun361的博客-CSDN博客_函数指针

25.多线程和多进程区别(windows下)

1.进程:进程是多个线程容器,包含可执行模块或DLL模块代码和数据,也包括动态分配内存空间,子进程崩溃不影响主程序稳定,线程有更安全操作和通讯机制(管道、文件、套字节、信号)

2.线程:线程有内核对象(操作系统用他来管理线程)和线程栈(维护线程所需代码和局部变量)组成,线程在进程中共享内存的,开销比较小,线程同步和加锁比较麻烦(同步方式有1.事件(Event);2)信号量(semaphore);3)互斥量(mutex)4)临界区(Critical section)。一个线程崩溃 影像整个程序。

26.重载、覆盖、重定义

Overload  重载

C++程序中,可以将语义、功能相似的几个函数用同一个名字表示,但参数不同(包括类型、顺序不同),即函数重载
1)相同的范围(在同一个类中);
2)函数名字相同;
3)参数不同;

Override    覆盖

是指派生类函数覆盖基类函数,特征是:
1)不同的范围(分别位于派生类与基类);
2)函数名字相同;
3)参数相同;
4)基类函数必须有virtual 关键字。

hide:隐藏
是指派生类的函数屏蔽了与其同名的基类函数,规则如下:
(1)如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏。
(2)如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏(注意别与覆盖混淆)

27.什么是虚函数?什么是纯虚函数?

虚函数是允许被其子类重新定义的成员函数。

虚函数的声明:virtual returntype func(parameter);引入虚函数的目的是为了动态绑定;

纯虚函数声明:virtual returntype func(parameter)=0;引入纯虚函数是为了派生接口。(使派生类仅仅只是继承函数的接口)

28.new和malloc的区别?

  • new是运算符,malloc()是一个库函数
  • new会调用构造函数,malloc不会;
  • new返回指定类型指针,malloc返回void*指针,需要强制类型转换;
  • new会自动计算需分配的空间,malloc不行;
  • new可以被重载,malloc不能。

29.static (静态)和const分别怎么用,类里面static和const可以同时修饰成员函数吗?

1.静态全局变量\局部变量

在全局变量之前加上关键字static,全局变量就被定义成为一个全局\局部静态变量。

 1)内存中的位置:静态存储区(静态存储区在整个程序运行期间都存在)

 2)初始化:未经初始化的全局静态变量会被程序自动初始化为0(自动对象的值是任意的,除非他被显示初始化),在类外定义

 3)作用域:全局静态变量在声明他的文件之外是不可见的。准确地讲从定义之处开始到文件结尾,局部静态变量内存并没有被释放,只是不在作用域内。

30.什么是多态?多态有什么用途?

在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。如果对象类型是派生类,就调用派生类的函数;如果对象类型是基类,就调用基类的函数。

多态有两种:静态多态(早绑定)、动态多态(晚绑定)。静态多态是通过函数重载实现的;动态多态是通过虚函数实现的。

32.sizeof和strlen的区别?

1.sizeof是操作符,参数为任意类型,主要计算类型占用内存大小。

   strlen()是函数,其函数原型为:extern unsigned int strlen(char *s);其参数为char*,strlen只能计算以"\0"结尾字符串的长度,计算结果不包括"\0"。

2.当将字符数组作为sizeof()的参数时,计算字符数组占用内存大小;当将字符数组作为strlen()函数,字符数组转化为char*。因为sizeof的参数为任意类型,而strlen()函数参数只能为char*,当参数不是char*必须转换为char*。

33.内联函数和宏定义的区别

1.宏定义不是函数,但是使用起来像函数。预处理器用复制宏代码的方式代替函数的调用,省去了函数压栈退栈过程,提高了效率。

   内联函数本质上是一个函数,内联函数一般用于函数体的代码比较简单的函数,不能包含复杂的控制语句,while、switch,并且内联函数本身不能直接调用自身。如果内联函数的函数体过大,编译器会自动      的把这个内联函数变成普通函数。

2. 宏定义是在预处理的时候把所有的宏名用宏体来替换,简单的说就是字符串替换

    内联函数则是在编译的时候进行代码插入,编译器会在每处调用内联函数的地方直接把内联函数的内容展开,这样可以省去函数的调用的开销,提高效率

3. 宏定义是没有类型检查的,无论对还是错都是直接替换

    内联函数在编译的时候会进行类型的检查,内联函数满足函数的性质,比如有返回值、参数列表等

34.内联函数与普通函数的区别

1. 内联函数和普通函数的参数传递机制相同,但是编译器会在每处调用内联函数的地方将内联函数内容展开,这样既避免了函数调用的开销又没有宏机制的缺陷。

2. 普通函数在被调用的时候,系统首先要到函数的入口地址去执行函数体,执行完成之后再回到函数调用的地方继续执行,函数始终只有一个复制。

    内联函数不需要寻址,当执行到内联函数的时候,将此函数展开,如果程序中有N次调用了内联函数则会有N次展开函数代码。

3. 内联函数有一定的限制,内联函数体要求代码简单,不能包含复杂的结构控制语句。如果内联函数函数体过于复杂,编译器将自动把内联函数当成普通函数来执行。

35.C++中成员函数能够同时用static和const进行修饰?

static修饰的函数表示该函数是属于类的,而不是属于某一个对象的,没有this指针。const修饰的函数表示该函数不能改变this中的内容,会有一个隐含的const this指针。两者是矛盾的

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路奇怪

有钱出钱,没钱多出编程主意啊

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值