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
}