page contents

Golang与C语言的指针对比

总结一下golang中的指针与C语言的指针的用法. 总体一致:  C的代码:     int *number;    number = (int *) malloc(sizeof(int));    *number = 3;    printf("%d\n", *number); golang的...


attachments-2021-05-3c4SUSOH6094a31ad743d.png

总结一下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));

也可以说是一样的, 只不过在使用结构中的元素时没有了"->"操作符:

结构体的地址传参与数组的方式一样, 当然, 和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中指针指针的内容的值是不需要使用"*"操作符的, 但是指针的指针(或者继续多层时)需要显式使用"*"符号.

* 三层以上的指针使用是比较少的. 两层还是常见, 如main函数的参数char * argv[]

更多相关技术内容咨询欢迎前往六星社区了解。

如果你想用Python开辟副业赚钱,但不熟悉爬虫与反爬虫技术,没有接单途径,也缺乏兼职经验
关注下方微信公众号:Python编程学习圈,获取价值999元全套Python入门到进阶的学习资料以及教程,还有Python技术交流群一起交流学习哦。

attachments-2022-06-yVlOwKR162abf0e86ae59.jpeg

  • 发表于 2021-05-07 10:24
  • 阅读 ( 567 )
  • 分类:Golang

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
轩辕小不懂
轩辕小不懂

2403 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1474 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章