C#基础操作符详解
本節內容:
1.操作符概覽;
2.操作符的本質;
3.操作符與運算順序
4.操作符詳解。
?
1.操作符概覽:
?
?
?
操作符(Operator)也譯為”運算符”
操作符是用來操作數據的,被操作符操作的數據稱為操作數(Operand)
表格從上往下優先級遞減,同一行運算符的優先級一樣一般按從左到右算,
“=”賦值操作符,是先運算右邊的值再運算左邊的值,所以是最后運算的。
?
2.操作符的本質
①操作符的本質是函數(即算法)的”簡記法”
假如沒有發明”+”只有Add函數,算式3+4+5將可以寫成Add(Add(3,4),5)
假設沒有發明”*”只有Mul函數,那么算式3+4*5將只能寫成Add(3,Mul(4,5))
可見有操作符可讀性更強。
②操作符不能脫離與它關聯的數據類型(比如double數據類型的除法與int類型的除法相同數據結果不同)
可以說操作符就是與固定數據相關聯的一套基本算法的簡記法。
示例:為自定義的數據類型創建操作符。(格式為把方法名字改為”operator ?想要定義的操作符”如:”operator +”)如下例子進一步說明了C#里面的操作符就是方法,也就是函數的一個簡記法。
?
復制代碼
class Person{public string Name;//public static List<Person>GetMary(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.操作符與運算順序
①操作符的優先級
可以使用圓括號提高被括起來的表達式的優先級。
圓括號可以嵌套。
不像數學里面有方括號和花括號,在C#語法中”[]”與”{}”有專門的用途。
②同優先級操作符的運算順序
除了帶有賦值功能的操作符,同優先級操作符都是有左到右進行運算,
帶有賦值功能的操作符的運算順序是由右到左(比如賦值運算符”=”),
與數學運算不同,計算機語言的同優先級運算沒有”結合率”:
3+4+5只能理解為Add(Add(3,4),5)不能理解為Add(3,Add(4,5)。
?
4.1基本操作符
①(成員訪問操作符)”.”操作符(上表中寫為X.Y):四種功能;
*訪問命名空間當中的子集命名空間;
*訪問名稱空間當中的類型;
*訪問類型的靜態成員(靜態成員隸屬于類本身故用類可以訪問,而用類的對象不能訪問類的靜態成員);
*訪問對象的成員(包括數據成員和方法);
②方法調用操作符”()”即方法后面跟著的那對圓括號(上表寫為f(x))。
調用方法一定要加圓括號,但是:
Action myAction = new Action(c.PrintHello);//把PrintHello方法交給委托對象myAction管理
??myAction();//這樣在委托對象后面加個圓括號就相當于調用了被它管理的方法了,
這個時候PrintHello方法可以不帶圓括號。
③元素訪問操作符”[]”
???int[] myIntArray = new int[13];//創建int數組的實例13個元素
???int[] myIntArray2 = new int[]{1,2,3,4,5};//也可以在后面加花括號輸入相應值,這對或括號叫做"初始化器",[]里不寫數組大小會根據初始化器自動賦值...
???myIntArray[0]=2;//訪問的是第一個數組元素,訪問數組元素,[]里寫的是偏移量,從0開始。
?
Dictionary<string, Student> stuDic = new Dictionary<string, Student>();//一個類名后面,跟著一個尖括號表示這個類是泛型
????????????//泛型是不完整的類如Dictionary<string, Student>在尖括號里要說明索引的類型(string)與值的類型(Student)(順帶一提Dictionary是一個字典類型)
?
*總結元素訪問操作符”[]”里面放的是索引里面不一定是整數,如以下舉例。
復制代碼
1 class Program2 {3 static void Main(string[] args)4 {5 Dictionary<string, Student> stuDic = new Dictionary<string, Student>();//一個類名后面,跟著一個尖括號表示這個類是泛型6 //泛型是不完整的類如Dictionary<string, Student>在尖括號里要說明索引的類型(string)與值的類型(Student)(順帶一提Dictionary是一個字典類型)7 for (int i = 1; i < 100; i++)8 {9 Student stu = new Student(); 10 stu.Name = "s_" + i.ToString(); 11 stu.Score = 100+i; 12 stuDic.Add(stu.Name, stu);//把stu放進字典里面,所以為stu.Name,值為stu 13 } 14 Student number6 = stuDic["s_6"];//說明了[]里不一定是整數,而一定是索引 15 Console.WriteLine(number6.Score); 16 } 17 } 18 class Student 19 { 20 public string Name; 21 public int Score; 22 }?
④x--與x++:叫做后置的加加和后置的減減:
Int x=100; int y=x++;結果為x=101;y=100;因為x++是先賦值再進行自增;
--x與++x:叫做前置的加加和前置的減減:先進行自增或自減后進行賦值。
?
⑤typeof()操作符和default()操作符
*typeof操作符的作用為查看變量的種類:
Type t = typeof(int);
????????????Console.WriteLine(t.Namespace);
????????????Console.WriteLine(t.FullName);
????????????Console.WriteLine(t.Name);
*Default操作符使操作數取默認值:數值型為0,引用型為null,
??int x=default(int);//default操作的類型為結構體類型即數值類型時就返回內存塊當中為0的值:
??Console.WriteLine(x);
輸出為0;
??Form myForm = default(Form);//default操作數的類型為引用類型時就返回內存塊當中為0的值即為null
??Console.WriteLine(myForm==null);
輸出為true;
當為枚舉型enum時:?Level level=default(Level);
???????????? Console.WriteLine(level);
??enum Level
????{
????????Mid,
????????Low,
????????High
}
結果為Mid,如果把Mid的位置和Low互換則結果為Low,這是因為當default操作符遇到枚舉類型會把它當做數值型來處理,即第一個元素為0,后面的依次+1;
如果這樣寫:
enum Level
????{
????????Mid=1,
????????Low=0,
????????High=2
}則返回值為Low。當用default獲取枚舉值的時候要小心,如果這樣寫:
enum Level
????{
????????Mid=1,
????????Low=3,
????????High=2
}返回值為0,出錯了,所以在設置枚舉值時最好給元素一個0的整數值。
?
先說明:關鍵字var:幫助生成隱式類型變量:
?int x;//顯式變量,明確的告訴了編譯器x屬于什么數據類型;
?????????var y;//隱式變量,告訴編譯器y的類型暫時不知道,當我賦值的時候看著辦
C#是強類型語言變量一旦確定數據類型就不可以變更。
⑥new操作符:
*幫助我們在內存當中創建一個類型的實例并且立刻調用這個實例的實例構造器(所謂的構造函數),并取得的實例地址....
??new Form();//調用默認實例構造器
創建這個實例之后如果沒有任何變量去引用它,訪問它,過一會垃圾收集就把這個實例所占用的堆內存當做垃圾給收回來了。
*除了創建實例和調用實例構造器之外還能把new取得的實例地址通過賦值符號交給負責訪問這個實例的變量。這樣就在變量和實例之間構成了引用關系。有了這個引用關系之后就可以通過這個變量來訪問實例。如:?Form myForm=new Form();//調用默認實例構造器
??myForm.Text = "Hello!";//通過變量來訪問實例
?
*上面為主要功能,以下為附加功能:調用實例的初始化器:
??Form myForm = new Form() {Text="Hello!" };在實例后面加花括號里面加屬性的值。
可以初始化多個屬性,中間逗號隔開。
還有:有的時候用實例只是一次性的沒必要創建一個引用變量去初始化它,可以采用這時初始化器就發揮作用了:new Form(){Text=”Hello!”}.ShowDialog();只是由于沒有引用變量引用(沒有小孩牽著這個氣球,氣球一會就飛走了)所以一段時間后,垃圾回收器把它的堆內存回收。
a、錯覺:要創建類的實例就一定要使用new操作符,錯誤的。如string Name = "Hello!";
String是一個類,創建實例時不用new操作符,這種方式叫做C#的”語法糖衣”,原因為為了統一使string與int的書寫格式,而把string類的new操作符隱藏起來了,string可以用new但平常不這么用。類似的還有數組:
用new操作符:
int[] myArray = new int[10];//由于int的實例構造器有點特殊不用圓括號調用;
不用new操作符時:
?int[] myArray = { 1,2,3,4};
b、new操作符特殊用法:為匿名類型創建實例,
Form myForm=new Form(){Text=”Hello!”};當為非匿名類型創建實例時new后面要加類型名,
當為匿名類型創建實例時:如:
Var person=new {Name=”Mr li”,Age=34};//new操作符后面不跟類型,直接用初始化器初始化實例,什么類型?讓編譯器根據初始化內容自行判斷,不過該實例一定要有引用變量引用,不知道類型?用var隱式變量即可。那到底是什么類型呢?
Console.WriteLine(Person.GetType().Name);
輸出為:<>f__AnonymousType0`2
“<>f__AnonymousType”為約定的前綴,0表示我在程序中創建的第一個,’2表示這個類型為泛型類,構成這個類型的時候你需要兩個類型來構成它,哪兩個類型呢?就是初始化器里面的一個是string,一個是int。這是在創建匿名類型時編譯器自己識別的類型。
這里才真正體現出var類型(全部)功能的強大之處與重要性。因為如上一種情況就算你想寫出它的類型也不知道叫什么名字。
*記住new操作符與var隱式變量組合的使用方法:是為匿名對象創建對象并且用隱式類型變量來引用這個實例。
c、new操作符有危險性(功能強大伴隨的濫用風險)一旦在某個類里面(比如main函數隸屬的Program類)用new操作符創建了某個類的實例(比如在main函數中創建Form類),那么這個類(Form)就與主類(Program)緊緊耦合在一起,Pragram類就緊緊依賴于Form類,一旦某個類(Form)出現問題,整個耦合體都無法正常運行。即new操作符會造成緊耦合。那怎么解決?在軟件工程有項非常重要和實用的技術叫做”設計模式”,在”設計模式”當中有一種非常重要的模式叫做”依賴注入”(dependenty injection),該模式就是幫助我們把緊耦合變成相對松的耦合。有概念即可:new操作符有風險慎用,大型程序中為了避免有緊耦合的情況我們有一種叫做”依賴注入”的設計模式可以使用,實現不必關注。
*程序設計追求”高內聚低耦合”
d、new關鍵字的多用性(不是操作符而是關鍵字):如
class Student
????{
????????public void Report()
????????{
????????????Console.WriteLine("I'm a student");
????????}
????}
????class CsStudent:Student
????{
????????new?public void Report()//這叫子類對父類方法的隱藏,這里的new便不是操作符而是修飾符用來修飾new后面的方法的。(并不常見)
????????{
????????????Console.WriteLine("I'm a Cstudent");
????????}
}
則?Student stu = new Student();
????????????stu.Report();
????????????CsStudent csStu = new CsStudent();
????????????csStu.Report();時分別調用各自的Report()方法。
?
⑦checked()和unchecked()操作符:用來檢查()內的值在內存中是否有溢出:(Overflow)
C#是強類型語言,任何一個變量它在內存里面都有數據類型,而數據類型有個非常重要的作用就是表示這種數據類型的實例在內存當中能夠占多大的空間,一個值在內存空間所占的大小決定了這個值能夠表達的范圍,一旦超出這個范圍這個值就產生了溢出。Checked就是告訴我們要去檢出溢出,unchecked則告訴我們不用:
?uint x = uint.MaxValue;
????????????Console.WriteLine(x);
????????????string binStr = Convert.ToString(x, 2);
????????????Console.WriteLine(binStr);
????????????try
????????????{
????????????????uint y = checked(x + 1);//檢測x+1是否溢出,溢出后去catch捕獲異常
????????????????Console.WriteLine(y);
????????????}
????????????catch (OverflowException ex)
????????????{
????????????????Console.WriteLine("There is overflow");
????????????}
Unchecked()操作符表示不用檢查,C#中默認該種方式。Checked也有其他用法:
Checked
{
??try
????????????{
????????????????uint y = checked(x + 1);//檢測x+1是否溢出,溢出后去catch捕獲異常
????????????????Console.WriteLine(y);
????????????}
????????????catch (OverflowException ex)
????????????{
????????????????Console.WriteLine("There is overflow");
????????????}
}
直接判斷整個語句塊中所有語句是否有溢出。
?
⑧delegate操作符(關鍵字)最主要的作用為聲明一種叫委托的數據類型,委托是C#非常重要的概念。本節主要講其作為操作符的作用(非常稀有因為拉姆達表達式(Lambda Expressions)的出現就是來替代delegate當做操作符的場景):使用delegate生成匿名方法:
?this.myButton.Click +=delegate (object sender, RoutedEventArgs e)//使用delegate聲明了一個匿名方法
????????{
????????????this.myTextBox.Text = "Hello World!";
????????};
程序原本應為:this.myButton.Click += myButton_Click;
?void myButton_Click(object sender, RoutedEventArgs e)
????????{
????????????this.myTextBox.Text = "Hello World!";
????????}
現在替代這用用法的拉姆達表達式:
?this.myButton.Click += (sender, ?e)=>
????????{
????????????this.myTextBox.Text = "Hello World!";
????????};
語法的演變可見C#語法越來越簡潔,功能越來越強大。
?
⑨sizeof()操作符:
a、只能獲取結構體類型在內存中所占字節數,默認情況下:sizeof只能去獲取基本數據類型他們的實例在內存當中所占的字節數,基本數據類型:比如int、uint...說白了就是C#關鍵字里面那些除了string和object的數據類型:因為這兩個為引用類。
b、在非默認的情況下可以使用sizeof去獲取自定義的結構體類型的實例它在內存中占的字節數,但是需要把它放在不安全的上下文當中:
??unsafe
???{
????int x=sizeof(Student);
???}
Decimal數據類型精確度比double高占16個字節;
⑩最后一個”基本操作符”:”->”
*類(class)屬于引用類型,結構體(struct)屬于值類型。C#中有嚴格的規定像指針操作,取地址操作,用指針去訪問成員的操作,只能用來操作結構體類型,不能用它們去操作引用體類型。(Class)
要運行不安全代碼除了要把它放在unsafe{}里面,還要再項目->最后一項(相應項目屬性)->生成->勾選”允許生成不安全代碼”,所謂雙重保險。
使用該操作符時要在unsafe情況下使用:
unsafe
????????????{
????????????????Student stu;
????????????????stu.ID = 1;
????????????????stu.Score = 99;
????????????????Student*pStu=&stu;
????????????????pStu->Score = 100;
????????????????Console.WriteLine(stu.Score);
????????????}
?
4.2一元操作符:
只要有一個操作數跟在它后面就可以構成表達式,也叫單目操作符。
?
①&x和*x操作符(很少見有印象即可):
這兩個操作符同樣也需要在不安全的上下文中運行:&是取地址操作符。
簡單錯誤:*pStu.錯誤:由于.為基本操作符優先級大于*所以是先進行pStu.的操作正確應該為:(*pStu).即加個括號。
?
②+、-、!、~四個一元操作符:
-運算符可造成內存溢出:
int a = int.MinValue;
?int b =checked( -a);//原因在于int.MaxValue與int.MinValue絕對值不一樣。
?
~求反操作符,對操作數轉化為2進制,進行二進制的按位取反。
計算機取相反數的原理:先把該數轉化為2進制再按位取反+1?
!操作符只能用來操作布爾類型的數據,
?
③++x;--x運算符:單獨使用時x++與++x沒有區別。
?
4.3、強制類型轉化操作符:(T)x,T表示某種數據類型。
類型轉換:
①隱式(implicit)類型轉換,常見的為以下三種情況:
*不丟失精度的轉換:小字節數(存儲空間)的數據類型向多字節(存儲空間)的數據類型轉換不會丟失精度,比如金魚從魚缸里放到游泳池里還是好好的。例如:
??int x = int.MaxValue;
??long y = x;
這就是在不丟失精度的情況下進行的隱式類型轉換,具體哪些數據類型可向哪些無丟失精度類型轉換見C#語言定義文檔6.1.2:
隱式數值轉換為:(原則為從小的向大的轉)
l?從?sbyte?到?short、int、long、float、double?或?decimal。
l?從?byte?到?short、ushort、int、uint、long、ulong、float、double?或?decimal。
l?從?short?到?int、long、float、double?或?decimal。
l?從?ushort?到?int、uint、long、ulong、float、double?或?decimal。
l?從?int?到?long、float、double?或?decimal。
l?從?uint?到?long、ulong、float、double?或?decimal。
l?從?long?到?float、double?或?decimal。
l?從?ulong?到?float、double?或?decimal。
l?從?char?到?ushort、int、uint、long、ulong、float、double?或?decimal。
l?從?float?到?double。
從?int、uint、long?或?ulong?到?float?的轉換以及從?long?或?ulong?到?double?的轉換可能導致精度損失,但決不會影響數值大小。其他的隱式數值轉換決不會丟失任何信息。
不存在向?char?類型的隱式轉換,因此其他整型的值不會自動轉換為?char?類型。
?
*子類向父類的轉換;
例如定義三個互相繼承的類:
復制代碼
class Animal{public void Eat(){Console.WriteLine("Eat");}}class Human:Animal{public void Think(){Console.WriteLine("think");}}class Teacher:Human{public void Teach(){Console.WriteLine("Teach");}?
在main函數中:
?Teacher t = new Teacher();
????????????Human h = t;//這種就是子類向父類隱式類型換
而h.只能訪問Human類的成員,不能訪問Teacher類的成員,因為引用變量只能訪問它這個變量的類型它所具有的成員,注意是這個變量的類型是(Human)而不是這個變量引用的類型(Teacher)。(簡單的比喻比如人的父類是猴子,但猴子的只能做猴子的行為而不能做人類的行為。)
*裝箱;見上一節。
?
②顯式(explicit)類型轉換:為什么要有?因為這種轉換有精度的丟失,編譯器要你明明白白的寫出來,讓你知道有精度的丟失,也要轉換數據類型。
*有可能丟失精度(甚至發生錯誤)的轉換,即cast(鑄造):在數據前面加個圓括號:(T)x,T里面為強轉后的數據類型。
例如:
uint x = 65536;
ushort y = (ushort)x;//這樣才能成立,因為ushoort的最大值比x小
具體見語言定義文檔6.2.1;注意強制類型轉換時由有符號類型向無符號類型轉換,符號位拿來當數據了肯定會丟失精度。所以在對有符號類型進行強轉時要格外注意。
*拆箱
*使用Convert類:
首先:如下情況:
?string str1=Console.ReadLine();//ReadLine方法是讀取一行輸入
?string str2 = Console.ReadLine();
?Console.WriteLine( str1+str2);//
若輸入:12 12則輸出的是1212,原因為由于操作符與數據類型相關聯,當+識別到左右兩邊的數據都是string類型時則把兩個字符串連接起來,得到的就是1212的字符串而不是我們想要的值24。
正確做法為:?int x = Convert.ToInt32(str1);
????????????int y = Convert.ToInt32(str2);
這個例子就是非常常見的數據類型轉換例子。
?
有的數據類型不能使用cast這種方式如int和string這兩種數據類型差距太大。這時需要借助工具類(如Convert類)來進行類型轉換。如:?Convert.ToInt32(x);這個類相當于一個類型轉換樞紐,幾乎可以把當前數據類型轉換成全部想要的數據類型。
*ToString方法與各類數據類型的Parse/TryParse方法:
有時候我們需要把其他數據如int轉化為字符串類型數據這時候有兩種方法可以選擇:
第一種:調用Conver類的ToString靜態方法:?Convert.ToString(36種重載形式);詳見”強制類型轉換ToString”
第二種:調用數值類型數據的ToString實例(非靜態)方法來完成轉換:?x.ToString(3個重載);ToString方法但就是把實例轉化為一個字符串,創建一個Object對象:object o;o.會出現四個方法其中就有”ToString”說明所有的數據類型都有這個方法(一切數據類型都由object派生)
Parse(解析):這里的th1.Text和th2.Text都是字符串類型(string)
??double x = double.Parse(th1.Text);
????????????double y = double.Parse(th2.Text);
可以這樣改寫,小小的缺點:只能解析格式正確的數據如()里輸入1ab格式不對就不能自動解析并轉換為double類型。
這時可以使用TryParse方法:?double x = double.TryParse();
具體涉及內容以后會講。
?
③自定義數據類型轉換操作符
示例;*操作符的本質就是方法的簡記法
例如:創建了兩個類:
class Stone
????{
????????public int Age;
????}
????class Monkey
????{
????????public int Age;
}
在main函數中進行類型轉換:
Stone stone = new Stone();
Monkey m = (Monkey)stone;
顯然不行編譯器不知道給怎么轉換,我們要告訴它,由于是stone進行類型轉換所以在stone類里面添加具體語句:
class Stone
????{
????????public int Age;
????????public static explicit operator Monkey(Stone stone)//可以理解為顯式類型轉換操作符就是一個目標類型的實例的構造器,但是這個構造器不是寫在目標類型的類里面而是寫在被轉換的數據類型里面(而前面有四個操作符public static explicit operator ).
????????{
????????????Monkey m = new Monkey();
????????????m.Age = stone.Age / 500;//表示如何轉換
????????????return m;
????????}
????}
這樣編譯器就知道要怎么轉換了,繼續回到main函數:
?Stone stone = new Stone();
?stone.Age = 5000;
?Monkey m = (Monkey)stone;
?Console.WriteLine(m.Age);
按照stone類里面定義(m.Age = stone.Age / 500;)的對stone對象進行轉換,輸出為:10;
?
該方式為顯式轉換,隱式只需要:?public static implicit?operator Money(Stone stone)
即把?explicit改成implicit然后類型轉換時:?Money m = stone;可以把stone對象的前綴(Money)省略。
?
4.4、算術運算符:詳見語言定義文檔7.8.1
務必留意”類型提升”:算術運算符都會產生,默認的類型提升如int型的數據與double的數據相乘為了不丟失精度,int型先隱式轉換為double再進行計算。
“/“整數除法要注意除0異常,浮點數的除法沒有該異常。
?double a = double.PositiveInfinity;//正無窮大
?double b = double.NegativeInfinity;//負無窮大
?
double x=(double)5/4;
結果為浮點型的1.25因為()類型轉換操作符優先級大于算術運算符,所以先對5進行類型轉換為double再進行除法,除法過程中運算符發現兩邊類型不同進行”類型提升”
?
有時候取余操作符%也會進行”類型提升”,也有浮點數取余。
?
4.5、位移操作符:<<(左移)、>>(右移)
表示:數據在內存當中的2進制的結構向左或者向右進行一定位數的平移:
int x = 7;
int y = x << 1;//x左移一位
??string strx = Convert.ToString(x, 2).PadLeft(32, '0');
??string stry = Convert.ToString(y, 2).PadLeft(32, '0');
??Console.WriteLine(strx);
??Console.WriteLine(stry);
輸出顯示為:00000000000000000000000000000111
00000000000000000000000000001110明顯左移了一位
當沒有溢出的情況下左移就是×2右移就是÷2.
移位過多會產生溢出由于默認是unchecked所以不會有異常。
*左移無論是正負數補進來的都是0,右移如果操作的是正數最高位補進來的是0,負數則補1;
?
4.6、關系操作符<,>,<=,>=;
所有關系操作符的運算結果都是布爾類型的,除了可以比較數值類型還可以比較字符類型。
?char char1='a';
?char char2='A';
?ushort u1 = (ushort)char1;
?ushort u2 = (ushort)char2;結果為u1=97;u2=65,;(對應Unicode碼表)
還可以比較字符串,只能比是否相等。
string str1 = "ABc";
string str2 = "Abc";
Console.WriteLine(str1.ToLower()==str2.ToLower());都轉換為小寫輸出結果為相等。
還可以調用:?string.Compare();返回正值則第一個大于第二個,負值則小于,0則相等,比較方式為把兩個字符串對齊依次比較字母對應的Unicode碼。
?
4.7、類型檢驗操作符,is,as
is操作符結果是布爾類型,作用為檢驗某個對象是否為某個類(可以判斷分類):
Teacher t=new Teacher();
Var result=t is Teacher;
Var result=t is Animal;//由于Teacher的父類為Animal所以這個判斷也為true;反過來不行
as操作符的作用為:
Object o=new Teacher();
Teacher t=o as Teacher;即如果o對象是Teacher類則把o對象的地址交給Teacher類的引用變量t,否則把null值給t。
?
4.8、邏輯位與(&),邏輯位或(|),邏輯按位異或(^);
所謂位與就是按位求與,求與時把1當做真,0當做假,真&真為真,真&假為假,假&假為假。例如:
? 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);
輸出結果為:
00000000000000000000000000000111
00000000000000000000000000011100
00000000000000000000000000000100
按位或(|),真|真為真,假|真為真,假|假為假。
按位異或(^),兩位相同為真,不同為假。
?
4.9、條件與(&&),條件或(||):用來操作布爾類型的值,最后結果也是布爾類型的值。
條件與(&&):左右兩邊都是真,整體值才為真;條件或(||):左右兩邊有一個真整體即為真。
條件與(&)與條件或(|)具有短路效應:?if (x>y&&a++>3)當條件較多時條件與只要發現左邊的值為假則不用判斷右邊的值了直接返回false,條件或情況類似,如果左邊為真則直接返回true。
?*由于存在該效應我們寫代碼時要盡量避免。
?
4.10、null合并操作符(??):
?int ? y=null;//相當于暫時給y賦null值以后可變
?int c = y ?? 1;//判斷y是否為null是就用1賦值給y。
?
4.11、條件操作符:?:(是唯一一個可以接收三個數的操作符):就是if..else分支的簡寫:
?y = (x >= 60)?? 100 : 0;表示x如果>=60就把100賦值給y否則把0賦值給y,往往用圓括號把條件括起來提高可讀性。
?
4.12、(優先級最低)賦值表達式與lambda表達式:=,+=,%=,-=,>>=,<<=,&=,^=,|=
表示先運算再賦值,lambda表達式(=>)后面會講到。
不過都要注意數據類型,運算符會根據兩邊的數據類型來判斷進行的是整數運算還是浮點數運算還是其他。*賦值運算符的運算順序是從右到左。例如:
Int x=3;
Int y=4;
Int z=5;
Int a=x+=y+=Z;先算右邊的y+=z即y=y+z;...
多抽出1分鐘來學習,讓你的生命更加精彩!
總結
- 上一篇: 速度比肩移动SSD aigo U396
- 下一篇: Office Web Apps安装部署(