C#语言入门详解笔记(5)—P10、P11、P12 操作符详解_1_2_3

14 篇文章 5 订阅

C#语言入门详解_哔哩哔哩_bilibiliC#语言入门详解搬运,随youtube上进度更新。刘老师的C#视频教程到30集就告一段落了,感谢刘老师在这5年间的付出。能上youtube的同学可以去刘老师的主页观看,https://www.youtube.com/channel/UCmvAggiJGwJGSzAtqFRBQ7g重新上传,修复31P无声音问题https://www.bilibili.com/video/BV1wx411K7rb目录

1、操作符概览

2、操作符的本质

2.1、操作符的本质是 函数(即算法)的“简记法”

2.2、操作符不能脱离与它关联的数据类型

3、优先级与运算顺序

3.1、操作符的优先级

3.2、同优先级操作符的运算顺序

 4、各类操作符的示例

4.1、基本操作符

(1)x.y:成员访问操作符

(2)f(x):方法调用操作符

(3)a[x]:元素访问操作符

(4) x++/x--:后置加/减

(5)new:创建实例并调用实例构造器

(6)typeof:查看类型内部结构

(7)default:获取类型默认值

(8)checked & unchecked : 检查 / 不检查 一个值在内存是否溢出

(9)delegate : 目前用于委托,后面讲

(10)sizeof: 获取一个对象在内存中所占字节数

(11)->: 指针操作,访问内存;只能访问结构体类型。

4.2、一元操作符,又叫单目操作符

(1)&x:取地址操作符,取出地址交给一个指针变量。*x:指针操作符

(2)+ - !~:正负非反;

(3)++x --x:前置的自增自减

(4)(T)x:强制类型转换

 4.3、 乘法运算符

(1)注意数值提升

(2)整除

(3)浮点除法

(4) %:取余操作符

 4.4、加减

(1)加减也会产生类型提升

(2)+:连接字符串

 4.5、位移操作符

(1)不产生溢出时,左移就是乘以2,右移是除以2

(2)左移太多,如果在check中会报错,overflow异常

(3) 左移补位是0,右移根据正负不同会不一样,正数补0,负数补1

4.6、关系和类型检测

(1)关系操作符

(2)is:类型检验操作符

(3)as:类型检验操作符

4.7、逻辑与、或、异或;条件与、或

(1)&:位与

(2)|:位或

(3)^:按位异或,两位不一样时才是真

 (4)&&:条件与

(5)||:条件或

(6) 条件与和或的短路效应

4.8、null合并??和条件操作符?:

(1)int?:int?可空类型

 (2)??:Null值合并

(3)?: :条件操作符

 ​

4.9、赋值和lamda表达式

(1)+=: 加法运算和赋值合并

(2)赋值操作符从右向左

5、类型转化

5.1、隐式(implicit)类型转换

5.2、显示(explicit)类型转换

5.3、自定义类型转化操作符


1、操作符概览

  •  操作符(Operator)也译为“运算符”
  • 操作符是用来操作数据的,被操作符操作的数据成为操作数(Operand)
  • 赋值操作符从右到左运算

2、操作符的本质

2.1、操作符的本质是 函数(即算法)的“简记法”

  • 假如没有发明“+”、只有Add函数,算式3+4+5将写成Add(Add(3,4),5)

  • 加入没有发明“×”、只有Mul函数,那么算式3+4×5将写成dd(3,Mul(4,5)),注意优先级

2.2、操作符不能脱离与它关联的数据类型

  •  可以说操作符就是与固定数据类型相关联的一套基本算法的简记法

  • 示例:为自定义数据类型创建操作符

    class Program
    {
        static void Main(string[] args)
        {
            Person person1 = new Person();
            Person person2 = new Person();
            person1.Name = "Deer";
            person2.Name = "Deer's wife";
            //List<Person> nation = Person.GetMarry(person1, person2);
            List<Person> nation = person1 + person2;
            foreach (var item in nation)
            {
                Console.WriteLine(item.Name);
            }
        }
    }    
    class Person
    {
        public string Name;

        //public static List<Person>GetMarry(Person p1,Person p2)
        public static List<Person> operator +(Person p1,Person p2)
        {
            List<Person> people = new List<Person>();
            people.Add(p1);
            people.Add(p2);
            for (int i = 0; i < 11; i++)
            {
                Person child = new Person();
                child.Name = p1.Name + "&" + p2.Name + "s child";
                people.Add(child);
            }

            return people;
        }
    }

3、优先级与运算顺序

3.1、操作符的优先级

  • 可以使用圆括号提高被括起来表达式的优先级

  • 圆括号可以嵌套

  • 不像数学里有方括号和花括号,在C#语言里“[]”与“{}”有专门的用途

3.2、同优先级操作符的运算顺序

  • 除了带有赋值功能的操作符,同优先级操作符从左到右运算
  • 带有赋值功能的操作符的运算顺序是从右到左
  • 与数字运算不同,计算机语言的同优先级运算没有“结合律”

3 + 4 + 5只能理解为Add(Add(3, 4), 5)不能理解为Add(3, Add(4, 5))

 4、各类操作符的示例

4.1、基本操作符

(1)x.y:成员访问操作符

名称空间.。访问外层名称空间的子集名称空间。访问名称空间中的类型。访问类型中的静态成员(还可以访问实例的成员)

(2)f(x):方法调用操作符

圆括号

并不是所有方法调用都需要圆括号,委托就不需要 

(3)a[x]:元素访问操作符

            int[] myIntArray = new int[] {1,2,3,4,5};//{}是初始化器
            Console.WriteLine(myIntArray[0]);
            Console.WriteLine(myIntArray[4]);
            Console.WriteLine(myIntArray[myIntArray.Length-1]);

方括号里面放索引,不一定是整数

    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<string, Student> stuDic = new Dictionary<string, Student>();
            for (int i = 0; i < 100; i++)
            {
                Student stu = new Student();
                stu.Name = "s_" + i.ToString();
                stu.Score = 100 + i;
                stuDic.Add(stu.Name, stu);
            }

            Student number6 = stuDic["s_6"];
            Console.WriteLine(number6.Score);
        }
    }
    class Student
    {
        public string Name;
        public int Score;
    }

(4) x++/x--:后置加/减

先赋值,再计算

(5)new:创建实例并调用实例构造器

  • new还可以调用初始化器

Form myForm = new Form(){ Text = "Hello!" };

new Form().ShowDialog();//可以执行,从左到右;

  • 语言糖衣:为简化操作,隐藏了new操作符 
string name = "Tim";//语言糖衣:为简化操作,隐藏了new操作符

  • new为匿名类型创建对象,var为隐式类型变量引用变量 
    class Program
    {
        static void Main(string[] args)
        {
            var person = new { Name = "Mr.Okay", Age = 34 };
            Console.WriteLine(person.Name);
            Console.WriteLine(person.Age);
            Console.WriteLine(person.GetType().Name);
        }
    }

 

  • new操作符使用时需要小心:紧耦合——当Form()类不存在时,Program也将运行失败;对于大型项目,可以采用“依赖注入”将紧耦合变成松耦合
    class Program
    {
        static void Main(string[] args)
        {
            var myForm = new Form();
        }
    }
  • 继承与隐藏

这里的new 是修饰符

(6)typeof:查看类型内部结构

    class Program
    {
        static void Main(string[] args)
        {
            Type t = typeof(int);
            Console.WriteLine(t.Namespace);
            Console.WriteLine(t.FullName);
            Console.WriteLine(t.Name);
            int c = t.GetMethods().Length;
            foreach (var mi in t.GetMethods())
            {
                Console.WriteLine(mi.Name);
            }
            Console.WriteLine(c);
        }
    }

(7)default:获取类型默认值

使用枚举类型时一定要给一个0对应的值

class Program
    {
        static void Main(string[] args)
        {
            double x = default(double);//值类型
            Console.WriteLine(x);//默认值是0

            Form myForm = default(Form);//引用类型
            Console.WriteLine(myForm==null);//默认值是null

            Level level = default(Level);//枚举类型
            Console.WriteLine(level);//默认值是第一个

            Level1 level1 = default(Level1);//枚举类型,显式赋值
            Console.WriteLine(level1);//默认值是Mid

            Level2 level2 = default(Level2);枚举类型,显式赋值,无0会出错
            Console.WriteLine(level2);//默认值是0
        }
    }
    enum Level
    {
        Low,
        Mid,
        High
    }
    enum Level1
    {
        Low = 2,
        Mid = 0,
        High = 1
    }
    enum Level2
    {
        Low = 2,
        Mid = 3,
        High = 1
    }

(8)checked & unchecked : 检查 / 不检查 一个值在内存是否溢出

  •  内存溢出演示
        static void Main(string[] args)
        {
            uint x = uint.MaxValue;
            Console.WriteLine(x);
            string binStr = Convert.ToString(x, 2);
            Console.WriteLine(binStr);
            uint y = x + 1;
            Console.WriteLine(y);
        }

  • 溢出提醒
        static void Main(string[] args)
        {
            uint x = uint.MaxValue;
            Console.WriteLine(x);
            string binStr = Convert.ToString(x, 2);
            Console.WriteLine(binStr);
            try
            {
                uint y = checked(x + 1);
                Console.WriteLine(y);
            }
            catch(OverflowException ex)
            {
                Console.WriteLine("There's overflow!");
            }

        }

另一种写法,语句块中的所有代码都将被检测。

            checked
            {
                try
                {
                    uint y = x + 1;
                    Console.WriteLine(y);
                }
                catch (OverflowException ex)
                {
                    Console.WriteLine("There's overflow!");
                }
            }

            unchecked
            {
                try
                {
                    uint y = x + 1;
                    Console.WriteLine(y);
                }
                catch (OverflowException ex)
                {
                    Console.WriteLine("There's overflow!");
                }
            }

(9)delegate : 目前用于委托,后面讲

  • 匿名方法语法,创建一个不能被调用的方法;过时的语法
    public partial class C____lesson : Window
    {
        public C____lesson()
        {
            InitializeComponent();
            this.myButton.Click += delegate (object sender, RoutedEventArgs e)
            {
                this.myTextBox.Text = "Hello, World!";
            };
        }
    }
  • 现在使用lamda表达式,更加方便
        public C____lesson()
        {
            InitializeComponent();
            this.myButton.Click += (sender, e) =>
            {
                this.myTextBox.Text = "Hello, World!";
            };
        }

(10)sizeof: 获取一个对象在内存中所占字节数

两个注意:

1.默认情况下,sizeof只能获取基本类型所占字节数,除了string和object(sizeof只能获取结构体数据类型)

        static void Main(string[] args)
        {
            int x = sizeof(double);
            Console.WriteLine(x);
        }

2.非默认情况下, sizeof可以获取自定义类型,但需要把它放在不安全的上下文中

P.S.为什么是16,这是高级话题,现在不先不讲

(11)->: 指针操作,访问内存;只能访问结构体类型。

        static void Main(string[] args)
        {
            unsafe
            {
                Student stu;
                stu.ID = 1;
                stu.Score = 99;
                Student* pStu = &stu;
                pStu->Score = 100;//通过指针访问并修改对象的值
                Console.WriteLine(stu.Score);
            }
        }

4.2、一元操作符,又叫单目操作符

(1)&x:取地址操作符,取出地址交给一个指针变量。*x:指针操作符

        static void Main(string[] args)
        {
            unsafe
            {
                Student stu;
                stu.ID = 1;
                stu.Score = 99;
                Student* pStu = &stu;
                pStu->Score = 100;
                (*pStu).Score = 1000;
                Console.WriteLine(stu.Score);
            }
        }

(2)+ - !~:正负非反;

  • 带符号的最大最小值会出问题

  • ~:按位取反

        static void Main(string[] args)
        {
            int x = 12345678;
            int y = ~x;//按位取反
            string xStr = Convert.ToString(x, 2).PadLeft(32, '0');
            string yStr = Convert.ToString(y, 2).PadLeft(32, '0');
            Console.WriteLine(xStr);
            Console.WriteLine(yStr);
        }

  • -:负号,按位取反再+1,所以以下例子得到相同结果

  • !:叹号,取非操作符,只能操作bool值
bool b1 = false;
bool b2 = !b1;
Console.WriteLine(b2);//True

(3)++x --x:前置的自增自减

  • 前置++/-- 是先自增/减 再赋值;后置++/-- 是先赋值,再自增/自减少 

(4)(T)x:强制类型转换

5.2节

 4.3、 乘法运算符

(1)注意数值提升

会根据参与运算的数值类型判断结果的数值类型;

如果用double乘以int类型,结果是double,这就是数值提升。

(2)整除

整数类型结果也是整数

被除数不能是0

(3)浮点除法

结果是浮点类型;

被除数可以是0,正数结果是infinity,正无穷大;负数结果是-infinity,负无穷大;

正无穷大 / 负无穷大 = NaN;

        static void Main(string[] args)
        {
            double x = (double)5 / 4;
            Console.WriteLine(x);

            double y = (double)(5 / 4);
            Console.WriteLine(y);
        }

浮点类型的1;

(4) %:取余操作符

 4.4、加减

(1)加减也会产生类型提升

(2)+:连接字符串

 4.5、位移操作符

(1)不产生溢出时,左移就是乘以2,右移是除以2

        static void Main(string[] args)
        {
            int x = 7;
            int y = x << 1;
            string strX = Convert.ToString(x, 2).PadLeft(32, '0');
            string strY = Convert.ToString(y, 2).PadLeft(32, '0');
            Console.WriteLine(strX);
            Console.WriteLine(strY);
            Console.WriteLine(y);
        }

(2)左移太多,如果在check中会报错,overflow异常

(3) 左移补位是0,右移根据正负不同会不一样,正数补0,负数补1

4.6、关系和类型检测

(1)关系操作符

        static void Main(string[] args)
        {
            int x = 5;
            double y = 4.0;
            var result = x > y;
            Console.WriteLine(result);
        }

  • != 
        static void Main(string[] args)
        {
            int x = 5;
            double y = 4.0;
            var result = x != y;
            Console.WriteLine(result);
        }

  •  字符比大小
        static void Main(string[] args)
        {
            char char1 = 'a';
            char char2 = 'A';
            var result = char1 > char2;
            Console.WriteLine(result);
            Console.WriteLine((ushort)char1);
            Console.WriteLine((ushort)char2);
        }

(2)is:类型检验操作符

结果是bool类型

(3)as:类型检验操作符

class Program   
    {
        static void Main(string[] args)
        {
            object o = new Teacher();
            Teacher t = o as Teacher;
            if(t != null)
            {
                t.Teach();
            }
        }
    }
    class Animal
    {
        public void Eat()
        {
            Console.WriteLine("Eating...");
        }
    }
    class Human : Animal
    {
        public void Think()
        {
            Console.WriteLine("Who I am");
        }
    }
    class Teacher : Human
    {
        public void Teach()
        {
            Console.WriteLine("I teach progamming.");
        }
    }

4.7、逻辑与、或、异或;条件与、或

(1)&:位与

        static void Main(string[] args)
        {
            int x = 7;
            int y = 28;
            int z = x & y;
            string strX = Convert.ToString(x, 2).PadLeft(32, '0');
            string strY = Convert.ToString(y, 2).PadLeft(32, '0');
            string strZ = Convert.ToString(z, 2).PadLeft(32, '0');
            Console.WriteLine(strX);
            Console.WriteLine(strY);
            Console.WriteLine(strZ);
        }

真 & 真 = 真;假 & 真 = 假; 真 & 假 = 假。 

(2)|:位或

        static void Main(string[] args)
        {
            int x = 7;
            int y = 28;
            int z = x | y;
            string strX = Convert.ToString(x, 2).PadLeft(32, '0');
            string strY = Convert.ToString(y, 2).PadLeft(32, '0');
            string strZ = Convert.ToString(z, 2).PadLeft(32, '0');
            Console.WriteLine(strX);
            Console.WriteLine(strY);
            Console.WriteLine(strZ);
        }

 假 & 真 = 真;真 & 真 = 真; 真 & 假 = 真。 

 

(3)^:按位异或,两位不一样时才是真

        static void Main(string[] args)
        {
            int x = 7;
            int y = 28;
            int z = x ^ y;
            string strX = Convert.ToString(x, 2).PadLeft(32, '0');
            string strY = Convert.ToString(y, 2).PadLeft(32, '0');
            string strZ = Convert.ToString(z, 2).PadLeft(32, '0');
            Console.WriteLine(strX);
            Console.WriteLine(strY);
            Console.WriteLine(strZ);
        }

 (4)&&:条件与

        static void Main(string[] args)
        {
            int x = 4;
            int y = 5;
            int a = 100;
            int b = 200;
            if (x<y && a<b)
            {
                Console.WriteLine("Hello");
            }
        }

(5)||:条件或

        static void Main(string[] args)
        {
            int x = 4;
            int y = 5;
            int a = 100;
            int b = 200;
            if (x>y || a<b)
            {
                Console.WriteLine("Hello");
            }
        }

(6) 条件与和或的短路效应

  •  条件与的短路

        static void Main(string[] args)
        {
            int x = 4;
            int y = 5;
            int a = 3;
            int b = 200;
            if (x>y && a++>3)
            {
                Console.WriteLine("Hello");
            }
            Console.WriteLine(a);
        }

 &&左边表达式为false时,右边表达式不会被执行。

  • 条件或也一样,如果左边时真,右边不会执行

4.8、null合并??和条件操作符?:

(1)int?:int?可空类型

        static void Main(string[] args)
        {
            //Nullable<int> x = null;//可空类型
            int? x = null;//和 Nullable一回事
            x = 100;
            Console.WriteLine(x);
        }

 (2)??:Null值合并

        static void Main(string[] args)
        {
            int? x = null;
            int y = x ?? 1;//如果x = null,则y为1
            Console.WriteLine(y);
        }

(3)?: :条件操作符

        static void Main(string[] args)
        {
            int x = 80;
            string str = (x >= 60) ? "Pass" : "Failed";
            Console.WriteLine(str);
        }

 

4.9、赋值和lamda表达式

(1)+=: 加法运算和赋值合并

(2)赋值操作符从右向左

5、类型转化

5.1、隐式(implicit)类型转换

例子:

    class Program
    {
        static void Main(string[] args)
        {
            Teacher t = new Teacher();
            Human h = t;
            Animal a = h;
            a.Eat();
        }
    }
    class Animal
    {
        public void Eat()
        {
            Console.WriteLine("Eating...");
        }
    }
    class Human : Animal
    {
        public void Think()
        {
            Console.WriteLine("Who I am");
        }
    }
    class Teacher : Human
    {
        public void Teach()
        {
            Console.WriteLine("I teach progamming.");
        }
    }
  • 装箱

5.2、显示(explicit)类型转换

  • 有可能丢失精度(甚至发生错误)的转换,即cast

  • (T)x:cast-铸造。
        static void Main(string[] args)
        {
            Console.WriteLine(ushort.MaxValue);
            uint x = 65536;
            ushort y = (ushort)x;
            Console.WriteLine(y);
        }

这个例子是把32位数据放入16位的空间里面,低16位放进去了,但是高16位舍弃 。

  • 有符号的转无符号时也要注意 
  • 拆箱

  • 使用Convert类

  • ToString方法与各数据类型的Parse/TryParse方法

  • 数值类型转string类型:应用场景——文本框显示数值

  •  Parse方法:只能解析格式正确的字符串

  • TryParse方法:解析成功返回true

5.3、自定义类型转化操作符

  • 示例

    class Program   
    {
        static void Main(string[] args)
        {
            Stone stone = new Stone();
            stone.Age = 5000;
            Monkey wuKong = (Monkey)stone;
            Console.WriteLine(wuKong.Age);
        }
    }
    class Stone
    {
        public int Age;

        public static explicit operator Monkey(Stone stone)//石头转化位猴子
        {
            Monkey m = new Monkey();
            m.Age = stone.Age / 500;
            return m;
        }
    }
    class Monkey
    {
        public int Age;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值