C语言核心背诵知识点

一、定义变量四件事

1、比照类型分配对应大小空间。

2、取变量名(所有标识符都表示数据)

3、赋初值为0,不赋初值则为乱值。

这里的不赋初值为乱值说的是栈上的变量。

初始化全局变量分配到data段,未初始化全局变量分配到bss段,值为0

静态局部变量不赋初值,值自动为0.

4、变量一定有首地址,&为取地址符号。

二、关于字符串

用双引号引起来的字符序列,字符串中有两类字符,一类是普通字符,原样输出,一类是特殊字符:主要包括转义字符格式化输出相关字符。

转义字符:

\n表示换行  \t表示制表符  \\反斜杠字符本身

\b光标向前移动一个字符的位置,但并不删除该位置的字符。

格式化输出字符:

格式化输出整形:%d %o %x %u

格式化输出实型:%f %e

格式化输出字符、字符串:%c %s

%% 输出一个%

三、关于转义字符

1、\就是转义字符,后面跟着的字符成为字符本身,失去系统赋予的特殊意义或被赋予新的意义。

2、在双引号或单引号引起来的字符序列中,\ooo(最多三个八进制)表示用八进制作为ASCII码值对应的那个字符,\xhh(最多两个十六进制)表示用十六进制作为ASCII码值对应的字符。

四、关于sizeof

能够测试常量、变量、数组、类型所占或应占内存空间的大小,单位是字节。

1、测试字符串,就是字符个数加1。

2、测试变量,就是测试变量对照类型分配的空间的大小。

3、测试数组名,就是数组所占空间大小。

4、测试类型,就是类型应占空间大小。

5、测试指针变量,在32位系统下都是4个字节, 在64位系统下都是8字节。

6、数组名作为函数形参将退化成指针变量,字节数为4或者8。

五、关于函数

1、 定义在下面,调用在上面的函数需要进行函数原型的声明,告诉编译器有这样类型的函数(函数返回值类型、函数名称、参数和参数类型),编译器通过函数原型声明检查函数调用语法是否正确。

      定义在上面,调用在下面的函数可以不进行函数原型的声明。

2、函数的返回值类型表示函数调用结束后返回的数值类型,根据返回值类型定义一个相同类型的变量接受函数返回值,进行下一步的处理;函数的形参是分配空间接受实参的值;函数体中定义的变量叫做局部变量,作用范围是本函数,也就是说不同函数使用相同名字的局部变量是不冲突的。

3、函数被调用时产生栈帧,形参分配空间接受实参的值,函数调用结束后,形参和局部变量分配的内存将自动释放。(不能返回局部变量的地址)。

4、必须按照数目一样、类型一样、顺序一样进行实参和形参的结合,实参向形参传递数据是单向传递,只能由实参传递给形参,形参的改变不影响实参。

想要改变主调函数的值,必须将变量的地址传递给被调用函数中,被调用函数通过点找块(地址前加*)改变主调函数变量的值。

 六、关于指针

1、指针,也叫地址,内存块的首地址,是常量。数组名就是一个常量地址(不能自增自减,也不能另附新值)。

2、指针变量,存放指针的变量。int * p表示p用来存放int型内存块地址,int *是整型内存块地址。char * p表示p用来存放char型内存块地址,char * 是char型内存块地址。注意:

1、未初始化指针变量禁止使用。

2、把谁的地址赋值给指针变量,我们说指针变量就指向了谁。

3、64位系统下所有的指针变量占8个字节,32位系统下所有指针变量占4个字节。

      指向二维数组的指针变量:

int a[5][10]
//用什么样的变量保存a?     int (*p)[10] =a;
//用什么样的变量保存a【0】?    int *p = a[0];

3、*p的含义:点找块,根据p代表的地址找到对应的内存块。注意:

1、如果p为NULL,*p将崩溃。

2、如果p为乱值,*p将奔溃。 

 4、p+n(地址量+整型量)表示从p代表的地址开始向右偏移n个存储单元,计算出一个新的地址。

5、p【n】:下标运算符,从0开始,表示p代表的地址后第n个内存块。

七、运算符的优先级和它的关键知识点

所有表达式的运算规则:从左到右两两运算符比较优先级,左边的优先级高先计算左边的,右边优先级高的继续向右找直到相对优先级较高的进行计算。如果优先级相同看结合性,单目右结合,双目左结合,三目嵌套右结合计算左结合,左结合先计算左边的,右结合继续向右找,直到找到相对较高的,重复以上步骤,注意&&和||的短路特性。

优先级运算符结合性关键知识点
1[]   ()   .   ->

.是结构体变量里面的

->是结构体变量指针指向内存块里的某个成员

2

- !~ ++ --

& * 强转

sizeof()

1、只有变量才能自增自减。

2、单独的i++和++i没有区别,在其他表达式就有区别了,变量在前,先用变量参与表达式运算,然后在立即自增自减。符号在前,变量先自增自减,在参与所在表达式的运算

3、如果多于两个++或--连写,编译器识别前两个++或--为自增自减运算。

3* / %

1、两个整数相除必得整数,此为地板除,向下取整。

2、分子或分母有一个是浮点数,即为通常意义的除法。

3、分母不能为0,否则崩溃。

1、%用于计算两个数相除后得到的余数。

2、参与运算的量必须是整数,结果也是整型量。

3、某个整型量和n取余,结果范围是【0~n-1】.

4+ - 
5>> <<

>>右移n位等于原数 / 2^n

<<左移n位等于原数 * 2^n

6<= < >= >

1、运算结果只能是0(假)或1(真)。

2、只能做两个数之前的关系。

7==      !=
8&(按位与)两个数对应bit位逐个运算,有0则0
9^ (按位异或)对应bit位相同为0,不同为1
10|(按位或)对应位有一个为1,则为1
11&&(逻辑与)

1、运算结果只能为1(真)或0(假)。

2、注意短路特性。

12|| (逻辑或)
13三目运算符
14= += -= *= /= %= >>= <<= &= |= ^=1、=左侧一定是变量,右侧啥都可以,只要类型匹配就行。
15逗号运算符

1、把逗号看成分号求运算,因为逗号表达式是多条语句的表达式写法。

2、逗号表达式的结果是最后一个表达式的结果。

八、标识符命名规则 

用来标识变量、符号常量、数组、函数的符号。

1、只能用数字、字母、下划线组成。

2、不能用数字开头,只能以字母、下划线开头。

3、不能和系统关键字、用户定义函数、系统库函数重名。

4、头文件中有很多以下划线开头的内部变量名,建议用户避免使用。

5、区分大小写。

6、起名要见名知意。

九、五大分区

1、栈区(stack):函数的形参和局部变量分配到栈区,大小1~2M,栈是向下增长(栈底在上,栈顶在下),内存自动产生,自动释放。

      栈(Stack)的FILO特性指的是“First In Last Out”(先进后出)的原则。在栈这种数据结构中,数据的添加(称为“入栈”或“压栈”)和移除(称为“出栈”或“弹栈”)都只能在栈顶进行。因此,最先被添加到栈中的元素将会是最后被移除的,这就形成了FILO(先进后出)的特性

2、堆区(heap):用malloc函数分配,必须通过free函数手动释放,如果不释放就会导致内存泄漏。

3、常量文本区:不允许修改,否则崩溃。

4、全局静态区:全局变量和静态局部变量分配到全局静态区。

静态局部变量:局部变量前加static,函数调用结束后,静态局部变量分配的内存不释放,值仍然保留,每次函数重新调用是也不会为其重新分配内存,只初始化一次。

5、程序运行区:存放每一条指令。

十、scanf六点

1、输入数据时采用的分隔符应与格式控制中的分隔符一致。格式控制中无普通字符时,输入数值型数据可用空格、Tab键、回车键作分隔符。

2、输入数据时不可规定精度,但可指定宽度。

3、输入格式符带有*,表示指针读取位置指针向后改变。

4、有无符号数可用%d,%o,%x,%u格式读入。

5、用C格式符读入字符时,任何输入都是有效字符。

6、遇到空格、回车、Tab键;遇到指定宽度结束;非法输入情况下认为数据输入结束。

遇到空格、Tab、回车遇到指定宽度结束非法字符结束
%e %f %u %d %x %0YesYesYes
%cNoYesNo
%sYesYesNo

十一、关于结构体

1、 字节对齐:

(1)、结构体各成员的起始位置相对于结构体变量的起始位置的偏移量应该是这种类型的倍数。

(2)、结构体变量占总字节数应该是结构体各成员最大类型所占字节数的倍数。

2、读入或输出数据时,不能整体的读入或者整体输出,只能逐个结构体成员读入或输出。

3、相同类型的结构体变量能够相互赋值。

十二、static和extern关键字的作用。

变量函数
extern

1、定义在下面的全局变量,在上面需要使用时,可以加extern声明,表示使用已经分配好内存的全局变量。

2、定义在其他文件中全局变量,而在本文件中使用,可以加extern声明即可使用。

1、定义在其他文件中的函数,想在本文件使用,加extern即可使用。(其他文件中函数不可加static)
static

1、局部变量前static,表示静态局部变量分配到全局静态区,每次函数调用结束后,内存不释放,值仍然保留,每次函数重新调用时,也不会为其重新分配内存,只初始化一次。

2、全局变量前加static,表示静态全局变量,该变量只能被本文件使用,其他文件不能使用,这是避免命名冲突的方法

1、函数前加static,表示他是个静态函数,仅限本文件使用,其他文件不能使用,也是避免命名冲突的方法

十三、函数调用与宏调用的区别

1、函数调用时,先求实参表达式的值,然后带入形参,而使用带参的宏,只是将实参的字符代替了宏中的形参。

2、函数调用是在程序运行时处理的,为形参分配临时的内存单元,宏是在编译前进行,展开式不分配内存单元,不进行值的传递,没有返回值概念。

3、函数中的实参与形参都需要进行类型定义,并且二者类型要求一致,不一致需要进行强制转换。宏不存在类型问题,宏名无类型,参数无类型,宏定义时,字符串可以是任何类型数据。

4、宏替换不占用运行时间,只占编译时间,函数调用则占运行时间。

针对宏我们说两点:

1、带参数的宏

#define 宏名(形参)  字符串                              【字符串中包含()中的形参,并且带括号】

2、不带参的宏

 #define PI  3.1415

 #define S(r)  PI*r*r

注意:1、宏名与带参数的括弧之间不能有空格。

           2、带参的宏定义形参不分配内存单元,不用进行类型定义,带参宏调用实参要有具体的值,用实参代替形参,需要进行类型定义,带参宏只是进行符号代换,不存在值传递问题。

           3、宏定义中形参标识符,宏调用中实参可以是表达式。

           4、宏定义字符串中的形参需要用括号括起来,

十四、指针数组和数组指针   函数指针和指针函数

1、指针数组

本质是数组,数组的元素都是指针。

int *ptr[3]; // 声明一个指针数组,它可以存储3个整型指针  
ptr[0] = &var1;  
ptr[1] = &var2;  
ptr[2] = &var3;  

2、数组指针

本质是指针,指向一个数组。数组指针的类型必须明确指定它所指向的数组的类型和大小

int arr[3] = {1, 2, 3};  
int (*ptr)[3]; // 声明一个指向有3个整数的数组的指针  
ptr = &arr; // ptr现在指向arr

arr 在大多数情况下(作为表达式)会被解释为指向数组首元素的指针(int*)。
&arr 取的是整个数组的地址,类型为 int (*)[3]。
当你想要一个指针指向整个数组时(比如,你想通过指针来访问数组的维度信息),你应该使用 &arr。

3、函数指针

本质是指针,指向函数的指针,(变量)保存函数的首地址 

作用是:为了回调函数,解决差异化问题。

int add(int a, int b);//假设我们有一个函数原型如下
int (*funcPtr)(int, int);//可以声明一个指向这个函数的指针
funcPtr = add; // 将 add 函数的地址赋给 funcPtr  
int result = funcPtr(5, 3); // 通过函数指针调用 add 函数

4、指针函数

指针函数:返回指针的函数,这个指针可以是任何类型的指针,包括指向数据或函数的指针。

int* createInteger() {  //createInteger 是一个指针函数,它返回一个指向 int 的指针。
    int *p = (int*)malloc(sizeof(int)); // 动态分配内存  
    if (p != NULL) {  
        *p = 10; // 假设我们给这个整数赋值为10  
    }  
    return p; // 返回指向整数的指针  
}
int *ptr = createInteger(); // 调用指针函数  
if (ptr != NULL) {  
    printf("%d\n", *ptr); // 解引用指针并打印值  
    free(ptr); // 释放动态分配的内存  
}

 十五、const关键字的作用。

         const是定义常变量的关键字,作用是声明一个变量为常量,即这个变量的值在程序运行期间不能被修改。可以用于修饰多种类型的变量,包括基本数据类型(如intfloatchar等)、指针(包括指向常量的指针和常量指针)、数组和结构体等。 

指针常量常量指针
const

1、char * const str

2、指针本身是常量,指向的地址不能被改变。但是可以通过这个指针来修改它所指向内存块的值。

1、const char * str

2、他是一个指针,指向的内容是常量。不能通过这个指针来修改它所指向的变量的值,但是可以指向其他变量。

int x = 5;  
int *const ptr = &x; // ptr是一个指针常量,指向x的地址,ptr的值(即指向的地址)不能被改变
const int x = 5;  
const int *ptr = &x; // ptr是一个常量指针,指向x,但不能通过ptr修改x的值

十六、strlen函数与strtok函数 

1、strlen 定义在<string.h>头文件中

      strlen的函数原型如下:

size_t strlen(const char* str);

    返回值:strlen函数返回一个unsigned long long int类型的值,表示字符串的长度。

    参数:strlen函数接受一个const char*类型的参数,即指向字符串的指针。这个指针指向的字符串必须以'\0'结尾。

    作用:从某个地址开始,截至到第一个'\0',中间字符的个数。

2、strtok定义在<string.h>头文件中

      strtok的函数原型如下:

char* strtok(char* str, const char* delim);

    返回值:strtok函数返回一个char*类型的指针,指向被切割出的子串的首地址。如果没有更多的子串,或者参数不合法,则返回NULL。

    参数:第一个参数str:在第一次调用strtok函数时,str指向要被切割的字符串。在后续的调用中,应将str设置为NULL,以便继续从上次的位置切割。

             第二个参数delim:包含分隔符的字符串。strtok函数会在str指向的字符串中查找delim字符串中的任意字符作为分隔符。

    作用:分解字符串为一组字符串,str为要分解的字符串,delim为分割符字符。

说明:1、非可重入函数(每次调用得到的结果不同)。

           2、破坏原来的串。

十七、 数值型数组和char数组的对比。

4ac5a4e290a546da8e75e076bf0142d2.png

十八、每个数据类型的字节数和数据范围。

Int 4字节 数值范围:-21亿-21亿                   unsigned int 4字节 数值范围;0-42亿

Short int 2字节 数值范围:-32768-32767       unsigned short int 数值范围:0-65535

Long int 4字节 数值范围:-21亿-21亿             unsigned long int 4字节 数值范围;0-42亿

Longlongint 8字节 数值范围: -2^63 - 2^63-1   unsigned longlong int 8字节 0-2^64-1

十九、整形常量的三种写法,实型常量的两种写法。

1、整形常量:有三种表现形式(都是二进制的快速记法):a、十进制

                                                                                               b、八进制:0开头

                                                                                               c、十六进制 : 0x开头

2、实型常量:有两种表现形式(都是以十进制形式):a、十进制小数形式

                                                                                        b、指数形式(科学计数法)

二十、关于数组

1、数目固定、类型相同、连续存放的一组有序树的集合 。

2、C语言规定,数组名就是首地址,他是一个指针常量 。

3、Str[i]表示的是str代表的地址后的第i个内存块。

4、{0}表示给str[0]赋值为0,这叫部分元素赋初值,其他未赋值的元素自动为0,如果不附初值,则为乱值。

5、下标的范围是[0,n-1],否则越界访问。

6、数组作为函数形参,退化成指针变量。

7、数组定义以后,  编译器就会为这个数组在内存中分配一串连续的存储单元用于存放数组元素的值。数组名表示存储单元的首地址, 存储单元的多少由数组的类型和数组的大小决定

二十一、判断大端还是小端

大端是将数据的高位存储在内存的低地址处,小端存储是将数据的低位存储在内存的低地址处。

区分大小端的两种方法:

#include <stdio.h>
int main(){
    int a = 1;
    if(*(char*)&a == 1){
        printf("little endian");
    }else{
        printf("big endian");
    }
}




#include <stdio.h>
union A{
    int a;
    char b;
};
int main(){
    union A a;
    a.a = 1;
    if(a.b == 1){
        printf("little endian");
    }else{
        printf("big endian");
    }
}

二十二、联合体和结构体 

结构体和联合体的区别:(结构体参考第十一条)
 1,结构体各个成员是字节对齐的,每个结构体成员相对于结构变量起始位置的偏移量是该成员类型的大小的倍数。
    结构体变量占用的总字节数,应该是结构体成员中最大类型所占字节数的倍数。
2,联合体是所有成员中最大类型所占字节数,所有成员公用一块内存。

2 联合体的应用场景:
(1)判断系统用的是big endian 还是 little endian(参考第二十一条    )
(2)强制类型转换(int 和 char数组转换,float 和 char数组转换)

int main(){
    char b[4] = {0x12,0x34,0x56,0x78};
    int a = *(int *)b;
    printf("%#x",a);
}


//使用联合体实现强转功能
#include <stdio.h>
union A{
    int a;
    char b[4];
};
int main(){
    union A a;
    a.b[0] = 0x12;
    a.b[1] = 0x34;
    a.b[2] = 0x56;
    a.b[3] = 0x78;
    printf("%#x",a.a);
}

(3)用一个成员把值存储在一个联合中,然后用另一个成员查看内容。一般用在位域场景。
(4)便于阅读代码。
(5)在结构中储存与其成员有从属关系的信息。

二十三、位域操作

  位域(bit-field)是一种特殊的结构体成员,允许我们按位对成员进行定义,指定其占用的位数。

如果程序的结构中包含多个开关的变量,即变量值为 TRUE/FALSE,如下:

#include <stdio.h>
#include <string.h>
 
/* 定义简单的结构 
这种结构需要 8 字节的内存空间*/
struct
{
  unsigned int widthValidated;
  unsigned int heightValidated;
} status1;
 
/* 定义位域结构 */
struct
{
  unsigned int widthValidated : 1;
  unsigned int heightValidated : 1;
} status2;
 
int main( )
{
   printf( "Memory size occupied by status1 : %d\n", sizeof(status1));
   printf( "Memory size occupied by status2 : %d\n", sizeof(status2));
 
   return 0;
}

 二十四、文件       

1、文件的定义:存储在外存储器上的数据集合。                                                                            2、文件按存储形式分类:文本文件:每个字符通过相应的ASCII码存储在文件中。

                                    二进制文件:直接把数据以二进制文件保存。

3、文件指针:程序通过FILE类型指针建立和文件的联系,对文件进行操作。

FILE *fp1 //指向FILE类型结构体的指针变量。

  fp1用于存放文件的缓冲区首地址,指向一个文件。

4、文件的打开(fopen):

为了打开一个文件,要为该文件定义一个文件类型指针,然后使用fopen函数打开文件。

格式:

FILE *文件指针名;
文件指针名 = fopen("文件名”,“文件使用方式”);
文件使用方式
符号意义若指定文件不存在
r(read)只读方式打开一个文本报错
w(write)只写方式创建一个文本创建一个新文件
a(append)从文件末尾写数据报错
wb只写方式打开一个二进制文件创建一个新文件
w+读和写,创建一个新的文件创建一个新的文件
a+打开一个文件,在文件尾读和写创建一个新文件
wb+读和写,创建一个二进制文件创建一个新文件
ab+打开一个二进制文件,在文件尾进行读写创建一个新文件

 除了上方特定使用方式,其他文件使用方式,如果指定文件不存在,都会报错、

t(text)文本文件,可省略
b(banary)二进制文件
+读和写

 

返回值:

  • 如果 fopen 成功打开了文件,它将返回一个指向该文件的 FILE 对象的非空指针。
  • 如果 fopen 因为任何原因(如文件不存在、没有访问权限等)无法打开文件,它将返回 NULL
FILE * fp;
fp = fopen(".\\abc\\b.txt", "r");

5、文件的关闭(fclose):

格式:

fclose(文件指针);

返回值:操作正常返回0,否则返回EOF(-1)。

如果不关闭文件,将会丢失数据。

#include <stdio.h>
#include<stdlib.h>
int main() {
    FILE *fp;
    if((fp= fopen("test.txt","w"))==NULL){
        printf("cannot open file\n");
        exit(0);
    }
    fclose(fp);
}

6、文件的读写

     a、字符读写

     字符读函数

格式:字符变量 = fgetc(文件指针);

ch = fgetc(fp);//从fp指向文件中读出一个字符,赋给字符变量ch

功能:从指定文件读入一个字符,该文件必须是以读或者读写方式打开。

返回值:调用成功返回读入字符,文件结束时返回文件结束符EOF(-1)

     字符写函数

格式:fputc(字符量,文件指针);

fputc('a',fp);//把a写到fp指向的文件中

功能:将一个字符写道磁盘文件上去。

返回值:调用成功返沪输出字符,失败返回EOF(-1)

     b、字符串读写

     读字符串函数

格式:fgets(字符数组名,n,文件指针);

fgets(str,9,fp);//从fp所指文件中读出8个字符送入字符数组str中。

功能:从指定文件读入n-1个字符到字符数组,最后加一个'\0'结束符,在读完n-1个字符之前遇到换行符或者文件结束符(EOF),读入即结束。

返回值:字符数组的首地址。

       写字符串函数

格式:fputs(字符串,文件指针);

fputs("abcd",fp);//把字符串“abcd”写入fp所指文件中

功能:向指定文件输出一个字符串,’\0‘结束符不输出。其中字符串可以是字符串常量、字符数组或者指针变量。 

返回值:调用成功返回0,否则返回EOF。

     c、格式读写

格式:fscanf(文件指针,"格式控制字符串",地址表列);

fscanf(fp,"%d,%f",&i,&t);//表示将磁盘文件中的数据送给变量i,t。

           fprintf(文件指针,“格式控制字符串”,输出列表);

fprintf(fp,"%d,%6.2f",i,t);//将变量i和t按指定格式输出到fp指向文件。

       d、数据块读写 

格式:fread(内存地址,数据项字节数,数据项个数,文件指针);

fread(a,2,5,fp);//从fp指向文件中读入5个整数,依次送入整型数组a中

           fwrite(内存地址,数据项字节数,数据项个数,文件指针);

for(int i=0;i<n;i++){
    fwrite(&arr[i],sizeof(struct student),1,fp);
}//每次向fp指向文件中写入一项写入struct student类型的结构体对象数组 arr 的数据

7、判断文件结束函数 feof()

格式:feof(文件指针);

feof(文件指针);

功能:判断文件位置指针是否到文件尾。

返回值:返回为1表示已经到文件尾部。

              返回为0表示还未到文件结束处。

大一C语言的必背知识点包括以下内容: 1. 数据类型:了解C语言的基本数据类型,包括整型、浮点型、字符型等,并了解它们的取值范围和存储大小。 2. 变量和常量:学会声明和定义变量,了解变量的作用域和生命周期。同时,了解常量的概念和使用方法。 3. 运算符:掌握C语言中的各种运算符,包括算术运算符、关系运算符、逻辑运算符等,并了解它们的优先级和结合性。 4. 控制语句:学会使用条件语句(if-else语句、switch语句)和循环语句(for循环、while循环、do-while循环)来控制程序的流程。 5. 数组:了解数组的概念和使用方法,包括一维数组和多维数组,并学会使用数组进行数据的存储和处理。 6. 函数:掌握函数的定义和调用,了解函数的参数传递和返回值,学会编写自定义函数来实现特定的功能。 7. 指针:理解指针的概念和使用方法,包括指针的声明、指针的运算和指针与数组的关系。 8. 结构体:了解结构体的概念和使用方法,学会定义和操作结构体变量,包括结构体的成员访问和结构体数组的使用。 9. 文件操作:学会使用C语言提供的文件操作函数来读写文件,包括打开文件、读取文件内容和写入文件内容等操作。 10. 动态内存分配:了解动态内存分配的概念和使用方法,学会使用malloc()和free()函数来进行内存的动态分配和释放。 以上是大一C语言的必背知识点,掌握了这些知识点可以帮助你更好地理解和编写C语言程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值