week_03手写笔记

今日内容

1.什么是面向对象
本质就是面向过程

面向过程: 以步骤为单位,亲力亲为的一步步完成某一个具体的事情
非静态方法的调用格式:		对象名.方法();
1.1 面向对象的思想特点
1.更符合我们生活中的思想行为习惯
2.让复杂的事情简单化
3.让我们从执行者变成指挥者
1.2 面向对象的三大特征
1.封装
2.继承
3.多态
面向对象设计原则:不断地创建对象,只会对象做事情
1.3 面向过程和面向对象的关系
面向过程: 以步骤为单位,亲力亲为的一步步完成某一个具体的事情
面向对象:替我们执行面向过程的一个中间关系
2.类和对象的关系
类和对象的关系式相辅相成的
对象:描述具体的事物
类:描述一组事物的属性和行为的集合(官方概念)
   描述现实世界事物的属性和行为的统称!(现实概念)
  事物:学生事物
  属性:姓名,年龄,性别,身高,爱好等等------对应  类中的成员变量,全部小写,类中方法外
  行为:吃喝睡玩等等-----对应类中的成员方法,写成员方法的时候去掉static
  
  类描述的是事物和行为的集合,但是没有给出具体的事物
  具体的学生事物----使用代码具体体现出来----就是创建对象
  				类名 对象名 = new 类名() ; 固定格式
  				对象名.成员变量(属性) = 赋值 ;
  				对象名.成员方法(行为) ;
 //学生类 
  class Student{
	String name ; 				//定义成员变量
	int age ;
	String sex ;
	public void study(String stu){        //创建成员方法
		System.out.println(name+"正在"+stu);
	}
	public void play(String pl){
		System.out.println(name+"正在"+pl);
	}
}
class StudentDemo{								//测试类,类名必须与文件名保持一致.且用大驼峰命名法
	public static void main(String[] args){			
		Student student = new Student() ;	//创建对象    类名 方法名 = new 类名();  方法名用小驼峰命名法
		student.name = "段志虎" ;				//给成员变量赋值
		student.age = 25 ;
		student.sex = "男" ;
		System.out.println("学生姓名:"+student.name) ;	//输出
		System.out.println("年龄:"+student.age);
		System.out.println("性别:"+student.sex) ;
		student.study("硬件测试") ;					//调用成员方法  
		student.play("王者荣耀") ;
	}
}
3.工具idea的使用
4.手机类并且测试
//定义一个手机类
class Phone{
	//成员变量---类中方法外定义的变量
	String brand ; //品牌
	
	int price ; //价格 
	
	String color ; //颜色
	
	String memory ; //机身内存
	
	
	//成员方法:去掉static
	///callPhone(String name),name:某个人的名称
	
	public void callPhone(String name){
		System.out.println("使用手机正在给"+name+"打电话") ;
	} 
	
	//sendMsg(String name), 给name 打发短信
	public void sendMsg(String name){
		System.out.println("使用手机给"+name+"发短信") ;
	}
	
	//	playGame():玩游戏
	public void playGame(String gameName){
		System.out.println("使用手机玩"+gameName);
	}
	
	
}


//手机类的测试类
class PhoneTest{
	public static void main(String[] args){
		
		//手机类定义完毕,需要创建具体的事物来描述具体的手机
		//创建一个手机类对象
		Phone phone  = new Phone() ;//Phone@6d06d69c 地址值
		System.out.println(phone) ;
		System.out.println(phone.brand+"---"
		+phone.price+"---"+phone.color+"---"+phone.memory) ;
		
		//赋值
		phone.brand = "华为mate30pro" ;
		phone.price = 6799 ;
		phone.color = "翡翠绿" ;
		phone.memory = "128G" ;
		System.out.println(phone.brand+"---"
		+phone.price+"---"+phone.color+"---"+phone.memory) ;
		
		//打电话
		phone.callPhone("高圆圆") ;
		//发短信:
		//public void sendMsg(String name)
		phone.sendMsg("张佳宁") ;
		//public void playGame(String gameName)
		phone.playGame("csgo") ;
	}
}
5.什么是封装
5.1 封装的概念
定义:就是将一个事物中的属性私有化,对外私有
作用:保证了数据的安全性,对外提供的公共的访问方法来访问,不能直接方法
代码中体现:就是将类中的所有成员变量加入关键字private;
private的特点:成员变量和成员方法,只能在当前类中访问,外界类不能直接使用,但是可以间接的共用方法访问;
 公共方法:setxxx()/getXXX方法-----称为"setter和getter"
5.2 封装的代码体现
//定义一个类
class Demo{

    //公共的成员变量
    public int num ;
    private int num2 = 200;//private修饰的私有成员变量

    //私有的成员方法,也只能在本来访问
    private void method(){
        System.out.println("method Demo...");
    }

    //公共成员方法
    public void function(){
        method(); //公共访问间接访问私有本来私有方法
        System.out.println("=====================");
        System.out.println("function Demo");
    }
    //公共成员方法
    public void show(){
        System.out.println(num);
        System.out.println(num2);//num2私有的
    }
}
6.成员变量和局部变量的区别(面试题)
1)书写位置不同
	局部变量:在方法声明上或者方法定义中
	成员变量:类中方法外
2)内存的位置 
	局部变量:在栈内存中
	成员变量:在堆内存中
3)生命周期不同
	局部变量:随着方法调用而存在,随着方法调用结束而消失
	成员变量:随着对象的创建而存在,随着对象的创建完毕等待垃圾回收器空闲的时候回收而消失掉
4)初始化值不同
	局部变量:在使用之前必须初始化
	成员变量:存在系统默认初始化,可以赋值,但是一般不会直接赋值,都是通过		对象名.成员变量名=赋值
7.方法形式参数问题(如果是基本数据类型/引用数据类型作为形式参数的区别)
idea中的神键:alt+enter; 
形式参数如果是基本类型数据,形参的改变不会影响实际参数
形式参数如果是引用数据类型,形参的改变会直接改变实际参数(引用数据类型除过String)
	String作为引用类型,是一种特殊的引用数据类型,效果和基本数据类型一致,形参的改变不会影响实际参数(因为String是常量	String str = "abc")
	形式参数是类(引用数据类型);调用方法的时候,实际参数需要传递的是当前类的具体对象,所以需要new一个实际的对象(空间地址值)
	public  class Student {
    public void study(){
        System.out.println("好好学习,天天向上") ;
    }
}
class StudentDemo{
    public void methon(Student student){
        student.study() ;
    }
}
class StudentTest{
    public static void main(String[] args) {
        StudentDemo student = new StudentDemo();
        Student s = new Student() ;
        student.methon(s);
    }
}

8.什么是匿名对象(没有名字对象)
定义:没有名字的对象		格式: new 类名();
有名字的对象   类名 对象名 = new 类名();
匿名:优点:1)在实际开发中,匿名对象不要多次,使用一次即刻 ,使用完即刻就会被垃圾清理站清理,因为没有栈内存指向堆内存
2)匿名对象可以作为参数传递
3)匿名对象,从内存角度考虑,可以节省内存

9.属性加入私有化,如何操作
封装:将一个事物的所有属性私有化private,保证其安全性对外提供setXXX赋值方法和getXXX获取方法注意:局部变量的取名需要见名知意
10.this关键字特点
当局部变量隐藏了成员变量的时候,提供了一个关键字 thisthis:代表的是当前类对象的地址值引用		this.变量名------>变量名----->成员变量名(地址值)		主要在公共方法setXXX中使用		事物属性私有化之后,提供对外开放的公共方法的快捷键:			alt+ins键(有的笔记本需要按fn键)---->选择getter and setter ----->选择ctrl+A全选即可作用:为了区分局部变量和成员变量名称一致的时候,局部变量隐藏成员变量,加入this
11.什么是构造方法
构造方法是一个与类同名,没有返回值类型的方法,对象的创建就是通过构造方法完成的	构造方法分为无参构造方法和有参构造方法;构造方法可以重载构造方法的作用:给成员变量赋值构造方法的赋值:在new的时候直接赋值构造方法的使用:无参构造方法+setXXX()和getXXX()去使用 			2)有参构造方法+getXXX()
11.1给成员变量赋值有几种方式?
1)无参构造方法+setXXX() 赋值和getXXX()获取值	快捷键:alt+ins--->construstor----->selet none2)有参构造方法() (直接赋值)+ getXXX()(获取值)	快捷键:alt+ins------>construstor---->全选所有属性
11.2 setxxx():公共的访问方法
11.3 构造方法赋值(代码体现)
public class Student {

    private String name ;
    private String gender ;
    private int age ;
    private String height;

    public Student(String name, String gender, int age, String height) { //有参构造
        this.name = name;
        this.gender = gender;
        this.age = age;
        this.height = height;
    }

    public Student() {		//无参构造
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getHeight() {
        return height;
    }

    public void setHeight(String height) {
        this.height = height;
    }
    public void study(String name){
        System.out.println("学生正在学习"+name);
    }
    public void sellp(){
        System.out.println(name+"正在睡觉");
    }
}
ublic class StudentTest {
    public static void main(String[] args) {
        Student student = new Student() ;		//无参构造赋值
        student.setName("高圆圆");
        student.setAge(23);
        student.setGender("女");
        student.setHeight("180cm");
        System.out.println("学生姓名\t年龄\t性别\t身高");
        System.out.println(student.getName()+"\t\t"+student.getAge()+"\t\t"+student.getGender()+"\t\t"
        +student.getHeight());
        student.study("英语");
        student.sellp();

        System.out.println("------------------------------"); //方式二,有参构造赋值
        Student student1 = new Student("高圆圆","女",23,"180cm") ;
        System.out.println("学生姓名\t年龄\t性别\t身高");
        System.out.println(student1.getName()+"\t\t"+student1.getAge()+"\t\t"+student1.getGender()+"\t\t"
                +student1.getHeight());
        student1.study("英语");
        student1.sellp();
    }
}
11.4 构造方法的注意事项
1.构造方法名和类名相同
2.构造方法没有返回值类型,连void都没有
3.当我们写的非测试类中当没有提供任何构造方法,系统会默认提供无参构造方法,所以我们以后写方法都要提供无参构造方法.
4.如果我们给了其中的有参构造方法,系统则不会默认提供无参构造方法,我们在使用无参构造方法new对象时,就会报错
12.类中成员加入构造方法后,如何写一个标准类
13.static关键字
static是一个静态修饰符,可以被多个对象"共享,共用"
静态变量跟类直接相关,是优先于对象进内存
static关键字的特点:
1)被static修饰的变量或者方法--被称为类变量/类方法,因为他们是随着类的加载二加载,优先于对象先存在的
2)static不能和this共存!
		this:代表的是当前类的对象的地址值引用--创建对象
3)static基本的特点:共享共用
			如果需求告诉我们要体现共享共用,可以static修饰
4)被静态修饰的变量/方法,通过
				类名.变量/方法名	访问
		
13.1 关于static写一个自定义一个数组工具类
13.2 静态方法的注意事项
非静态的成员方法,可以访问静态的,也可以访问非静态的
	静态的成员方法只能调用静态的变量和方法
14.代码块: 静态代码块—构造代码块–构造方法的优先级(了解)
代码块;在java中就是大括号包裹起来的内容,在类的成员位置
分类:局部代码块:在方法定义中的{},用来限定变量的生命周期
构造代码块:在类中的成员位置(类中方法外),作用就是可以对数据进行初始化
	特点:如果一个类中有构造代码块,先执行构造代码块,然后执行构造方法,构造代码块的优先级高于构造方法
静态代码块:static
	特点:随着类的加载而加载,而且优先于对象存在,类加载一次,静态代码块就执行一次
静态代码块>构造代码块>构造方法
15.继承
15.1 什么是继承
定义:将多个类的共享内容抽取出来放在一个独立的类中,那么这个独立的类和多个类产生的关系就叫继承关系
关键字:extends
格式			class 父类名{}
			 class  子类名 extends 父类名{
			 }
	class Person{ //父类 ,将共性内容抽取到这个类
    private String name ;//姓名
    private int age ;
    public String getName() {
        return name;
    }
    public void setName(String name) {//"高圆圆"
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    //直接写成员方法
    public void eat(){
        System.out.println("饿了就需要吃饭");
    }
    public void sleep(){
        System.out.println("困了就需要休息...");
    }
}
//子类学生类
class Student extends  Person{}
//老师类
class Teacher extends  Person{}
//测试类
public class ExtendsDemo {
    public static void main(String[] args) {
        //创建学生类对象
        Student s = new Student();
        s.setName("高圆圆 ");//公共的访问被继承过来了,可以访问啊!
        s.setAge(42);
        System.out.println(s.getName()+"---"+s.getAge());
        s.eat();
        s.sleep();
        //创建老师类对象
        Teacher t = new Teacher() ;
        t.setName("苍老师") ;
        t.setAge(20) ;
        System.out.println(t.getName()+"---"+t.getAge());
        t.eat();
        t.sleep();
    }
}

15.2 继承的好处
1.提高了代码的复用性
2.提供了代码的维护性
3.类与类之间的关系,是"多态"的基础;
15.3 继承的特点
1)在java中,类与类的继承关系,只支持单继承,不支持多继承!
		格式:	class 父类名{}
			class 子类名 extend 父类名{}
	不能出现class 子类名 extend 父类名1,父类名2{}
2)虽然不能多继承,但是可以多层继承.
		爷爷---父亲(继承爷爷)--儿子(继承父亲)
15.3.1 继承中的注意事项
1)子类继承父类,只能继承父类的非私有成员变量和非私有成员方法,构造方法不能被继承
15.4 继承的使用
15.5 什么时候使用继承思想
1.什么时候讲一个变量定义为成员变量的时机?
	如果当前这个成员变量能够描述现实世界真实属性的属性的时候,否则就是局部变量,多使用局部变量,成员变量的范围大,跟对象有关,随对象的访问而存在,访问结束而消失,可以节省内存空间.
2.什么时候使用继承思想呢?
	不要为了使用部分功能而使用继承思想!因为继承具有局限性
	如果类A是类B的一种或者类B是类A的一种,那么我们使用"继承思想"
15.6 继承中的成员的关系问题
15.6.1 类的成员以及继承中的构造方法的访问问题(重点)
1)成员变量		
	1)子类继承父类,如果子类的成员变量和父类的成员名称不一致的情况
		办法:分别访问方法
		
	2)子类继承父类,子类的成员变量和父类的成员名称一致的情况		
		办法: 就近原则(现在子类的局部变量中找,有就使用)			System.out.println(num)			
				如果在子类局部位置中没有,就在子类的成员位置中找		   this.num
				如果在子类的成员位置没有,就在父类的成员位置中找			super.name
				如果还没有,就报错
		
	this.成员变量就是直接访问当前类的成员变量
	super.变量名就是直接访问父类的成员变量
	super代表父类的空间标识,也就是父类的对象的地址值引用
2)构造方法
	1)子类继承父类,不能继承父类的构造方法,但是可以通过super访问父类的构造方法
		*存在继承关系,需要让父类的数据先初始化,因为我的子类 可能用到父类的数据
	2)super如何访问
			子类继承父类,子类的所有构造方法都会默认先访问父类的无参构造方法--super().可以隐藏不写
	3)如果父类中只有有参构造方法,没有无参构造方法,子类如何访问父类的有参构造?
		解决办法:1)手动给父类无参构造方法添加
				2)不给出父类无参构造方法,只要让父类的数据进行初始化	super(XXX)
				3)先在子类的有参构造方法中通过this()访问本类的无参,然后再本类的无参构造方法中,super(str."xx")访问父类的有参
	开发中:继承关系的构造方法
			子类的无参访问父类的无参 super()
			子类的有参访问父类的有参super(XXX)
3)成员方法
	1)子类继承父类,子类的成员方法和父类的成员方法名称不一致的情况
		解决办法:1)分别访问
	2)如果子类和父类出现了一模一样的方法,如何访问?(权限修饰符 void 方法名以及参数列表)
		解决办法:先执行子类的这个方法,如果子类没有这个方法,再执行父类的方法
15.6.2 方法重写
定义:就是子类出现了和父类一模一样的方法!子类吧父类的关系覆盖了						
	权限修饰符 返回值类型 方法名以及参数列表都一样
15.7 引入自定义常量—final关键字
final:状态修饰符号---最终的,无法修改,加上这个关键字,那么此方法无法被覆盖
final的特点:1)最终的,无法更改
2)修饰类,该类无法被继承
3)修饰成员方法,该方法不能被重写
4)修饰成员变量,此时变量是一个常量---"自定义常量",只能被赋值一次,修饰成员变量必须给值,局部变量可以不给值,但是只能赋值
final的应用场景:结合public static final一块使用:自定义常量
public static final 基本数据类型 变量名 = 值----编译时期常量,jvm不用加载
基本数据类型
16 多态
16.1 多态的定义
就是一个事物在不同时刻体现的不同形态
宏观角度考虑:水有固态液态气态
微观角度考虑:就是内存角度考虑:内存中的变化
多态的前提条件:1)继承关系
2)必须存在方法重写,因为子类需要覆盖父类的功能
3)必须有父类引用指向子类对象----称为:"向上转型"
		格式:  Fu fu = new Zi() ;
		
16.2 多态的成员访问特点(重点)
1)成员变量是非静态,编译看左,运行看左;
			Fu fu = new Zi()
			fu.成员变量;
	
2)成员方法(非静态)
			编译看左,运行看右	子类的方法覆盖了父类,使用子类的成员方法
3)构造方法:分层初始化
16.3 多态的好处
1)提高代码的复用性
2)提高了代码的扩展性(由多态保证:父类引用指向子类对象)(重点)
	Fu fu = new Zi(),如果方法的形式参数是引用类型,父类类型可以传递子类对象!!!
16.4 多态的弊端
1)不能访问子类的特有功能
	解决办法:1)创建子类的对象  子类对象.特有功能方法//不推荐,耗费内存空间
			2)既然可以父类引用执行子类对象(使用的都是父类的东西)
			那可以将父类的引用强制转换为子类的引用,称为向下转型(前提:必须存在向上转换类型)
			格式: 子类型 变量名 = (子类型) 父类型引用
注意:向下转型使用不当会出现运行时期异常:classcastexception(类转换错误)
<think>我们正在分析代码:`LOCAL WEEK_PLAN week_record_plan;` 根据代码的命名和结构,我们可以推测: 1. `LOCAL` 可能是一个宏,用于修饰变量的存储类别(如静态局部变量)或平台相关的属性(如内存分配位置)。 2. `WEEK_PLAN` 很可能是一个自定义的结构体类型,用于表示一周的计划。 3. `week_record_plan` 是变量名,表明这是一个用于记录周计划的变量。 因此,这行代码声明了一个类型为`WEEK_PLAN`的变量`week_record_plan`,并用`LOCAL`修饰。 下面我们详细分析: ### 1. `LOCAL` 宏的含义 在嵌入式或跨平台代码中,`LOCAL`宏通常用于指定变量的存储位置或链接属性。常见情况: - 定义为`static`:将变量作用域限制在文件内(静态局部变量)[^1]。 - 定义为空:在预编译时移除,此时变量为全局变量但仅在本文件使用(通过头文件包含可能变为多个副本)。 - 平台相关属性:如在某些RTOS中表示任务局部存储。 例如,在头文件中可能有: ```c #ifdef __GNUC__ #define LOCAL static #else #define LOCAL #endif ``` ### 2. `WEEK_PLAN` 结构体 根据名称,它应该是一个描述周计划的结构体。其内部成员可能包括: - 日期范围(起始日期和结束日期) - 每天的计划条目数组(例如7天) - 其他元数据(如计划ID、状态等) 示例定义: ```c typedef struct { uint8_t plan_id; struct { uint8_t start_hour; uint8_t start_minute; uint8_t end_hour; uint8_t end_minute; char activity[32]; } daily_plan[7]; } WEEK_PLAN; ``` ### 3. 变量 `week_record_plan` 这是一个具体的周计划实例,用于记录或存储当前的一周计划。 ### 4. 可能存在的问题 - **内存占用**:如果结构体较大(尤其是包含数组成员),在资源受限的嵌入式系统中可能造成栈溢出(如果声明在函数内部)或占用过多静态存储区。 - **数据持久性**:如果`LOCAL`定义为`static`,则变量在程序运行期间会一直存在,但掉电后数据会丢失。若需要持久化存储,应考虑使用非易失性存储器(如Flash)。 - **线程安全**:在RTOS环境中,若多个任务访问此变量且`LOCAL`不是线程局部存储,则需加锁保护。 ### 5. 使用场景 - 在嵌入式设备中记录用户设置的一周计划(如定时任务)。 - 作为临时缓冲区,用于从外部存储加载周计划数据。 ### 示例代码片段 假设在某个任务函数中: ```c void task_week_planner(void) { LOCAL WEEK_PLAN week_record_plan; // 如果LOCAL定义为static,则每次调用都会使用同一个变量 // 从EEPROM加载周计划 eeprom_read_week_plan(&week_record_plan); // 使用周计划数据... if (week_record_plan.daily_plan[0].activity[0] != '\0') { // 执行周一计划 } } ``` ### 建议 - 查看`LOCAL`宏的定义,明确其作用。 - 确认`WEEK_PLAN`结构体的定义,了解其内存布局和大小。 - 根据应用场景,评估是否需要增加数据持久化机制。 如果这段代码出现在嵌入式系统中,请特别注意内存使用和持久化需求。 §§相关问题§§ 1. 在嵌入式系统中如何设计结构体以节省内存? 2. 如何实现配置数据的掉电保存? 3. 多任务环境下如何安全地访问全局配置数据?</think>### 代码 `LOCAL WEEK_PLAN week_record_plan;` 解析 #### 1. **代码含义** - `LOCAL`:通常表示作用域限定符(类似 `static`),可能是: - 自定义宏(如 `#define LOCAL static`) - 平台相关限定符(如嵌入式系统中的本地存储区) - `WEEK_PLAN`:自定义结构体类型,用于描述周计划(需结合上下文定义) - `week_record_plan`:结构体实例变量名,表示"周记录计划" #### 2. **典型用途** 结合引用[1]的日常计划管理场景: ```c /* WEEK_PLAN 结构体可能定义(示例)*/ typedef struct { uint8_t day_mask; // 日期掩码(如0b0011111表示周一到周五) TimeSlot slots[7]; // 每日时间段(引用[1]中的时间表) EnvConfig env; // 环境配置(如引用[1]的clean desk/lighting) } WEEK_PLAN; // 使用示例 LOCAL WEEK_PLAN week_record_plan = { .day_mask = 0x7F, // 全周生效 .slots = { {06,30, "Wake & stretch"}, {07,00, "Breakfast"}, {21,15, "Evening review"}, {22,30, "Lights out"} }, .env = {DESK_CLEAN, LIGHT_STRONG} }; ``` #### 3. **关键作用** 1. **计划持久化** 在嵌入式系统中存储周计划配置,支持掉电保存(如EEPROM存储) 2. **行为控制** 驱动设备按计划执行操作(如定时唤醒/休眠) 3. **资源管理** 封装时间、环境配置等参数(引用[1]的灯光/噪音控制) #### 4. **潜在问题** | 风险类型 | 原因 | 解决方案 | |----------|------|----------| | **内存溢出** | 结构体过大(如含长字符串) | 使用指针+动态内存 | | **数据竞争** | 多任务访问共享变量 | 加互斥锁保护 | | **配置丢失** | 未持久化存储 | 实现EEPROM备份机制 | | **对齐问题** | 跨平台结构体打包差异 | 使用 `#pragma pack(1)` | #### 5. **最佳实践** 1. **初始化检查** ```c if(sizeof(week_record_plan) > MAX_PLAN_SIZE) { log_error("Plan size overflow!"); // 防止内存越界 } ``` 2. **访问封装** ```c WEEK_PLAN* get_week_plan(void) { static mutex_t lock; mutex_lock(&lock); return &week_record_plan; // 线程安全访问 } ``` 3. **持久化设计** ```c void save_to_eeprom(void) { eeprom_write(PLAN_ADDR, (uint8_t*)&week_record_plan, sizeof(WEEK_PLAN)); } ``` ### 相关问题 1. 嵌入式系统中如何设计跨重启的配置存储机制? 2. 时间驱动型任务调度有哪些常见实现模式? 3. 结构体内存对齐对嵌入式系统性能有何影响?[^1] 4. 如何验证配置数据的完整性和有效性? 5. 多任务环境下共享资源配置的同步策略有哪些?[^2]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值