GO語言系列(二)- 基本數據類型和操做符

1、文件名 & 關鍵字 & 標識符

  • 1.全部go源碼以.go結尾golang

  • 2.標識符以字母或下劃線開頭,大小寫敏感數組

  • 3._是特殊標識符,用來忽略結果app

  • 4.保留關鍵字框架

2、Go程序的基本結構

package main

import "fmt"

func main() {
	fmt.Println("hello world")
}

 1. 任何一個代碼文件隸屬於一個包ide

 2.import 關鍵字,引用其餘包函數

import ("fmt")
import ("os")
一般習慣寫成
import (
"fmt"
"os"
)

 3.golang可執行程序,package main, 而且有且只有一個main入口函數性能

 4.包中函數調用ui

  a.同一個包中函數,直接調用this

  b.不一樣包中函數,經過包名+點+函數名進行調用spa

 5.包訪問控制權限

  a.大寫意味着這個函數/變量是可導出的

  b.小寫意味着這個函數/變量是私有的,包外部不能訪問

小練習

1. 寫一個程序,對給定一個數字n,求出全部兩兩相加等於n的組合

package main

import "fmt"

func list(n int) {
    for i := 0; i <= n; i++ {
        fmt.Printf("%d+%d=%d\n", i, n-i, n)
    }
}

func main() {
    list(10)
}

// go build -o bin/list.exe go_dev/day2/example1/main
練習1

2. 一個程序包含兩個包add和main,其中add包中有兩個變量:Name和age。請問main包中如何訪問Name和age?

package add

// 方式一
// var Name string = "hello world"
// var Age int = 10

// 方式一
// var Name string = "hello world"
// var Age int = 10

// 方式二
var Name string
var Age int

func Test() {
    Name = "hello wrold"
    Age = 20
}
add.go
package main

import (
    "fmt"
    "go_dev/day2/example2/add"
)

func main() {
    // 方式一 直接調用
    // fmt.Println("Name=", add.Name)
    // fmt.Println("Age=", add.Age)

    // 方式二 先調用函數
    add.Test()
    fmt.Println("Name=", add.Name)
    fmt.Println("Age=", add.Age)
}
main.go

3. 包別名的應用,開發一個程序,使用包別名來訪問包中的函數?

package main

import (
    "fmt"
    a "go_dev/day2/example2/add"
)

func main() {
    // 方式一 直接調用
    // fmt.Println("Name=", add.Name)
    // fmt.Println("Age=", add.Age)

    // 方式二 先調用函數
    // add.Test()
    // fmt.Println("Name=", add.Name)
    // fmt.Println("Age=", add.Age)

    // 包的別名
    a.Test()
    fmt.Println("Name=", a.Name)
    fmt.Println("Age=", a.Age)
}
main.go

4. 每一個源文件均可以包含一個init函數,這個init函數自動被go運行框架調用。開發一個程序演示這個功能?

package add

// 先執行全局變量,在執行init函數, 在執行main函數

// 方式一
// var Name string = "hello world"
// var Age int = 10

// 方式二
var Name string
var Age int

func Test() {
    Name = "hello wrold"
    Age = 20
}

func init() {
    Name = "hello wrold"
    Age = 20
}
add.go
package main

import (
    "fmt"
    // "go_dev/day2/example2/add"
    a "go_dev/day2/example2/add"
)

func main() {
    // 方式一 直接調用
    // fmt.Println("Name=", add.Name)
    // fmt.Println("Age=", add.Age)

    // 方式二 先調用函數
    // add.Test()
    // fmt.Println("Name=", add.Name)
    // fmt.Println("Age=", add.Age)

    // 包的別名
    // a.Test()
    // fmt.Println("Name=", a.Name)
    // fmt.Println("Age=", a.Age)

    // init
    fmt.Println("Name=", a.Name)
    fmt.Println("Age=", a.Age)
}
main.go

5. 包的只初始化,不引用。請開發一個程序,演示這個作法

package test

import "fmt"

var Name string = "hello world"
var Age int = 1000

func init() {
    fmt.Println("Name=", Name)
    fmt.Println("Age=", Age)

    Age = 10
    fmt.Println("Age=", Age)
    fmt.Println("this is a test....")
}
test.go
package add

import (
    _ "go_dev/day2/example2/test"
)
add.go

3、函數聲明和註釋

 1.函數聲明:func 函數名字(參數列表)(返回值列表){}

 2. 註釋,兩種註釋,單行註釋://和多行註釋 /* */

4、常量和變量

1. 常量

  • (1). changliang使用const修飾,表明永遠是隻讀的,不能修改
  • (2). const只能修飾boolean,number(int相關類型、浮點類型、complex)和string
  • (3). 語法:const identifier[type] = value,其中type能夠省略
  • (4). 比較優雅的寫法
const (
  a = 0
  b = 1
  c = 2   
)
  • (5). 更加專業的寫法
const (
  a = iota
  b   // 1
  c   // 2
)

練習

1. 定義兩個常量Man=1和Female=2,獲取當前時間的秒數,若是能被Female整除,則在終端打印female,不然打印man。Second := time.Now().Unix()

package main

import (
    "fmt"
    "time"
)

const (
    Man    = 1
    Female = 2
)

func main() {
    second := time.Now().Unix()
    if second%Female == 0 {
        fmt.Println("Female")
    } else {
        fmt.Println("Man")
    }
}
main.go

二、變量

 (1). 語法:var identifier type

例1

var a int
var b string
var c bool
var d int = 8
var e string = "hello world"

 例2

var (
a int   // 默認爲0
b string  // 默認爲「」
c bool   // 默認爲false
d  = 8
e  = "hello world"
)

 練習

1. 寫一個程序獲取當前運行的操做系統名稱和PATH環境環境變量的值,並打印在終端。

package main

import (
    "fmt"
    "os"
)

func get_os() {
    go_os := os.Getenv("GOOS")
    fmt.Printf("the operaing system is: %s\n", go_os)
    path := os.Getenv("PATH")
    fmt.Printf("Path is: %s\n", path)
}

func main() {
    get_os()
}
main.go

變量的做用域

  • 1.  在函數內部聲明的變量叫作局部變量,生命週期僅限於函數內部。

  • 2. 在函數外部聲明的變量叫作全局變量,生命週期做用於整個包,若是是大寫的,則做用於整個程序。

5、數據類型和操做符

1. 值類型和引用類型

  • 值類型:變量直接存儲值,內存一般在棧中分配

  • 引用類型:變量存儲的是一個地址,這個地址存儲最終的值。內存一般在堆上分配。經過GC回收。

值類型:基本數據類型int、float、bool、string以及數組和struct

引用類型:指針、slice、map、chan等都是引用類型。

練習:

  • 寫一個程序用來打印值類型和引用類型變量到終端,並觀察輸出結果
package main

import "fmt"

func main() {
	a := 5
	b := make(chan int, 1)

	fmt.Println("a=", a)
	fmt.Println("b=", b)

}

輸出
// a= 5
// b= 0xc00003a070
  • 寫一個程序,交換兩個整數的值。好比: a=3; b=4; 交換以後:a=4;b=3
package main

import "fmt"

var n int = 100

/*
賦值語句只能在函數中, 如下狀況都會報錯
var a int
a = 100
或者
a := 100
*/

func swap(a int, b int) {
    tmp := a
    a = b
    b = tmp
}

func swap1(a int, b int) (int, int) {
    return b, a
}

func swap2(a *int, b *int) {
    // 改變的是地址指向的那片內存的值
    tmp := *a
    *a = *b
    *b = tmp
}

func test() {
    // 類型轉換
    var a int8 = 100
    var b int16 = int16(a) //  賦值必須類型相同

    fmt.Printf("a=%d, b=%d", a, b)
}

func main() {
    first := 10
    second := 20

    // 方式一
    swap(first, second) // copy的是first和second的變量值

    fmt.Println("first=", first)
    fmt.Println("second=", second)

    // 方式二
    a, b := swap1(first, second)

    fmt.Println("a=", a)
    fmt.Println("b=", b)

    // 方式三
    c, d := second, first

    fmt.Println("c=", c)
    fmt.Println("d=", d)

    // 方式四
    swap2(&first, &second) // copy的是first和second的地址

    fmt.Println("first=", first)
    fmt.Println("second=", second)

    test()

}
交換a和b的四種方式

2. 數據類型和操做符

  • 數據類型

 (1) bool類型,只能存true或false

 (2) 相關操做符,!、&&、||

 (3) 數字類型,主要有int、int八、int1六、int3二、int6四、uint八、uint1六、uint3二、uint6四、float3二、float64

 (4) 類型轉換,type(variable),好比:var a int=8;  var b int32=int32(a)

 (5) 字符類型:var a byte = 'c'

 (6) 字符串類型:var str string = "hello world"

注:字符串表示兩種方式:

  1)「」    雙引號:支持轉義字符,如\n, \t, %%等等

  2)``   (反引號): 不支持轉義字符,內容按原樣輸出

  • 操做符

(1) 邏輯操做符:=、!=、<、<=、>和>=

(2) 數學操做復:+、-、*、/ 等等

練習

  • 使用math/rand生成10個隨機整數,10個小於100的隨機整數以及10個隨機浮點數?
package main

import (
    "fmt"
    "math/rand"
    "time"
)

func init() {
    rand.Seed(time.Now().Unix())
}

func main() {

    for i := 0; i < 10; i++ {
        a := rand.Int()
        fmt.Println(a)
    }

    for i := 0; i < 10; i++ {
        a := rand.Intn(100)
        fmt.Println(a)
    }

    for i := 0; i < 10; i++ {
        a := rand.Float32()
        fmt.Println(a)
    }
}
main.go
  • 字符串兩種表示方式
package main

import "fmt"

func main() {
    var str = "hello world\n"
    var str1 = `
        牀前明月光,
        疑是地上霜,
        舉頭望明月,
        低頭思故鄉。
    `
    var b byte = 'c'

    fmt.Println(str)
    fmt.Println(str1)
    fmt.Println(b)
    fmt.Printf("%c\n", b)
}

輸出:
hello world


        牀前明月光,
        疑是地上霜,
        舉頭望明月,
        低頭思故鄉。
    
99
c
字符串兩種表示方式
  • 字符串逆轉
package main

import "fmt"

func reverse(str string) string {
    var result string
    strlen := len(str)
    for i := 0; i < strlen; i++ {
        result = result + fmt.Sprintf("%c", str[strlen-i-1])
    }
    return result
}

func reverse1(str string) string {
    var result []byte
    tmp := []byte(str)
    length := len(str)
    for i := 0; i < length; i++ {
        result = append(result, tmp[length-i-1])
    }
    return string(result)
}

func main() {
    str1 := "hello"
    str2 := "world"

    // str3 := str1 + " " + str2
    str3 := fmt.Sprintf("%s %s", str1, str2)
    n := len(str3)

    fmt.Println(str3)
    fmt.Printf("len(str3)=%d\n", n)

    substr := str3[0:5]
    fmt.Println(substr)

    substr = str3[6:]
    fmt.Println(substr)

    result := reverse(str3)
    fmt.Println(result)

    result1 := reverse1(str3)
    fmt.Println(result1)
}
main.go

6、棧和堆

  • 棧是在棧內存中分配的,公用的,性能最高, 堆是在系統內存中分配的

  • 基本數據類型是在棧中存儲的 引用數據類型是在堆中存儲的

函數傳參:作了一個拷貝,若是參數爲變量值,則函數內部對變量作的操做不會影響實際變量的值。若傳的參數爲地址,則對地址指向變量的操做會影響實際變量的值。

package main

import "fmt"

func modify(a int) {
	a = 10
	return
}

func modify1(a *int) {
	*a = 10
}

func main() {
	a := 5
	b := make(chan int, 1)

	fmt.Println("a=", a)
	fmt.Println("b=", b)

	modify(a) // 作了一個拷貝, 不影響原來的值
	fmt.Println("a=", a)

	modify1(&a) // 參數傳了一個地址,對其指向的變量值進行操做會影響其地址指向的變量值
	fmt.Println("a=", a)
}

// 棧是在棧內存中分配的,公用的,性能最高, 堆是在系統內存中分配的
// 基本數據類型是在棧中存儲的 引用數據類型是在堆中存儲的

/*
a= 5
b= 0xc00008c000
a= 5
a= 10
*/

練習做業

  • 1. 判斷 101-200 之間有多少個素數,並輸出全部素數。注:定義:爲在大於1的天然數中,除了1和它自己之外再也不有其餘因數的數稱爲質數
  • 2. 打印出100-999中全部的「水仙花數」,所謂「水仙花數」是指一個三位數,其各位數字立方和等於該數自己。例如:153 是一個「水仙花數」,由於 153=1 的三次方+5 的三次方+3 的三次方。
  • 3. 對於一個數n,求n的階乘之和,即: 1! + 2! + 3!+…n!

參考

// 判斷 101-200 之間有多少個素數,並輸出全部素數。
package main

import (
    "fmt"
    "math"
)

func isPrime(n int) bool {
    sqrt_n := int(math.Sqrt(float64(n))) + 1
    for i := 2; i < sqrt_n; i++ {
        if n%i == 0 {
            return false
        }
    }
    return true
}

func main() {
    var n int
    var m int

    fmt.Printf("請輸入兩個數字:")
    fmt.Scanf("%d%d", &n, &m)

    for i := n; i < m; i++ {
        if isPrime(i) == true {
            fmt.Printf("%d\n", i)
        }
    }
}
做業一
/*
 打印出100-999中全部的「水仙花數」,所謂「水仙花數」是指一個三位數,其各位數字立方和等於該數自己。
例如:153 是一個「水仙花數」,由於 153=1 的三次方+5 的三次方+3 的三次方。
*/

package main

import (
    "fmt"
    "strconv"
)

func isShuixianhua(n int) bool {
    var i, j, k int
    i = n % 10
    j = (n / 10) % 10
    k = (n / 100) % 10
    sum := i*i*i + j*j*j + k*k*k
    return sum == n
}

func isShuixianhua2(n int) bool {
    var result = 0
    str := strconv.Itoa(n)
    for i := 0; i < len(str); i++ {
        num := int(str[i] - '0')
        result += (num * num * num)
    }
    number, err := strconv.Atoi(str)
    if err != nil {
        fmt.Printf("can not convert %s to int\n", str)
    }
    if result == number {
        return true
    }
    return false
}

func main() {
    var n int
    var m int

    fmt.Printf("請輸入兩個數字:")
    fmt.Scanf("%d,%d", &n, &m)

    for i := n; i <= m; i++ {
        if isShuixianhua(i) == true {
            fmt.Println(i)
        }
    }
}
做業二
// 對於一個數n,求n的階乘之和,即: 1! + 2! + 3!+…n!

package main

import "fmt"

func sum(n int) uint64 {
    var s uint64 = 1
    var sum uint64 = 0
    for i := 1; i <= n; i++ {
        s = s * uint64(i)
        fmt.Printf("%d!=%d\n", i, s)
        sum += s
    }
    return sum
}

func main() {
    var n int

    fmt.Printf("請輸入一個數字:")
    fmt.Scanf("%d", &n)

    s := sum(n)
    fmt.Println(s)
}
做業三
相關文章
相關標籤/搜索