Golang的指针运算方式

摘要

Go语言在进行指针移动时候,不能像C语言一样使用++的形式进行递增,而需要采用另一种特殊的运算形式。

具体实例

  • C语言实现指针对动态数组访问

通过下标对动态数组进行访问

#include <stdio.h>
#include <stdlib.h>

void alloc (int *a,int n){
	a=(int*)malloc(n*sizeof(n));
	for(int i=0;i<n;i++){
		a[i]=i*i+1;
	}
	for(int i=0;i<n;i++){
		printf("a[%d]=%d;\n",i,a[i]);
	}
}

访问结果:
利用下标访问动态数组

通过指针对动态数组进行访问

#include <stdio.h>
#include <stdlib.h>

void alloc (int *a,int n){
	a=(int*)malloc(n*sizeof(n));
	for(int i=0;i<n;i++){
		a[i]=i*i+1;
	}
	int *p = a;
	for(int i=0;i<n;i++){
		printf("i=%d,\t *p=%d;\n",i,*p);
		p++;
	}
}

访问结果:
通过指针访问结果
在C语言中,可以直接利用指针++的方式快速定位到下一个元素。Go语言中,这个方式是行不通的!!!

  • Go语言实现指针对动态数组访问

在Golang中,不能直接利用++的形式快速定位到下一个元素,其标识指针地址的uintptr类型,本质上是一个uint类型的数值,uintptr的运算实际上是uint的运算。

直接采用下标访问数组

import "fmt"

func main() {
	var a []int
	alloc(a,5)
}

func alloc(a []int, n int){
	a=make([]int,n)
	for i:=0;i<len(a);i++{
		a[i]=i*i+1
	}
	for i:=0;i<n;i++ {
		fmt.Printf("a[%d]=%d;\n",i,a[i])
	}
}

访问结果
下标访问数组的结果
采用指针++的方式访问数组
代码如下

func main() {
	var a []int
	alloc(a,5)
}

func alloc(a []int, n int){
	a=make([]int,n)
	for i:=0;i<len(a);i++{
		a[i]=i*i+1
	}
	var ptr *int = &a[0]
	for i:=0;i<n;i++ {
		fmt.Printf("i=%d, *p=%d;\n",i,*ptr)
		p:=uintptr(unsafe.Pointer(ptr))
		p++ // p++
		ptr=(*int)(unsafe.Pointer(p))
	}
}

访问结果:
在这里插入图片描述

原因分析,主要原因是因为Go语言中p++不是跳转到与该指针临近的下一个指针,而是真正的指针地址的具体值+1,此时可以把具体的指针打印出来对比。
分析代码如下:

func main() {
	var a []int
	alloc(a,5)
}

func alloc(a []int, n int){
	a=make([]int,n)
	for i:=0;i<len(a);i++{
		a[i]=i*i+1
	}
	var ptr *int = &a[0]
	for i:=0;i<n;i++ {
		fmt.Printf("&a[%d]=%d, p=%d;\n",i,&a[i],ptr)
		p:=uintptr(unsafe.Pointer(ptr))
		p++ // p++
		ptr=(*int)(unsafe.Pointer(p))
	}
}

结果显示
分析结果打印
解决方式,实际就是进行指针计算时候,用数组元素的实际字节大小替代掉++,具体代码如下所示:

纠正后的程序源代码

func main() {
	var a []int
	alloc(a,5)
}

func alloc(a []int, n int){
	a=make([]int,n)
	for i:=0;i<len(a);i++{
		a[i]=i*i+1
	}
	var ptr *int = &a[0]
	for i:=0;i<n;i++ {
		fmt.Printf("i=%d, *p=%d;\n",i,*ptr)
		p:=uintptr(unsafe.Pointer(ptr))
		p=p+unsafe.Sizeof(int(0)) // 指针移动
		ptr=(*int)(unsafe.Pointer(p))
	}
}

修正后的正确结果
在这里插入图片描述

结论

利用Go语言的指针访问动态数组不能直接像C语言一样利用++的形式进行数组访问,而需要加上实际的元素大小进行移动。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值