golang指標與C指標的異同

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

總結一下golang中的指標與C語言的指標的用法。

總體一致: 

C的代碼:
int *number;number = (int *) malloc(sizeof(int));*number = 3;printf("%d\n", *number);
golang的代碼:
var pointer *int;pointer = new(int);*pointer = 3;fmt.Println(*pointer);

多重指標情況:

C的代碼:

    int **outer;    int *inter;    inter = (int *) malloc(sizeof(int));    *inter = 3;    outer = &inter;    //地址一樣    printf("%p\n", inter);    printf("%p\n", *outer);    //值一樣    printf("%d\n", *inter);    printf("%d\n", **outer);


golang的代碼:
    var outer **int;    var inter *int;    inter = new(int);    *inter = 3;    outer = &inter;    //地址一樣    fmt.Println(inter);    fmt.Println(*outer);    //值一樣    fmt.Println(*inter);    fmt.Println(**outer);


C語言的下面這種方式在golang裡實現:
int **outer;    int *inter;    inter = (int *) malloc(sizeof(int));    outer = (int **) malloc(sizeof(int));       *inter = 3;    *outer = inter;    //地址一樣    printf("%p\n", inter);    printf("%p\n", *outer);    //值一樣    printf("%d\n", *inter);    printf("%d\n", **outer);
在golang中:    
var inter *int;    var outer **int;    inter = new(int);    *inter = 3;    outer = new(*int);    *outer = inter;    //地址一樣    fmt.Println(inter);    fmt.Println(*outer);    //值一樣    fmt.Println(*inter);    fmt.Println(**outer);

上面都是在玩指標, 下面看看基本的資料結構.

基本的資料結構有: 數組與結構體 (map和樹之類的不在討論範圍)
golang中的數組與C中的數組有很大的差別
golang中的數組是這樣說的: Arrays are values, not implicit pointers as in C.

0. 數組做參數時, 需要被檢查長度.
1. 變數名不等於數組開始指標!

2. 不支援C中的*(ar + sizeof(int))方式的指標移動. 需要使用到unsafe包
3. 如果p2array為指向數組的指標, *p2array不等於p2array[0]

例子0   數組做參數時, 需要被檢查長度.
func use_array( args [4]int ){    args[1] = 100;}func main() {    var args = [5]int{1, 2, 3, 4, 5};    use_array(args);    fmt.Println(args);}

編譯出錯: cannot use args (type [5]int) as type [4]int in function argument, 需要有長度上的檢查

例子1   變數名不等於數組開始指標!

func use_array( args [4]int ){    args[1] = 100;}func main() {    var args = [5]int{1, 2, 3, 4, 5};    use_array(args);    fmt.Println(args);}


輸出結果是 [1 2 3 4], 沒有儲存結果, 數組名的用法與C的不一樣. 在golang裡是這樣的:
// 又長度檢查, 也為地址傳參func use_array( args *[4]int ){    args[1] = 100;  //但是使用還是和C一致, 不需要別加"*"操作符}            func main() {            var args = [4]int{1, 2, 3, 4};    use_array(&args); //數組名已經不是表示地址了, 需要使用"&"得到地址    fmt.Println(args);}

例子2   如果p2array為指向數組的指標, *p2array不等於p2array[0]

對比一下C和golang在這方面的差別:
void main(int argc, char *argv[]){    int *p2array;    p2array = (int *) malloc(sizeof(int) * 3);    //等於p2array[0]    *p2array = 0;    printf("%d\n", *p2array + 1);}* 輸出為1
func main() {    var p2array *[3]int ;    p2array = new([3]int);    fmt.Printf("%x\n", *p2array + 1); //不管p2array是指標變數還是陣列變數, 都只能使用"[]"方式使用}* 報錯.

golang中的結構體也與C中的有差別

下面的方式是相當一致的:

C版本的:

typedef struct    {          int x;        int y;    } Point;    Point p;    p.x = 10;    p.y = 20;       //開始地址    printf("%p\n", &p);    //某元素地址    printf("%p\n", &(p.x));


golang版本的:
type Point struct{        x int;        y int;    };       var p Point;    p.x = 10;    p.y = 20;    fmt.Printf("%p\n", &p);    fmt.Printf("%p\n", &(p.x));

使用allocate的方式:
C代碼:
typedef struct    {          int x;        int y;    } Point;    Point *p;    p = (Point *) malloc(sizeof(Point));    p->x = 10;    p->y = 20;       //開始地址    printf("%p\n", p); //地址    //某元素地址    printf("%p\n", &(p->x));
golang代碼:
type Point struct{        x int;        y int;    };       var p *Point;    p = new(Point);    p.x = 10;    p.y = 20;    fmt.Printf("%p\n", p); //地址    fmt.Printf("%p\n", &(p.x));

也可以說是一樣的, 只不過在使用結構中的元素時沒有了"->"操作符:

There is no -> notation for structure pointers. Go provides the indirection for you.

結構體的地址傳參與數組的方式一樣, 當然, 和C的風格也是一模一樣的. 如下例子:

C代碼:
#include <stdio.h>#include <stdlib.h>typedef struct    {        int x;        int y;    } Point;    void use_struct(Point *arg){    arg->x = 100;}void main(int argc, char *argv[]){        Point *p;    p = (Point *) malloc(sizeof(Point));    p->x = 10;    p->y = 20;        use_struct(p);    printf("%d\n", p->x);}
golang代碼:
import "fmt"type Point struct{    x int;    y int;};func use_sturct( p *Point ){    p.x = 100;}func main() {    var p *Point;    p = new(Point);    p.x = 10;    p.y = 20;    use_sturct(p);    fmt.Printf("%d\n", p.x);}

總的來說......
在傳參方面, 大體上看與C的相同:
f(ar);    // passes a copy of ar   fp(&ar);  // passes a pointer to ar
* 只是變數名是不是表示首個地址 有區別
"&" 與C語言一樣是得到變數的指標. 與C有點不同, 取golang中指標指標的內容的值是不需要使用"*"操作符的, 但是指標的指標(或者繼續多層時)需要顯式使用"*"符號.
在 http://golang.org/doc/go_spec.html#Selectors 一節中有描述。

* 三層以上的指標使用是比較少的. 兩層還是常見, 如main函數的參數char * argv[]
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.