黑马程序员——CSharp基础

---------------------- Windows Phone 7手机开发.Net培训、期待与您交流! ----------------------

 

发现我的学习方法有问题,郁闷学了这么久了还没有什么进展,好像没有多少知识是属于自己的,在传智上终于找到了原因,我一直在模仿,模仿视频模仿别人的代码,没有用脑子去想,这样下去花费再多的时间精力也不会有明显的进步。昨天星期天,我学了一整天,从早上五点到晚上十二点半,累了听下音乐。我现在真的很恨,很讨厌自己把时间精力花费在那些消遣娱乐的事情上,一切愉快对我来说都是无聊,最大的无聊是为无儿费尽辛劳。我不知道以前在怕什么,现在我不怕了,想什么时候学习就什么什么学习,想在哪里学就在哪里学,我豁出去了。

语句以{}结束分号;分号可以省略。

Do

{  };分号可写可不写

While(条件);这个分号一定不能少。

异常捕获:

Try

{

 程序有可能出错的代码

}

Catch

{

         出错后的处理

}

只有try中的代码出错时才会执行Catch中的代码,否则不执行。

程序跳出循环有两种:一种是循环条件成立用Break语句,另一种是条件不成立。

如果希望程序是Break跳出则不执行的代码可以用if(成立的条件==false),表示只有条件成立时才执行这段代码,Break语句跳出来的不执行。

常量的定义,只要在变量前加const

Const 类型常量名 =常量值

cons修饰的常量不能定义静态的。

常量的好处:可以重复利用,防止数据被恶意修改。

常量只可以在定义时赋值。

枚举:enum 自己起的类型名称{值1,值2,……};值不需要加双引号。

枚举的值在定义时是有编号的,可以强类型转换,当值1的编号发生改变时,值2的编号会自动加1。修改编号:值1=3

如何把一个字符串转换成枚举类型

(自己定义的枚举类型)(Enum.Parse(typeof(自己定义的枚举类型),”待转换的字符串”);

例:enum fruit {apple,peach,banana,grape}

Console.WriteLine("whatdo you want to eat ?");

            stringwanteat = Console.ReadLine();

try{

            fruitenumfruit=(fruit)(Enum.Parse(typeof(fruit),wanteat));

            Console.WriteLine("do you want to eat"+enumfruit+"?");

}

Catch

{

Console.writeline(“不好意思,你输入的水果不在我们的提供满园内,不能转换为枚举类型”);

}

            Console.ReadKey();

结构:访问修饰符 struct结构名{定义结构成员}

enum Gerder { 男, 女}

    public struct Person

    {

        public string name;

        public Gerder sex;

        public int age;

}

结构的使用:

Person huangzhong;

            huangzhong.name = "黄珍";

            huangzhong.sex = Gerder.男;

            huangzhong.age = 24;

 

方法的重载:一般在同一个类中,方法名相同,方法的参数的个数不同,或对应位置上的类型不同,才能够成方法的重载。与返回值没有无关,编译器会根据参数来调用对应的方法。

方法的Out参数和ref参数:

函数参数默认是值传递的,相当于把值复制了一份,并不影响其本身。用out则表示是内部为外部变量赋值,通常用在函数需要有多个返回值的场合。

static void Main(string[] args)

        {

            intnum = 100;

            intresult = taxi(num);

num的值依然为100,result的值为200;

            intn = 1000;没有意义

            intnnd = yyd(out n);

加out表示通过参数返回值n的值变成了2000,nnd的值为2000;

        }

        static int taxi(int b)

        {

            b+=2;可以不用赋初值就可以使用。

            b = 200;

            returnb;

        }

      

        static int yyd( out int aa)

        {

          aa+=200;错误:必须先赋值,再使用。

            aa = 2000;

            returnaa;

        }

如果将out ref代替,则aa不必先赋值就可以使用。由此得出结论:out只能把值传出去,ref不但能把值传出去,还可以把值传入,是双向的。

Int.Parseint.TryPase

Int.Parse转换不成功则抛异常。

Int.Parse是尝试转换,转换成功则通过OUT返值并返回一个Bool类型true,转换失败则返回False

例子如下:

string s = "123ooo";

            intree;

            Console.WriteLine(int.Parse(s));

            if(int.TryParse(s,outree))

            {

                Console.WriteLine("trypase success" + ree);

            }

            else

            {

                Console.WriteLine("have error,fail");

            }

            Console.ReadLine();

实例:飞行棋项目代码

class Program
    {
        //在下面的数组存储我们游戏地图各个关卡
        //数组的下标为0的元素对应地图上的第一格,下标为1的元素对应第二格。。下标为N的元素对应N+1格
        //在数组中用  1:表示幸运轮盘◎  2:表示地雷☆   3:表暂停▲ 4:表时空隧道Ж  0:表普通□
        static int[] Map = new int[100];
        static int[] playerpost = { 0,0 };//playerpost[0]存玩家A的下标,playerpost[1]存玩家B的下标。


        static void Main(string[] args)
        {
            Random r =new Random ();//r是产生随机数用的
            bool[] isStop = { false, false };//isStop[0]表示A是否走到了暂停isStop[1]表示B 如果走到暂停,则设置为ture.
            int step = 0;//用于存放产生的随机数

            string[] names = new string[2];//names0存玩家A姓名,names1存玩家B姓名。
            string input ="";//用于存储用户的输入,只能输入1或2选择运气。
            string msg = "";//用于存储用户踩到关卡时输出的话。

            ShowUI();//显示游戏名称
            Console.WriteLine("请输入玩家A的姓名!");
            names[0] = Console.ReadLine();
            while (names[0] == "")
            {
                Console.WriteLine("玩家的姓名不能为空,请重新输入!");
                names[0] = Console.ReadLine();
            }

            Console.WriteLine("请输入玩家B的姓名!");
            names[1] = Console.ReadLine();

            while (names[1] == "" || names[1] == names[0])
            {
                if (names[1] == "")
                {
                    Console.WriteLine("玩家的姓名不能为空,请重新输入!");
                }
                if (names[1] == names[0])
                {
                    Console.WriteLine("姓名不能相同,请重新输入!");

                }

                names[1] = Console.ReadLine();
            }
            Console.Clear();
            ShowUI();
            Console.WriteLine("the game starting........");
            Console.WriteLine("player{0}use A 表示", names[0]);
            Console.WriteLine("player{0}use B 表示", names[1]);
            Console.WriteLine("如果AB在同一位置用<>表示", names[1]);

            InitialMap();//初始化地图
            DrawMap();//绘制地图
            Console.WriteLine("start game ...");

            //这个循中让玩家A和玩家B轮流掷骰子,当玩家A或玩家B的坐标>=99时结束循环。
            while (playerpost[0] < 99 && playerpost[1] < 99)
            {
                if (isStop[0] == false)
                {
                    #region //玩家A掷骰子
                    Console.WriteLine("press anykey to thow diece...", names[0]);
                    ConsoleKeyInfo rec = Console.ReadKey(true);
                    step = r.Next(1, 7);//产生一个1至6之间的随机整数
                    /以下为先按Tap,再按F1,再输入一个数。
                    if (rec.Key == ConsoleKey.Tab)
                    //if (rec.Key == ConsoleKey.Tab && rec .Modifiers ==ConsoleModifiers .Control)
                    //if (rec.Key == ConsoleKey.Tab && rec.Modifiers == (ConsoleModifiers.Control|ConsoleModifiers .Shift ))
                    {
                        ConsoleKeyInfo cc = Console.ReadKey();
                      
                        if (cc.Key ==ConsoleKey.F1 )
                        {
                        step = ReadInt(1, 100);
                        }
                    }
                   
                  
                    以下为按下Tab键则前进去20步。
                    //if (rec.Key == ConsoleKey.Tab)
                    //{ step = 20; }
                    //else
                    //{
                    //    step = r.Next(1, 7);//产生一个1至6之间的随机整数
                    //}
                    Console.WriteLine("{0}掷出了:{1}", names[0], step);
                    Console.WriteLine("按任意键开始行动……");
                    Console.ReadKey(true);
                    playerpost[0] = playerpost[0] + step;//注意:一旦坐标发生改变,就要判断坐标值是否大于99或小于0;
                    CheckPost();//检测坐标是否越界

                    if (playerpost[0] == playerpost[1])//玩家A踩到玩家B
                    {
                        playerpost[1] = 0;
                        msg = string.Format("{0}踩到了{1},{1}退回原点", names[0], names[1], names[1]);
                    }
                    else
                    {//没踩到,要判断玩家A现在所在的位置是否有其它关卡
                        switch (Map[playerpost[0]])
                        {
                            case 0://普通,没有效果。
                                msg = "";
                                break;
                            case 1://走到了幸运轮船关卡
                                Console.Clear();
                                DrawMap();
                                Console.WriteLine("{0}走到了幸运轮盘,请选择运气:1 则交换位置。 2 则轰炸对方。", names[0]);
                                int userSelect = ReadInt(1, 2);
                                if (userSelect == 1)
                                {//要与对方交换位置
                                    int temp = playerpost[0];
                                    playerpost[0] = playerpost[1];
                                    playerpost[1] = temp;
                                    msg = string.Format("{0}选择了与对方交换位置!", names[0]);
                                }
                                else
                                { //轰炸对方
                                    playerpost[1] = playerpost[1] - 6;
                                    CheckPost();
                                    msg = string.Format("{0}轰炸了{1},{1}退六格!", names[0], names[1]);

                                }

                                break;
                            case 2://踩到了地雷
                                playerpost[0] = playerpost[0] - 6;
                                CheckPost();
                                msg = string.Format("{0}踩到了地雷退六格!", names[0]);
                                break;
                            case 3://暂停一次
                                isStop[0] = true;
                                msg = string.Format("{0}走到红灯,下次暂停一次!", names[0]);
                                break;
                            case 4://时空隧道
                                playerpost[0] = playerpost[0] + 10;
                                msg = string.Format("{0}进入了时空隧道,爽歪歪,进十步!", names[0]);
                                break;
                        }
                    }
                    //Console.WriteLine("按任意键开始行动……");
                    //Console.ReadKey(true);
                    Console.Clear();
                    DrawMap();
                    if (msg != "")
                    {
                        Console.WriteLine(msg);
                    }
                    Console.WriteLine("{0}掷出了{1},行动完成!", names[0], step);
                    Console.WriteLine("******玩家A和玩家B的位置如下*********");
                    Console.WriteLine("{0}的位置为:{1}", names[0], playerpost[0]);
                    Console.WriteLine("{0}的位置为:{1}", names[1], playerpost[1]);


                    //Console.Clear();
                    //DrawMap();


                    #endregion
                }
                else
                {//说明isStop==true
                    isStop[0] = false;//将值改为false让其下次可以掷骰子。
                }
                if (playerpost[0] >= 99)
                { break; }

                if (isStop[0] == false)
                {
                    #region //玩家B掷骰子
                    Console.WriteLine("press anykey to thow diece...", names[1]);
                    Console.ReadKey(true);
                    step = r.Next(1, 7);//产生一个1至6之间的随机整数
                    Console.WriteLine("{0}掷出了:{1}", names[1], step);
                    Console.WriteLine("按任意键开始行动……");
                    Console.ReadKey(true);
                    playerpost[1] = playerpost[1] + step;//注意:一旦坐标发生改变,就要判断坐标值是否大于99或小于0;
                    CheckPost();//检测坐标是否越界

                    if (playerpost[0] == playerpost[1])//玩家B踩到玩家A
                    {
                        playerpost[0] = 0;
                        msg = string.Format("{0}踩到了{1},{1}退回原点", names[1], names[0], names[0]);
                    }
                    else
                    {//没踩到,要判断玩家A现在所在的位置是否有其它关卡
                        switch (Map[playerpost[1]])
                        {
                            case 0://普通,没有效果。
                                msg = "";
                                break;
                            case 1://走到了幸运轮船关卡
                                Console.Clear();
                                DrawMap();
                                Console.WriteLine("{0}走到了幸运轮盘,请选择运气:1 则交换位置。 2 则轰炸对方。", names[1]);
                                int userSelect = ReadInt(1, 2);
                                if (userSelect == 1)
                                {//要与对方交换位置
                                    int temp = playerpost[0];
                                    playerpost[0] = playerpost[1];
                                    playerpost[1] = temp;
                                    msg = string.Format("{0}选择了与对方交换位置!", names[1]);
                                }
                                else
                                { //轰炸对方
                                    playerpost[1] = playerpost[1] - 6;
                                    CheckPost();
                                    msg = string.Format("{0}轰炸了{1},{1}退六格!", names[1], names[0]);

                                }


                                break;
                            case 2://踩到了地雷
                                playerpost[1] = playerpost[1] - 6;
                                CheckPost();
                                msg = string.Format("{0}踩到了地雷退六格!", names[1]);
                                break;
                            case 3://暂停一次
                                isStop[0] = true;
                                msg = string.Format("{0}走到红灯,下次暂停一次!", names[1]);
                                break;
                            case 4://时空隧道
                                playerpost[1] = playerpost[1] + 10;
                                msg = string.Format("{0}进入了时空隧道,好爽,进十步!", names[1]);
                                break;
                        }
                    }
                    //Console.WriteLine("按任意键开始行动……");
                    //Console.ReadKey(true);
                    Console.Clear();
                    DrawMap();
                    if (msg != "")
                    {
                        Console.WriteLine(msg);
                    }
                    Console.WriteLine("{0}掷出了{1},行动完成!", names[1], step);
                    Console.WriteLine("******玩家A和玩家B的位置如下*********");
                    Console.WriteLine("{0}的位置为:{1}", names[0], playerpost[0]);
                    Console.WriteLine("{0}的位置为:{1}", names[1], playerpost[1]);

                    #endregion
                }
                else
                {//说明isStop==true
                    isStop[1] = false;//将值改为false让其下次可以掷骰子。
                }
            }
            //判断谁胜利,谁失败。
            Console.Clear();
            ShowUI();
            if (playerpost[0] >= 99)
            {
                Console.WriteLine("{0}胜利了!", names[0]);
            }
            else
            {
                Console.WriteLine("{0}胜利了!", names[1]);
            }

            Console.ReadKey();

        }


        static void ShowUI()
        {
            Console.WriteLine("**********************************************");
            Console.WriteLine("***                                        ***");
            Console.WriteLine("             骑  士  飞  行  棋               ");
            Console.WriteLine("***                                        ***");
            Console.WriteLine("**********************************************");
        }
        /// <summary>
        /// 对玩家A和玩家B坐标越界的判断
        /// </summary>
        static void CheckPost()
        {
            for (int i = 0; i <= 1; i++)
            {
                if (playerpost[i] > 99)
                {
                    playerpost[i] = 99;
                }
                if (playerpost[i] < 0)
                {
                    playerpost[i] = 0;
                }
            }
        }

 

        static void InitialMap()
        {
            for (int i = 0; i < Map.Length; i++)
            {
                Map[i] = 0;
            }
            //用于存储在地图中为地雷的下标
            int[] luckyTurn = { 6, 23, 40, 55, 69, 83 };
            int[] landMine = { 5, 13, 17, 33, 38, 50, 63, 82, 94 };
            int[] pause = { 9, 27, 60, 93 };
            int[] timeTunnel = { 20, 25, 45, 66, 77, 88, 98 };
            for (int i = 0; i < luckyTurn.Length; i++)
            {
                int pos = luckyTurn[i];
                Map[pos] = 1;

            }
            for (int i = 0; i < landMine.Length; i++)
            {
                Map[landMine[i]] = 2;
            }
            for (int i = 0; i < pause.Length; i++)
            {
                Map[pause[i]] = 3;
            }
            for (int i = 0; i < timeTunnel.Length; i++)
            {
                Map[timeTunnel[i]] = 4;
            }
        }

        static string GetMapString(int pos)
        {
            string result = "";
            if (playerpost[0] == pos && playerpost[1] == pos)
            {
                Console.ForegroundColor = ConsoleColor.Blue;
                result = "<>";
            }
            else if (playerpost[0] == pos)
            {
                Console.ForegroundColor = ConsoleColor.Blue;
                result = "A";
            }
            else if (playerpost[1] == pos)
            {
                Console.ForegroundColor = ConsoleColor.Blue;
                result = "B";
            }
            else
            {
                switch (Map[pos])
                {
                    case 0:
                        Console.ForegroundColor = ConsoleColor.Cyan;
                        result = "□";
                        break;
                    case 1:
                        Console.ForegroundColor = ConsoleColor.DarkMagenta;
                        result = "◎";
                        break;
                    case 2:
                        Console.ForegroundColor = ConsoleColor.Green;
                        result = "☆";
                        break;
                    case 3:
                        Console.ForegroundColor = ConsoleColor.DarkYellow;
                        result = "▲";
                        break;
                    case 4:
                        Console.ForegroundColor = ConsoleColor.Red;
                        result = "Ж";
                        break;

                }
            }
            return result;
        }
        static void DrawMap()
        {
            Console.WriteLine("幸运轮盘◎  地雷☆   暂停▲  空隧道Ж  普通□");
            //画第一行
            for (int i = 0; i <= 29; i++)
            {

               Console .Write ( GetMapString(i));

            }
            //第一行绘制完毕换行
            Console.WriteLine();
            //画第一列
            for (int i = 30; i <= 34; i++)
            {
                //绘制作29个双空格
                for (int j = 0; j < 29; j++)
                {
                    Console.Write("  ");
                }
                //Console .WriteLine (GetMapString(i));
                string str = GetMapString(i);
                Console .WriteLine (str);
             
            }
            //Console.WriteLine();
            //画第二行
            for (int i = 64; i >= 35; i--)
            {
                Console.Write(GetMapString(i));

            }

            //画第二列
            Console.WriteLine();
            for (int i = 65; i < 70; i++)
            {
                Console.WriteLine(GetMapString(i));
 
            }
            //最后一行
            for (int i = 70; i < 100; i++)
            {
                Console.Write(GetMapString(i));
 
            }
            Console.WriteLine();
            Console.ResetColor();

 

 


        }
        static int ReadInt()
        {
            int i = ReadInt(int.MinValue, int.MaxValue);
            return i;
        }
        static int ReadInt(int min, int max)
        {
            while (true)
            {
                try
                {
                    int number = Convert.ToInt32(Console.ReadLine());
                    if (number < min || number > max)
                    {
                        Console.WriteLine("只能输入{0}-{1}之间的数字,请重新输入!", min, max);
                        continue;
                    }
                    return number;
                }
                catch
                {
                    Console.WriteLine("只能输入数字,请重新输入:");
                }
            }
        }

    }

 

以下为参考资料

关于object类型:

1.object类型可以来引用任何类型的实例;

2.object类型可以存储任何类型的值;

3.可以定义object类型的参数;

4.可以把object作为返回类型。

但是--这样做有很大的问题

1.会因为程序员没有记住使用的类型而出错,造成类型不兼容;

2.值类型和引用类型的互化即装箱拆箱使系统性能下降。

C#2.0提出的泛型就是避免强制类型转换,减少装箱拆箱提高性能,减少错误。

System.Collections.Generic命名空间提供许多集合类和接口的泛型版本。

定义:

public classGenericList<T>

{

   public void Add(T input)//T制定成类型参数

   public T Add()//T制定成返回值

}

<T>T是类型参数,起占位符的作用,编译时被真正类型取代。

使用泛型:

GenericList<int>list1 = new GenericList<int>();

GenericList<string>list2 = new GenericList<string>();

GenericList<类名> list3 = new GenericList<类名>();

GenericList<类名<int>> list4= new GenericList<类名<int>>();

list1为例编译器生成以下的方法:

   public void Add(int input)

   public int Add()

 

有多个类型参数的泛型类:

public class 类名<T,U>

 

泛型约束:

确保泛型类使用的参数是提供特定方法的类型。

public class GenericList<T> where T :IEmployee

假如IEmployee接口包含A方法,编译器会验证用于替换T的类型一定要实现IEmployee接口。

 

泛型方法:允许采取定义泛型类时采用的方式

 

//定义泛型方法

static void Swap<T>(ref T lhs, ref Trhs)

 

{ T temp; temp = lhs; lhs = rhs; rhs =temp; }

//使用泛型方法

 

public static void TestSwap(){    int a=1,b=3;

Swap<int>(ref a,ref b);

 

 

strings1="Hello",s2="world";

Swap<string>(ref s1,ref s2);}

 

有泛型类,泛型接口,泛型方法,泛型委托

好处是不像数组需要一开始就定义长度,泛型能自动增长。而且方便索引,排列等。      

 泛型是具有占位符(类型参数)的类、结构、接口和方法,这些占位符是类、结构、接口和方法所存储或使用的一个或多个类型的占位符。泛型集合类可以将类型参数用作它所存储的对象的类型的占位符;类型参数作为其字段的类型及其方法的参数类型出现。泛型方法可以将其类型参数用作其返回值的类型或者其某个形参的类型。  由于.NET Framework泛型的类型参数之实际类型在运行时均不会被消除 泛型约束

,运行速度会因为类型转换的次数减少而加快。  另外,使用 GetType方法可於程序运行时得知泛型及其类型参数的实际类型,更可以运用反射编程。  允许对个别泛型的类型参数进行约束,包括以下几种形式(假设 C是泛型的类型参数,是一般类、泛类,或是泛型的类型参数):T是一个类。T是一个值类型。T具有无参数的公有建构方法。T实现接口 IT C,或继承自 C

 

继承:结构不支持继承,但可以实现接口。

继承(加上封装和多形性)是面向对象的编程的三个主要特性(也称为支柱)之一。继承用于创建可重用、扩展和修改在其他类中定义的行为的新类。其成员被继承的类称为基类,继承这些成员的类称为派生类。派生类只能有一个直接基类。但是,继承是可传递的。如果 ClassB 派生出 ClassCClassA派生出 ClassB,则 ClassC会继承 ClassB ClassA 中声明的成员。

从概念上来说,派生类是基类的专用化。例如,如果您有一个基类Animal,则可以有一个名为Mammal的派生类和一个名为Reptile的派生类。Mammal是一个AnimalReptile也是一个Animal,但每个派生类均表示基类的不同专用化。

定义一个类从其他类派生时,派生类隐式获得基类的除构造函数和析构函数以外的所有成员。因此,派生类可以重用基类中的代码而无需重新实现这些代码。可以在派生类中添加更多成员。派生类以这种方式扩展基类的功能。

 

抽象方法和虚方法


当基类将方法声明为virtual时,派生类可以用自己的实现重写该方法。如果基类将成员声明为abstract,则在直接继承自该类的任何非抽象类中都必须重写该方法。如果派生类自身是抽象的,则它继承抽象成员而不实现它们。抽象成员和虚成员是多态性的基础,多态性是面向对象的编程的第二个主要特性。有关更多信息,请参见多态性(C#编程指南)

抽象基类


如果希望禁止通过new关键字直接进行实例化,可以将类声明为abstract如果这样做,则仅当从该类派生新类时才能使用该类。抽象类可以包含一个或多个自身声明为抽象的方法签名。这些签名指定参数和返回值,但没有实现(方法体)。抽象类不必包含抽象成员;但是,如果某个类确实包含抽象成员,则该类自身必须声明为抽象类。自身不是抽象类的派生类必须为抽象基类中的任何抽象方法提供实现。有关更多信息,请参见抽象类、密封类及类成员(C#编程指南)抽象类设计

接口


接口是一种引用类型,有点像仅包含抽象成员的抽象基类。类在从接口实现时必须为该接口的所有成员提供实现。类虽然只能从一个直接基类派生,但可以实现多个接口。

接口用于为不一定具有关系的类定义特定功能。例如,System.IEquatable(OfT)接口可由任何类或构造实现,这些类或构造必须启用代码来确定该类型的两个对象是否等效(但是该类型定义等效性)。IEquatable(OfT)不表示基类和派生类之间存在的同一种关系(例如MammalAnimal)。

派生类对基类成员的访问


派生类可以访问基类的公共成员、受保护成员、内部成员和受保护内部成员。即使派生类继承基类的私有成员,仍不能访问这些成员。但是,所有这些私有成员在派生类中仍然存在,且执行与基类自身中相同的工作。例如,假定一个受保护基类方法访问私有字段。要使继承的基类方法正常工作,派生类中必须有该字段。

禁止进一步派生


类可以将自身或其成员声明为sealed,从而禁止其他类从该类自身或其任何成员继承。

派生类隐藏基类成员


派生类可以通过以相同的名称和签名声明基类成员来隐藏这些成员。可以使用new修饰符显式指示成员不作为基类成员的重写。不是必须要使用new,但如果不使用new,将生成编译器警告。

 ---------------------- Windows Phone 7手机开发.Net培训、期待与您交流! ---------------------- 详细请查看:http://net.itheima.com/


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值