【题解】XiyouMobile2024纳新一面题解

XiyouMobile2024纳新一面题解

1.Hello,3G!(5分)

说说下述代码的输出结果,以及为什么会有这样的输出? strlen和sizeof的区别是什么?

#include <stdio.h>
#include <string.h>
int main() {
    char str1[] = "Hello, 3G!";
    char str2[20] = "Hello";
    char str3[20] = {'H', 'e', 'l', 'l', 'o'};
    printf("strlen(str1) = %zu\n", strlen(str1));
    printf("sizeof(str1) = %zu\n", sizeof(str1));
    printf("strlen(str2) = %zu\n", strlen(str2));
    printf("sizeof(str2) = %zu\n", sizeof(str2));
    printf("strlen(str3) = %zu\n", strlen(str3));
    printf("sizeof(str3) = %zu\n", sizeof(str3));
    return 0;
}

输出:

strlen(str1) = 10
sizeof(str1) = 11
strlen(str2) = 5
sizeof(str2) = 20
strlen(str3) = 5
sizeof(str3) = 20

分析:

  1. char str1[] = "Hello, 3G!";
    • 初始化了一个包含Hello, 3G!的字符数组,这个字符串有10个字符,C语言中,字符串以空字符‘\0’结尾,所以这个数组的大小为11
    • strlen(str1)计算字符串长度,不包括结尾的空字符,所以输出结果为10
    • sizeof(str1)计算这个数组所占字节数,输出结果为11
  2. char str2[20] = "Hello";
    • 定义了一个大小为20的字符数组,并初始化为"Hello",这个字符串有5个字符,再加上结尾的空字符‘\0’,一共有6个字符
    • strlen(str2)计算字符串长度,不包括结尾的空字符,所以输出结果为5
    • sizeof(str1)计算这个数组所占字节数,输出结果为20
  3. char str3[20] = {'H', 'e', 'l', 'l', 'o'};
    • 定义了一个大小为20的字符数组,并初始化了5个字符,未完全初始化,该数组其它元素默认初始化为0
    • strlen(str2)计算字符串长度,不包括结尾的空字符,所以输出结果为5
    • sizeof(str1)计算这个数组所占字节数,输出结果为20

strlen和sizeof的区别

  • sizeof是一个**计算数据类型所占空间大小(字节数)**的单目运算符,在计算字符串的空间大小时,包含结尾的空字符‘\0’
  • strlen是一个计算字符串长度函数,使用时需要引用头文件#include <string.h>,在计算字符串长度时,不包含结尾的空字符‘\0’

2.怎么停不下来?!(5分)

讲讲程序会输出什么吧!运用相关知识解释原因。

#include <stdio.h>
int main() {
    unsigned char i = 5;
    while (i >= 0) {
        printf("%d ", i);
        i--;
    }
    return 0;
}

输出:

无限循环打印 i 的值,i 的值从5递减到0,然后到255,继续递减,无限循环

分析:

unsigned char i = 5;定义了一个无符号字符型变量i,初始化为5。由于无符号字符型变量取值范围是0~255,当i递减到0后,继续递减,此时i的值变为255,然后继续递减,所以while (i >= 0)这个条件会一直为真,该循环为无限循环

相关知识:

  • 任何存储与计算机的数据,其本质都是以二进制码存储
  • unsigned char类型的变量占一个字节(即8位),因此它能表示的数值范围是0(00000000)~255(11111111)
  • 在计算机系统中,数值一律用补码来表示和存储。
  • 正数原码=补码,负数补码={原码符号位不变} + {数值位按位取反后+1}
  • 由于计算机只有加法运算器,当i递减到0后,继续递减即0(00000000)+(-1)(11111111)= 255(11111111)

3.宏定义与宏函数(10分)

这段函数会输出什么?为什么会有这样的输出?

#include <stdio.h>
#define A "Welcome to join 3G!\n"
#define B "Hello!"
#define C(x) ((x)+4)
#define N 4
#define Y(n) ((N+2)*n)
int main() {
    int z = 2 * (N + Y(5 + 1));
    printf("%d\n", z);
    printf("%s %d%d", B, printf(A), C(printf(A)));
}

输出:

70
Welcome to join 3G!
Welcome to join 3G!
Hello! 2024

分析:

  1. #define A "Welcome to join 3G!\n":定义了一个字符串常量 A,代表 "Welcome to join 3G!\n"
  2. #define B "Hello!":定义了一个字符串常量 B,代表 "Hello!"
  3. #define C(x) ((x)+4):定义了一个带参数的宏 C,它接受一个参数 x,并返回 (x)+4 的结果。
  4. #define N 4:定义了一个常量 N,值为 4
  5. #define Y(n) ((N+2)*n):定义了一个带参数的宏 Y,它接受一个参数 n,并返回 ((N + 2) * n) 的结果。
  6. int z = 2 * (N + Y(5 + 1));
    • 首先计算 Y(5 + 1),即 ((N + 2) * 5 + 1),其中 N4,所以 ((4 + 2) * 5 + 1) = 31
    • 然后计算 N + Y(5 + 1),即 4 + 31 = 35
    • 最后计算 2 * (N + Y(5 + 1)),即 2 * 35 = 80,并将结果赋值给变量 z
  7. printf("%d\n", z);输出变量 z 的值,即 70
  8. printf("%s %d%d", B, printf(A), C(printf(A)));
    • printf(A) 会输出字符串 "Welcome to join 3G!\n",同时返回输出的字符数,即20
    • printf("%s %d%d", B, printf(A), C(printf(A))) 首先输出字符串 "Hello!",然后输出 printf(A) 的返回值 20,接着输出 C(printf(A)) 的值,即 24

宏定义与宏函数:

  • 预处理器不做计算,不对表达式求值,它只进行替换(在编译前进行)

4.真假小a(10分)

说说下述代码的运行结果,并尝试分析解释这段代码

#include <stdio.h>
int a = 10;
void func() {
    int a = 20, c = 40;
    static int b = 30;
    b++;
    c++;
    printf("a = %d, b = %d, c = %d\n", a, b, c);
}
int main() {
    func();
    func();
    printf("a = %d\n", a);
    return 0;
}

运行结果:

a = 20, b = 31, c = 41
a = 20, b = 32, c = 41
a = 10

分析:

  1. int a = 10;定义了一个全局变量 a,其作用域是整个程序。
  2. void func()
    • int a = 20, c = 40;func 函数内部,定义了局部变量 ac,它们的作用域仅限于 func 函数内部。
    • static int b = 30;定义了静态局部变量 b,它的作用域也在 func 函数内部,但它在程序的整个生命周期内都存在,并且只在第一次进入函数时初始化。
  3. main 函数中第一次调用 func
    • func 函数内部,局部变量 a 的值为 20,静态局部变量 b 的初始值为 30,然后 b 自增为 31,局部变量 c 的值为 40,然后 c 自增为 41
    • 输出 "a = 20, b = 31, c = 41"
  4. main 函数中第二次调用 func
    • 局部变量 a 的值仍然为 20,静态局部变量 b 的值为上一次调用结束后的 31,然后 b 自增为 32,局部变量 c 的值重新初始化为 40,然后 c 自增为 41
    • 输出 "a = 20, b = 32, c = 41"
  5. printf("a = %d\n", a);输出全局变量"a = 10"

相关知识:

  • 全局变量和局部变量的变量名相同时,遵循局部优先原则
  • static修饰局部变量(静态局部变量)
    • 在函数中声明变量时, static 关键字指定变量只初始化一次并在之后调用该函数时保留其状态
    • 改变局部变量的存储位置(局部变量存储在栈区,静态局部变量存储在静态区),不改变作用域,只改变生命周期(局部变量进作用域创建,出作用域销毁;而静态局部变量直到程序结束才销毁)

5.这啥啊,一堆符号(10分)

以下程序的运行结果是什么,你知道运算符的优先级吗?

#include <stdio.h>
int count =-1;
int calculate(int num) {
    while (1) {
        switch (num) {
            case 0:
                num = (num ^ 10) + 10;
            case 31:
                num = (num | 0);
            break;
            case 9:
                num += 6;
            break;
            case 20:
                num = num >> 1;
            num-= 7;
            break;
            case 3:
                count += num;
            num = (num ^ 7) + 5;
            break;
            case 15:
                num += count++;
            count = count << 3;
            break;
            case 10:
                return (1 << ++num)- count;
            default:
                num = (num & 1) ? num + 1 : num- 4;
            break;
        }
    }
}
int main() {
    int start = 0;
    int y = calculate(start);
    printf("answer == %d\n", y);
    printf("%d\n", count);
    return 0;
}

运行结果:

answer == 2024
24

分析:

  1. int count =-1;初始化全局变量count=-1
  2. int start = 0;初始化start=0
  3. int y = calculate(start);
    • 调用函数calculate,并将返回值赋给y
    • 首先,执行case 0:num = (num ^ 10) + 10;得到num=20
    • 由于没有break;继续执行下一条case 3:将 num 与 0 进行按位或运算,得到num=20
    • case 20:先将 num 右移一位,然后再减去 7,num=3
    • case 3:将全局变量 count 加上 num,然后将 num 先进行异或运算 (num ^ 7),再加上 5,count=2,num=9
    • case 9:num加6,num=15
    • case 15:将 num 加上 count,然后将 count 进行左移三位操作,count=24,num=17
    • default:如果 num1 进行按位与运算结果为真(即 num 为奇数),则将 num1;否则将 num4。连续执行三次,num=10
    • case 10: 返回 (1 << ++num)- count,即先将 num 自增 1,然后进行左移一位运算,再减去 count。返回值为2024
  4. y=2024,count=24

相关知识:

  • 按位与:&

    • 两个都为1,结果为1,其余情况为0
  • 按位或:|

    • 两个都为0,结果为0,其余情况为1
  • 按位异或:^

    • 一个为1,一个为0,结果为1,其余情况为0
  • 左移:<<

    • 左移n位相当于乘以2的n次方
  • 右移:>>

    • 右移n位相当于除以2的n次方

6.指针数组,数组指针(10分)

请结合以下代码讲述指针数组和数组指针的含义与区别

#include <stdio.h>
int main() {
    //简述这段代码的输出结果,并解释原因
    int values[] = {10, 20, 30, 40, 50};
    int *ptrArr[5] = {0};
    int (*arrPtr)[5] = &values;
    for (int i = 0; i < 5; i++) {
        ptrArr[i] = &values[i];
    }
    for (int i = 0; i < 5; i++) {
        printf("%d ", *ptrArr[i]);
    }
    printf("\n");
    for (int i = 0; i < 5; i++) {
        printf("%d ", (*arrPtr)[i]);
    }
    return 0;
}

输出结果:

10 20 30 40 50
10 20 30 40 50

分析:

  1. int values[] = {10, 20, 30, 40, 50};
    • 定义了一个整数数组 values
  2. int *ptrArr[5] = {0};
    • 定义了一个指针数组 ptrArr,并初始化为0
  3. int (*arrPtr)[5] = &values;
    • 定义了一个指向数组的指针 arrPtr
  4. 第一个循环:
    • 将指针数组 ptrArr每个元素指向 values 数组的相应元素
  5. 第二个循环:
    • 遍历指针数组 ptrArr,并输出每个指针所指向的整数。由于在第一个循环中,将 ptrArr 的每个元素分别指向了 values 数组的相应元素,所以这个循环会输出 values 数组的元素,即 10 20 30 40 50
  6. 第三个循环:
    • 这里使用指向数组的指针 arrPtr 来访问 values 数组的元素。arrPtr 指向了整个 values 数组,(*arrPtr) 解引用后得到的是 values 数组本身,所以 (*arrPtr)[i] 可以用来访问 values 数组的各个元素。同样,这个循环也会输出 values 数组的元素,即 10 20 30 40 50

指针数组和数组指针的含义与区别

  • 含义:

    • 指针数组:本质是一个数组,该数组中的每个元素都是一个指针
    • 数组指针:本质是一个指针,指向了一个数组
  • 区别:

    • 指针数组是一个包含若干个指针的数组,p是数组名,当执行p+1时,则p会指向数组中的下一个元素。

    • 数组指针也称行指针,也就是说,当指针p执行p+1时,指针会指向数组的下一行

7.怎么还是指针!(10分)

简述这段代码的输出结果,并解释原因

#include <stdio.h>
int main(){
    int arr[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} };
    int* ptr1 = (int*)(&arr + 1);
    int* ptr2 = (int*)(*(arr + 1));
    printf("*(ptr1- 1) = %d\n", *(ptr1- 1));
    printf("*(ptr2 + 7) = %d\n", *(ptr2 + 7));
    printf("*(arr[0] + sizeof(int) * 11) = %d\n", *(arr[0] + 11));
    printf("*(arr[2] + 3) = %d\n", *(arr[2] + 3));
    printf(" *(*(arr+2) + 3) = %d\n", *(*(arr + 2) + 3));
    printf("*(*(&arr[1] + 1) + 3) = %d\n", *(*(&arr[1] + 1) + 3));
    return 0;
}

输出结果:

*(ptr1- 1) = 12
*(ptr2 + 7) = 12
*(arr[0] + sizeof(int) * 11) = 12
*(arr[2] + 3) = 12
*(*(arr+2) + 3) = 12
*(*(&arr[1] + 1) + 3) = 12

分析:

  1. int arr[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} };
    • 定义了一个 3×4 的二维整数数组 arr,并初始化了其元素。
  2. int* ptr1 = (int*)(&arr + 1);
    • &arr 是一个指向整个二维数组的指针。当对其进行 &arr + 1 操作时,指针会移动到整个二维数组之后的位置。然后将其强制转换为 int* 类型的指针 ptr1
  3. int* ptr2 = (int*)(*(arr + 1));
    • arr 是一个指向一维数组(包含 4 个整数)的指针数组。arr + 1 指向第二行的一维数组,*(arr + 1) 解引用后得到第二行的一维数组的首地址,然后将其强制转换为 int* 类型的指针 ptr2
  4. printf("*(ptr1 - 1) = %d\n", *(ptr1 - 1));
    • ptr1 指向二维数组之后的位置,ptr1 - 1 则指向二维数组的最后一个元素,即 12。所以输出 12
  5. printf("*(ptr2 + 7) = %d\n", *(ptr2 + 7));
    • ptr2 指向第二行的一维数组的首地址,ptr2 + 7 指向第二行一维数组的第 8 个元素(从 0 开始计数),也就是第三行的最后一个元素 12。所以输出 12
  6. printf("*(arr[0] + sizeof(int) * 11) = %d\n", *(arr[0] + 11));
    • arr[0] 是第一行一维数组的首地址,arr[0] + sizeof(int) * 11 指向第一行一维数组的第 12 个元素(因为 sizeof(int)4 字节,乘以 11 就是向后移动 44 字节,即第 12 个元素),也就是第三行的最后一个元素 12。所以输出 12
  7. printf("*(arr[2] + 3) = %d\n", *(arr[2] + 3));
    • arr[2] 是第三行一维数组的首地址,arr[2] + 3 指向第三行一维数组的第 4 个元素,即 12。所以输出 12
  8. printf(" *(*(arr+2) + 3) = %d\n", *(*(arr + 2) + 3));
    • arr + 2 指向第三行的一维数组,*(arr + 2) 解引用后得到第三行一维数组的首地址,*(arr + 2) + 3 指向第三行一维数组的第 4 个元素,即 12。所以输出 12
  9. printf("*(*(&arr[1] + 1) + 3) = %d\n", *(*(&arr[1] + 1) + 3));
    • &arr[1] 是第二行一维数组的地址,&arr[1] + 1 指向第三行一维数组的地址,*(&arr[1] + 1) 解引用后得到第三行一维数组的首地址,*(&arr[1] + 1) + 3 指向第三行一维数组的第 4 个元素,即 12。所以输出 12

8.结构体与联合体(10分)

题目:给出以下代码块,描述输出结果以及原因

#include <stdio.h>
#define INT_PTR int*
#define CHAR_PTR char*
typedef int* int_ptr;
typedef char* char_ptr;
struct MyData {
    int i;
    char c;
    INT_PTR iptr1,iptr2;
    int_ptr iptr3,iptr4;
    double d;
};
union MyUnion {
    int i;
    char c;
    CHAR_PTR cptr1,cptr2;
    char_ptr cptr3,cptr4;
    float d;
};
int main() {
    printf("Size of MyData: %zu\n", sizeof(struct MyData));
    printf("Size of MyUnion: %zu\n", sizeof(union MyUnion));
    return 0;
}

输出结果(X64):

Size of MyData: 48
Size of MyUnion: 8

分析:

  1. 先定义了两个宏 INT_PTRCHAR_PTR,分别代表 int*char*。同时使用 typedef 定义了 int_ptrchar_ptr 类型别名,分别对应 int*char*
  2. struct MyData
    • INT_PTR iptr1,iptr2;定义了一个整数指针iptr1和一个整数iptr2
    • int_ptr iptr3,iptr4;定义了两个整数指针iptr3iptr4
    • 这个结构体包含了两个整数iiptr2(占2*4=8个字节),一个字符c(占1个字节),三个整数指针iptr1iptr3iptr4(占3*8=24个字节),一个双精度浮点数d(占8个字节)(一共41个字节)
    • 由于结构体内存对齐,这个结构体实际大小为48(稍后解释)
  3. union MyUnion
    • CHAR_PTR cptr1,cptr2;定义了一个字符指针cptr1和一个字符cptr2
    • char_ptr cptr3,cptr4;定义了两个字符指针cptr3cptr4
    • 这个联合体包含了两个字符ccptr2,一个整数i,三个字符指针cptr1cptr3cptr4,一个单精度浮点数d(其中字符指针所占字节数最大为8)
    • 所以这个联合体大小为8
  4. sizeof分别求这个结构体和联合体大小(所占字节数)

相关知识

1.definetypedef

  • define是预处理指令(宏定义),只进行简单的替换;
  • typedef是一个关键字,对已存在的数据类型取别名
  • INT_PTR iptr1,iptr2;等价于int *iptr1,iptr2;所以iptr1是整数指针,而iptr2是整数
  • int_ptr iptr3,iptr4;则是定义了两个int_ptr类型的变量,即int *类型

2.结构体struct和联合体union

  • 结构体各成员拥有自己的内存,各自使用互不干涉,同时存在,遵循内存对齐原则。一个结构体变量的总长度等于所有成员长度之和。
  • 联合体各成员共用一块内存空间,并且同时只有一个成员可以得到这块内存的使用权,各变量共用一个内存首地址。一个联合体变量的总长度至少能容纳最大的成员变量,且要满足是所有成员变量类型大小的整数倍

3.结构体内存对齐

  • 规则

    • 第一个成员在与结构体变量偏移量为0的地址处。(即结构体的首地址处,即对齐到处)

    • 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。

    • 结构体的总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。

    • 如果嵌套了结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

    • 对齐数 = 该结构体成员变量自身的大小与编译器默认的一个对齐数的较小值。(注:VS中的默认对齐数为8,不是所有编译器都有默认对齐数,当编译器没有默认对齐数的时候,成员变量的大小就是该成员的对齐数。)

  • 对于该题的结构体struct MyData,其对齐方式如下图所示

  • 从图中可以直观地看到这个结构体一共占48个字节

在这里插入图片描述

9.好一个递归,一递起来就发狠了!忘情了!…(10分)

#include <stdio.h>
int function(int n){
    if (n < 5) {
        return n;
    }else {
        return function(n-1) + function(n-3);
    }
}
int main(){
    int n=10;
    printf("%d\n", function(n));
    return 0;
}

输出结果:

41

分析:

  1. function(10)
    • 因为 10 >= 5,所以返回 function(9) + function(7)
  2. function(9)
    • 因为 9 >= 5,所以返回 function(8) + function(6)
  3. function(8)
    • 因为 8 >= 5,所以返回 function(7) + function(5)
  4. function(7)
    • 因为 7 >= 5,所以返回 function(6) + function(4)
  5. function(6)
    • 因为 6 >= 5,所以返回 function(5) + function(3)
  6. function(5)
    • 因为 6 >= 5,所以返回 function(4) + function(2)
  7. function(4)
    • 因为 4 < 5,所以直接返回4
  8. function(3)
    • 因为 3 < 5,所以直接返回3
  9. function(2)
    • 因为 2 < 5,所以直接返回2
  10. 计算
    - function(5) = function(4) + function(2) = 4 + 2 = 6
    - function(6) = function(5) + function(3) = 6 + 3 = 9
    - function(7) = function(6) + function(4) = 9 + 4 = 13
    - function(8) = function(7) + function(5) = 13 + 6 = 19
    - function(9) = function(8) + function(6) = 19 + 9 = 28
    - function(10) = function(9) + function(7) = 28 + 13 = 41

递归

1. 什么是递归

  • 递归是指程序调用自身的编程思想,即一个函数调用本身

2. 递归三要素

  • 第一要素:递归的定义
    • 接什么参数,返回什么值,代表什么含义
  • 第二要素:递归的拆解
    • 确定单层递归的逻辑(把大问题拆解成小问题)
  • 第三要素:递归的出口
    • 确定终止条件(到什么时候应该结束)

3. 递归的优缺点

  • 优点:
    • 结构清晰、可读性强
  • 缺点:
    • 运行效率较低、耗费计算时间和占用存储空间多
    • 可能导致栈溢出

10.对小球进行持续殴打,直到他承认自己是次品。(10分)

8 个小球,有一个次品,不知次品小球的轻重。请你用一台无砝码天平称,找出这个次品小球,最少需要几次能 秤出来?怎样秤能保证秤的次数最少?

  • 最少需要两次(运气爆棚)

    • 1.随便选俩球称量,记为A、B,刚好不平衡
    • 2.再用A(B)和剩余6个球中任意一个称量
      • 平衡,则次品是B(A)
      • 不平衡,则次品是A(B)
  • 正常情况保证称的次数最少(3次)

    • 1.将8个球分成四组,每组俩个(记为12,34,56,78),先用12和34称量
      • 不平衡(次品在1234中)
        • 2.用1和2称量
          • 不平衡(次品在12中)
            • 3.用1(2)和其他6个球任意一个称量
              • 平衡(次品是2(1))
              • 不平衡(次品是1(2))
          • 平衡(次品在34中)
            • 3.用3(4)和其他6个球任意一个称量
              • 平衡(次品是4(3))
              • 不平衡(次品是3(4))
      • 2.2平衡(次品在5678中)
        • 2.用5和6称量
          • 不平衡(次品在56中)
            • 3.用5(6)和其他6个球任意一个称量
              • 平衡(次品是6(5))
              • 不平衡(次品是5(6))
          • 平衡(次品在78中)
            • 3.用7(8)和其他6个球任意一个称量
              • 平衡(次品是8(7))
              • 不平衡(次品是7(8))

11.排序算法(10分)

简单说说你所知道的排序算法。选择一种你较为了解的排序方法,现场说说原理并使用代码实现。

冒泡排序

  • 原理
    • 从序列的第一个元素开始,比较相邻的两个元素,如果它们的顺序错误(如:从小到大排序时,前一个元素大于后一个元素),则交换它们的位置。继续比较下一对相邻元素,执行相同的操作,直到序列的末尾。
  • 分析
    • 核心是多趟排序
    • 以升序排序为例,假设有n个数。
      • 第一趟排序目的是找到整个数组中最大的数并把它排在最后端;
      • 第二趟排序目的是在剩下的n-1个数找出最大的(即整个数组中第二大的数)并把它放在倒数第二位
      • …….
      • 这样一轮一轮的比较,直到只剩下一个数时(完成了n-1趟的排序)这个排序就完成了,从而实现从小到大的排序。
  • 实现
 void bubble_sort(int arr[], int n) {
     for(int i=0;i<n-1;i++) {
         for(int j=0;j<n-i-1;j++) {
             if(arr[j]>arr[j+1]){
                 int temp=arr[j];
                 arr[j]=arr[j+1];
                 arr[j+1]=temp;
             }
         }
     }
 }
  • 优化
void bubble_sort(int arr[], int n) {
    for(int i=0;i<n-1;i++) {//
        int flag=1;//用于标记这一趟排序是否发生了交换
        for(int j=0;j<n-i-1;j++) {//
            if(arr[j]>arr[j+1]){
                flag=0;//如果发生了交换,将flag置为0
                int temp=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=temp;
            }
        }
        if(flag) {//如果这一趟排序没有发生交换,说明数组已经有序,可以提前结束排序
            break;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值