第三周学习

字符串函数

字符串替换:string Replace(string oldValue, string newValue);
将字符串中的出现oldValue的地方替换为newValue。
例:字符串替换

        string s = "2323232333";
        s = s.Replace("3","2");
        Console.WriteLine(s);

取子字符串:string Substring(int startIndex);
取从位置startIndex开始一直到最后的子字符串
string Substring(int startIndex, int length);
取从位置startIndex开始长度为length的子字符串,如果子字符串的长度不足length则报错。
例:从第三位取长度为三。

        String s = "abc123dssafddf";
        string s1 = s.Substring(2);
        string s1 = s.Substring(2, 3);//第二个参数是长度,不是结束位置

案例:截取字符串前5个,string s2 = s1.Substring(0, Math.Min(s1.Length, 5));//取字符串的长度和5中的最小值来截取。谁小取谁。

         // 取s.length-2,5中的最小值
          String s = "abc12f";
        //string s1 = s.Substring(2, s.Length - 2>5?5:s.Length -2);
        //int i = 5;
        //string s2 = (i == 5 ? "是" : "否");//等价于if...else..
        //string s2;
        //if (i == 5)
        //{
        //    s2 = "是";
        //}
        //else
        //{
        //    s2 = "否";
        //}
        
        //Math.Min返回两个参数中的最小值
        string s1 = s.Substring(2, Math.Min(s.Length - 2, 5));
        Console.WriteLine(s1);

bool Contains(string value);
判断字符串中是否含有子串value

        string s = "伟大的共产党召开大会";
        if (s.Contains("共产党"))//判断字符串是否含有子字符串bool类型
        {
           Console.WriteLine("禁止发表");
        }
        else
        {
            Console.WriteLine("可以发表");
        }

bool StartsWith(string value);
判断字符串是否以子串value开始;
bool EndsWith (string value)
判断字符串是否以子串value结束;

string s = "ATM我是你们的忠实听众";
        if (s.StartsWith("ATM"))//是否以某个字符串开头
        {
            Console.WriteLine("短信正确");
        }
        else
        {
            Console.WriteLine("短信错误");
        }

int IndexOf(string value):
取子串value第一次出现的位置;

         string s = "我爱北京敏感词";
        //int i = s.IndexOf("北京");
        int i = s.IndexOf("南京");//不存在则返回-1
        //在字符串在字符串中第一次出现的位置(以第一个字符为序号)
        Console.WriteLine(i);

字符串的处理练习

练习1:接收用户输入的字符串,将其中的字符以与输入相反的顺序输出。“abc"→"cba”

        string s = Console.ReadLine();
        for (int i = s.Length - 1; i >= 0; i--)
        {
            char ch = s[i];
            Console.Write(ch);
        }

课上练习2:接收用户输入的一句英文,将其中的单词以反序输出。“hello c sharp"→"sharp c hello”

        string line = Console.ReadLine();
        string[] strs = line.Split(new char[]{' '},
        StringSplitOptions .RemoveEmptyEntries  );
        string t = " ";
        for (int i = strs.Length - 1; i >= 0; i--)
            {
                string  str = strs[i];
                str = str + t;
                Console.Write(str);
            }

练习3:从Email中提取出用户名和域名:[email protected]。IndexOf找到@的位置。然后用SubString截取。要考虑Email地址错误的情况(必须含有@,并且@不能在最开始、最后出现),如果错误告诉用户。

        string email = Console.ReadLine();
        if (!email.Contains("@") || email.StartsWith("@") || email.EndsWith("@"))
        {
            Console.WriteLine("Email地址不正确");
            return;
        }
        int atIndex = email.IndexOf("@");//取@第一次出现的位置
        string usename = email.Substring(0, atIndex);//取子字符串,长度为atIndex
        string domain = email.Substring(atIndex + 1);//从atIndex +1开始取字符串
        Console.WriteLine("用户名{0}域名{1}",usename ,domain ); 

练习4:文本文件中存储了多个文章标题、作者,标题和作者之间用若干空格(数量不定)隔开,每行一个,标题有的长有的短,输出到控制台的时候最多标题长度20,如果超过20,则截取长度17的子串并且最后添加“…”,加一个竖线后输出作者的名字。

        string[] lines = System.IO.File.ReadAllLines(@"F:\2.txt",Encoding .Default );
        foreach (string line in lines)
        {
            string[] strs = line.Split( new char []{' '} ,      
            StringSplitOptions.RemoveEmptyEntries);
            int arcticlength = strs[0].Length ;
            string str = string.Join("|",strs);       
            if (arcticlength > 20)
            {
                string s = strs[0].Substring(0, 17);
                Console.WriteLine(s + "..." + "|"+strs[1]);
            }
            else
            {
                Console.WriteLine(str);
            }
        }
        Console.ReadKey();       

练习5:自己动手写聊天自动应答,能够回答不同城市的天气、回答感情问题、问的次数过多还会饿死,提问可以模糊提问(包含指定关键词)。
问“天气:北京”就回复“北京的天气是晴”。

        Console.WriteLine("你好!我是机器人!");
        int i = 0;
        while (i < 10)
        {
            i++;
            string str = Console.ReadLine();
            if ( str.Contains("天气:") )
            {
                string city = str.Substring(3);
                Console.WriteLine("{0}的天气晴朗", city);
            }
            else if (str.Contains("我") && (str.Contains("帅") || str.Contains("漂亮")))
            {
                Console.WriteLine("你好骚啊");
            }
            else if (str.StartsWith("88") || str.StartsWith("再见") || str.StartsWith("bye"))
            {
                Console.WriteLine("萨又拿啦!");
                return;
            }
            else
            {
                Console.WriteLine("我听不懂你在说什么");
            }
           
        }
        Console.WriteLine("别问了,再问我就要饿死了");
        Console.ReadKey();

ASCII的使用

例:从a打印到z

static void Main(string[] args)
    {
      for (char c='a';c<='z';c++)
      {
          Console.WriteLine (c);
      }
    }

例:把小写w改为大写W

        char ch = (char )('w' + ('A' - 'a'));
        Console.WriteLine(ch);

变量的作用域

变量名:变量名就像试验实例容器的编号,在一个实验室中,编号不能重复。如果去了更高一级的实验室,就不能和下属的实验室的容易编号重复。只要不出实验室,不同实验室之间的容器编号可以重复。
变量名规范:第一个字符小写,其后的每个单词的第一个字母大写
例:while声明变量。

        //int i = 3;
       // while (true)
        //{
           // int i = 5;//错误
        //Console.WriteLine(i);
       // }
        //变量的作用域是变量声明的最近一层的包着他的大括号
        while (true)
        {
            int i = 3;
        }
        while (true)
        {
            int i = 5;
        }

在同一个括号内变量定义不能重名,括号可以嵌套,但是通过函数的调用并不在这个范围内
例:int i;for(i=0)和for(int i=0)的区别

         int i;
        for (i = 0; i < 5; i++)
        {
        }
        看起来int i在for的{}外面,其实逻辑是在{}里面的
        for (int i=0;i <5;i++)
        {
        }
        
        for (int i=0;i <5;i++)
        {
            int sum = i;
        }
        Console.WriteLine(sum);//错误:出了{}就出了作用域

例:变量的声明顺序

        //变量用之前才声明
        int[] nums = { 5,10,15};
        int sum = 0;
        for (int i = 0; i < nums.Length; i++)
        {
            int t = nums[i] * i;
            sum = sum + t;
        }
        Console.WriteLine(sum );
        
        //变量用的时候声明会更好
        //int[] nums = { 5, 10, 15 };
        //int sum = 0;
        //int t = 0;
        //for (int i = 0; i < nums.Length; i++)
        //{
        //     t = nums[i] * i;
        //    sum = sum + t;
        //}
        //Console.WriteLine(sum);

例:函数的变量和方法的无关

static void Main(string[] args)
    {
         string name = "aaa";
         DotIt();
         Console.ReadLine();
    }
         static void DotIt()
    {
         //两个函数之间无法访问各自内部定义的变量
        //如果需要则需要通过参数传递
        //Console.WriteLine(name);
    }

面向对象的概念

面向对象:(OOP,Object-Oriented programming)不是取代面向过程的。
OOA架构、OOD设计。

类、对象。
类是抽象的,对象是具体的。
人”是类,“张三”是“人”这个类的对象。按钮就是类,某个按钮就是对象。
类不占内存,对象才占内存。
对象可以叫做类的实例(Instance)。
类就像int,对象就像10。

字段Field(和某个对象相关的变量)
字段就是类的状态(不同的对象可能不一样的状态就是字段)。
人这个类有姓名、年龄、身高等字段。
字段描述对象特点的数据。
眼睛的个数不能做为字段,因为所有人的眼睛个数都一样,没有差异性。

方法Method(函数)
方法就是类能够执行的动作,比如问好、吃饭等。
类的继承,类之间可以有继承关系,比如“电脑”类可以从“电器”类继承,这样的好处是“电脑”类只需要定义自己特有的字段、方法就可以,也就是只要定义内存大小、CPU型号这些字段或者弹出光驱等方法就可以。
父类(Parent)、基类(Base,基业,祖宗十八代传下来的)。
电脑类是电器类的子类(ChildClass)。
重用。父类有的子类都有。

面向对象的三个特性:封装、继承、多态。

定义类:class 名字
一个类可有有多个实例。
类就是把一系列相关的变量(状态)、行为定义为一个整体。字段记录的就是这个对象相关的数据。

       class Program
     {
          static void Main(string[] args)
       {
         person p1 = new person();
         //定义Person类变量p1,指向创建的person类的对象
         p1.gender = true;
         p1.height = 180;
         p1.name = "亚当";
         p1.SayHello();
         Console.Read();
       }
    }
    
     class person
{
     //定义字段
    //这里和在Main中写 string name="sun";bool gender;不一样,这里是在声明类的字段
     public string name="sun";//这也不是在声明变量,这是在声明字段
     public bool gender;
     public int height = Convert.ToInt32("130");//给字段赋值可以调用一行代码
    //赋值代码会在对象创建的时候执行
    
     //易错:类的定义只能定义字段、方法等,不能直接写其他代码
    //Console.WriteLine("");
    
    //定义方法
     public void SayHello()
    {
        Console.WriteLine("你好");
    }
    public int GetHeight()
    {
        return 180;
    }
}

例:数字转汉字

static void Main(string[] args)
    {
        Console.WriteLine(TOCH (1234));
        Console.ReadKey();
    }
     static string TOCH(int num)
    {
        string result = "";
        string str = Convert.ToString(num );//数字转为字符串
        for (int i = 0; i < str.Length; i++)
        {
            int wei = str.Length - i ;//
            if (wei ==1)//个位
            {
                result = result + ToCHChar(str[i]);
            }
            else if (wei == 2)//十位
            {
                result = result + ToCHChar(str[i]) + "十";
            }
            else if (wei == 3)//百位
            {
                result = result + ToCHChar(str[i]) + "百";
            }
            else if (wei == 4)//千位
            {
                result = result + ToCHChar(str[i]) + "千";
            }
        }
        return result; 
        }
         static char ToCHChar(char c)
    {
        switch (c)
        {
            case '1':
                return '一';
            case '2':
                return '二';
            case '3':
                return '三';
            case '4':
                return '四';
            case '5':
                return '五';
            case '6':
                return '六';
            case '7':
                return '七';
            case '8':
                return '八';
            case '9':
                return '九';
            case '0':
                return '零';
            default :
                return ' ';
        }
    }

成员的访问级别

字段、方法、属性都可以叫做类的成员Member,它们都需要定义访问级别。
访问级别的用处在于控制成员在哪些地方可以被访问,这样达到面向对象中“封装”的目的。
几个访问级别:public(任何地方都可以访问);
private(默认级别。只能由本类中的成员访问)。

永远不要把字段public;字段一般都是private;字段开头小写

//调用者只能通过方法来请求对象改变它的状态,是否改变
//改变多少是类自己决定的,这是为什么字段不能public的原因
//不至于出现升高为负的情况

    static void Main(string[] args)
    {
       p1.Feed("金克拉");
       Console.WriteLine(p1.height);
        Console.ReadKey();
    }
     public void Feed(string foodname)
     {
         if (foodname == "金克拉")
         {
             height = height + 10;
         }
         else if (foodname == "碧生源")
         {
             if(height <=1)
             {
                 return ;
             }
             height = height - 1;
         }
     }

对象的引用

int、decimal、bool、byte、enum等基础类型(值类型)是传递拷贝;
对象(引用类型)则是传递引用。
因为基础类型不怎么占内存,而对象则比较占内存。
函数间传递对象。
为对象变量重新赋值。p2=p1是让p2指向p1指向的对象。

static void Main(string[] args)
    {
         //new的操作相当于根据类的定义在内存中创建一块独立的区域
        //所以两个对象修改各自的字段不受影响
        //person p1 = new person();
        //p1.height = 180;//修改p1指向的对象的height字段的值为180

          //person p2 = new person();
         //person p2 = p1;//p2指向p1当前所指向的对象
         //p2.height = 190;
        
         //Console.WriteLine(p1.height);//读取p1指向对象的值
        //Console.WriteLine(p2.height);

        //DotIt(p1);
        //Console.WriteLine(p2.height);
        
        //person p1 = null;//p1不指向任何对象,
        //如果p1之前指向过对象,则切断p1和对象间关系
        
        person p1 = new person();
        p1.height = 50;
        
         p1 = null;//切断p1和对象间关系
        //以后如果碰都NullReferenceException,先看变量是不是指向了对象
        p1.height = 60;//p1没有指向任何对象
         //所以无法“修改指向对象的height属性”,因此报错
        //编译的错误和运行的错误
          Console.ReadKey();
    }
    //函数间传递普通的类的对象也是引用传递
    static void DotIt(person p)
    {
        p.height = 3000;
    }

猜你喜欢

转载自blog.csdn.net/qq_43393323/article/details/83416718