Golang——多种运算符及优先级
運算符:
- 很久以前,流傳程序=算法+數據這樣的說法。
- 算法是什么?通俗點說就是解決問題的過程。小到加法指令,大到成千上萬臺服務器組成的分布式計算集群。拋去抽象概念和宏觀架構,最終都由最基礎的機器指令過程去處理不同層次存儲設備里的數據。學習語言和設計架構不同,我們所關心的就是微觀層次,諸如語法規則所映射的機器指令, 以及數據存儲位置和格式等等。其中,運算符和表達式用來串聯數據和指令,算是最基礎 的算法。
- 另有一句話:硬件的方向是物理,軟件的結局是數學
全部運算符列表:
+ & += &= && == != ( ) - | -= |= || < <= [ ] * ^ *= ^= <- > >= { } / << /= <<= ++ = := , ; % >> %= >>= -- ! ... . :&^ &^=一元運算符優先級最高,二元則分成五個級別,從高往低分別是:
- 相同優先級的二元運算符,從左往右依次計算
- 一元運算符:運算中只有1個操作數參與,如:i++,i–
- 二元運算符:運算中只有2個操作數參與,如:+ - * / % a+b
沒有乘冪和絕對值運算符,對應的是標準庫math里的Pow、Abs函數實現。
二元運算符:
操作數類型必須相同,除非是無顯式類型聲明的常量,且該常量操作數會自動轉換為另一 操作數類型。當然,位移操作會有些不同
func main() {const i = 1 // 無顯式類型聲明的常量var j byte = 10b := i + j // v自動轉換為byte/uint8類型。fmt.Printf("%T, %v\n", b, b)const x float32 = 1.1d := x + i // v自動轉換為float32類型。fmt.Printf("%T, %v\n", d, d) }打印結果:
uint8, 11 float32, 2.1位移右操作數必須是無符號整數,或可以轉換的無顯式類型常量
func main() {i := 1 // i是有符號int類型。j := 2 << i // 無效操作:2 << i (2 << i 已評估但未使用)fmt.PrintLn(j) }如果是非常量位移表達式,那么會優先將無顯式類型的常量左操作數轉型
func main() {var i uint = 3j := 1.0 << 3 //常量表達式(包括常量展開)。fmt.Printf("%T,%v\n", j, j) // int, 8x := 1.0 << i // 無效操作:1 << i (shift of type float64)fmt.Printf("%T, %v\n", x, x) // 因為x沒有提供類型,那么編譯器通過1.0推斷,顯然無法對浮點數做位移操作。var y int32 = 1.0 << i //自動將1.0轉換為int32類型。fmt.Printf("%T, %v\n", y, y) // int32, 8 }位運算符:
二進制位運算符比較特別的就是bit clear,在其他語言里很少見到
AND 按位與:都為1 a & b 0101 & 0011 = 0001 OR 按位或:至少一個1 a | b 0101 | 0011 = 0111 XOR 按位亦或:只有一個1 a ^ b 0101 ^ 0011 = 0110 NOT 按位取反(一元) ^a ^0111 = 1000 AND 按位清除(bit clear) a &^ b 0110 &^ 1011 = 0100 LEFT SHIFT 位左移 a << 2 0001 << 3 = 1000 RIGHT SHIFT 位右移 a >> 2 1010 >> 2 = 0010位清除(and NOT)和位亦或(XOR)是不同的。它的右操作數作用類似位圖,將有標記的左操作數對應二進制位重置為0,以達到一次清除多個標記位的目的
const (read2 byte = 1 << iotawriteexecfreeze )func main() {a := read2 | write | freezeb := read2 | freeze | execc := a &^ b // 相當于a^ read ^ freeze,但不能包括execfmt.Printf("%04b &^ %04b = %04b\n", a, b, c) }打印結果:
1011 &^ 1101 = 0010算術運算符:
+:加
-:減
*:乘
/:除,取結果的商
%:取余,取結果的余數
整數操作只能得到整數,要想得到小數,必須有浮點數參與運算。/和%運算除數不能為0
演示:
func test2() {a := 1b := 2c := 0fmt.Println("a + b = ", a+b) //3fmt.Println("a - b = ", a-b) //-1fmt.Println("a * b = ", a*b) //2fmt.Println("a / b = ", a/b) //0fmt.Println("a % b = ", a%b) //1fmt.Println("a / c = ", a/c) //panic: runtime error: integer divide by zerofmt.Println("a % c = ", a%c) //panic: runtime error: integer divide by zero }字符+
兩邊都是數值時,+號是做加法運算,兩邊都是字符串時是做字符串拼接
char類型參與算術運算,使用的是計算機底層對應的十進制數值。
‘a’ --------- 97 a-z是連續的,'b’對應的值是98,'c’是99
‘A’ --------- 65 A-Z是連續的,'B’對應的值是66,'C’是67
‘0’ --------- 48 0-9是連續的,'1’對應的值是49,'2’是50
自增自減運算:
自增、自減運算符只能作為獨立語句,不能用于表達式。
表達式通常是求值代碼,可作為右值或參數使用。表達式可作為語句用,但語句卻不能當做表達式。
| ++ | 自增 | 變量的值加1 |
| - - | 自減 | 變量的值減1 |
++和-- 只能放在變量的后面使用,不支持放在前面
參與操作的時候,如果放在變量的后邊,先拿變量參與操作,后拿變量做++或者–。
最常見的用法:單獨使用。
賦值運算符:
作用:將一個表達式的值賦給左邊,左邊必須是可修改的,不能是常量。賦值運算符隱含了強制類型轉換。
| = | 普通賦值 | a=10,將10賦值給變量a |
| += | 加后賦值 | a+=b,將a+b的值給a |
| -= | 減后賦值 | a-=b,將a-b的值給a |
| *= | 乘后賦值 | a*=b,將a×b的值給a |
| /= | 除后賦值 | a/=b,將a÷b的商給a |
| %= | 取余后賦值 | a%=b,將a÷b的余數給a |
賦值運算符和算術運算符一起使用的時候,會優先計算算術運算符
var sum = 100sum += 5 //105sum /= 5 + 5 // sum = sum /(5=5)println(sum)關系運算符:
| == | a==b,判斷a和b的值是否相等,成立為true,不成立為false |
| != | a!=b,判斷a和b的值是否不相等,成立為true,不成立為false |
| > | a>b,判斷a是否大于b,成立為true,不成立為false |
| >= | a>=b,判斷a是否大于等于b,成立為true,不成立為false |
| < | a<b,判斷a是否小于b,成立為true,不成立為false |
| <= | a<=b,判斷a是否小于等于b,成立為true,不成立為false |
關系運算符的結果都是boolean類型,要么是true,要么是false。
不要把==寫成=,==是判斷是否相等,=是賦值
關系運算符和算術運算符、賦值運算符一起運算時的優先級是
算術運算符 > 關系運算符 > 賦值運算符
func test8() {num1 := 1num2 := 2sum := num1+3 > num2 // 先計算num1+3,再拿num1+3的結果和num2比較,最后賦值給sumfmt.Println("num1 == num2", num1 == num2) //falsefmt.Println("num1 != num2", num1 != num2) //truefmt.Println("num1 > num2", num1 > num2) //falsefmt.Println("num1 >= num2", num1 >= num2) //falsefmt.Println("num1 < num2", num1 < num2) //truefmt.Println("num1 <= num2", num1 <= num2) //truefmt.Println("sum = ", sum) //true }邏輯運算符:
邏輯運算符把各個運算的關系表達式連接起來組成一個復雜的邏輯表達式,以判斷程序中的表達式是否成立,判斷的結果是 true 或 false。
在邏輯與運算中,只要有一個表達式的值為false,那么結果就可以判定為false了,沒有必要將所有表達式的值都計算出來,短路與操作就有這樣的效果,可以提高效率。同理在邏輯或運算中,一旦發現值為true,右邊的表達式將不再參與運算。
- 短路與&&,如果左邊為真,右邊執行;如果左邊為假,右邊不執行。
- 短路或||,如果左邊為假,右邊執行;如果左邊為真,右邊不執行。
| ! | 邏輯非 | !a,結果和a的結果正好相反 |
| && | 短路與 | 作用和&相同,但是有短路效果 |
| || | 短路或 | 作用和|相同,但是有短路效果 |
運算符優先級:
優先級按照先后順序排序
| () | .().函數名用的 |
| ! 單目運算符 | 邏輯非 |
| &單目運算符 | 取地址用的 |
| */%雙目運算符 | 算術運算 |
| +-雙目運算符 | 算術運算 |
| &&雙目運算符 | 邏輯運算 |
| ||雙目運算符 | 邏輯運算 |
| =、+=、-=、*=、/=雙目運算符 | 賦值運算 |
總結
以上是生活随笔為你收集整理的Golang——多种运算符及优先级的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 认识API
- 下一篇: java中抓阄_如何进行抓阄