作為網路安全初學者,會遇到采用Go語言開發的惡意樣本,因此從今天開始從零講解Golang編程語言,一方面是督促自己不斷前行且學習新知識;另一方面是分享與讀者,希望大家一起進步,前文介紹了Golang的運算,包括算術運算、邏輯運算、賦值運算、位運算及編程練習,這篇文章將詳細講解順序控制陳述句和條件控制陳述句, 這系列文章入門部分將參考“尚硅谷”韓順平老師的視頻和書籍《GO高級編程》,詳見參考文獻,并結合作者多年的編程經驗進行學習和豐富,且看且珍惜吧!后續會結合網路安全進行GO語言實戰深入,加油~
這些年我學過各種編程語言,從最早的C語言到C++,再到C#、PHP、JAVA,再到IOS開發、Python,到最新的GO語言,學得是真的雜,有時候覺得編程語言恰恰是最簡單的,而通過一門編程語言能夠解決實際問題或深入底層才是其價值所在,并且當我們學好一門編程語言后,其他編程語言都非常類似,殊途同歸,學起來也很迅速,

原始碼下載地址:
- https://github.com/eastmountyxz/Go-learning
前文參考:
- [GO語言基礎] 一.為什么我要學習Golang以及GO語言入門普及
- [GO語言基礎] 二.編譯運行、語法規范、注釋轉義及API標準庫知識普及
- [GO語言基礎] 三.變數宣告、資料型別、識別符號及編程練習12題
- [GO語言基礎] 四.算術運算、邏輯運算、賦值運算、位運算及編程練習
- [GO語言基礎] 五.順序控制陳述句和條件控制陳述句(if、else、switch)
文章目錄
- 一.順序控制陳述句
- 二.條件控制陳述句
- 1.單分支控制
- 2.雙分支控制
- 3.多分支控制
- 4.嵌套分支
- 三.switch分支控制
- 四.編程練習
- 1.題目
- 2.答案
- 五.總結
在程式中,程式運行的流程控制決定程式是如何執行的,也是大家必須要掌握的,主要有三大流程控制陳述句,這篇文章先介紹前兩個流程控制,
- 順序控制
- 分支控制
- 回圈控制
一.順序控制陳述句
順序控制是指程式從上到下逐行地執行,中間沒有任何判斷和跳轉,其流程圖如下所示:

下面舉個簡單的案例說明,代碼中沒有判斷,程式按照默認的流程執行,即順序控制,
package main
import "fmt"
func main() {
//假如還有97天放假 問多少個星期多少天
var num int = 97
var week int
var day int
week = num / 7
day = num % 7
fmt.Printf("%d個星期零%d天 \n", week, day)
//定義一個變數保存華氏溫度 轉換成攝氏溫度
//攝氏溫度=5/9*(攝氏溫度-32)
var huashi float32 = 134.2
var sheshi float32
sheshi = 5.0 / 9 * (huashi - 32)
fmt.Printf("%v 對應的攝氏溫度=%v \n", huashi, sheshi)
}
輸出結果如下圖所示:

注意,Golang中定義變數時采用合法的前向參考,比如正確形式:
func main() {
var num1 int = 10 //宣告num1
var num2 int = num1 + 20 //使用num1
fmt.Println(num2)
}
錯誤形式:
func main() {
var num2 int = num1 + 20 //使用num1
var num1 int = 10 //宣告num1(x)
fmt.Println(num2)
}
二.條件控制陳述句
分支控制是讓程式有選擇執行,包括三種常見形式:
- 單分支
- 雙分支
- 多分支
1.單分支控制
基本語法如下:
if 條件運算式 {
執行代碼塊
}
說明:當條件運算式為True時,就會執行括號中的代碼塊, 注意{}是必須有的,即使只寫一行代碼,對應的流程圖如下所示:

案例分析:撰寫代碼實作輸入人的年齡,如果年齡大于18歲,則輸出“你的年齡大于18歲”,
package main
import "fmt"
func main() {
//輸入年齡
var age int
fmt.Println("請輸入年齡:")
fmt.Scanln(&age)
//單分支判斷
if age > 18 {
fmt.Println("你的年齡大于18歲")
}
}
輸出結果如下圖所示:

注意事項:
- 在golang中支持在if陳述句直接定義一個變數,如下所示:
if n := 20; n > 5 {
fmt.Println("定義變數的值數字大于5")
}
2.雙分支控制
基本語法如下:
if 條件運算式 {
執行代碼塊1
} else {
執行代碼塊2
}
說明:當條件運算式為True時,否則執行代碼塊2,注意{}是必須有的,即使只寫一行代碼, 對應的流程圖如下所示:

案例分析:撰寫代碼實作輸入人的年齡,如果年齡大于18歲,則輸出“你的年齡大于18歲”;否則輸出“你的年齡小于等于18歲”,
package main
import "fmt"
func main() {
//輸入年齡
var age int
fmt.Println("請輸入年齡:")
fmt.Scanln(&age)
//單分支判斷
if age > 18 {
fmt.Println("你的年齡大于18歲")
} else {
fmt.Println("你的年齡小于等于18歲")
}
}
輸出結果如下圖所示:

注意事項:
- 條件運算式是age > 18,執行代碼塊1和執行代碼塊2
- 雙分支只會執行其中一個分支
條件陳述句嵌套
案例:對下列代碼,若有輸出,指出輸出結果,
package main
import "fmt"
func main() {
var x int = 4
var y int = 1
//雙分支嵌套判斷
if (x > 2) {
if (y > 2) {
fmt.Println(x + y)
fmt.Println("執行陳述句:----a----")
}
fmt.Println("執行陳述句:----b----")
} else {
fmt.Println("x is", x, "y is", y)
fmt.Println("執行陳述句:----c----")
}
}
輸出結果如下圖所示:

條件判斷
- 宣告兩個int32型變數并復制,判斷兩個數之和,如果大于等于50輸出
- 宣告兩個float64型變數,判斷第一個數大于10.0,并且第二個數小于20.0輸出兩數之和
- 宣告兩個int32型變數,判斷兩者之和是否能被3又能被5整除,輸出資訊
package main
import "fmt"
func main() {
//判斷兩個數之和大于等于50
var n1 int32 = 10
var n2 int32 = 50
if n1 + n2 >= 50 {
fmt.Println("相加結果大于等于50")
}
//判斷第一個數大于10.0,并且第二個數小于20.0
var n3 float64 = 11.0
var n4 float64 = 17.0
if n3 > 10.0 && n4 < 20.0 {
fmt.Println("輸出兩數之和 =", (n3+n4))
}
//判斷兩者之和是否能被3又能被5整除
var n5 int32 = 10
var n6 int32 = 5
if (n5 + n6) % 3 == 0 && (n5 + n6) % 5 ==0 {
fmt.Println("能被3和5整除")
}
}
輸出結果如下圖所示:

錯誤案例1:編譯錯誤,缺少括號{}
- syntax error: unexpected newline, expecting { after if clause

錯誤案例2:編譯錯誤,else不能換行
- syntax error: unexpected else, expecting }

3.多分支控制
基本語法如下:
if 條件運算式1 {
執行代碼塊1
} else if 條件運算式2 {
執行代碼塊2
}
...
else {
執行代碼塊n
}
說明:
- 先判斷條件運算式1是否成立,如果為True,就執行代碼塊1
- 如果條件運算式1位False,就去判斷條件運算式2是否成立,如果條件運算式2成立,就執行代碼塊2
- 依次類推,如果所有的條件運算式不成立,就執行else陳述句塊
- else不是必須的
- 注意:多分支陳述句只能有一個執行入口
對應的流程圖如下所示:

案例分析:撰寫代碼實作考試成績判斷,如果成績大于等于90則為A,如果成績[80,90)則為B,依次類推不及格為E,
package main
import "fmt"
func main() {
//輸入變數
var score int
fmt.Println("請輸入成績:")
fmt.Scanln(&score)
//多分支判斷
if score >= 90 {
fmt.Println("該同學成績為A")
} else if score >=80 && score < 90 {
fmt.Println("該同學成績為B")
} else if score >=70 && score < 80 {
fmt.Println("該同學成績為C")
} else if score >=60 && score < 70 {
fmt.Println("該同學成績為D")
} else {
fmt.Println("該同學成績為E")
}
fmt.Printf("成績為:%d", score)
}
輸出結果如下圖所示:

注意事項:
- 初學者需要注意多分支陳述句的條件判斷,經常會陷入判斷融合的情況,比如下圖只會輸出“ok1”,

案例1:融合bool型別多分支判斷
package main
import "fmt"
func main() {
//多分支判斷
var b bool = true
if b == false {
fmt.Println("a")
} else if b {
fmt.Println("b")
} else if !b {
fmt.Println("c")
} else {
fmt.Println("d")
}
}
輸出結果為“b”,如果將第一個判斷修改成“b=false”是否能編譯通過呢?答案是否,它會提示編譯錯誤,因為if條件運算式不能是賦值陳述句,

案例2:輸入一個字符,判斷:
- 它是否為大寫字母,如果是轉換成小寫;
- 它是否為小寫字母,如果是轉換層大寫;
- 否則,輸出原字符
package main
import "fmt"
func main() {
var ch byte
var res byte
fmt.Println("請輸入字母:")
fmt.Scanf("%c", &ch)
//大小寫轉換
if ch >= 'A' && ch <= 'Z' {
res = ch + 32
} else if ch >= 'a' && ch <= 'z' {
res = ch - 32
} else {
res = ch
}
fmt.Printf("輸入字母:%c %v \n", ch, ch)
fmt.Printf("輸出結果:%c %v \n", res, res)
}
輸出結果如下圖所示,這道題目非常棒,希望大家熟練掌握,知識點包括:
- ASCII碼大小寫轉換方法
- 多分支條件陳述句
- char字符型變數輸入輸出

4.嵌套分支
在一個分支結果中又完整嵌套另一個完整的分支結構,里面的分支結構稱為內層分支,外面的分支結構稱為外層分支,基本語法如下:
if 條件運算式 {
if 條件運算式 {
陳述句塊
} else {
陳述句塊
}
....
}
注意事項:
- 嵌套分支不宜過多,建議控制在三層內
案例分析:
- 參加百米運動會,如果用時8秒以內進入決賽,否則提示淘汰;并且根據性別提示進入男子組或女子組,我們輸入成績和性別進行相關判斷,
package main
import "fmt"
func main() {
var sex string
var second float64
fmt.Println("請輸入秒數:")
fmt.Scanln(&second)
//嵌套分支
if second <=8 {
fmt.Println("請輸入性別:")
fmt.Scanln(&sex)
if sex == "男" {
fmt.Println("進入決賽的男子組")
} else if sex == "女" {
fmt.Println("進入決賽的女子組")
} else {
fmt.Println("性別輸入錯誤")
}
} else {
fmt.Println("淘汰未進入決賽")
}
}
輸出結果如圖所示:

三.switch分支控制
switch陳述句用于基于不同條件執行不同動作,每個case分支都是唯一的,從上往下逐一測驗,直到匹配為止,注意,匹配項后面不需要再加break,
基本語法如下:
switch 運算式 {
case 運算式1, 運算式2, ...:
陳述句塊1
case 運算式3, 運算式4, ...:
陳述句塊2
....
default:
陳述句塊n
}
對應的流程圖如下所示:
- switch的執行流程是先執行運算式,得到值,然后和case的運算式進行比較,如果相等,就匹配到;接著執行對應case的陳述句塊,然后退出switch控制,
- 如果switch運算式的值沒有和任何case的運算式匹配成功,則執行default的陳述句塊,執行后退出switch的控制,
- golang中的case后的運算式可以有多個,使用逗號間隔,
- golang中的case陳述句塊不需要寫break,因為默認會有,即在默認情況下,當程式執行完case陳述句塊后,就直接退出該switch控制結構,

下面簡單實作一個switch陳述句案例,請撰寫程式實作輸入某個字符,然后a表示周一,b表示周二,c表示周三,根據用戶的輸入依次顯示資訊,
package main
import "fmt"
func main() {
var key byte
fmt.Println("請輸入a到g的一個字符")
fmt.Scanf("%c", &key)
//switch陳述句
switch key {
case 'a':
fmt.Println("今天星期一")
case 'b':
fmt.Println("今天星期二")
case 'c':
fmt.Println("今天星期三")
case 'd':
fmt.Println("今天星期四")
case 'e':
fmt.Println("今天星期五")
case 'f':
fmt.Println("今天星期六")
case 'g':
fmt.Println("今天星期天")
default:
fmt.Println("輸入有誤....")
}
}
輸出結果如下圖所示:

注意事項:
(1) case和switch后是一個運算式,即常量值、變數、一個有回傳值的函式等

(2) case后的各個運算式值的資料型別,必須和switch的運算式資料型別一致

(3) case后面可以帶多個運算式,使用逗號間隔,如下圖所示:

(4) case后的運算式如果是常量值,則要求不能重復

(5) case后面不需要帶break,程式匹配到一個case后就會執行對應的代碼塊,然后退出switch,如果一個都匹配不到,則執行default
(6) default陳述句不是必須的
(7) switch后也可以不帶運算式,類似于if-else分支來使用;同時case中也可以對范圍進行判斷
package main
import "fmt"
func main() {
//switch后不接運算式 類似于if-else分支來使用
var age int = 10
switch {
case age == 10:
fmt.Println("年齡為10")
case age == 20:
fmt.Println("年齡為20")
default:
fmt.Println("沒有匹配到")
}
//case中也可以對范圍進行判斷
var score int = 90
switch {
case score > 90:
fmt.Println("成績優秀...")
case score >= 70 && score <= 90:
fmt.Println("成績良好...")
case score >=60 && score <70:
fmt.Println("成績及格...")
default:
fmt.Println("不及格")
}
}
(8) switch后也可以直接宣告定義變數,分好結束,但不推薦使用,

(9) switch穿透fallthrough,如果在case陳述句塊后增加fallthrough,則會繼續執行下一個case,也叫switch穿透,
package main
import "fmt"
func main() {
//switch穿透fallthrough
var age int = 10
switch age {
case 10:
fmt.Println("年齡為10")
fallthrough //默認只能穿透一層
case 20:
fmt.Println("年齡為20")
fallthrough
case 30:
fmt.Println("年齡為30")
default:
fmt.Println("沒有匹配到")
}
}
輸出結果如下圖所示:

(10) Type Switch,switch陳述句還可以被用于type-switch來判斷某個interface(介面)變數中實際指向的變數型別,后續文章會補充interface,
package main
import "fmt"
func main() {
//type-switch
var x interface{} //定義空介面
var y = 10.0
x = y
switch i := x.(type) {
case nil:
fmt.Printf("x的型別是:%T", i)
case int:
fmt.Printf("x是int型")
case float64:
fmt.Printf("x是float64型") //輸出結果
case func(int) float64:
fmt.Printf("x是func(int)型")
case bool, string:
fmt.Printf("x是bool或string型")
default:
fmt.Println("未知型別")
}
}
最后簡單總結switch和if的區別:
- 如果判斷的具體數值不多,而且符合整數、浮點數、字符、字串這幾種型別,建議使用switch陳述句,簡潔高效,
- 其他情況:對區間判斷和結果為bool型別的判斷使用if,并且if的使用范圍更廣,
- 作者個人習慣是使用if陳述句,很少用到switch陳述句,
四.編程練習
1.題目
(1) 判斷一個年份是否是閏年,閏年的條件是符合以下二者之一,
- 年份能被4整除,但不能被100整除
- 年份能被400整除
(2) 請分別使用if和switch陳述句實作成績判斷,輸出分數對應的等級,
- [100, 90] => A
- [80, 90) => B
- [70, 80) => C
- [60, 70) => D
- [0, 60) => E
(3) 根據淡旺季的月份和年齡,實作一個票價系統,
- 旺季:4-10月
成人(18-60歲):60
兒童(<18):半價
老人(>60):1/3 - 淡季
成人:40
其他:20
(4) 使用switch陳述句實作:根據用戶輸入月份,輸出對應春夏秋冬季節,
(5) 求ax^2+bx+c=0方程的根,a、b、c分別為函式的引數,如果b^2-4ac>0,則有兩個解;如果b^2-4ac=0,則有一個解;否則無解,
- 提示:x1=(-b+sqrt(b^2-4ac))/2a
- 提示:x2=(-b-sqrt(b^2-4ac))/2a
2.答案
(1) 判斷一個年份是否是閏年,閏年的條件是符合以下二者之一,
- 年份能被4整除,但不能被100整除
- 年份能被400整除
代碼如下:
package main
import "fmt"
func main() {
//判斷閏年
var year int
fmt.Println("請輸入年份:")
fmt.Scanln(&year)
if (year % 4 == 0 && year % 100 !=0) || year % 400 == 0 {
fmt.Println(year, "是閏年~")
} else {
fmt.Println(year, "不是閏年~")
}
}
輸出結果如下圖所示:

(2) 請分別使用if和switch陳述句實作成績判斷,輸出分數對應的等級,
- [100, 90] => A
- [80, 90) => B
- [70, 80) => C
- [60, 70) => D
- [0, 60) => E
代碼如下:
package main
import "fmt"
func main() {
var score int
fmt.Println("請輸入分數:")
fmt.Scanln(&score)
//if判斷
if score >= 90 {
fmt.Println("分數等級為A")
} else if score >= 80 && score < 90 {
fmt.Println("分數等級為B")
} else if score >= 70 && score < 80 {
fmt.Println("分數等級為C")
} else if score >= 60 && score < 70 {
fmt.Println("分數等級為D")
} else {
fmt.Println("不及格等級為E")
}
//switch判斷
switch {
case score > 90:
fmt.Println("分數等級為A")
case score >= 80 && score < 90:
fmt.Println("分數等級為B")
case score >=70 && score < 80:
fmt.Println("分數等級為C")
case score >=60 && score < 70:
fmt.Println("分數等級為D")
default:
fmt.Println("不及格等級為E")
}
}
輸出結果如下圖所示:

(3) 根據淡旺季的月份和年齡,實作一個票價系統,
- 旺季:4-10月
成人(18-60歲):60
兒童(<18):半價
老人(>60):1/3 - 淡季
成人:40
其他:20
代碼如下:
package main
import "fmt"
func main() {
//出票系統
var month byte
var age byte
var price float64 = 60.0
fmt.Println("請輸入游玩月份:")
fmt.Scanln(&month)
fmt.Println("請輸入游客年齡:")
fmt.Scanln(&age)
if month >= 4 && month <= 10 {
//旺季
if age > 60 {
fmt.Printf("%v月 票價 %v 年齡 %v \n", month, price / 3, age)
} else if age >= 18 {
fmt.Printf("%v月 票價 %v 年齡 %v \n", month, price, age)
} else {
fmt.Printf("%v月 票價 %v 年齡 %v \n", month, price / 2, age)
}
} else {
//淡季
if age >= 18 && age < 60 {
fmt.Println("淡季成人票價 40")
} else {
fmt.Println("淡季兒童和老人票價 20")
}
}
}
輸出結果如下圖所示:

(4) 使用switch陳述句實作:根據用戶輸入月份,輸出對應春夏秋冬季節,
代碼如下:
package main
import "fmt"
func main() {
//季節判斷
var month byte
fmt.Println("請輸入月份:")
fmt.Scanln(&month)
switch month {
case 3, 4, 5:
fmt.Println("Spring")
case 6, 7, 8:
fmt.Println("Summer")
case 9, 10, 11:
fmt.Println("Autumn")
case 12, 1, 2:
fmt.Println("Winter")
default:
fmt.Println("Error Input")
}
}
輸出結果如下圖所示:

(5) 求ax^2+bx+c=0方程的根,a、b、c分別為函式的引數,如果b^2-4ac>0,則有兩個解;如果b^2-4ac=0,則有一個解;否則無解,
- 提示:x1=(-b+sqrt(b^2-4ac))/2a
- 提示:x2=(-b-sqrt(b^2-4ac))/2a
注意,需要引入math.Sqrt(num)即可求平方根
package main
import "fmt"
import "math"
func main() {
/*
分析思路
1) a,b,c是給出的變數
2) 使用給出的數學公式和多分支陳述句計算
3) 匯入math包計算平方根
*/
var a float64
var b float64
var c float64
fmt.Println("請輸入abc三個變數")
fmt.Scanf("%f %f %f", &a, &b, &c)
fmt.Printf("a=%v b=%v c=%v \n", a, b, c)
m := b * b - 4 * a * c
if m > 0 {
x1 := (-b + math.Sqrt(m)) / (2 * a)
x2 := (-b - math.Sqrt(m)) / (2 * a)
fmt.Printf("x1=%v x2=%v", x1, x2)
} else if m == 0 {
x1 := (-b + math.Sqrt(m)) / (2 * a)
fmt.Printf("x1=%v", x1)
} else {
fmt.Printf("無解")
}
}
輸出結果如下圖所示:

五.總結
寫到這里,這篇基礎性Golang文章介紹完畢,希望您喜歡!祝大家新年快樂,牛氣沖天,也希望自己能分享更優秀、更深入的文章,
- 一.順序控制陳述句
- 二.條件控制陳述句
1.單分支控制
2.雙分支控制
3.多分支控制
4.嵌套分支 - 三.switch分支控制
- 四.編程練習
1.題目
2.答案
Go基本運算和進制轉換了解后,后面的文章將詳細介紹Go語言的條件陳述句和回圈陳述句知識,并結合案例進行普及,希望這篇基礎性文章對您有幫助,寫得不好的地方還請海涵,同時非常感謝參考文獻中的大佬們的文章分享,尤其是韓順平老師,深知自己很菜,得努力前行,也希望自己能深入下去,未來四年好好研究Go編程語言,做更多實際工程,寫更好的文章,共勉!
源代碼下載地址:
- https://github.com/eastmountyxz/Go-learning
2020年在github的綠瓷磚終于貼完了第一年提交2100余次,獲得1500多+stars,開源93個倉庫,300個粉絲,挺開心的,希望自己能堅持在github打卡五年,督促自己不斷前行,簡單總結下,最滿意的資源是YQ爆發時,去年2月分享的輿情分析和情感分析,用這系列有溫度的代碼為武漢加油;最高贊的是Python影像識別系列,也獲得了第一位來自國外開發者的貢獻補充;最花時間的是Wannacry逆向系列,花了我兩月逆向分析,幾乎成為了全網最詳細的該蠕蟲分析;還有AI系列、知識圖譜實戰、CVE復現、APT報告等等,當然也存在很多不足之處,希望來年分享更高質量的資源,也希望能將安全和AI頂會論文系列總結進來,真誠的希望它們能幫助到大家,感恩有你,一起加油~

2020年8月18新開的“娜璋AI安全之家”,主要圍繞Python大資料分析、網路空間安全、人工智能、Web滲透及攻防技術進行講解,同時分享論文的演算法實作,娜璋之家會更加系統,并重構作者的所有文章,從零講解Python和安全,寫了近十年文章,真心想把自己所學所感所做分享出來,還請各位多多指教,真誠邀請您的關注!謝謝,

(By:娜璋AI之家 Eastmount 2021-02-16 星期二 夜于貴陽 https://blog.csdn.net/Eastmount)
參考文獻:
- Go官網:https://golang.org/
- 韓老師視頻:https://www.bilibili.com/video/BV1pt41127FZ
- https://www.runoob.com/go/go-tutorial.html
- Go中文網在線標準庫檔案:https://studygolang.com/pkgdoc
- 《C程式設計》譚浩強老師
- 《GO高級編程》
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/260337.html
標籤:其他
