加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

golang指针与C指针的异同

发布时间:2020-12-16 19:28:16 所属栏目:大数据 来源:网络整理
导读:总结一下golang中的指针与C语言的指针的用法。 总体一致: C的代码: int *number;number = (int *) malloc(sizeof(int));*number = 3;printf("%dn",*number); golang的代码: var pointer *int;pointer = new(int);*pointer = 3;fmt.Println(*pointer); 多重

总结一下golang中的指针与C语言的指针的用法。

总体一致:

C的代码:
int *number;
number = (int *) malloc(sizeof(int));
*number = 3;
printf("%dn",*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("%pn",inter);
    printf("%pn",*outer);
    //值一样
    printf("%dn",*inter);
    printf("%dn",**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("%pn",**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,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,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("%dn",*p2array + 1);
}
* 输出为1
func main() {
    var p2array *[3]int ;
    p2array = new([3]int);
    fmt.Printf("%xn",*p2array + 1); //不管p2array是指针变量还是数组变量,都只能使用"[]"方式使用
}
* 报错.

golang中的结构体也与C中的有差别

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

C版本的:

typedef struct
    {  
        int x;
        int y;
    } Point;


    Point p;
    p.x = 10;
    p.y = 20;
   
    //开始地址
    printf("%pn",&p);
    //某元素地址
    printf("%pn",&(p.x));


golang版本的:
type Point struct{
        x int;
        y int;
    };
   
    var p Point;
    p.x = 10;
    p.y = 20;
    fmt.Printf("%pn",&p);
    fmt.Printf("%pn",&(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("%pn",p); //地址
    //某元素地址
    printf("%pn",&(p->x));
golang代码:
type Point struct{
        x int;
        y int;
    };
   
    var p *Point;
    p = new(Point);
    p.x = 10;
    p.y = 20;
    fmt.Printf("%pn",p); //地址
    fmt.Printf("%pn",&(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("%dn",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("%dn",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[]

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读