Ubuntu 16.04系统中GCC 9.1编译器安装方法及C++17标准测试示例

严正声明:本文系作者davidhopper原创,未经许可,不得转载。

2019年8月2日更新:
本文方法适用于GCC 9.1.0,只需将原文中的GCC 7.3.0替换为GCC 9.1.0即可。
为什么要更新到GCC 9.1.0?因为该版本可支持C++ 17标准的并行策略。
如何使用C++17标准的并行策略,参考我的另一篇博客:《Ubuntu 16.04系统中使用GCC 9.1及Intel TBB库运行C++17 STL并行算法库》。

2017年底,C++17标准正式颁布,该标准的最大贡献是,提供了STL库算法的并行运算版本,对于我这种喜欢追求算法性能的程序员而言,无疑是一个极大的福音。幸运地是,Linux系统标准编译器GCC能完美地支持C++ 17标准,但需升级到7.0以上版本;不幸地是,Ubuntu 16.04版本自带的GCC版本为5.4.0,可支持C++ 14标准,但基本不支持C++ 17标准。怎么办?那就从零开始,从GCC官方网站下载、安装最新标准的编译器吧。

一、下载GCC 7.3.0版本源代码

进入GCC官方网站:https://gcc.gnu.org/,发现目前最新版本是7.3.0(2018年3月24日 )。本来想省点事,直接下载二进制版本进行安装,但打开相关页面后,发现居然没有Ubuntu系统的二进制版本,这不是赤裸裸地歧视吗?话虽如此,但活人还能让尿憋死?既然官网不提供,那我就自己下载源代码编译、安装。
1
目前,GCC源代码提供两种下载方式:镜像网站下载和SVN服务器下载。目前,我只使用GIT版本控制工具,对于SVN这种跟不上趟的玩意,我根本不屑使用,还是从镜像服务器下载好了。打开镜像服务器列表网页一看:https://gcc.gnu.org/mirrors.html,居然没有大中国,又是赤裸裸地歧视啊。看在老毛子数学和软件算法都很牛逼的份上,我就选他的镜像服务器吧:http://mirror.linux-ia64.org/gnu/gcc/,具体下载网址为:http://mirror.linux-ia64.org/gnu/gcc/releases/gcc-7.3.0/
2
3

二、编译安装GCC 7.3.0

2.1 解压源代码压缩包

从镜像服务器下载GCC 7.3.0版源代码压缩包“gcc-7.3.0.tar.gz”后,首先将其放置于一个合适的目录,进行解压(我将“gcc-7.3.0.tar.gz”放置于目录“/home/davidhopper/code/gcc”中),命令如下:

cd ~/code/gcc
tar zxvf gcc-7.3.0.tar.gz

结果就是所有源代码文件全部解压到了目录“/home/davidhopper/code/gcc/gcc-7.3.0”中。

2.2 建立构建文件夹

由于GCC官网的安装文档强烈建议不要在源代码文件中进行编译,而需另外建立一个构建文件夹(原文为:First, we highly recommend that GCC be built into a separate directory from the sources which does not reside within the source tree. This is how we generally build GCC; building where srcdir == objdir should still work, but doesn’t get extensive testing; building where objdir is a subdirectory of srcdir is unsupported.),因此,我在“/home/davidhopper/code/gcc”目录中另行创建一个单独的构建文件夹“gcc-7.3.0-build”,整个目录结构如下图所示:
3

2.3 下载依赖包

此时,我以为只要进入构建文件夹,然后执行如下配置命令就可以生成Makefile了,真是“too simple, sometimes naive”,世界哪有这么美好?

cd ~/code/gcc/gcc-7.3.0-build
../gcc-7.3.0/configure

果不其然,上述命令产生的错误信息如下,原来是缺少几个依赖包:GMP 4.2+, MPFR 2.4.0+, MPC 0.8.0+,需要我们自己下载。

configure: error: Building GCC requires GMP 4.2+, MPFR 2.4.0+ and MPC 0.8.0+.
Try the --with-gmp, --with-mpfr and/or --with-mpc options to specify
their locations.  Source code for these libraries can be found at
their respective hosting sites as well as at
ftp://gcc.gnu.org/pub/gcc/infrastructure/.  See also
http://gcc.gnu.org/install/prerequisites.html for additional info.  If
you obtained GMP, MPFR and/or MPC from a vendor distribution package,
make sure that you have installed both the libraries and the header
files.  They may be located in separate packages.

4
注意:上面的提示信息存在一个坑,就是ftp://gcc.gnu.org/pub/gcc/infrastructure/现在根本不存在,你如果进入该网页去下载依赖包,恐怕是到死也完不成任务,因此必须将其替换为镜像服务器地址。例如,我选择的老毛子服务器地址为:ftp://gcc.gnu.org/pub/gcc/infrastructure/
下载方法有两种:
第一种是笨办法,老老实实地进入镜像服务器网址,然后依次下载:GMP 6.1.0, MPFR 3.1.4, MPC 1.0.3压缩包(只要满足GMP 4.2+, MPFR 2.4.0+, MPC 0.8.0+要求即可,并不一定是我所写的这几个版本),并将其解压到“/home/davidhopper/code/gcc/gcc-7.3.0”目录,同时建立其符号链接目录。也就是说,在“/home/davidhopper/code/gcc/gcc-7.3.0”目录中会多出三个子文件夹:gmp-6.1.0、mpfr-3.1.4、mpc-1.0.3以及其其符号链接目录:gmp、mpfr、mpc。解压及建立符号链接命令如下:

cd ~/code/gcc/gcc-7.3.0
tar zxvf gmp-6.1.0.tar.gz
tar zxvf mpfr-3.1.4.tar.gz
tar zxvf mpc-1.0.3.tar.gz
ln -s  gmp-6.1.0 gmp
ln -s  mpfr-3.1.4 mpfr
ln -s  mpc-1.0.3 mpc

第二种是省事的办法,首先使用vi编辑器打开依赖包下载脚本文件:contrib/download_prerequisites

cd ~/code/gcc/gcc-7.3.0
vi contrib/download_prerequisites

将该文件里的base_url='ftp://gcc.gnu.org/pub/gcc/infrastructure/'替换为:base_url='http://mirror.linux-ia64.org/gnu/gcc/infrastructure/',即将不存在的服务器地址替换为镜像服务器地址。接下来,执行如下命令自动下载并解压依赖包:

bash contrib/download_prerequisites

如果提示如下信息,则代表下载并解压成功:

2018-03-24 21:01:37 URL:http://mirror.linux-ia64.org/gnu/gcc/infrastructure/gmp-6.1.0.tar.bz2 [2383840/2383840] -> "./gmp-6.1.0.tar.bz2" [1]
2018-03-24 21:01:46 URL:http://mirror.linux-ia64.org/gnu/gcc/infrastructure/mpfr-3.1.4.tar.bz2 [1279284/1279284] -> "./mpfr-3.1.4.tar.bz2" [1]
2018-03-24 21:01:51 URL:http://mirror.linux-ia64.org/gnu/gcc/infrastructure/mpc-1.0.3.tar.gz [669925/669925] -> "./mpc-1.0.3.tar.gz" [1]
2018-03-24 21:01:58 URL:http://mirror.linux-ia64.org/gnu/gcc/infrastructure/isl-0.16.1.tar.bz2 [1626446/1626446] -> "./isl-0.16.1.tar.bz2" [1]
gmp-6.1.0.tar.bz2: 确定
mpfr-3.1.4.tar.bz2: 确定
mpc-1.0.3.tar.gz: 确定
isl-0.16.1.tar.bz2: 确定
All prerequisites downloaded successfully.

如果出现如下信息,则表示包:gmp-6.1.0.tar.bz2没有下载成功:

2018-03-24 20:54:39 URL:http://gcc.parentingamerica.com/infrastructure/mpc-1.0.3.tar.gz [669925/669925] -> "./mpc-1.0.3.tar.gz" [1]
2018-03-24 20:56:16 URL:http://gcc.parentingamerica.com/infrastructure/isl-0.16.1.tar.bz2 [1626446/1626446] -> "./isl-0.16.1.tar.bz2" [1]
gmp-6.1.0.tar.bz2: 失败
sha512sum: 警告:1 个校验和不匹配
error: Cannot verify integrity of possibly corrupted file gmp-6.1.0.tar.bz2

这是因为网络连接不正常造成的,解决方案是,进入目录“/home/davidhopper/code/gcc/gcc-7.3.0”,手动将已下载的“mpc-1.0.3.tar.gz”、“isl-0.16.1.tar.bz2”文件删除,重新执行bash contrib/download_prerequisites命令下载。如果仍然提示失败,则应使用vi编辑器修改contrib/download_prerequisites
文件里的base_ur=...换为另一个能够正常连接并下载的镜像服务器地址。

2.4 运行configure命令生成Makefile

再次进入构建文件夹,执行如下配置命令生成Makefile:

cd ~/code/gcc/gcc-7.3.0-build
../gcc-7.3.0/configure

结果又出了一个妖蛾子,错误提示如下:

configure: error: I suspect your system does not have 32-bit 
development libraries (libc and headers). If you have them, 
rerun configure with --enable-multilib. If you do not have them, 
and want to build a 64-bit-only compiler, rerun configure with 
--disable-multilib.

5
也就是说,configure推断本机没有32位开发库,如果的确有就加上--enable-multilib选项,否则就使用--disable-multilib选项只构建64位版本。现在的机器谁还用32位系统,于是我立即重新运行配置程序如下:

../gcc-7.3.0/configure --disable-multilib

结果令人欣慰,总算在构建目录“/home/davidhopper/code/gcc/gcc-7.3.0-build”中生成了Makefile。

2.5 运行make命令编译构建GCC编译器

接下来的事情似乎很简单,只要运行make命令(需指出的是, Make程序支持并发处理,你的处理器有几个核,就可以加上-j x选项,以便加快编译速度)就可以编译构建GCC编译器了,事实证明,我又把问题估计简单了一些。

cd ~/code/gcc/gcc-7.3.0-build
make -j 8

编译了不一会,就出现如下错误:

checking LIBRARY_PATH variable... contains current directory
configure: error: 
*** LIBRARY_PATH shouldn't contain the current directory when
*** building gcc. Please change the environment variable
*** and run configure again.

于是立即在网上搜索解决方案,找到如下类似的靠谱答案

出现这个错误的原因是由于环境变量的LD_LIBRARY_PATH中出现了当前目录。
找了好久不知道是啥原因,因为不可能把这目录放在环境变量啊。后来发现,
通常我们写环境变量都喜欢写:
export LD_LIBRARY_PATH = $LD_LIBRARY_PATH:foo/bar
如果一开始LD_LIBRARY_PATH不存在的话,这个上面这串环境变量开头就是冒号,
这就把当前文件夹包含进去了。一般来说我们挺需要这种效果,因为在编译的时候
可以include某些东西,但是对于编译glibc来说这个是多余的。
最简单的解决方法就是unset LD_LIBRARY_PATH,这能把这个环境变量直接干掉。

好吧,开始照方抓药,重新执行如下命令:

unset LIBRARY_PATH
../gcc-7.3.0/configure --disable-multilib
make -j 8

在我机器上大约等了一个小时,最后全部构建成功。

2.6 运行sudo make install命令安装GCC编译器

cd ~/code/gcc/gcc-7.3.0-build
sudo make install

因为我在运行configure命令时,没有指定安装目录,因此上述命令会将最新版本的GCC编译器安装到默认位置:/usr/local,也就是说,头文件在/usr/local/include目录,可执行文件在/usr/local/bin目录,库文件在/usr/local/lib目录。

2.7 指定本机使用最新版本GCC编译器

使用update-alternatives命令配置增加最新版本编译器,注意:gcc是编译C程序的默认程序,g++是编译C++程序的默认程序。

# update-alternatives --install <链接> <名称> <路径> <优先级>
sudo update-alternatives --install /usr/bin/gcc gcc /usr/local/bin/gcc 50
sudo update-alternatives --install /usr/bin/g++ g++ /usr/local/bin/g++ 50

使用下述命令查询当前已经安装的GCC编译器版本:

# 查询本机已有GCC编译器情况
sudo update-alternatives --query gcc
# 查询本机已有G++编译器情况
sudo update-alternatives --query g++

我机器上的显示结果为:

Name: gcc
Link: /usr/bin/gcc
Status: auto
Best: /usr/local/bin/gcc
Value: /usr/local/bin/gcc

Alternative: /usr/bin/gcc-5
Priority: 20

Alternative: /usr/local/bin/gcc
Priority: 50
Name: g++
Link: /usr/bin/g++
Status: auto
Best: /usr/local/bin/g++
Value: /usr/local/bin/g++

Alternative: /usr/bin/g++-5
Priority: 20

Alternative: /usr/local/bin/g++
Priority: 50

选择默认使用的GCC编译器版本:

# 交互配置GCC编译器
sudo update-alternatives --config gcc
# 交互配置G++编译器
sudo update-alternatives --config g++

在我机器上的结果如下,选择默认选项“0”即可。

有 2 个候选项可用于替换 gcc (提供 /usr/bin/gcc)。

  选择       路径              优先级  状态
------------------------------------------------------------
* 0            /usr/local/bin/gcc   50        自动模式
  1            /usr/bin/gcc-5       20        手动模式
  2            /usr/local/bin/gcc   50        手动模式

要维持当前值[*]请按<回车键>,或者键入选择的编号:
有 2 个候选项可用于替换 g++ (提供 /usr/bin/g++)。

  选择       路径              优先级  状态
------------------------------------------------------------
* 0            /usr/local/bin/g++   50        自动模式
  1            /usr/bin/g++-5       20        手动模式
  2            /usr/local/bin/g++   50        手动模式

要维持当前值[*]请按<回车键>,或者键入选择的编号:

可以使用如下命令查询当前的gccg++版本:

# 查询gcc版本
gcc --version
# 查询g++版本
g++ --version

三、C++ 17标准程序测试

写一个C++ 17标准中关于结构化绑定(structured bindings)的小程序,代码如下:

#include <iostream>
#include <tuple>
#include <map>
#include <stdexcept>

bool divide_remainder(int dividend, int divisor, int &fraction, int &remainder)
{
    if (divisor == 0)
    {
        return false;
    }
    fraction = dividend / divisor;
    remainder = dividend % divisor;
    return true;
}

std::pair<int, int> divide_remainder(int dividend, int divisor)
{
    if (divisor == 0)
    {
        throw std::runtime_error{"Attempt to divide by 0"};
    }
    return {dividend / divisor, dividend % divisor};
}

int main()
{
    { // old school way
        int fraction, remainder;
        const bool success{divide_remainder(16, 3, fraction, remainder)};
        if (success)
        {
            std::cout << "16 / 3 is " << fraction << " with a remainder of " << remainder << "\n";
        }
    }

    { // C++11 way
        const auto result(divide_remainder(16, 3));
        std::cout << "16 / 3 is " << result.first << " with a remainder of " << result.second << "\n";
    }

    { // C++11, ignoring fraction part of result
        int remainder;
        std::tie(std::ignore, remainder) = divide_remainder(16, 5);
        std::cout << "16 % 5 is " << remainder << "\n";
    }

    { // C++17, use structured bindings
        auto[fraction, remainder] = divide_remainder(16, 3);
        std::cout << "16 / 3 is " << fraction << " with a remainder of " << remainder << "\n";
    }

    { // C++17, decompose a tuple into individual vars
        std::tuple<int, float, long> tup{1, 2.0, 3};
        auto[a, b, c] = tup;
        std::cout << a << ", " << b << ", " << c << "\n";
    }

    { // C++17, use structured binding in for-loop

        std::map<std::string, size_t> animal_population{
            {"humans", 7000000000},
            {"chickens", 17863376000},
            {"camels", 24246291},
            {"sheep", 1086881528}
            /* … */
        };

        for (const auto & [ species, count ] : animal_population)
        {
            std::cout << "There are " << count << " " << species << " on this planet.\n";
        }
    }
}

编译命令如下:

g++ -g -Wall -std=c++17 *.cpp -o test

运行测试程序及结果如下:

./test
16 / 3 is 5 with a remainder of 1
16 / 3 is 5 with a remainder of 1
16 % 5 is 1
16 / 3 is 5 with a remainder of 1
1, 2, 3
There are 24246291 camels on this planet.
There are 17863376000 chickens on this planet.
There are 7000000000 humans on this planet.
There are 1086881528 sheep on this planet.

四、可能遇到的问题

4.1 使用G++7.3.0构建多线程程序,运行程序时出现类似“./main: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.22’ not found (required by ./main)”的错误

写一个使用C++ 17标准实现多线程的小程序,代码如下:

#include <iostream>
#include <queue>
#include <tuple>
#include <condition_variable>
#include <thread>

using namespace std;
using namespace chrono_literals;

queue<size_t> q;
mutex mut;
condition_variable cv;
bool finished = false;

void producer(size_t items) {
    for (size_t i = 0; i < items; ++i) {
        this_thread::sleep_for(100ms);
        {
            lock_guard<mutex> lk(mut);
            q.push(i);
        }
        cv.notify_all();
    }

    {
        lock_guard<mutex> lk(mut);
        finished = true;
    }
    cv.notify_all();
}

void comsumer() {
    while (!finished) {
        unique_lock<mutex> lk(mut);
        cv.wait(lk, []() {
            return !q.empty() || finished;
        });

        while (!q.empty()) {
            cout << "Got " << q.front() << " from queue. " << endl;
            q.pop();
        }
    }
}

int main() {
    thread t1(producer, 10);
    thread t2(comsumer);

    t1.join();
    t2.join();

    cout << "Finished! " << endl;
    return 0;
}

编译命令如下:

g++ -g -Wall -std=c++17 -pthread *.cpp -o main

运行测试程序:

./main

提示如下错误信息:

./main: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.22' not found (required by ./main)

6
这是因为没有使用“libstdc++.so.6”版本不够新造成的,解决方法如下:
首先,在GCC 7.3.0的安装目录(如果未更改,默认安装路径为:/usr/local)中查找“libstdc++.so.6”,命令如下:

find /usr/local -name "libstdc++.so.6"

结果如下:

/usr/local/lib64/libstdc++.so.6

接着,将/usr/lib/x86_64-linux-gnu/libstdc++.so.6修改后缀名备份,并将/usr/local/lib64/libstdc++.so.6复制到本地,命令如下:

cd /usr/lib/x86_64-linux-gnu
# 备份原有版本
sudo mv libstdc++.so.6 libstdc++.so.6.bk
# 复制新版本
sudo cp /usr/local/lib64/libstdc++.so.6 ./
# 更新共享库缓存
sudo ldconfig

然后,确认检查新的“libstdc++.so.6”文件已包含`GLIBCXX_3.4.22’版本(该步骤可不执行)。

strings ./libstdc++.so.6 | grep GLIBC

7
最后,进入测试程序所在目录,重新运行生成的程序:

cd ~/code/C++17/SimpleProducerConsumerThread/ 
./main

结果如下:

Got 0 from queue. 
Got 1 from queue. 
Got 2 from queue. 
Got 3 from queue. 
Got 4 from queue. 
Got 5 from queue. 
Got 6 from queue. 
Got 7 from queue. 
Got 8 from queue. 
Got 9 from queue. 
Finished! 

4.2 无法将GCC编译器版本降级

最新版本的GCC编译器虽然用起来很舒服,但一些旧代码可能还是需要老版本的GCC编译器才能编译,这时我们自然想到使用sudo update-alternatives --config gcc命令去配置版本,但经过实践发现,无论我怎么设置选项,gcc -v命令总是输出如下信息:

使用内建 specs。
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-pc-linux-gnu/7.3.0/lto-wrapper
目标:x86_64-pc-linux-gnu
配置为:../gcc-7.3.0/configure --disable-multilib
线程模型:posix
gcc 版本 7.3.0 (GCC)

也就是说,无法将GCC版本降级。
该问题产生的原因是,我们将GCC7.3.0的优先级设置得太高了。由于GCC7.3.0的优先级高、版本也新,无论我们怎么手动选择GCC版本,系统仍然会匹配版本较新的GCC程序。
解决方法是:将老版本的GCC程序优先级设置得更高。具体操作如下:

# 1.删除原有低优先级的老GCC配置项
sudo update-alternatives --remove gcc /usr/bin/gcc-5
sudo update-alternatives --remove g++ /usr/bin/g++-5
# 2.以更高的优先级重新安装老GCC配置项
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 70
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 70
# 3.这时就可以更改当前使用的GCC版本了
sudo update-alternatives --config gcc
sudo update-alternatives --config g++
<think>好的,我需要回答用户关于在Ubuntu 16.04安装GCC编译器的问题。首先,我应该查看用户提供的引用资料,看看有没有相关的安装步骤。根据引用[2],提到了使用`sudo apt install build-essential`命令来安装GCC、G++和make等工具。这可能是一个关键步骤。 接下来,用户可能还关心如何验证安装是否成功。我记得通常安装完成后可以通过运行`gcc --version`来检查版本,这个信息是否需要包含进去?是的,应该告诉用户如何确认安装成功。 然后,用户提供的引用[3]中提到了修改环境变量,但安装GCC可能需要这一步,除非涉及到自定义路径。过可能用户会需要知道如何设置环境变量,但根据引用[2]的步骤,可能build-essential已经处理好了路径问题,所以可能需要额外配置。过是否需要提到这一点呢?可能需要,除非用户遇到问题。 另外,用户提到的系统Ubuntu 16.04,而引用[2]中的命令是否适用于这个版本?是的,因为build-essential包在Ubuntu的各个版本中都是可用的,包括16.04。所以应该推荐使用这个命令。 还有,是否需要更新软件源列表?通常在安装软件之前,建议运行`sudo apt update`来确保包列表是最新的。所以应该建议用户先执行这个步骤,再安装build-essential。 然后,用户可能想知道安装的是哪个版本的GCCUbuntu 16.04默认的GCC版本应该是5.x,但可能需要确认。引用[1]提到GCC是跨平台编译器的标准,所以安装后用户可以得到一个稳定版本。 最后,是否需要提到其他安装方法,比如从源码编译?但根据用户的问题,他们可能更倾向于简单的apt安装方法,所以可能需要深入其他方法,除非用户特别需要。但根据提供的引用,没有提到源码安装,所以可以专注于apt安装。 总结步骤应该是: 1. 更新包列表:sudo apt update 2. 安装build-essential:sudo apt install build-essential 3. 验证安装gcc --version 可能还需要提醒用户注意权限问题,需要使用sudo。另外,如果用户需要特定版本的GCC,可能需要额外步骤,但默认情况下build-essential会安装系统默认版本。 相关问题部分,可以生成关于如何安装其他组件、检查版本、卸载GCC或者安装多版本GCC的问题。例如: 1. 如何安装特定版本的GCC编译器2. 如何在Ubuntu中切换同版本的GCC3. 如何卸载GCC编译器? 需要确保问题与安装GCC相关,并且基于用户提供的引用内容。例如引用[3]提到了Apache的配置,但可能和GCC关系大,所以可能在这里涉及。</think>### Ubuntu 16.04 安装 GCC 编译器教程 #### **步骤说明** 1. **更新软件源列表** 在终端执行以下命令,确保获取最新的软件包信息: ```bash sudo apt update ``` 此操作会同步服务器上的软件包列表到本地[^2]。 2. **安装 build-essential 工具集** build-essential 包含 GCC、G++、make 等核心编译工具。执行命令: ```bash sudo apt install build-essential ``` 系统会自动安装默认版本的 GCCUbuntu 16.04 默认版本为 GCC 5.x)。 3. **验证安装** 安装完成后,通过以下命令检查 GCC 版本: ```bash gcc --version ``` 若输出类似 `gcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0`,则表明安装成功[^1]。 #### **补充说明** - **安装其他组件**:如需开发库(如 `libc6-dev`),可通过 `sudo apt install libc6-dev` 单独安装- **多版本管理**:若需安装其他版本的 GCC(如 GCC 7),可使用 `sudo apt install gcc-7`,再通过 `update-alternatives` 切换版本。 ---
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值