C语言(一):32个关键字及其用法

由ASCII标准定义的C语言关键字共32个:

数据关键字12个:char,double,float,enum,unsigned ,int,long,short,signed,struct,union,void

控制语句关键字12个:for,do,while,break,continue,if,else,goto,switch,case,default,return

存储类型关键字4个:auto,extern,regsiter,static

其他关键字4个:const,sizeof,typedef,volatile

一、数据关键字(12个):

  1.  char :声明字符型变量或函数
    char p = 'a'; //注意使用单引号
    char getSigleChar(); //函数返回值为char类型
    
    char *p = 'abcd'; //也可以使用双引号
    char* getCharArray(); //函数返回值为char*类型
    /*
    char* getCharArray()
    {
        char* str = NULL;
        char x[127];
        scanf("%s", &x);
        str = x;
        return str;
    }
    */
  2.  short :声明短整型变量或函数 
     
    short i = 123; //short的范围是范围-32768~+32767(总范围2的16次方),标准定义不得低于16位,两个字节
    signed short i = 123; //i可以表示-32768~+32767
    unsigned short i = 123; //只取整数,i可以表示0~65535
    
    short getShortNum(); //函数返回值是short类型
    signed short getSignedShortNum(); //函数返回值是signed short类型
    unsigned short getUnsignedShortNum(); //函数返回值是unsigned short类型
  3.  int: 声明整型变量或函数
     
    int i = 123; //int的数据范围为-2147483648~2147483647(总范围是2的32次方),占用4个字节。注意:之前的微型机中2的16次方,数据范围为-32768~32767
    signed int i = 123; //signed int的数据范围是:-2147483648~2147483647
    unsigned int i = 123; //unsigned int的数据范围是:0~4294967295
    
    int getIntNum(); //函数返回值为int类型
    signed int getSignedIntNum(); //函数返回值为signed int类型
    unsigned int getUnisgnedIntNum(); //函数返回值为unsigned int类型
    
    const int i= 123; //注意当const和int一起使用时一定一定一定要给i赋值,const int i;是错误的
  4.  long :声明长整型变量或函数 
     
    long i = 123; //long的数字范围是-2147483648~2147483647(总数范围是2的32次方)占4个字节
    signed long i = 123; //signed long的范围是-2147483648~2147483647
    unsigned long long i = 123; //unsigned long long的范围是0~4294967295
    
    long getLongNum(); //函数返回值是long类型
    signed getSignedNum(); //函数返回值是signed long类型
    unsigned getUnsignedNum(); //函数返回值是unsigned long类型
    
    
    long long i = 123; //long long的范围-9223372036854775808~9223372036854775807(总数范围是2的64次方)占8个字节
    signed long long i = 123; //signed long long的范围-9223372036854775808~9223372036854775807
    unsigned long long i = 123; //unsigned long long的范围是0~1.844674407×10¹⁹
    
    long long getLongLongNum(); //函数返回值是long long类型
    signed long long getSignedLongLongNum(); //函数返回值是signed long long类型
    unsigned long long getUnsignedLongLongNum(); //函数返回值是unsigned long long类型
  5.  float:声明浮点型变量或函数 
     
    float a = 1.23; //float的范围是1.175494351E–38到3.402823466E+38,有效位是6~7位,占4个字节,单精度浮点型
    float getFloatNum(); //函数返回值是float类型
    
  6.  double :声明双精度变量或函数 
     
    double i = 1.23; //double的范围是2.2250738585072014E–308~1.7976931348623158E+308,有效位是15~16个,占8个字节,双精度浮点型
    double getDoubleNum(); //函数返回值是double类型
    
  7.  enum :声明枚举类型 
     
    enum weekday{sun,mon,tue,wed,thu,fri,sat}; //枚举元素从零开始,定义为0,1,2,...。sun的值是0,sta的值是6。
    
    enum weekday a,b,c;
    a=(enum weekday)2; //只能把枚举值赋予枚举变量,不能把元素的数值直接赋予枚举变量。如果一定要把数值赋予枚举变量,则必须使用强制类型转换。
  8.  signed:声明有符号类型变量或函数
    signed char a = 123; //char类型能存储的范围是-128~127
    signed char getSignedChar(); //函数返回值是char类型
  9. unsigned:声明无符号类型变量或函数 
     
    unsigned char a = 233; //unsigned char的范围是0~255
    unsigned char getUnsignedChar(); //函数返回值是unsigned char类型
  10.  struct:声明结构体变量或函数 
     
    struct student
    {
        int num;
        char name[20];
        char sex;
        float score;
    }; //注意结尾的分号
  11. union:声明共用体(联合)数据类型 
     
    union foo{
        int i;
        char c;
        double k;
    }; //注意最后的分号不要忘记
  12. void :声明函数无返回值或无参数,声明无类型指针(基本上就这三个作用)
    void getNothingFromFunc(); //作用一: 对函数返回的限定,函数无返回值
    int function(void); //作用二:对函数参数的限定,函数没有入参
    
    void* memcpy(void* dest, const void* src, size_t len); //如果函数的参数可以是任意类型指针,那么应声明其参数为void *

注意:

  • 共用体和结构体都是由多个不同的数据类型成员组成,但在任何同一时刻,共用体只存放一个被选中的成员,而结构体的所有成员都存在。
  • 对于共用体的不同成员赋值,将会对其他成员重写,原来成员的值就不存在了,而对于结构体的不同成员赋值是相互不影响的。

二、控制语句关键字(12个):

1、循环语句 (5个)

  • for:一种循环语句(可意会不可言传)
    for(int i = 0; i < 10; i++) //起始条件; 判断条件; 循环执行后执行的语句
    {
        printf("i = %d\n", i);
    }
  • do :循环语句的循环体 
     
    int i = 0;
    do{
        i++;
        printf("Hello")
    }while(i < 10); //判断条件,执行10次
    //先执行循环,后判断条件
  • while :循环语句的循环条件 
     
    int i = 0;
    while(i < 10)
    {
        i++;
        printf("%d\n",i)
    } //判断条件,循环10次
    //先判断条件,再执行循环
  • break:跳出当前循环 
     
    for(int i = 0; i < 10; i++) //起始条件; 判断条件; 循环执行后执行的语句
    {
        if(i > 5)
        {
            break; //break经常和if判断一起使用,
        }
        printf("i = %d\n", i);
    }
  • continue:结束当前循环,开始下一轮循环 
     
    for(int i = 0; i < 10; i++) //起始条件; 判断条件; 循环执行后执行的语句
    {
        if(i > 5)
        {
            continue; //continue经常和if判断一起使用,
        }
        printf("i = %d\n", i);
    }

2、条件语句 (3个)

  • if: 条件语句
    int i = 10;
    if(i < 11)
    {
        printf("%d\n", i);
    }
  • else :条件语句否定分支(与 if 连用)
    int i = 10;
    if(i < 11)
    {
        printf("%d\n", i);
    }else{
        printf("hello");
    }
  • goto:无条件跳转语句 
     
    int main()
    {
        int a = 2, b = 3;
        if(a > b) //条件不成立
        {
            goto aa;
        }
        printf("hello");
        aa::printf("s"); //需要设置label标签,
        return 0;
    } //此时,结果结果是打印“hellos”
    
    int main()
    {
        int a = 2, b = 3;
        if(a < b)  //条件成立
        {
            goto aa;
        }
        printf("hello");
        aa::printf("s"); //需要设置label标签,
        return 0;
    } //此时,结果结果是打印“s”

3、开关语句 (3个)

  • switch :用于开关语句
  • case:开关语句分支 
  • default:开关语句中的“其他”分支
    double score;
    printf("请输入分数:\n");
    scanf("%lf",&score);
    switch((int)(score/10))  //switch()的参数类型不能为实型,可以是整型和字符型,这里强制类型转化为int
    {    
        case 10:    
        case 9:
            printf("A(最好)\n");
            break;    
        case 8:
            printf("B(优秀)\n");
            break;    
        case 7:
            printf("C(良好)\n");
            break;    
        case 6:
            printf("D(及格)\n");
            break;    
        case 5:
        case 4:
        case 3:
        case 2:
        case 1:
        case 0:
            printf("E(不及格)\n");
            break;
        default:
            printf("Error!\n");
    }

4、返回语句(1个)

  • return :子程序返回语句(可以带参数,也看不带参数)
    int function1()
    {
        int i = 1;
        return 1;
        //return(i); //这样也可以
    }
    void function2()
    {
        int i = 1;
        //return; //这样也可以,也可以去掉这一句
    }

    注意:很多教程都提到了void main(),但是这样写是完全错误的,因为在C++之父Bjarne Stroustrup (已经仙逝)在他的主页上的 FAQ 中明确地写着 “The definition void main( ) { /* ... */ } is not and never has been C++, nor has it even been C”。所以这种定义基本是不存在的,至于为什么能通过编译,这就和编译器(有些会自动添加return 0)有关系了。有兴趣的可以看看C99关于main函数的定义标准(相比之前,标准定义只有从int main(void)变为int main(),其他基本没有修改)。

三、存储类型关键字(4个)

  1. auto :声明自动变量 一般不使用
    auto double a=3.7; //表示a为一个自动存储的临时变量。
    
    /*
    在C++11标准的语法中,auto被定义为自动推断变量的类型。
    auto x = 5.2;//这里的x被auto推断为double类型
    不过C++11的auto关键字时有一个限定条件,那就是必须给申明的变量赋予一个初始值,否则编译器在编译阶段将会报错。
    */
  2. extern:声明变量或函数是在其他文件中声明(也可以看做是引用变量) 
     
    //A.cpp
    extern int i;
    int main()
    {
        i=100;//试图使用B中定义的全局变量
    }
    //B.cpp
    int i;
    
    
    extern int f(); //如果函数的声明中带有关键字extern,仅仅是暗示这个函数可能在别的源文件里定义,没有其它作用。即下述两个函数声明没有明显的区别和int f();是一样的。
    //当然,这样的用处还是有的,就是在程序中取代include “*.h”来声明函数,在一些复杂的项目中,最好所有的函数声明前添加extern修饰。
    
    
    /*
    在C++环境下使用C函数的时候,常常会出现编译器无法找到obj模块中的C函数定义,从而导致链接失败的情况,C++语言在编译的时候为了解决函数的多态问题,会将函数名和参数联合起来生成一个中间的函数名称,而C语言则不会,因此会造成链接时找不到对应函数的情况,此时C函数就需要使用extern "C"进行链接指定,这告诉编译器,请保持我的名称,不要给我生成用于链接的中间函数名。
    */
    下面是一个标准的写法:
    //在.h文件的头上
    #ifdef __cplusplus
    #if__cplusplus
    extern "C"{
        #endif
        #endif/*__cplusplus*/
        ...
        ...
        //在.h文件结束的地方
        #ifdef__cplusplus
        #if__cplusplus
    }
    #endif
    #endif/*__cplusplus*/
  3. register:声明积存器变量 
     
    /*
    resgister修饰符暗示编译程序相应的变量将频繁的使用,如果可能的话,应将其保存在CPU的寄存器中,以加快存储速度。
    */
    #ifdef NOSTRUCTASSIGN
    memcpy(d, s, i)
    {
        register char *d;
        register int i;
    }
    #endif
    
    
    //register变量必须是一个单个的值,并且长度应该小于或者等于整型的长度。
    //因为register变量可能不存放在内存中,所以不能用“&”来获取register变量的地址。
    
    //实际上,许多编译程序都会忽略register修饰符,因为尽管它完全合法,但它仅仅是暗示而不是命令。
  4. static :声明静态函数
    static char str[10]; //static定义的变量默认初始化为0
    //static变量存放在静态存储区,所以它具备持久性和默认值0。
    
    
    /*
    函数分为内部函数和外部函数
    当一个源程序由多个源文件组成时,C语言根据函数能否被其它源文件中的函数调用,将函数分为内部函数和外部函数。
    */
    static void calledInSameFile(); //内部函数(静态函数)
    //内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名,因为同名也没有关系。
    
    
    void calledInDiffFile(); //或者下面一种
    extern void calledInDiffFile(); //外部函数(非静态函数)

    注意:static在C++中的含义会不一样,因为C++是面向对象语言,所以在类中的static会有额外的含义。

    #include<iostream>
    using namespace std;
    
    class Myclass
    {
        public:
            Myclass(int a, int b, int c);
            void GetSum();
        private:
            int a;
            int b;
            int c;
            static int Sum; //声明静态数据成员
    };
    
    int Myclass::Sum = 0; //初始化静态数据成员
    
    Myclass::Myclass(int a, int b, int c)
    {
        this->a = a;
        this->b = b;
        this->c = c;
        Sum += a + b + c;
    }
    void Myclass::GetSum()
    {
        cout<<"Sum = "<<Sum<<endl;
    }
    int main()
    {
        Myclass M(1, 2, 3);
        M.GetSum();
        Myclass N(4, 5, 6);
        N.GetSum();
        M.GetSum();
    }
    
    /*输出结果是:(1+2+3 = 6; 6+4+5+6 = 21)
    Sum = 6
    Sum = 21
    Sum = 21
    
    这个说明了静态数据成员在程序中只有一份拷贝, 由该类型的所有对象共享访问,也就是说,静态数据成员的值对每个对象都是一样的,它的值可以更新。
    */
    //体内定义,体外初始化,且必须初始化,子类为主,屏蔽父类
    
    
    //----------------------------------------------------------------------------
    //----------------------------------------------------------------------------
    #include<iostream>
    using namespace std;
    
    class Myclass
    {
        public:
            Myclass(int a, int b, int c);
            static void GetSum(); //声明静态成员函数
        private:
            int a, b, c;
            static int Sum; //声明静态数据成员
    }
    
    int Myclass::Sum = 0; //初始化静态数据成员
    
    Myclass::Myclass(int a, int b, int c)
    {
        this->a = a;
        this->b = b;
        this->c = c;
        Sum+= a + b + c;
    }
    
    void Myclass::GetSum()
    {
        cout<<"Sum = "<<endl;
    }
    
    int main()
    {
        Myclass M(1, 2, 3);
        M.GetSum();
        Myclass N(4, 5, 6);
        N.GetSum();
        Myclass::GetSum();
    }
    //结果不变,但是注意,静态成员函数无法访问数于对象的非静态数据成员,也无法访问非静态成员函数,只能调用其余的静态数据成员和静态成员函数。
    //体内定义,体外实现,且必须实现,不能为虚函数,子类为主,屏蔽父类
    
    

四、其它关键字(4个)

  1. const :声明只读变量 
     
    //const 在前面
    const int nValue; //const 修饰的是int,整型固定,但是nValue的值是也不变的
    const char* pContent; //const 修饰的是char*, 指针类型固定,但是pContent是可以变的
    const char* const pContent; //pContent和*pContent都被const修饰,都不可变。
    
    //const 在后面
    int const nValue; //const修饰的是nValue,在一定程度上和const int nValue相同,nValue的值不能修改
    char const *pContent; //const修饰的是*,pContent是可以改变的
    char* const pContent; //const修饰的是pContent,*pContent是可以改变的
    char const * const pContent; //pContent和*pContent都被const修饰, 都不可以改
    
    //const推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时继承它的优点。
  2. sizeof:计算数据类型长度
    //在C语言中要注意sizeof是运算符,而不是函数
    
    int i;
    sizeof(i); //sizeof(对象i的类型)
    sizeof i; //sizeof 对象
    sizeof(int); //sizeof(类型)
    //同种类型的不同对象其sizeof值都是一致的
    
    
    char foo()
    {
        printf("foo() has been called.\n");
        return 'a';
    }
    int main()
    {
        size_tsz = sizeof(foo()); // foo()的返回值类型是char,所以sz = sizeof(char), foo()并不会被调用
        printf("sizeof(foo()) = %d\n", sz);
    }
    //注意C99标准规定,函数、不能确定类型的表达式以及位域成员不能被计算sizeof值
    //最新的C99标准规定sizeof也可以在运行时刻进行计算,但是最好还是认为sizeof是在编译期执行的,这样能让程序的可移植性强些,因为有些编译器没有完全实现C99标准。
    //所以在32位计算机中,一个指针函数的返回值是4,但是在64位系统中结果是8。
    
    
  3. typedef:用以给数据类型取别名(当然还有其他作用)
    typedef int size; //size是int的别名
    typedef char Line[10]; //Line是具有10个char元素的数组
    typedef char* pstr; //pstr是字符指针
    
    typedef struct tagNode
    {
        char* pItem;
        struct tagNode* pNext; //注意这里不能写下面的别称pNode替换struct tagNode*,因为此时还没定义
    }*pNode;
    //还可以这样做,更规范一些
    struct tagNode
    {
        char* pItem;
        struct tagNode* pNext;
    };
    typedef tagNode* pNode;
    
    

    typedef和#define的区别:

    //#define属于在预编译期的单纯的拷贝
    typedef char* pStr;
    char string[4] = "abc";
    const char* p1 = string;
    const pStr p2 = string;
    p1++;
    p2++; //错误,原因是指针的星号*是优先向右结合的,在*p1中const修饰的是char,在p2中const修饰的是char*,所以,p1可以++,但是p2不可以++
    
    
  4. volatile:说明变量在程序执行中可被隐含地改变
    volatile int i=10; //当要求使用volatile声明的变量的时候,读取的数就会被立即保存起来,下次使用int a=i;时不要改变i的值(如果是指针有可能会发生变化)。
    //尤其是多线程中,无法判定何时这个变量会发生变化。加上volatile修饰这个变量表示这个变量是容易被修改的
    
    /*
    一般来说,volatile用在如下的地方:
    1、中断服务程序中修改的供其他程序检测的变量需要加volatile
    2、多任务环境下各任务间共享的标志应该加volatile
    3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都有可能有不同的意义
    */

----------------------------------------------------------------------------------------------------------------------

一般说C语言的32个关键字就是指以上的这些,但是除此之外,在后来的C&C++语言的新标准中增加了一些关键字

----------------------------------------------------------------------------------------------------------------------

C99增加的关键字(5个)

  1. inline:内联函数
    关键字inline必须与函数实现放在一起才能使函数成为内联,仅仅将inline放在函数声明前面不起任何作用。
  2. restrict:一种类型限定符
    用于限定和约束指针,并表明指针是访问一个数据对象的唯一且初始的方式,即它告诉编译器,所有修改该指针所指向内存中内容的操作都必须通过该指针来修改,而不能通过其它途径(其它变量或指针)来修改。目的是帮助编译器进行更好的优化代码,生成更有效率的汇编代码。
  3. _Bool:布尔型
    bool为布尔型用作逻辑判断;BOOL在<windef.h>typedef int BOOL,在<wtypes.h>typedef long BOOL;_Bool类型只有0和1这两个值
  4. _Complex:新增的数据类型,用来表示复数
    #include<complex.h>
    #include<stdio.h>
    
    
    int main()
    {
        double complex x = 5.2;
        double complex y = 5.0 * I; 大写I表示虚数单位,也就是-1的平方根
        double complex z = x + y;
        printf("z = %f\n", z); //不知道为啥只能显示实部,无法显示虚部。以后找到解决办法再贴上
    
        return 0;
    }
  5. _Imaginary:虚数类型,没有实部的(目前已经和_Complex合并)
    #include<complex.h>
    
    double imaginary x = 5.0 * I; //大写I表示虚数单位,即-1的平方根
    //现在已经无法像上面这么定义,只能通过下面的方式定义了
    double complex x = 5.0 * I;

关于复数的方法,C++有关于类的实现:

#include<iosteam>
#include<complex>

using namespace std;

int main()
{
    complex<double> x(1, 2.1);
    complex<double> y(0, 5.0);
    complex<double> z;
    z = x + y;
    std::cout<<"x = "<<endl;
    std::cout<<"y = "<<endl;
    std::cout<<"z = "<<endl;

    return 0;
}
/*最后的结果可以实现实部和虚部的组合:
x = (1,2.1)
z = (0,5)
y = (1,7.1)
*/

C11增加的关键字(7个)(下面的代码未进行测试。。。)

  1. _Alignas:修改声明对象对齐要求的指定符,出现在声明的语法中。
    #include<stdalign.h>
    #inlcude<stdio.h>
    
    //每一个struct see_t 类型的对象会在16字节边界对齐
    //(注意:需要注意支持 DR 444)
    
    struct sse_t
    {
        alignas(16) float sse_data[4];
    };
    
    //这种struct data的每一个对象都会在128字节边界对齐
    struct data
    {
        char x;
        alignas(128) char cacheline[128]; //过对齐的char数组对象,不是过对齐的char对象的数组
    };
    
    int main()
    {
        printf("sizeof(data) = %zu(1 byte + 127 bytes padding + 128-byte array)\n", sizeof(struct data));
        printf("alignment of sse_t is %zu\n", alignof(struct sse_t));
        alignas(2048) struct data d;
    }
  2. _Alignof:返回由类型标识符所指定的类型的任何实例所要求的对齐字节数
     
    #include <stdio.h>
    #include <stddef.h>
    #include <stdalign.h>
     
    int main(void)
    {
        printf("Alignment of char = %zu\n", alignof(char));
        printf("Alignment of max_align_t = %zu\n", alignof(max_align_t));
        printf("alignof(float[10]) = %zu\n", alignof(float[10]));
        printf("alignof(struct{char c; int n;}) = %zu\n", alignof(struct {char c; int n;}));    
    }
  3. _Atomic:原子类型指定符及限定符
     
    #include <stdio.h>
    #include <threads.h>
    #include <stdatomic.h>
     
    atomic_int acnt;
    int cnt;
     
    int f(void* thr_data)
    {
        for(int n = 0; n < 1000; ++n) {
            ++cnt;
            ++acnt;
            // 对于此例,宽松内存顺序是足够的,例如
            // atomic_fetch_add_explicit(&acnt, 1, memory_order_relaxed);
        }
        return 0;
    }
     
    int main(void)
    {
        thrd_t thr[10];
        for(int n = 0; n < 10; ++n)
            thrd_create(&thr[n], f, NULL);
        for(int n = 0; n < 10; ++n)
            thrd_join(thr[n], NULL);
     
        printf("The atomic counter is %u\n", acnt);
        printf("The non-atomic counter is %u\n", cnt);
    }
  4. _Static_assert:静态断言
    #include <assert.h>
    int main(void)
    {
        // 测试数学是否正常工作
        static_assert(2 + 2 == 4, "Whoa dude!"); // 或 _Static_assert(...
     
        // 这会在编译时产生错误。
        static_assert(sizeof(int) < sizeof(char),"this program requires that int is less than char");
    }
  5. _Noreturn:指定函数不会由于执行到 return 语句或抵达函数体结尾而返回
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <stdnoreturn.h>
     
    // 在 i <= 0 时导致未定义行为
    // 在 i > 0 时退出
    noreturn void stop_now(int i) // 或 _Noreturn void stop_now(int i)
    {
        if (i > 0) exit(i);
    }
     
    int main(void)
    {
      puts("Preparing to stop...");
      stop_now(2);
      puts("This code is never executed.");
    }
  6. _Thread_local:线程存储类限定符
     
    //库接口:
    // flib.h
    #ifndef FLIB_H
    #define FLIB_H
    void f(void);              // 带外部链接的函数声明
    extern int state;          // 带外部链接的对象声明
    static const int size = 5; // 带内部链接的只读对象定义
    enum { MAX = 10 };         // 常量定义
    inline int sum (int a, int b) { return a+b; } // inline 函数定义
    #endif // FLIB_H
    
    
    //库实现:
    // flib.c
    #include "flib.h"
    static void local_f(int s) {}  // 带内部链接的定义(只用于此文件)
    static int local_state;        // 带内部链接的定义(只用于此文件)
     
    int state;                     // 带外部链接的定义( main.c 使用)
    void f(void) {local_f(state);} // 带外部链接的定义( main.c 使用)
    
    应用代码:
    // main.c 
    #include "flib.h"
    int main(void)
    {
        int x[MAX] = {size}; // 使用常量和只读变量
        state = 7;           // 修改 flib.c 中的 state
        f();                 // 调用 flib.c 中的 f()
        return 0;
    }
  7. _Generic:泛型表达式
    #include <stdio.h>
    #include <math.h>
     
    // tgmath.h 宏 cbrt 的可能实现
    #define cbrt(X) _Generic((X), \
                  long double: cbrtl, \
                      default: cbrt,  \
                        float: cbrtf  \
    )(X)
     
    int main(void)
    {
        double x = 8.0;
        const float y = 3.375;
        printf("cbrt(8.0) = %f\n", cbrt(x)); // 选择默认的 cbrt
        printf("cbrtf(3.375) = %f\n", cbrt(y)); // 将 const float 转换成 float,
                                                // 然后选择 cbrtf
        return 0;
    }

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值