高软 go语言 lab4

c语言版本见这里:
https://www.shiyanlou.com/courses/reports/1275196

go语言版本:
知识点:
1.go语言互斥锁:
http://www.jb51.net/article/57335.htm

2.unsafe包类型强制转换:
http://www.open-open.com/lib/view/open1479110225641.html

分成两个文件:
menu_v2.5.go:

// menu_v2.5
package main

import (
    "fmt"
    "math"
    "os"
    "strings"
    "time"
    "unsafe"
)

type DataNode struct {
    next    *DataNode
    cmd     string
    desc    string
    handler func()
}

var head *LinkTable = nil

func findCmd(head *LinkTable, cmd string) *DataNode {
    var pNode *DataNode = (*DataNode)(unsafe.Pointer(getLinkTableHead(head)))
    for pNode != nil {
        if strings.Compare(pNode.cmd, cmd) == 0 {
            return pNode
        }
        pNode = (*DataNode)(unsafe.Pointer(getNextLinkTableNode(head, (*LinkTableNode)(unsafe.Pointer(pNode)))))
    }
    return nil
}

func ShowAllCmd(head *LinkTable) int {
    var pNode *DataNode = (*DataNode)(unsafe.Pointer(getLinkTableHead(head)))
    for pNode != nil {
        fmt.Println(pNode.cmd, "----", pNode.desc)
        pNode = (*DataNode)(unsafe.Pointer(getNextLinkTableNode(head, (*LinkTableNode)(unsafe.Pointer(pNode)))))
    }
    return SUCCESS
}

func help() {
    ShowAllCmd(head)
}

func add() {
    var a, b, c int
    fmt.Println("Please input two integer numbers:")
    fmt.Scanln(&a, &b)
    c = a + b
    fmt.Printf("The result of add cmd is:\n")
    fmt.Printf("%d + %d = %d\n", a, b, c)
}

func sub() {
    var a, b, c int
    fmt.Println("Please input two integer numbers:")
    fmt.Scanln(&a, &b)
    c = a - b
    fmt.Printf("The result of sub cmd is:\n")
    fmt.Printf("%d - %d = %d\n", a, b, c)
}

func mul() {
    var a, b, c int
    fmt.Println("Please input two integer numbers:")
    fmt.Scanln(&a, &b)
    c = a * b
    fmt.Printf("The result of mul cmd is:\n")
    fmt.Printf("%d * %d = %d\n", a, b, c)
}

func div() {
    var a, b, c int
    fmt.Println("Please input two integer numbers:")
    fmt.Scanln(&a, &b)
    c = a / b
    fmt.Printf("The result of div cmd is:\n")
    fmt.Printf("%d / %d = %d\n", a, b, c)
}

func pow() {
    var a, b, c float64
    fmt.Println("Please input two float64 numbers:")
    fmt.Scanln(&a, &b)
    c = math.Pow(a, b)
    fmt.Printf("The result of pow cmd is:\n")
    fmt.Printf("%.6f ^ %.6f = %.6f\n", a, b, c)
}

func sqrt() {
    var a, c float64
    fmt.Println("Please input a float64 numbers:")
    fmt.Scanln(&a)
    c = math.Sqrt(a)
    fmt.Printf("The result of sqrt cmd is:\n")
    fmt.Printf("sqrt(%.6f) = %.6f\n", a, c)
}

func showTime() {
    fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
}

func quit() {
    os.Exit(0)
}

func InitMenuData(ppLinkTable **LinkTable) int {
    *ppLinkTable = CreateLinkTable()
    var pNode *DataNode

    pNode = new(DataNode)
    pNode.cmd = "version"
    pNode.desc = "menu program v2.5"
    pNode.handler = nil
    AddLinkTableNode(*ppLinkTable, (*LinkTableNode)(unsafe.Pointer(pNode)))

    pNode = new(DataNode)
    pNode.cmd = "help"
    pNode.desc = "this is help cmd!"
    pNode.handler = help
    AddLinkTableNode(*ppLinkTable, (*LinkTableNode)(unsafe.Pointer(pNode)))

    pNode = new(DataNode)
    pNode.cmd = "add"
    pNode.desc = "this is add cmd!"
    pNode.handler = add
    AddLinkTableNode(*ppLinkTable, (*LinkTableNode)(unsafe.Pointer(pNode)))

    pNode = new(DataNode)
    pNode.cmd = "sub"
    pNode.desc = "this is sub cmd!"
    pNode.handler = sub
    AddLinkTableNode(*ppLinkTable, (*LinkTableNode)(unsafe.Pointer(pNode)))

    pNode = new(DataNode)
    pNode.cmd = "mul"
    pNode.desc = "this is mul cmd!"
    pNode.handler = mul
    AddLinkTableNode(*ppLinkTable, (*LinkTableNode)(unsafe.Pointer(pNode)))

    pNode = new(DataNode)
    pNode.cmd = "div"
    pNode.desc = "this is div cmd!"
    pNode.handler = div
    AddLinkTableNode(*ppLinkTable, (*LinkTableNode)(unsafe.Pointer(pNode)))

    pNode = new(DataNode)
    pNode.cmd = "pow"
    pNode.desc = "this is pow cmd!"
    pNode.handler = pow
    AddLinkTableNode(*ppLinkTable, (*LinkTableNode)(unsafe.Pointer(pNode)))

    pNode = new(DataNode)
    pNode.cmd = "sqrt"
    pNode.desc = "this is sqrt cmd!"
    pNode.handler = sqrt
    AddLinkTableNode(*ppLinkTable, (*LinkTableNode)(unsafe.Pointer(pNode)))

    pNode = new(DataNode)
    pNode.cmd = "time"
    pNode.desc = "this is showtime cmd!"
    pNode.handler = showTime
    AddLinkTableNode(*ppLinkTable, (*LinkTableNode)(unsafe.Pointer(pNode)))

    pNode = new(DataNode)
    pNode.cmd = "quit"
    pNode.desc = "this is quit cmd!"
    pNode.handler = quit
    AddLinkTableNode(*ppLinkTable, (*LinkTableNode)(unsafe.Pointer(pNode)))

    return SUCCESS
}

func main() {
    fmt.Println("Hello World!")
    InitMenuData(&head)
    var cmd string
    fmt.Println("Welcome!Use 'help' to get how to use this system.")
    for true {
        fmt.Println("input a cmd >")
        fmt.Scanln(&cmd)
        var p *DataNode = findCmd(head, cmd)
        if p == nil {
            fmt.Println("Wrong cmd!Use 'help' to get Menu List.")
            continue
        }
        fmt.Println(p.cmd, " ---- ", p.desc)
        if p.handler != nil {
            p.handler()
        }
    }
}

linktable.go:

// linktable
package main

import (
    "fmt"
    "sync"
)

const SUCCESS = 0
const FAILURE = -1

type LinkTableNode struct {
    pNext *LinkTableNode
}

type LinkTable struct {
    pHead     *LinkTableNode
    pTail     *LinkTableNode
    SumOfNode int
    mutex     sync.Mutex
}

func CreateLinkTable() *LinkTable {
    var pLinkTable *LinkTable = new(LinkTable)
    if pLinkTable == nil {
        return nil
    }
    pLinkTable.pHead = nil
    pLinkTable.pTail = nil
    pLinkTable.SumOfNode = 0
    return pLinkTable
}

func DeleteLinkTable(pLinkTable *LinkTable) int {
    if pLinkTable == nil {
        return FAILURE
    }
    for pLinkTable.pHead != nil {
        var p *LinkTableNode = pLinkTable.pHead
        pLinkTable.mutex.Lock()
        pLinkTable.pHead = p.pNext
        pLinkTable.SumOfNode--
        pLinkTable.mutex.Unlock()

    }
    pLinkTable.pHead = nil
    pLinkTable.pTail = nil
    pLinkTable.SumOfNode = 0
    return SUCCESS
}

func AddLinkTableNode(pLinkTable *LinkTable, pNode *LinkTableNode) int {
    if pLinkTable == nil || pNode == nil {
        return FAILURE
    }
    pLinkTable.mutex.Lock()
    if pLinkTable.pHead == nil && pLinkTable.pTail == nil {
        pLinkTable.pHead = pNode
        pLinkTable.pTail = pNode
        pLinkTable.pTail.pNext = nil
        pLinkTable.SumOfNode = 1
    } else {
        pLinkTable.pTail.pNext = pNode
        pLinkTable.pTail = pNode
        pLinkTable.pTail.pNext = nil
        pLinkTable.SumOfNode++
    }
    pLinkTable.mutex.Unlock()
    return SUCCESS
}

func DelLinkTableNode(pLinkTable *LinkTable, pNode *LinkTableNode) int {
    if pLinkTable == nil || pNode == nil {
        return FAILURE
    }
    pLinkTable.mutex.Lock()
    var pWork *LinkTableNode = pLinkTable.pHead
    var pre *LinkTableNode = pWork
    if pLinkTable.pHead == pNode {
        pLinkTable.pHead = pWork.pNext
        pLinkTable.SumOfNode--
        return SUCCESS
    }
    for pWork != nil {
        if pWork == pNode {
            pre.pNext = pWork.pNext
            pLinkTable.SumOfNode--
            return SUCCESS
        }
        pre = pWork
        pWork = pWork.pNext
    }
    return FAILURE
}

func getLinkTableHead(pLinkTable *LinkTable) *LinkTableNode {
    if pLinkTable == nil {
        fmt.Println("LinkTable is empty")
        return nil
    }
    return pLinkTable.pHead
}

func getNextLinkTableNode(pLinkTable *LinkTable, pNode *LinkTableNode) *LinkTableNode {
    if pLinkTable == nil || pNode == nil {
        fmt.Println("Linktable is empty")
        return nil
    }
    var pWork *LinkTableNode = pLinkTable.pHead
    for pWork != nil {
        if pWork == pNode {
            return pWork.pNext
        }
        pWork = pWork.pNext
    }
    return nil
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值