码迷,mamicode.com
首页 > 其他好文 > 详细

7.pointers

时间:2018-03-17 01:06:05      阅读:261      评论:0      收藏:0      [点我收藏+]

标签:...   long   data-   data   got   ocs   pos   upd   play   

// Sample program to show the basic concept of pass by value.
package main

func main() {
    // Declare variable of type int with a value of 10.
    count := 10

    // Display the "value of" and "address of" count.
    println("count:\tValue Of[", count, "]\tAddr Of[", &count, "]")

    // Pass the "value of" the count.
    increment(count)

    println("count:\tValue Of[", count, "]\tAddr Of[", &count, "]")

}

// increment declares count as a pointer variable whose value is
// always an address and points to values of type int.
//增量声明count作为一个指针变量,其值为。
//始终是一个地址,并指向int类型的值。

//go:noinline
func increment(inc int) {

    // Increment the "value of" inc.
    inc++
    println("inc:\tValue Of[", inc, "]\tAddr Of[", &inc, "]")
}

/*
count:  Value Of[ 10 ]  Addr Of[ 0xc420045f68 ]
inc:    Value Of[ 11 ]  Addr Of[ 0xc420045f58 ]
count:  Value Of[ 10 ]  Addr Of[ 0xc420045f68 ]
*/

Sharing data I

// Sample program to show the basic concept of using a pointer
// to share data.
package main

func main() {

    // Declare variable of type int with a value of 10.
    count := 10

    // Display the "value of" and "address of" count.
    println("1.count:\tValue Of[", count, "]\t\tAddr Of[", &count, "]")

    // Pass the "address of" count.
    increment(&count)

    println("3.count:\tValue Of[", count, "]\t\tAddr Of[", &count, "]")
}

// increment declares count as a pointer variable whose value is
// always an address and points to values of type int.
//go:noinline
func increment(inc *int) {

    // Increment the "value of" count that the "pointer points to".
    *inc++
    println("2.inc:\tValue Of[", inc, "]\tAddr Of[", &inc, "]\tValue Points To[", *inc, "]")
}

/*
1.count:    Value Of[ 10 ]      Addr Of[ 0xc420045f68 ]
2.inc:  Value Of[ 0xc420045f68 ]    Addr Of[ 0xc420045f58 ] Value Points To[ 11 ]
3.count:    Value Of[ 11 ]      Addr Of[ 0xc420045f68 ]
*/

Sharing data II

// Sample program to show the basic concept of using a pointer
// to share data.
//示例程序演示使用指针的基本概念。
//分享数据。
package main

import "fmt"

// user represents a user in the system.//用户代表系统中的用户。
type user struct {
    name   string
    email  string
    logins int
}

func main() {
    // Declare and initialize a variable named bill of type user.
    bill := user{
        name:  "Bill",
        email: "bill@ardanlabs.com",
    }

    //** We don‘t need to include all the fields when specifying field
    // names with a struct literal.

    // Pass the "address of" the bill value. 通过“地址”的票据价值。
    display(&bill)

    // Pass the "address of" the logins field from within the bill value.
    increment(&bill.logins)

    // Pass the "address of" the bill value.
    display(&bill)

}

// increment declares logins as a pointer variable whose value is
// always an address and points to values of type int.
func increment(logins *int) {
    *logins++
    fmt.Printf("&logins[%p] logins[%p] *logins[%d]\n", &logins, logins, *logins)
}

// display declares u as user pointer variable whose value is always an address
// and points to values of type user.
func display(u *user) {
    fmt.Printf("%p\t%+v\n", u, *u)
}

/* 
0xc42007a180    {name:Bill email:bill@ardanlabs.com logins:0}
&logins[0xc42000c030] logins[0xc42007a1a0] *logins[1]
0xc42007a180    {name:Bill email:bill@ardanlabs.com logins:1}

*/

Escape Analysis 溢出分析

//逸出分析
// Escape Analysis

// Escape Analysis Flaws:
// https://docs.google.com/document/d/1CxgUBPlx9iJzkz9JWkb6tIpTe5q32QDmz8l0BouG0Cw/view

// Sample program to teach the mechanics of escape analysis.
package main

// user represents a user in the system.
type user struct {
    name  string
    email string
}

// main is the entry point for the application.
func main() {
    u1 := createUserV1()
    u2 := createUserV2()

    println("u1", &u1, "u2", &u2)
    /*
        V1 0xc420045ef8
        V2 0xc42000a040
        u1 0xc420045f50 u2 0xc420045f48

    */
}

// createUserV1 creates a user value and passed
// a copy back to the caller.
//go:noinline
func createUserV1() user {
    u := user{
        name:  "Bill",
        email: "bill@ardanlabs.com",
    }

    println("V1", &u)

    return u
}

// createUserV2 creates a user value and shares
// the value with the caller.
//go:noinline
func createUserV2() *user {
    u := user{
        name:  "Bill",
        email: "bill@ardanlabs.com",
    }

    println("V2", &u)

    return &u
}

/*
// See escape analysis and inling decisions.
$ go build -gcflags "-m -m"
# github.com/ardanlabs/gotraining/topics/go/language/pointers/example4
./example4.go:27: cannot inline createUserV1: marked go:noinline
./example4.go:41: cannot inline createUserV2: marked go:noinline
./example4.go:17: cannot inline main: non-leaf function
./example4.go:33: createUserV1 &u does not escape
./example4.go:49: &u escapes to heap
./example4.go:49:   from ~r0 (return) at ./example4.go:49
./example4.go:45: moved to heap: u
./example4.go:47: createUserV2 &u does not escape
./example4.go:21: main &u1 does not escape
./example4.go:21: main &u2 does not escape
// See the intermediate assembly phase before
// generating the actual arch-specific assembly.
$ go build -gcflags -S
"".createUserV1 t=1 size=221 args=0x20 locals=0x38
    0x0000 00000 (github.com/ardanlabs/gotraining/.../example4.go:27)   TEXT    "".createUserV1(SB), $56-32
    0x0000 00000 (github.com/ardanlabs/gotraining/.../example4.go:27)   MOVQ    (TLS), CX
    0x0009 00009 (github.com/ardanlabs/gotraining/.../example4.go:27)   CMPQ    SP, 16(CX)
    0x000d 00013 (github.com/ardanlabs/gotraining/.../example4.go:27)   JLS 211
    0x0013 00019 (github.com/ardanlabs/gotraining/.../example4.go:27)   SUBQ    $56, SP
    0x0017 00023 (github.com/ardanlabs/gotraining/.../example4.go:27)   MOVQ    BP, 48(SP)
    0x001c 00028 (github.com/ardanlabs/gotraining/.../example4.go:27)   LEAQ    48(SP), BP
// See the actual machine representation by using
// the disasembler.
$ go tool objdump -s main.main example4
TEXT main.main(SB) github.com/ardanlabs/gotraining/topics/go/language/pointers/example4/example4.go
    example4.go:18  0x104bf31   e8ba000000      CALL main.createUserV1(SB)
    example4.go:18  0x104bf36   488b0424        MOVQ 0(SP), AX
    example4.go:18  0x104bf3a   488b4c2408      MOVQ 0x8(SP), CX
    example4.go:18  0x104bf3f   488b542410      MOVQ 0x10(SP), DX
    example4.go:18  0x104bf44   488b5c2418      MOVQ 0x18(SP), BX
    example4.go:18  0x104bf49   4889442428      MOVQ AX, 0x28(SP)
    example4.go:18  0x104bf4e   48894c2430      MOVQ CX, 0x30(SP)
    example4.go:18  0x104bf53   4889542438      MOVQ DX, 0x38(SP)
    example4.go:18  0x104bf58   48895c2440      MOVQ BX, 0x40(SP)
// See a list of the symbols in an artifact with
// annotations and size.
$ go tool nm example4
 104bff0 T main.createUserV1
 104c0d0 T main.createUserV2
 104c1e0 T main.init
 10b2940 B main.initdone.
 104bf10 T main.main
 106cf80 R main.statictmp_4
*/
// Sample program to show how stacks grow/change.
package main

// Number of elements to grow each stack frame.
// Run with 10 and then with 1024
const size = 1024

// main is the entry point for the application.
func main() {
    s := "HELLO"
    stackCopy(&s, 0, [size]int{})
}

// stackCopy recursively runs increasing the size
// of the stack.
func stackCopy(s *string, c int, a [size]int) {
    println(c, s, *s)

    c++
    if c == 10 {
        return
    }

    stackCopy(s, c, a)
}


/*
0 0xc420089f60 HELLO
1 0xc420089f60 HELLO
2 0xc420099f60 HELLO
3 0xc420099f60 HELLO
4 0xc420099f60 HELLO
5 0xc420099f60 HELLO
6 0xc4200b9f60 HELLO
7 0xc4200b9f60 HELLO
8 0xc4200b9f60 HELLO
9 0xc4200b9f60 HELLO
*/

练习

package main

import "fmt"

func main() {

    // Declare an integer variable with the value of 20.
    value := 20

    // Display the address of and value of the variable.
    fmt.Println("Address Of:", &value, "Value Of:", value)

    // Declare a pointer variable of type int. Assign the
    // address of the integer variable above.
    p := &value

    // Display the address of, value of and the value the pointer
    // points to.
    fmt.Println("Address Of:", &p, "Value Of:", p, "Points To:", *p)
}


/*
Address Of: 0xc4200140a0 Value Of: 20
Address Of: 0xc42000c030 Value Of: 0xc4200140a0 Points To: 20
*/
// Declare a struct type and create a value of this type. Declare a function
// that can change the value of some field in this struct type. Display the
// value before and after the call to your function.
package main

import "fmt"

// user represents a user in the system.
type user struct {
    name        string
    email       string
    accessLevel int
}

func main() {

    // Create a variable of type user and initialize each field.
    bill := user{
        name:        "Bill",
        email:       "bill@ardanlabs.com",
        accessLevel: 1,
    }

    // Display the value of the accessLevel field.
    fmt.Println("access:", bill.accessLevel)

    // Share the bill variable with the accessLevel function
    // along with a value to update the accessLevel field with.
    accessLevel(&bill, 10)

    // Display the value of the accessLevel field again.
    fmt.Println("access:", bill.accessLevel)
}

// accessLevel changes the value of the users access level.
func accessLevel(u *user, accessLevel int) {

    // Set of value of the accessLevel field to the value
    // that is passed in.
    u.accessLevel = accessLevel
}


/*
access: 1
access: 10
*/

7.pointers

标签:...   long   data-   data   got   ocs   pos   upd   play   

原文地址:https://www.cnblogs.com/zrdpy/p/8586930.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!