C#学习(6)操作符

操作符概览

操作符概览

操作符的本质

  • 操作符的本质是函数(即算法)的“简记法”
  • 操作符不能脱离与它关联的数据类型
    • 可以说操作符就是与固定数据类型相关联的一套基本算法的简记法
    • 实例:为自定义数据类型创建操作符
namespace Operator
{
    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 = person1 + person2;
            foreach (var p in nation)
            {
                Console.WriteLine(p.Name);
            }
        }
    }

    class Person
    {
        public string Name;

        public static List<Person>operator+(Person p1,Person p2)//operator自定义操作符
        {
            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;
        }
    }
}

优先级与运算顺序

  • 操作符的优先级
    • 可以使用圆括号提高被括起来表达式的优先级
    • 圆括号可以嵌套
    • 不像数学里有圆括号和花括号,在C#语言里“()”和“{}”有专门的用途
  • 同优先级操作符的运算顺序
    • 除了带有赋值功能的操作符,同优先级操作符都是由左向右进行运算
    • 带有赋值功能的操作符的运算顺序是由右向左
    • 与数学运算不同,计算机语言的同优先级运算没有“结合律”
      • 3+4+5只能理解为Add(Add(3,4),5) 不能理解为Add(3,Add(4,5))
typeof
namespace Operator
{
    class Program
    {
        static void Main(string[] args)
        {
            Type t = typeof(int);//typeof访问类型内部结构 
            Console.WriteLine(t.Namespace);
            Console.WriteLine(t.FullName);
            Console.WriteLine(t.Name);

            int c = t.GetMethods().Length;
            foreach (var m in t.GetMethods())
            {
                Console.WriteLine(m.Name);
            }

            Console.WriteLine(c);
        }
    }
}
default
namespace Operator
{
    class Program
    {
        static void Main(string[] args)
        {
            int x = default(int);//获取结构体类型int的默认值
            Console.WriteLine(x);//“0”

            Form myform = default(Form);//获取引用类型Form的默认值
            Console.WriteLine(myform);//“null”

            Level l = default(Level);//获取枚举类型Level的默认值
            Console.WriteLine(l);//赋值为0的“Low”
        }
    }

    enum Level
    {
        Low = 0,
        Mid = 1,
        High = 2
    }
}

new
namespace Operator
{
    class Program
    {
        static void Main(string[] args)
        {
           Form myform_1 = new Form();//使用new操作符创建一个Form类的实例,并创建实例构造器,还能得到实例的内存地址,
                                    //并且把该地址通过赋值符号交给访问这个实例的变量,平常使用同类型的引用变量来引用这个实例  

            myform_1.Text = "Hello";//这样就可以通过变量来访问实例

            //new操作符附加功能:调用实例的初始化器,直接为属性设置初始值
            Form myform_2 = new Form() { Text="Hello",FormBorderStyle=FormBorderStyle.SizableToolWindow};

            //如果对实例对象的访问是一次性的  则没有必要创建引用变量来引用这个实例。使用new操作符创建一个实例
            //并创建一个初始化器来初始化属性,然后用“.”来访问它的某一个方法,对象过一会就会被垃圾回收器回收
            new Form() { Text = "Hello" }.ShowDialog();

            //使用new操作符为匿名类型创建对象,并且用隐式类型变量来引用这个实例
            var person = new { Name = "Mr.Okay", Age = 1 };
            Console.WriteLine(person.Age);
            Console.WriteLine(person.Name);
            Console.WriteLine(person.GetType().Name);
        }
    }

}
checked&unchecked(检查值是否有溢出)
namespace Operator
{
    class Program
    {
        static void Main(string[] args)
        {
            uint x = uint.MaxValue;//unit最大值
            Console.WriteLine(x);
            String binstr = Convert.ToString(x, 2);//2进制值
            Console.WriteLine(binstr);
            try
            {
                uint y =checked(x + 1);//加1后检测是否溢出
                Console.WriteLine(y);//使用checked检测到则执行catch语句
                                     //若使用unchecked则打印结果为0
            }
            catch (OverflowException oe)
            {

                Console.WriteLine("There's Overflow");//若有溢出抛出提示
            }


            checked//checked作为修饰符的用法,花括号中所有内容会被检测
            {
                try
                {
                    uint y = x + 1;
                    Console.WriteLine(y);
                                         
                }
                catch (OverflowException oe)
                {

                    Console.WriteLine("There's Overflow");//若有溢出抛出提示
                }
            }
        }
    }

}

delegate(现多采用其关键字形式实现委托,操作符形式现用Lambda表达式代替)
sizeof
namespace Operator
{
    class Program
    {
        static void Main(string[] args)
        {
            int x = sizeof(double);//sizeof可查看结构体在内存中所占字节数
            Console.WriteLine(x);//double类型为8
        }
    }

}
->
namespace Operator
{
    class Program
    {
        static void Main(string[] args)
        {
            unsafe
            {
                Student stu;
                stu.ID = 1;
                stu.Score = 99;
                Student* pstu = &stu;//取stu的地址
                pstu->Score = 100;//使用“->”操作符间接访问对象
                Console.WriteLine(stu.Score);//使用“.”操作符可直接访问。打印结果为100
            }
        }
    }

    struct Student
    {
        public int ID;
        public long Score;
    }

}

- & ~
namespace Operator
{
    class Program
    {
        static void Main(string[] args)
        {
            int x = 12345678;
            int y = ~x;//“~”按位取反
            string xstr = Convert.ToString(x, 2).PadLeft(32, '0');//打印二进制数。xstr和ystr按位相反
            string ystr = Convert.ToString(y, 2).PadLeft(32, '0');
            Console.WriteLine(xstr);
            Console.WriteLine(ystr);

            int z = -x;
            Console.WriteLine(z);//相反数原理为按位取反再加1
        }
    }
}

!
namespace Operator
{
    class Program
    {
        static void Main(string[] args)
        {
            Student stu = new Student(null);
            Console.WriteLine(stu.Name);
        }
    }

    class Student
    {
        public string Name;
        public Student(string initName)
        {
            if (!string.IsNullOrEmpty(initName))//"!"操作符常用作非空检测
            {
                this.Name = initName;
            }
            else
            {
                throw new ArgumentException("initName cannot be null or empty");
            }
        }
    }
}

x++ & ++x
namespace Operator
{
    class Program
    {
        static void Main(string[] args)
        {
            int x = 100;
            int y = x++;
            //相当于
            //int y = x;
            //x = y + 1;
            //先赋值,再加
            Console.WriteLine(x);//101
            Console.WriteLine(y);//100

            int a = 100;
            int b = ++a;
            //相当于
            //a = a + 1;
            //int b = a;
            //先加,再赋值
            Console.WriteLine(a);//101
            Console.WriteLine(b);//100
        }
    }  
}

(T)x (类型转换)
namespace Operator
{
    class Program
    {
        static void Main(string[] args)
        {
            string str1 = Console.ReadLine();
            string str2 = Console.ReadLine();
            int x = Convert.ToInt32(str1);//string转int
            int y = Convert.ToInt32(str2);
            Console.WriteLine(x + y);
        }
    }  
}
  • 隐式类型转换
    • 不丢失精度的转换
namespace Operator
{
    class Program
    {
        static void Main(string[] args)
        {
            int x = int.MaxValue;
            long y = x;
        }
    }  
}

隐式数值转换

  • 子类向父类的转换
namespace Operator
{
    class Program
    {
        static void Main(string[] args)
        {
            Teacher t = new Teacher();
            Human h = t;//子类向父类的转换
            Animal a = h;
            //当使用h访问类成员方法时只能访问Eat()和Think()方法

            //因为C#语言规定:当你试图用引用变量访问一个实例从成员的时候,
            //只能访问到该变量的类型所具有的成员。因此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 Programming");
        }
    }
}
  • 装箱
  • 显式类型转换
    在这里插入图片描述
    • 有可能丢失精度(甚至发生错误)的转换,即cast
namespace Operator
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(ushort.MaxValue);//65535
            uint x = 65536;
            ushort y = (ushort)x;//将大数据存放进小容量的数据类型中会发生精度丢失(强类型转换)
            Console.WriteLine(y);//0
        }
    }     
}
  • 拆箱
  • 使用Convert类
  • ToString方法和各数据类型的Parse/Try Parse方法
namespace Operator
{
    class Program
    {
        static void Main(string[] args)
        {
            double score = 3;
            string str1 = "1";
            string str2 = "2";
            int x = Convert.ToInt32(str1);
            int y = Convert.ToInt32(str2);
            Console.WriteLine(x);//int 1
            Console.WriteLine(y);//int 2
            int result = x + y;
            string str = result.ToString();
            Console.WriteLine(str);//string"3"

            double d = double.Parse(str);//double 3
            Console.WriteLine(d);
            bool b = double.TryParse(str,out score);//bool true
            Console.WriteLine(b);
        }
    }     
}
  • 自定义类型转换操作符
    • 示例
namespace Operator
{
    class Program
    {
        static void Main(string[] args)
        {
            Stone stone = new Stone();
            stone.Age = 5000;
            Monkey wukongsun = (Monkey)stone;
            Console.WriteLine(wukongsun.Age);//10
        }
    }
    
    class Stone
    {
        public int Age;
        public static explicit operator Monkey(Stone stone)//自定义类型转换操作符(显式),
                                                           //隐式选用implicit关键字
        {
            Monkey m = new Monkey();
            m.Age = stone.Age / 500;
            return m;
        }
    }

    class Monkey
    {
        public int Age;
    }
}
>>(左移) & <<(右移)
namespace Operator
{
    class Program
    {
        static void Main(string[] args)
        {
            int x = 7;
            int y = x >> 2;//2进制左移两位
            string str1 = Convert.ToString(x, 2).PadLeft(32, '0');
            string str2 = Convert.ToString(y, 2).PadLeft(32, '0');
            Console.WriteLine(str1);
            Console.WriteLine(str2);
            Console.WriteLine(y);//左移几位相当于乘以2的几次方。打印结果"28"
                                 //右移几位相当于除以2的几次方        
        } 
    }
}

打印结果

is & as
namespace Operator
{
    class Program
    {
        static void Main(string[] args)
        {
            Object o = new Teacher();
            if (o is Teacher) //o是否为Teacher类
            {
                Teacher t = (Teacher)o;
                t.Teach(); 
            }

            Teacher t1 = o as Teacher;//o是否像Teacher  是的话把对象o的地址交给t1  不是的话返回空值null
            if (t1 != null)
            {
                t1.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 Programming");
        }
    }
}
&(逻辑与) |(逻辑或) ^(逻辑异或)
namespace Operator
{
    class Program
    {
        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);
        } 
    }
}

与

namespace Operator
{
    class Program
    {
        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);
        } 
    }
}

或

namespace Operator
{
    class Program
    {
        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);
        } 
    }
}

异或

&&(条件与) ||(条件或)
namespace Operator
{
    class Program
    {
        static void Main(string[] args)
        {
            int x = 1;
            int y = 2;
            int a = 3;
            int b = 4;
            if (x < y && a < b)//条件为真
            {
                Console.WriteLine("Hello");//执行
            }

            if (x < y || a > b)//条件为真
            {
                Console.WriteLine("Hello");//执行
            }
        } 
    }
}
??(null值和并操作符)
namespace Operator
{
    class Program
    {
        static void Main(string[] args)
        {
            int? x = null;//给int类型的x变量赋空值
            int y = x ?? 1;//判断若x为空值。则给y赋值1
            Console.WriteLine(y);    
        } 
    }
}
?:(条件)
namespace Operator
{
    class Program
    {
        static void Main(string[] args)
        {
            int x = 80;
            string str = string.Empty;//str初始化为空字符串
            str = x > 60 ? "Pass" : "Failed";//判断x是否大于60  真则输出Pass,假则输出Failed
            Console.WriteLine(str);
        } 
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值