golang指针与C指针的异同

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

总体一致: 

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

多重指针情况:

C的代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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的代码: 
?
1
2
3
4
5
6
7
8
9
10
11
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里实现: 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
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中:    
?
1
2
3
4
5
6
7
8
9
10
11
12
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   数组做参数时, 需要被检查长度. 
?
1
2
3
4
5
6
7
8
9
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   变量名不等于数组开始指针!

?
1
2
3
4
5
6
7
8
9
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里是这样的: 
?
1
2
3
4
5
6
7
8
9
10
// 又长度检查, 也为地址传参
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在这方面的差别: 
?
1
2
3
4
5
6
7
8
void main( int argc, char *argv[]){
     int *p2array;
     p2array = ( int *) malloc ( sizeof ( int ) * 3);
     //等于p2array[0]
     *p2array = 0;
     printf ( "%d\n" , *p2array + 1);
}
* 输出为1
?
1
2
3
4
5
6
func main() {
     var p2array *[3] int ;
     p2array = new ([3] int );
     fmt.Printf( "%x\n" , *p2array + 1); //不管p2array是指针变量还是数组变量, 都只能使用"[]"方式使用
}
* 报错.

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

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

C版本的:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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版本的: 
?
1
2
3
4
5
6
7
8
9
10
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代码: 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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代码: 
?
1
2
3
4
5
6
7
8
9
10
11
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));

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

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

结构体的地址传参与数组的方式一样, 当然, 和C的风格也是一模一样的. 如下例子: 

C代码: 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#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代码: 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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的相同:  
?
1
2
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[] 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值