13.C++中static的应用及文件包含


欢迎访问个人网络日志🌹🌹知行空间🌹🌹


1.文件包含

.h文件中主要是用来声明函数和变量,有时候也可以用来定义函数和变量。

.h中最常见的就是重复包含,看下面例子

文件add.h:

int c = 10;
int add(int &a, int &b);

文件add.cpp:

#include "add.h"
int add(int &a, int &b)
{
     return a + b;
}

文件addA.h:

#include "add.h"
int addA(int a, int b);

文件addA.cpp:

#include "addA.h"
int addA(int a, int b)
{
     return add(a, b);
}

文件addB.h:

#include "add.h"
int addB(int a, int b);

文件addA.cpp:

#include "addB.h"
int addB(int a, int b)
{
     return add(a, b);
}

文件main.cpp:

#include <iostream>

#include "addA.h"
#include "addB.h"
int main(int argc, char **argv)
{
     int a = 1, b = 2;
     std::cout << addA(a, b) << " " << addB(a, b) << std::endl;
     return 0;
}

学过C++的肯定都知道上面代码编译会报错,因为包含add.h两次,导致重复声明了c变量。

g++ main.cpp -o m.o

In file included from addB.h:3,
                 from main.cpp:4:
add.h:3:5: error: redefinition of ‘int c’
    3 | int c = 10;
      |     ^
In file included from addA.h:3,
                 from main.cpp:3:
add.h:3:5: note: ‘int c’ previously defined here
    3 | int c = 10;

这种情况下解决办法最常用的就是在每个头文件中添加宏:

#ifndef __ADD_H__
#define __ADD_H__
...
#endif // __ADD_H__

然后,再编译发现就会发现可以编译成功。

依次将上面四个源文件编译完成:

g++ main.cpp -o m.o
g++ add.cpp -o a.o
g++ addA.cpp -o A.o
g++ addB.cpp -o b.o

链接时会导致报错:

g++ a.o A.o B.o m.o -o m
/usr/bin/ld: A.o:(.data+0x0): multiple definition of `c'; a.o:(.data+0x0): first defined here
/usr/bin/ld: B.o:(.data+0x0): multiple definition of `c'; a.o:(.data+0x0): first defined here
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':
(.text+0x24): undefined reference to `main'
collect2: error: ld returned 1 exit status

为什么会出错呢? 按照条件编译,add.h并没有重复包含,可是还是提示变量a重复定义了。 对比第一次报错,不加条件编译在编译时就报错,加了条件编译,编译能通过,但链接时报错。

在这里注意的是,变量/函数/类/结构体的重复定义不仅会发生在源程序编译的时候,在目标程序链接的时候同样也有可能发生。

c/c++编译的基本单元是.c.cpp文件,各个基本单元的编译是相互独立的,#ifndef等条件编译只能保证在一个基本单元(单独的.c.cpp文件)中头文件不会被重复编译,但是无法保证两个或者更多基本单元中相同的头文件不会被重复编译。

头文件尽量只有声明,不要有定义。

解决上面问题的一种办法是,在add.h中定义int c = 10;时加static修饰符,如下:

add.h文件:

#ifndef __ADD_H__
#define __ADD_H__
static int c = 10;
int add(int &a, int &b);
#endif // __ADD_H__

然后,就能编译通过了,static关键字在这里修饰定义的变量时局部变量,只在当前文件中可见。在编译A.oB.o时会在两个编译文件中分别定义变量c,因此就可以编译通过了,同样static也能用来修饰函数,表示函数只能在当前文件中被调用。函数的不同点在于,如果static修饰的函数定义在.h文件中,那么其他包含.h的文件能调用static修饰的函数,每个文件使用的是一个单独的函数;如果,static修饰的函数声明在.h文件中,定义在.cpp文件中,那么这个函数对其他文件将不可见。

// case 1:
// add.h
#ifndef __ADD_H__
#define __ADD_H__
static int add(int &a, int &b)
{
     return a + b;
}
#endif // __ADD_H__

// case 2:
// add.h
#ifndef __ADD_H__
#define __ADD_H__
static int add(int &a, int &b);
#endif // __ADD_H__
// add.cpp
#include "add.h"
int add(int &a, int &b)
{
     return a + b;
}
// addA.h
#include "add.h"
int addA(int &a, int &b);
// addA.cpp
#include "addA.h"
int addA(int &a, int &b)
{
     return add(a, b); // error, can't invoke add function since it is a static function
}

2.static的作用

由上面的例子看到了static的一种应用是限制函数或变量的作用域在当前源文件。static另外一个作用是定义静态数据和类中定义属于类而不是对象的成员

// main.cpp
int accumulate(int a)
{
    static int cc = 0;
    cc += a;
    return cc;
}

int main(int argc, char** argv)
{
     int re = 0;
     for(auto i=0; i<3; i++)
     {
          re = accumulate(i);
     }
     std::cout << re << std::endl;
     return 0;
}

上面累加函数accumulate中声明的cc变量是静态数据,保存在静态存储区(全局变量存储区), 因此延长了cc的生命周期,但static并不改变变量的作用域,因此还是只能在accumulate函数中使用。

此外就是static还可以用来修饰类中的数据成员或者成员函数,这样数据成员就保存在类的内存空间上而不是类实例对象的内存空间上。static修饰的成员函数中没有this指针,因此不能访问类中的非静态数据成员和方法。

类中的static数据成员,仍然受private等访问权限修饰符控制,若需通过类名::变量名来使用,需将其声明为public类型。

类中的static数据成员,需在类外初始化。

#include <iostream>

class Example {
    public:
        Example() : b(0) {};
    public:
        static int a;
    private:
        int b;
};

int Example::a = 10;
int main(int argc, char **argv)
{
     std::cout << Example::a << std::endl;
     return 0;
}

参考资料

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《Visual C++ 数据库系统开发完全手册》(目录) 第一篇 Visual C++编程篇 第1章 Visual C++ 6.0开发环境概述 1.1 Visual C++ 6.0概述 1.2 熟悉Visual C++ 6.0的集成开发环境 1.2.1 进入Visual C++ 6.0环境 1.2.2 Visual C++ 6.0的主菜单 1.2.3 Visual C++ 6.0的工具栏 1.2.4 工作区(Workspace)窗口 1.2.5 编辑窗口 1.2.6 输出(Output)窗口 第2章 C++语言基础 2.1 C++概述 2.1.1 C++主要特点 2.1.2 利用Visual C++编制C++程序 2.2 C++程序的组成 2.2.1 标识符 2.2.2 关键字 2.2.3 常量与变量 2.2.4 基本运算符 2.3 C++数据型 2.3.1 基本数据型 2.3.2 数组 2.3.3 指针 2.3.4 结构 2.3.5 枚举型 2.4 控制结构 2.4.1 顺序结构 2.4.2 分支结构 2.4.3 循环结构 2.4.4 转移语句 2.5 函数 2.5.1 函数的定义与调用 2.5.2 默认参数 2.5.3 函数重载概述 2.6 编译预处理指令 2.6.1 #include文件包含指令 2.6.2 #define宏定义指令 2.6.3 条件编译指令 第3章 面向对象的程序设计 3.1 概述 3.1.1 面向对象程序设计方法 3.1.2 面向对象程序设计特征 3.2 C++面向对象程序设计基础 3.2.1 C++的定义与实现 3.2.2 构造函数与析构函数 3.2.3 静态成员 3.2.4 this指针 3.2.5 友元函数 3.3 的继承机制 3.3.1 基与派生概念 3.3.2 单一派生 3.3.3 多重继承 3.3.4 虚基 3.4 多态性与虚函数 3.5 抽象与纯虚函数 3.6 C++模板 3.6.1 函数模板 3.6.2 模板 第4章 创建应用程序 4.1 应用程序向导 4.1.1 Visual C++ 6.0的向导型 4.1.2 Visual C++ 6.0应用程序向导 4.1.3 MFC应用程序的开发流程 4.2 应用程序向导生成文件 4.2.1 文件型 4.2.2 典型文件举例 4.3 ClassWizard(向导) 4.3.1 ClassWizard的功能 4.3.2 ClassWizard的简单应用 4.3.3 为项目添加新 4.3.4 手工添加消息处理函数 第5章 文档与视图 5.1 Document与View概述 5.2 Document与View之间的相互作用 5.2.1 CView的GetDocument()成员函数 5.2.2 CDocument的UpdateAllViews()成员函数 5.2.3 CView的OnUpdate()成员函数 5.3 菜单设计 5.3.1 建立菜单资源 5.3.2 添加菜单命令处理函数 5.3.3 弹出式菜单 5.4 工具栏和状态栏设计 5.4.1 建立工具栏资源 5.4.2 工具栏的显示 5.4.3 定制状态栏 5.5 使用不同的视图 5.5.1 滚动视图 5.5.2 网页视图 5.5.3 多文档视图 第6章 MFC原理及方法 6.1 MFC概述 6.2 Windows编程思想 6.2.1 Windows API 6.2.2 事件驱动程序 6.2.3 消息概述 6.3 MFC微软库 6.3.1 MFC发展历史 6.3.2 MFC应用程序的生与死 6.3.3 常用MFC文件及库文件 6.4 常用的MFC 6.4.1 CRuntimeClass结构 6.4.2 CObject 6.4.3 CCmdTarget 6.4.4 CWinThread 6.4.5 CWinApp 6.4.6 CWnd 6.4.7 CFrameWnd 6.4.8 CDocument和CView 6.5 MFC消息机制 6.5.1 系统定义的消息 6.5.2 用户定义的消息 6.5.3 消息映射 6.5.4 消息的发送 6.6 MFC宏 6.6.1 运行时型识别宏 6.6.2 MFC调试宏 第7章 对话框及常用控件 7.1 对话框概述 7.1.1 基于对话框的应用程序 7.1.2 对话框CDialog 7.2 向对话框添加菜单 7.3 向对话框添加工具栏 7.4 向对话框添加状态栏 7.5 Windows公共对话框 7.5.1 CColorDialog对话框 7.5.2 CFileDialog对话框 7.5.3 CFontDialog对话框 7.6 常用控件 7.6.1 控件概述 7.6.2 使用控件 7.6.3 通用控件成员 7.6.4 静态文本控件(Static Text) 7.6.5 按钮控件(Button) 7.6.6 编辑控件(Edit Box) 7.6.7 列表框控件(List Box) 7.6.8 组合框控件(Combo Box) 7.6.9 树视图控件(Tree Control) 7.6.10 列表视图控件(List Control) 7.6.11 标签控件(Tab Control) 7.7 ActiveX控件 7.8 制作ActiveX控件 7.8.1 制作ActiveX控件的方法 7.8.2 ActiveX控件创建实例 第8章 图形图像及打印技术 8.1 图形设备接口概述 8.2 设备环境CDC 8.2.1 设备环境简介 8.2.2 设备环境CDC 8.2.3 设置场景CDC的简单应用 8.3 画笔CPen 8.4 画刷CBrush 8.5 字体CFont 8.6 位图CBitmap 8.7 打印基础 8.8 如何打印表格 8.8.1 打印流程 8.8.2 怎样打印表格 第9章 程序调试与错误处理 9.1 概述 9.2 断点跟踪 9.3 调试窗口 9.3.1 Watch窗口 9.3.2 Call Stack窗口 9.3.3 Memory窗口 9.3.4 Variables窗口 9.3.5 Registers窗口 9.3.6 Disassembly窗口 9.4 错误处理 9.4.1 捕捉错误 9.4.2 C++的错误处理 9.4.3 编制错误处理程序 第二篇 数据库应用篇 第10章 管理SQL Server 2000 10.1 安装SQL Server 10.2 配置服务器 10.2.1 启动、暂停和停止SQL Server服务器 10.2.2 注册SQL Server 2000服务器 10.2.3 编辑SQL Server 2000注册信息 10.3 脚本概述 10.3.1 将数据库生成脚本 10.3.2 将指定表生成脚本 10.3.3 执行脚本 10.4 备份和还原数据库 10.4.1 备份和还原的概念 10.4.2 数据库备份 10.4.3 数据库还原 10.5 分离和附加数据库 10.5.1 分离数据库 10.5.2 附加数据库 10.6 导入、导出数据表 10.6.1 导入数据库 10.6.2 导入SQL Server数据表 10.6.3 导入其他数据源的数据表 10.6.4 导出数据库 10.6.5 导出SQL Server数据表 第11章 SQL Server 2000数据库设计与操作 11.1 关系数据库 11.1.1 数据库及关系数据库概述 11.1.2 数据库发展历史 11.1.3 关系型数据库 11.2 分析数据库 11.2.1 分析数据库结构 11.2.2 设计数据库 11.3 使用数据库 11.3.1 创建数据库 11.3.2 创建数据表 11.3.3 SQL Server的数据型 11.3.4 向数据表添加数据 11.4 建立索引 11.4.1 建立和删除惟一索引 11.4.2 定义主键索引 11.5 关系的建立与维护 11.5.1 建立一对一关系 11.5.2 建立一对多关系 11.5.3 删除关系 11.6 使用Visual C++ 6.0与数据库连接 11.6.1 ADO简介 11.6.2 使用ADO连接数据源前的准备工作 11.6.3 Connection与Recordset 11.6.4 打开数据与关闭数据连接 11.7 如何使用ADO 11.7.1 如何打开记录集 11.7.2 怎样使用记录集 11.8 重新封装ADO 11.8.1 RxADO的制作方法 11.8.2 RxRecordset的制作方法 第12章 数据查询技巧 12.1 SQL简介 12.2 查询命令SELECT 12.2.1 SELECT命令简介 12.2.2 SELECT子句 12.2.3 FROM子句 12.2.4 WHERE子句 12.2.5 使用ORDER BY排序查询结果 12.2.6 聚合函数 12.2.7 GROUP BY子句 12.2.8 HAVING子句 12.2.9 复杂查询 12.3 插入命令INSERT 12.3.1 INSERT命令简介 12.3.2 简单的INSERT命令 12.3.3 在插入命令使用SELECT 12.4 更新命令UPDATE 12.4.1 UPDATE命令简介 12.4.2 简单的UPDATE命令 12.4.3 在UPDATE更新命令使用子查询 12.5 删除命令DELETE 12.5.1 DELETE命令简介 12.5.2 简单的DELETE命令 12.5.3 在删除使用子查询 12.6 数据备份与数据还原 12.6.1 数据备份命令BACKUP 12.6.2 数据还原命令RESTORE 第13章 存储过程、触发器与视图 13.1 存储过程概述 13.2 存储过程的应用 13.2.1 新建存储过程 13.2.2 修改存储过程 13.2.3 删除存储过程 13.2.4 获取数据库存储过程 13.2.5 获取指定存储过程语句 13.2.6 存储过程的调用 13.3 触发器介绍 13.4 使用触发器 13.4.1 新建触发器 13.4.2 修改触发器 13.4.3 删除触发器 13.5 视图介绍 13.6 视图应用 13.6.1 新建视图 13.6.2 修改视图 13.6.3 删除视图 13.6.4 获得数据库所有的视图 13.6.5 获得指定视图语句 第三篇 实例开发篇 第14章 定制自己的工作环境 14.1 工具环境设置介绍 14.1.1 Editor 14.1.2 Tabs 14.1.3 Debug 14.1.4 Compatibility 14.1.5 Build 14.1.6 Directories 14.1.7 Source Control 14.1.8 Workspace 14.1.9 Macros 14.1.10 Format 14.2 定制自己的工作环境 14.3 常用快捷键 第15章 Visual C++ 6.0在资产设备管理系统应用 15.1 资产设备管理系统概述 15.1.1 开发背景及意义 15.1.2 系统目标 15.2 系统分析 15.2.1 系统规划 15.2.2 系统结构图 15.2.3 业务流程 15.3 数据库设计 15.3.1 数据库概念设计 15.3.2 数据库逻辑结构设计 15.4 处理过程分析 15.4.1 添加资产设备处理过程分析 15.4.2 计提折旧处理过程分析 15.5 程序框架设计 15.6 封装数据库操作 15.6.1 导入ADO动态链接库 15.6.2 封装ADO对象 15.7 菜单设计 15.8 设计状态栏 15.9 设计工具栏 15.10 主窗体设计 15.11 程序设计与编码 15.11.1 资产别程序设计 15.11.2 添加资产设备程序设计 15.11.3 修改资产设备程序设计 15.11.4 计提折旧程序设计 15.11.5 数据备份程序设计 15.11.6 数据还原程序设计 15.12 疑难问题分析解决 15.12.1 只允许输入数字的编辑框 15.12.2 更改静态文本的字体 15.12.3 为按钮控件添加图标 15.12.4 修改窗口图标 15.12.5 遍历窗口的控件 15.12.6 固定资产基本概念 15.12.7 固定资产计算公式 15.13 程序调试及错误处理 15.14 程序设计清单 15.15 技术、经验总结 15.15.1 技术总结 15.15.2 经验总结 15.16 系统的编译与发行 第16章 Visual C++ 6.0在物资管理系统应用 16.1 物资管理系统概述 16.1.1 系统简介 16.1.2 实现目标 16.2 系统分析 16.2.1 系统规划 16.2.2 系统结构图 16.2.3 业务流程 16.3 数据库设计 16.3.1 数据库概念设计 16.3.2 数据库逻辑结构设计 16.4 程序设计与编码 16.4.1 基础信息查询设计 16.4.2 商品信息管理模块 16.4.3 日常业务设计 16.4.4 出库统计排行模块 16.5 对话框资源对照说明 16.6 程序的打包与发行 16.6.1 组织安装信息 16.6.2 设置目标系统 16.6.3 设置安装画面 16.6.4 设置系统需求 16.6.5 安装打包程序 第17章 Visual C++ 6.0在商品采购管理系统应用 17.1 商品采购管理系统概述 17.1.1 开发背景 17.1.2 运行环境 17.2 系统调查 17.2.1 手工流程 17.2.2 需求分析 17.3 系统分析 17.3.1 系统功能 17.3.2 系统结构图 17.3.3 业务流程 17.4 数据库设计 17.4.1 数据库概念设计 17.4.2 数据库逻辑结构设计 17.5 数据库封装说明 17.5.1 概述 17.5.2 设计步骤 17.5.3 程序相关代码 17.6 主窗体设计 17.6.1 菜单设计 17.6.2 设计背景画面 17.6.3 程序设计与编码 17.7 采购管理设计 17.7.1 概述 17.7.2 设计步骤 17.7.3 程序相关代码 17.8 疑难问题分析解决 17.8.1 怎样取得当前日期 17.8.2 怎样取得当前路径 17.9 程序调试及错误处理 17.10 技术、经验总结 17.10.1 技术总结 17.10.2 经验总结 第18章 Visual C++ 6.0在仓库管理系统应用 18.1 仓库管理系统概述 18.1.1 开发背景及意义 18.1.2 系统目标 18.2 系统分析 18.2.1 系统规划 18.2.2 系统结构图 18.2.3 业务流程 18.3 数据库设计 18.3.1 数据库概念设计 18.3.2 数据库逻辑结构设计 18.4 处理过程分析 18.4.1 商品入库处理过程分析 18.4.2 商品入库查询处理过程分析 18.5 程序框架设计 18.6 菜单设计 18.7 工具栏设计 18.8 主窗体设计 18.9 程序设计与编码 18.9.1 父窗口设计 18.9.2 商品入库程序设计 18.9.3 库存盘点程序设计 18.9.4 入库查询程序设计 18.10 疑难问题分析解决 18.10.1 利用表格录入商品 18.10.2 联想录入表格的实现 18.11 程序调试及错误处理 18.12 程序设计清单 18.13 技术、经验总结 18.13.1 技术总结 18.13.2 经验总结 18.14 系统的编译与发行 第19章 Visual C++ 6.0在销售管理系统应用 19.1 销售管理系统概述 19.1.1 开发背景及意义 19.1.2 系统目标 19.2 系统分析 19.2.1 系统规划 19.2.2 系统结构图 19.2.3 业务流程 19.3 数据库设计 19.3.1 数据库概念设计 19.3.2 数据库逻辑结构设计 19.4 处理过程分析 19.4.1 商品入库处理过程分析 19.4.2 商品销售处理过程分析 19.5 数据库封装说明 19.5.1 概述 19.5.2 设计步骤 19.5.3 程序相关代码 19.6 主窗体设计 19.6.1 菜单设计 19.6.2 设计背景画面 19.6.3 程序相关代码 19.7 操作员管理程序设计 19.7.1 概述 19.7.2 设计步骤 19.7.3 程序相关代码 19.8 销售管理设计 19.8.1 概述 19.8.2 设计步骤 19.8.3 程序相关代码 19.9 疑难问题分析解决 19.9.1 不显示文字的密码编辑框 19.9.2 数据库参数 19.10 程序调试及错误处理 19.11 程序设计清单 19.12 技术、经验总结 19.12.1 技术总结 19.12.2 经验总结 19.13 系统的编译与发行 第20章 Visual C++ 6.0在图书管理系统应用 20.1 图书管理系统概述 20.1.1 开发背景及意义 20.1.2 系统目标 20.2 系统分析 20.2.1 系统规划 20.2.2 系统结构图 20.2.3 业务流程 20.3 数据库设计 20.3.1 数据库概念设计 20.3.2 数据库逻辑结构设计 20.4 处理过程分析 20.4.1 图书信息处理过程分析 20.4.2 销售查询处理过程分析 20.5 程序框架设计 20.6 主窗体设计 20.7 程序设计与编码 20.7.1 系统登录程序设计 20.7.2 操作员管理程序设计 20.7.3 图书信息管理程序设计 20.7.4 图书销售查询程序设计 20.8 疑难问题分析解决 20.8.1 在对话框添加文档/视图架构 20.8.2 在基于对话框程序实现打印及打印预览 20.9 异常处理 20.10 程序设计清单 20.11 技术、经验总结 20.11.1 技术总结 20.11.2 经验总结 20.12 系统的编译与发行 第21章 Visual C++ 6.0在学生管理系统应用 21.1 学生管理系统概述 21.1.1 开发背景及意义 21.1.2 系统目标 21.2 系统分析 21.2.1 系统规划 21.2.2 系统结构图 21.2.3 业务流程 21.3 数据库设计 21.3.1 数据库概念设计 21.3.2 数据库逻辑结构设计 21.4 处理过程分析 21.4.1 科室信息添加处理过程分析 21.4.2 学生违规登记处理过程分析 21.5 主窗体设计 21.6 程序设计与编码 21.6.1 科室信息管理程序设计 21.6.2 学生成绩录入程序设计 21.6.3 学生违规处理程序设计 21.6.4 学生成绩报表程序设计 21.7 疑难问题分析解决 21.7.1 导入Excel相关 21.7.2 在程序操作Excel 21.7.3 导入Word相关 21.7.4 在程序操作Word 21.8 系统测试 21.9 程序设计清单 21.10 技术、经验总结 21.10.1 技术总结 21.10.2 经验总结 21.11 系统的编译与发行
C++,`static`关键字可以应用于头文件的变量、函数。这里是对每种情况的解释: 1. 静态变量(static variables):当将`static`关键字应用于头文件的变量时,它将具有文件作用域(file scope)。这意味着在包含该头文件的所有源文件,该变量都将是唯一的。静态变量在每个源文件都有自己的副本,但它们具有相同的名称和型。这在需要共享状态或保持全局状态的情况下很有用。 2. 静态函数static functions):将`static`关键字应用于头文件函数时,它将限制该函数的可见性为当前编译单元(compilation unit)。这意味着函数只能在包含该头文件的源文件使用,而不能在其他源文件使用。静态函数对于实现“内部链接”(internal linkage)非常有用,即只能在当前编译单元访问。 3. 静态成员(static class members):在头文件声明的静态成员将在所有使用该头文件的源文件之间共享。静态成员只有一个副本,无论有多少个对象被创建。它们被用来表示级别的数据或功能,而不是实例级别的。例如,可以使用静态成员来计算的实例数或跟踪某个属性的总和。 需要注意的是,头文件通常用于声明函数和变量的接口,而不是定义它们的实现。因此,在头文件使用`static`关键字来定义变量或函数的实现可能会导致多个源文件的重复定义错误。通常,应该将实现放在源文件,然后在头文件声明接口和变量。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值