第二周学习内容

数组练习

练习:首先遍历nums1,用一个变量count统计非0的个数
创建一个长度为count的新数组nums2
遍历num1,把非0的值依次填入nums2中

        int[] nums1 = { 2, 3, 0, 5, 0, 6, -1 };
        int count = 0;
        for (int i = 0; i < nums1.Length; i++)
        {
            if (nums1[i] != 0)
            {
                count++;
            }
        }
        //Console.WriteLine(count);
        int[] nums2 = new int[count];
        int newIndex = 0;//记录新数据的拷贝数据
        for (int i = 0; i < nums1.Length; i++)
        {
            if (nums1[i] != 0)
            {
                nums2[newIndex] = nums1[i];
                newIndex++;//新数组的位置向前挪一下
            }
        }
        for (int i = 0; i < nums2.Length; i++)
        {
            Console.WriteLine(nums2[i]);
        }
        Console.ReadKey();

练习: 将一个字符串数组{“3”,“a”,“8”,“haha”}输出为|分割的字符串,“3|a|8|haha”

        string[] strs = { "3", "a", "8", "haha" };
        string s = "";//和string s;有区别
        for (int i = 0; i < strs.Length - 1; i++)
        {
            string str = strs[i];
            s = s + str + "|";//读一个变量前,这个变量必须被赋值
        }
        s = s + strs[strs.Length - 1];//加上最后一个
        Console.WriteLine(s);
        Console.ReadKey();

foreach循环

foreach(类型 变量名 in 数组名)
对数组进行逐个遍历
和for的区别:for可以不逐个遍历,比如每隔一个遍历一个,或者可以从后向前遍历

依次遍历names数组中的内容,对于每条数据都执行{}中的代码,
每次遍历的数组用in前面的变量表示,变量的类型是数组的类型

    string[] names = { "tom", "jerry", "lily" };
        //for (int i = 0; i < names.Length; i++)
        //{
        //    string str = names[i];
        //    Console.WriteLine(str);
        //}
     foreach (string str in names)
           {
            Console.WriteLine(str);
           }    

遍历数组

        int[] nums = { 3, 5, 9 };
        foreach (int n in nums)
        {
            Console.WriteLine(n);
        }

练习:分别打印数组中的名字

        string[] names = { "tom", "jerry", "lily" };
         foreach (string name in names)
        {
            Console.WriteLine("我的名字{0}", name);
        }
        Console.ReadKey();

函数

函数就是将一堆代码进行重用的一种机制;
函数就是一段代码,这段代码可能有输入的值(参数),可能会返回值。
函数:static 返回值类型 函数名(参数列表)
不用函数编写用户输入两个数,并输出它们的和。

static void Main(string[] args)
    {
        Console.WriteLine("请输入第一个数");
        string s1 = Console.ReadLine();
        int i1 = Convert.ToInt32(s1);
        Console.WriteLine("请输入第二个数");
        string s2 = Console.ReadLine();
        int i2 = Convert.ToInt32(s2);
        int i3 = i1 + i2;
        Console.WriteLine(i3);
        Console.ReadKey();
    }

用函数编写一:

    static void Main(string[] args)
    {
        int i1 = ReadInt("请输入第一个数");
        int i2 = ReadInt("请输入第二个数");
        ReadInt("请输入第一个数");//没有返回值也行,但没啥用
        int i3 = i1 + i2;
       Console.WriteLine(i3);
        Console.ReadKey();
    }
    static int ReadInt(string msg)//返回值类型 函数名(参数列表)
    {
        Console.WriteLine(msg);
        string s = Console.ReadLine();
        int i = Convert.ToInt32(s);
        return i;
    }

练习函数编写两个数的和

      static void Main(string[] args)
    {
        int i = Add(5, 6);
        Console.WriteLine(i);
        Console.ReadKey();
    }
         static int Add(int i1, int i2)
    {
        return i1 + i2;
    }

没有返回值的函数用 void

    static void SayHello()//表示函数没有返回值
    {
        Console.WriteLine("早上好");
        Console.WriteLine("中午好");
        Console.WriteLine("下午好");
    }

练习:提供一个函数,将用户提供的一个字符串重复n遍形成一个新的字符串"abc"3,返回给调用者一个字符串"abcabcabc"

    static void Main(string[] args)
    {
         Console.WriteLine("请输入字符串");
         string s=Console.ReadLine();
         int n = ReadInt("请输入次数");
        string resuit= Rpeat(s, n);
        //函数内部不关心参数怎么来的,也不关心返回值干什么用
        Console.WriteLine(resuit);
        Console.ReadKey();
    }
    //注意参数命名规则
    //不要在函数内部帮调用者WriteLine,不要帮调用者ReadLine
    //调用函数的地方的参数名字和函数声明时的名字没有对应关系
    static string Rpeat(string s, int n)
     {
        string t= "";
        for(int i=0;i<n;i++)
        {
            t = t + s;
        }
        return t;//把计算的结果返回
    }

练习:编写一个函数,将用户提供的两个整数中的的最大值返回

    static int mMax(int n1, int n2)
    {
        if (n1 > n2)
        {
            return n1;
        }
        else
        {
            return n2;
            //return"aaa";//函数答应返回int就必须返回int
            //不能不返回,不能返回其他类型
        }
    }

练习:return和break区别

      static void Hello()
    {
        for (int i = 0; i < 10; i++)
        {
            if (i == 3)
            {
                //break;
                return;
            }
            Console.WriteLine("aaaaa");
        }
        Console.WriteLine("Hello完成");
    }
   break会执行"Hello完成"   return不执行     

函数返回值易错点

一个函数如果“答应”返回一个非void类型的值,则函数的所有路径都要有返回值。比如将对输入年龄转换为年龄段描述的函数。
while()中赋值也不行,因为可能while一个循环都不执行。
错误一:所以路径都要有返回值,不能存在没有返回值的情况

    static int DoIt(int i)
    {
        if (i < 0) 
        {
            return 0 - 1;
       }
        else if (i>=0&&i<=10)
        {
           return 30;
        }
    }

错误二:存在没有返回值的情况

    static int DoIt(int n)
    {
       for (int i = 0; i < n; i++)
        {
           return i;
        }
    }
    练习:
    static void Main(string[] args)
    {
     int[] nums = { 3, 6, 8 };
     Console.WriteLine(Sum(nums));//函数要求提供什么数据,必须提供什么数据
      Console.ReadKey();
     }
     static int Sum(int[] values)
     {
        int sum = 0;
        foreach (int i in values)
        {
            sum = sum + i;
        }
        return sum;
      }

练习:编写一个从百度MP3下载音乐函数需要定哪些参数,
假设http://mp3.baidu.com/***.mp3

    static bool DownLoadMp3(string filename, string localfilename)
    //两个,歌名,下载到哪去
    {
        string ur1 = "http://mp3.baidu.com/filename.mp3";
    }

练习:调用者提供一个字符串数组,和一个字符串,把字符串数组用这个字符串分割起来

    static void Main(string[] args)
    {
        string [] strs = { "a", "c", "d" };
        string s = "()";
        string t = FenGe(strs ,s);
        Console.WriteLine(t);
        Console.ReadKey();
    }
    static string FenGe(string[] strs, string s)
    {
        string t = "";
        foreach (string str in strs)
        {
            t = t+str + s;
        }
        return t;
    }

函数重载

构成重载的条件:
同名的两个函数的签名(参数的类型、顺序、返回值的类型)不能完全一样;和参数的名字无关;函数的重载不关返回值类型 。
例子:

static void Next(int i)
    {
        Console.WriteLine(i+i);
    }
    
    static void next(int i)
    {
        Console.WriteLine(i + i);
    }
    
    //overload重载
    static void Next(string  boss)
    {
        if (boss == "毛")
        {
            Console.WriteLine("邓");
        }
        
  只有参数的类型、顺序不一致才能函数重名,函数返回值类型一直与否没有关系
   static int Next(string boss)//错误
    { 
    }

可变参数(params)

参数数组:
int sum(params int[] values)
int sum(string name,params int[] values)
可变参数数组必须是在最后一个

参数默认值(C#4.0) :void SayHello(string name,int age=20)
用重载来实现参数默认值的效果,在构造函数中用的特别多。

编写一个让用户输入一个数组并输出其中的最大值,使用可变参数就可以不用定义一个数组,可以直接输入一组数。

 static void Main(string[] args)
    {
        //int[] values = { 3,5,7,5,7,9,9};
        //int i = Max(values);
        //int i = Max(1, 2, 3);
        int j = Max(true,"",3, 5, 7, 1, 9);
        Console.WriteLine(j);
        Console.ReadKey();
    }
     //个数不确定的可变参数以数组的形式传递
    //可变参数一定要放在最后一个
    static int Max(bool b,string msg,params int[] values)
    {
        Console.WriteLine(msg);
        int max = 0;
        foreach (int value in values)
        {
            if (value > max)
            {
                max = value;
            }
        }
        return max ;
    }
    //设置参数默认值
    static void SayHello(string name,int age=20,bool gender=true )
        {
             Console.WriteLine("我是{0},我芳龄{1}",name,age );
        }

函数的ref、out参数

函数参数默认是值传递的,也就是“复制一份”。
ref必须先初始化,因为是引用,所以必须先“有”,才能引用;
而out则是内部为外部赋值,所以不需要初始化,而且外部初始化也没用。
ref应用场景内部对外部的值进行改变;
out则是内部为外部变量赋值,out一般用在函数有多个返回值的场所。
ref就是为了能折腾变量本身
例如:没有使用ref,变量本身的值不会变。

   static void Main(string[] args)
    {
        int i = 1;
        DotIt(i);
        Console.WriteLine(i);//输出1、2、1
        Console.ReadKey();
    }
    //int i传进来的时候是复制了一份传进来,折腾的是复制品
    static void DotIt(int i)
    {
        Console.WriteLine (i);
        i++;
        Console.WriteLine(i);
        i++;
    }
    使用ref
    static void Main(string[] args)
    { 
         int i1 = 10;
         int i2 = 20;
         
         //Swap(i1,i2 );//折腾的是复制品
        //用ref之前必须给变量赋值
        
        Swap(ref i1,ref i2);//传递引用。给ref传递参数时也要加上ref
        Console.WriteLine("i1={0},i2={1}",i1,i2)
        Console.ReadKey();
    }
      static void Swap(ref int i1, ref int i2)//reference
    {
        //标记为ref就是要求调用者传递变量的引用
        int temp = i1;
        i1 = i2;
        i2 = temp;
        
       //static void Swap(int i1, int i2)
        //{
       //    int temp = i1;
       //    i1 = i2;
       //    i2 = temp;
    }

out:就起到一个函数有两个返回值

   static void Main(string[] args)
    {
        bool b;//不需要为out赋值
        int i= Parse(Console.ReadLine(),out b);
        if(b)//和if(b==true)一样
        {
            Console.WriteLine ("成功,i={0}",i);
        }
        else 
        {
             Console.WriteLine ("错误");
        }
        Console.ReadKey();
    }
static int Parse(string s,out bool success)
    {
        if(s=="一")
        {
            success=true;
            return 1;
        }
        else if(s=="二")
        {
            success=true;
            return 2;
        }
        else
        {
            success=false ;
             return -1;
        }

例如: 把用户输入的字符串转换成数,如果用户输入的不是数,用Convert.ToInt32()转换就会报错。可以用int.TryParse(s, out i)

   static void Main(string[] args)
    {
        string s = Console.ReadLine();
        int i=0;
        if (int.TryParse(s, out i))
        {
            Console.WriteLine("成功" + i);
        }
        else
        {
            Console.WriteLine("输入错误" );
        }
        //int i = Convert.ToInt32(s);
        //i++;
        //Console.WriteLine(i);
        Console.ReadKey();
    }

字符串

char类型:用单引号包含字符,单引号中放且只能放一个字符。(‘a’)
单个字符也可以表示为字符串,还可以有长度为0的字符串。
null(表示空)和""(长度为0);‘f’(字符)和“f”(字符串)的区别。
练习:String.IsNullOrEmpty

 string s = "   ";//不是empty
        if(s==null||s==""||s==string.Empty )
         {
         }
          if (string.IsNullOrEmpty(s))//等价与s==null||s==""
        {
            Console.WriteLine("空");
        }

使用s.Length属性来获得字符串中的字符个数

       String s = "asadsfdfsdfdf";
        Console.WriteLine(s.Length);

string可以看做是char的只读数组。char c = s[1];。
例子:遍历输出string中的每个元素。

      string s = "asfadsfdf";
        foreach (char c in s)
        {
            Console.WriteLine(c);
        }

C#中字符串有一个重要的特性:不可变性,字符串一旦声明就不再可以改变。所以只能通过索引来读取指定位置的char,不能对指定位置的char进行修改。

        String s = "asadsfdfsdfdf"
        char c = s[3];//读取序号为0的位置的char,注意char的类型
        Console.WriteLine(c);
        //s[3]='1'//只能读,不能改

     char[] chars = { 'a', 'b', 'c' };
     chars[1] = '1';
     //字符串是不可变的,所以要先生成一个chae[],再对char[]进行修改
   //再根据char[]生成的新的字符串,但是原来的字符串没有改变(他就在那)

如果要对char进行修改,那么就必须创建一个新的字符串,用s. ToCharArray()方法得到字符串的char数组,对数组进行修改后,调用new string(char[])这个构造函数来创建char数组的字符串。一旦字符串被创建,那么char数组的修改也不会造成字符串的变化。
例子:将字符串中的第三位替换为w。

        string s = "asfsafdafdsfsd";
        char[] chars = s.ToCharArray();
        chars[2] = 'w';//是直接改char[]数组
        string s1 = new string(chars);
        Console.WriteLine(s1);
        Console.WriteLine(s);

string s=“abc”,是声明一个变量s,把s指向“abc“这个字符串

例:时间格式转换汉字大写 比如: “2009年9月5日” 转换成 “二零零九年九月五日”,输入字符串,返回字符串。写成一个函数

static void Main(string[] args)
    {
    string s = "2009年9月18日";
       string s1 = TOCHDate(s);
        Console.WriteLine(s1);
        Console.ReadKey();
    }
    static string TOCHDate(string date)
    {
        //{'零','一','二'},表驱动算法
        char[] chars = date.ToCharArray();
        for (int i = 0; i < chars.Length; i++)
        {
            char ch = chars[i];
            switch (ch)
            {
                case '1':
                    chars[i] = '一';
                    break;
                case '2':
                    chars[i] = '二';
                    break;
                case '3':
                    chars[i] = '三';
                    break;
                case '4':
                    chars[i] = '四';
                    break;
                case '5':
                    chars[i] = '五';
                    break;
                case '6':
                    chars[i] = '六';
                    break;
                case '7':
                    chars[i] = '七';
                    break;
                case '8':
                    chars[i] = '八';
                    break;
                case '9':
                    chars[i] = '九';
                    break;
                case '0':
                    chars[i] = '零';
                    break;
            } 
        }
        return new string(chars);
    }

要区分变量名和变量指向的值的区别。程序中可以有很多字符串,然后由字符串变量指向他们,变量可以指向其他的字符串,但是字符串本身没有变化。字符串不可变性指的是内存中的字符串不可变,而不是变量不变。

String类常用函数

ToLower():得到字符串的小写形式。
ToUpper():得到字符串的大写形式;
注意字符串是不可变的,所以这些函数都不会直接改变字符串的内容,而是把修改后的字符串的值通过函数返回值的形式返回。s.ToLower()与s=s.ToLower()
例:得到字符串小写形式

        string s = "ChinaRen";
        s.ToLower();//字符串是不可变的,所以转换后的值通过返回值
        string s1 = s.ToLower();
        Console.WriteLine(s);
        Console.WriteLine(s1);

例:忽略大小写比较用户名

           Console.WriteLine("请输入用户名:");
        string name = Console.ReadLine();
        //忽略大小写比较用户名
        name = name.ToLower();//并没有改变原先的字符串,只是指向新的字符串
        if (name == "admin")
        {
            Console.WriteLine("用户名存在");
        }
        else
        {
            Console.WriteLine("用户名不存在");
        }

去空格:Trim()

Trim()去掉字符串两端的空白(不会去掉中间的)。
例:去掉两边空格

        string s = "    ab  cd    ";
        Console.WriteLine(s.Length);
        s = s.Trim();//去掉两边的空格,不会去掉中间的
        Console.WriteLine(s.Length);
        Console.WriteLine(s);

忽略大小写比较

s1.Equals(s2, StringComparison.OrdinalIgnoreCase),两个字符串进行不区分大小写的比较。
例:两个字符串比较

        string s1 = "Admin";
        string s2 = "admin";
        Console.WriteLine(s1 == s2);
        Console.WriteLine(s1.ToLower() == s2.ToLower());
        //Ignore:忽略。Case:大小写(CaseSensitive:大小写敏感)
        Console.WriteLine(s1.Equals(s2, StringComparison.OrdinalIgnoreCase));

string s2 = string.Format("{0}年{1}月{2}日", year, month, day);
例: 用占位符、格式生成新的字符串

       // String.IsNullorEmpty()
        string s1=string.Format("我叫{0},我{1}岁","sun",100);
        Console.WriteLine(s1);

拼接string.Join("|", values)

拼接:string s1 = string.Join("|", values);//第一个参数是string类型分隔符
例:用"|"拼接字符串

        string [] value={"aa","bb","cc"};
        string s=string.Join ("|",value );//用分隔符拼接字符串数组
        Console.WriteLine(s);

string[] Split(): 分割字符串

string[] Split(params char[] separator):可以用可变参数

           string line = Console.ReadLine();//1,2,3,4,5,6
        string[] strs = line.Split(',', '|');//因为分隔结果可能是多个,所以string数组
        foreach (string str in strs)
        {
            Console.WriteLine(str);
        }

string[] Split(char[] separator, StringSplitOptions options)按char分割符分割,不能用可变参数,可以移除结果中的空白字符串,但不能去掉空格;

 string s="aaa,bbb,,cc,ddd,aaa,333,    90";
  //string [] strs=s.Split(',');
  //string[] strs = s.Split(',',',');
 char[] seps = {',', ',' };
   //移除空字符串
  //因为重载中StringSplitOptions放到最后,所以不能分隔符必须用chae[]传
   //不能用可变参数
  string[] strs = s.Split(seps,StringSplitOptions .RemoveEmptyEntries );
  foreach (string str in strs)
        {
            Console.WriteLine(str.Trim());//Trim去掉空格
        }

string[] Split(string[] separator, StringSplitOptions options)按照string分割符分割,移除空字符串,但不能移除空格。

        string s = "aaa|*bbb|*ccc";
        string[] seps = { "|*"};//new string[5];
        string[] seps = new string[] { "|*"};
        //没必要记住Split的这么多用法,用的时候能转到Split定义用起来就行
        string[] strs = s.Split(seps ,StringSplitOptions .RemoveEmptyEntries);
       string[] strs = s.Split(new string[] { "|*" }, StringSplitOptions.RemoveEmptyEntries);
        foreach (string str in strs)
        {
            Console.WriteLine(str.Trim());
        }

例子1:从日期字符串(“2008-08-08”)中分析出年、月、日;2008年08月08日

        string pDate = Console.ReadLine();
        string[] strs = pDate.Split ('-');
        string date = string.Format("{0}年{1}月{2}日", strs[0], strs[1], strs[2]);
        Console.WriteLine(date);
        Console.ReadKey();

例子2:从一个记录了学生成绩的文本文档,每个学生成绩是一行,每行是用|分割的数据,用|分割的域分别是姓名、年龄、成绩,写程序取出成绩最高学生的姓名和成绩。
参考:使用string[] lines = System.IO.File.ReadAllLines(@“c:\root.ini”, Encoding.Default);从文本文件读取数据,返回值为string数组,每个元素是一行。

string[] lines = System.IO.File.ReadAllLines(@"F:\root.txt",Encoding.Default);
        int score = 0;
        string name="";
        foreach (string line in lines )
         {
             string[] strs = line.Split('|');
             int chenji = int.Parse(strs[2]);
             if (chenji >score)
             {
                 score = int.Parse(strs[2]);
                 name = strs[0];
             }
        }
        Console.WriteLine("姓名:{0}   成绩:{1}",name,score);
        Console.ReadKey();

猜你喜欢

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