高软 go语言 lab5

来源:互联网 发布:人类永生不死知乎 编辑:程序博客网 时间:2024/06/08 04:17

利用callback函数参数使Linktable的查询接口更加通用
C语言版本:
https://www.shiyanlou.com/courses/reports/1276044

go语言版本
知识点:

  • go语言的unsafe.Pointer类型指针(对应C语言的void指针,go里面没有void指针)
    用法:
void *args  //C语言声明void型指针argsargs unsafe.Pointer   //go语言声明unsafe.Pointer型指针args                               //这是个特殊指针类型,不用加*args *int     //go语言声明int型指针,注意与上面的区别
  • go语言的callback用法

下面将c和go的函数片段拿出来作对比

c语言:SearchLinkTableNode函数,用到了callback机制(Condition作为callback函数)

tLinkTableNode * SearchLinkTableNode(tLinkTable *pLinkTable, int Conditon(tLinkTableNode * pNode, void *args), void *args){    if(pLinkTable == NULL || Conditon == NULL)    {        return NULL;    }    tLinkTableNode * pNode = pLinkTable->pHead;    while(pNode != NULL)    {        if(Conditon(pNode, args) == SUCCESS)        {            return pNode;        }        pNode = pNode->pNext;    }    return NULL;}

go语言:SearchLinkTableNode(注意callback函数Condition的特殊声明方法)

func SearchLinkTableNode(pLinkTable *LinkTable, Condition func(pNode *LinkTableNode, args unsafe.Pointer) int, args unsafe.Pointer) *LinkTableNode {    if pLinkTable == nil || Condition == nil {        return nil    }    var pNode *LinkTableNode = pLinkTable.pHead    for pNode != nil {        if Condition(pNode, args) == SUCCESS {            return pNode        }        pNode = pNode.pNext    }    return nil}

C语言:FindCmd

tDataNode* FindCmd(tLinkTable * head, char * cmd){    return  (tDataNode*)SearchLinkTableNode(head,SearchCondition, (void*) cmd);}

Go语言:FindCmd

func findCmd(head *LinkTable, cmd *string) *DataNode {    return (*DataNode)(unsafe.Pointer(SearchLinkTableNode(head, SearchCondition, unsafe.Pointer(cmd))))}

附录:完整代码

linktable.go:

// linktablepackage mainimport (    "fmt"    "sync"    "unsafe")const SUCCESS = 0const FAILURE = -1type 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 SearchLinkTableNode(pLinkTable *LinkTable, Condition func(pNode *LinkTableNode, args unsafe.Pointer) int, args unsafe.Pointer) *LinkTableNode {    if pLinkTable == nil || Condition == nil {        return nil    }    var pNode *LinkTableNode = pLinkTable.pHead    for pNode != nil {        if Condition(pNode, args) == SUCCESS {            return pNode        }        pNode = pNode.pNext    }    return nil}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}

menuV2.8.go

// menu_v2.8package mainimport (    "fmt"    "math"    "os"    "strings"    "time"    "unsafe")type DataNode struct {    next    *DataNode    cmd     string    desc    string    handler func()}var head *LinkTable = nilfunc SearchCondition(pLinkTableNode *LinkTableNode, args unsafe.Pointer) int {    var cmd *string = (*string)(unsafe.Pointer(args))    var pNode *DataNode = (*DataNode)(unsafe.Pointer(pLinkTableNode))    if strings.Compare(pNode.cmd, *cmd) == 0 {        return SUCCESS    }    return FAILURE}func findCmd(head *LinkTable, cmd *string) *DataNode {    return (*DataNode)(unsafe.Pointer(SearchLinkTableNode(head, SearchCondition, unsafe.Pointer(cmd))))}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    var Pcmd *string    fmt.Println("Welcome!Use 'help' to get how to use this system.")    for true {        fmt.Println("input a cmd >")        fmt.Scanln(&cmd)        Pcmd = &cmd        var p *DataNode = findCmd(head, Pcmd)        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()        }    }}
原创粉丝点击