换个语言学一下 Golang (8)——指针
定义
所谓指针其实你可以把它想像成一个箭头,这个箭头指向(存储)一个变量的地址。
因为这个箭头本身也需要变量来存储,所以也叫做指针变量。
Go的指针不支持那些乱七八糟的指针移位。它就表示一个变量的地址。看看这个例子:
package main
import (
"fmt"
)
func main() {
var x int
var x_ptr *int
x =
x_ptr = &x
fmt.Println(x)
fmt.Println(x_ptr)
fmt.Println(*x_ptr)
}
上面例子输出x的值,x的地址和通过指针变量输出x的值,而x_ptr就是一个指针变量。
0xc084000038
认真理清楚这两个符号的意思。
& 取一个变量的地址
* 取一个指针变量所指向的地址的值
考你一下,上面的例子中,如何输出x_ptr的地址呢?
package main
import (
"fmt"
)
func main() {
var x int
var x_ptr *int
x =
x_ptr = &x
fmt.Println(&x_ptr)
}
此例看懂,指针就懂了。
永远记住一句话,所谓指针就是一个指向(存储)特定变量地址的变量。没有其他的特别之处。
再变态一下,看看这个:
package main
import (
"fmt"
)
func main() {
var x int
var x_ptr *int
x =
x_ptr = &x
fmt.Println(*&x_ptr)
}
- x_ptr 是一个
指针变量,它指向(存储)x的地址; - &x_ptr 是
取这个指针变量x_ptr的地址,这里可以设想有另一个指针变量x_ptr_ptr(指向)存储这个x_ptr指针的地址; - &x_ptr 等价于`x_ptr_ptr
就是取这个x_ptr_ptr指针变量所指向(存储)的地址所对应的变量的值,也就是x_ptr的值,也就是指针变量x_ptr指向(存储)的地址,也就是x的地址。 这里可以看到,其实*&`这两个运算符在一起就相互抵消作用了。
用途
指针的一大用途就是可以将变量的指针作为实参传递给函数,从而在函数内部能够直接修改实参所指向的变量值。
Go的变量传递都是值传递。
package main
import (
"fmt"
)
func change(x int) {
x =
}
func main() {
var x int =
fmt.Println(x)
change(x)
fmt.Println(x)
}
上面的例子输出结果为
很显然,change函数改变的仅仅是内部变量x的值,而不会改变传递进去的实参。其实,也就是说Go的函数一般关心的是输出结果,而输入参数就相当于信使跑到函数门口大叫,你们这个参数是什么值,那个是什么值,然后就跑了。你函数根本就不能修改它的值。不过如果是传递的实参是指针变量,那么函数一看,小子这次你地址我都知道了,哪里跑。那么就是下面的例子:
package main
import (
"fmt"
)
func change(x *int) {
*x =
}
func main() {
var x int =
fmt.Println(x)
change(&x)
fmt.Println(x)
}
上面的例子中,change函数的虚参为整型指针变量,所以在main中调用的时候传递的是x的地址。然后在change里面使用*x=200修改了这个x的地址的值。所以x的值就变了。这个输出是:
new
new这个函数挺神奇,因为它的用处太多了。这里还可以通过new来初始化一个指针。上面说过指针指向(存储)的是一个变量的地址,但是指针本身也需要地址存储。先看个例子:
package main
import (
"fmt"
)
func set_value(x_ptr *int) {
*x_ptr =
}
func main() {
x_ptr := new(int)
set_value(x_ptr)
//x_ptr指向的地址
fmt.Println(x_ptr)
//x_ptr本身的地址
fmt.Println(&x_ptr)
//x_ptr指向的地址值
fmt.Println(*x_ptr)
}
上面我们定义了一个x_ptr变量,然后用new申请了一个存储整型数据的内存地址,然后将这个地址赋值给x_ptr指针变量,也就是说x_ptr指向(存储)的是一个可以存储整型数据的地址,然后用set_value函数将这个地址中存储的值赋值为100。所以第一个输出是x_ptr指向的地址,第二个则是x_ptr本身的地址,而*x_ptr则是x_ptr指向的地址中存储的整型数据的值。
0xc084000040
0xc084000038
小结
好了,现在用个例子再来回顾一下指针。
交换两个变量的值。
package main
import (
"fmt"
)
func swap(x, y *int) {
*x, *y = *y, *x
}
func main() {
x_val :=
y_val :=
swap(&x_val, &y_val)
fmt.Println(x_val)
fmt.Println(y_val)
}
很简单吧,这里利用了Go提供的交叉赋值的功能,另外由于是使用了指针作为参数,所以在swap函数内,x_val和y_val的值就被交换了。
换个语言学一下 Golang (8)——指针的更多相关文章
- 换个语言学一下 Golang (3)——数据类型
在 Go 编程语言中,数据类型用于声明函数和变量. 数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存. Go 语言按类别有以下几种 ...
- 换个语言学一下 Golang (12)——Web基础
一.web工作方式 我们平时浏览网页的时候,会打开浏览器,输入网址后按下回车键,然后就会显示出你想要浏览的内容.在这个看似简单的用户行为背后,到底隐藏了些什么呢?对于普通的上网过程,系统其实是这样做的 ...
- 换个语言学一下 Golang (5)——运算符
运算符用于在程序运行时执行数学或逻辑运算. Go 语言内置的运算符有: 算术运算符 关系运算符 逻辑运算符 位运算符 赋值运算符 其他运算符 接下来让我们来详细看看各个运算符的介绍. 算术运算符 下表 ...
- 换个语言学一下 Golang (1)
做技术的总是有些拗.这么多年一直在.net的框框里打转转.直到现在市场上.net工作越来越难找,项目越来越老才发现不做出改变不行了.就从学习Go开始吧. Go语言的特点 简洁.快速.安全 并行.有趣. ...
- 换个语言学一下 Golang(14) ——fmt包
Print() 函数将参数列表 a 中的各个参数转换为字符串并写入到标准输出中. 非字符串参数之间会添加空格,返回写入的字节数. func Print(a ...interface{}) (n int ...
- 换个语言学一下 Golang (13)——Web表单处理
介绍 表单是我们平常编写Web应用常用的工具,通过表单我们可以方便的让客户端和服务器进 行数据的交互.对于以前开发过Web的用户来说表单都非常熟悉.表单是一个包含表单元素的区域.表单元素是允许用户在表 ...
- 换个语言学一下 Golang (11)——使用包和测试
Go天生就是为了支持良好的项目管理体验而设计的. 包 在软件工程的实践中,我们会遇到很多功能重复的代码,比如去除字符串首尾的空格.高质量软件产品的特点就是它的部分代码是可以重用的,比如你不必每次写个函 ...
- 换个语言学一下 Golang (9)——结构体和接口
基本上到这里的时候,就是上了一个台阶了.Go的精华特点即将展开. 结构体定义 上面我们说过Go的指针和C的不同,结构体也是一样的.Go是一门删繁就简的语言,一切令人困惑的特性都必须去掉. 简单来讲,G ...
- 换个语言学一下 Golang (4)——变量与常量
一.变量定义 所谓的变量就是一个拥有指定名称和类型的数据存储位置. //看一个例子 package main import ( "fmt" ) func main() { var ...
随机推荐
- 动态查找之二叉树查找 c++实现
算法思想 二叉搜索树(又称二叉查找树或二叉排序树)BST树 二叉查找树 二叉查找树,也称二叉搜索树,或二叉排序树.其定义也比较简单,要么是一颗空树,要么就是具有如下性质的二叉树: (1)若任意节点的左 ...
- Shared variable in python's multiprocessing
Shared variable in python's multiprocessing https://www.programcreek.com/python/example/58176/multip ...
- 阿里云Maven仓库地址setting配置
<?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://mav ...
- 1093 - You can't specify target table 'account' for update in FROM clause
目的:查询一张表的相同的两条数据,并删除一条数据. 分析 先查询出相同的数据,然后删除 查询相同的数据 SELECT a.id FROM account a GROUP BY a.username H ...
- Python3基础 import...as 给导入的模块起别名
Python : 3.7.3 OS : Ubuntu 18.04.2 LTS IDE : pycharm-community-2019.1.3 ...
- (原)关于OpenSL ES播放音频数据的一个奇怪的问题
关于OpenSL ES播放音频数据的一个奇怪的问题 Author:lihaiping1603@aliyun.com 最近用业余时间做了一个android平台的播放器sdk,其中视频用的opengl e ...
- TransactionScope处理分布式事物时提示"事务已被隐式或显式提交,或已终止"
在连接字符串中加入"Enlist=false",问题就这样解决了. ConnectionString = "Data Source=.;Initial Catalog=c ...
- 微信小程序框架 同时兼容QQ小程序
最近一直在开发微信小程序,经过几个版本的迭代开发,代码终于能够达到框架级别,动态配置.除了界面有些寒酸以外,功能上还是挺完备的. 主要有以下特点 1.整个程序所需url地址均在api.js中定义,环境 ...
- 在日志中记录Java异常信息的正确姿势
遇到的问题 今天遇到一个线上的BUG,在执行表单提交时失败,但是从程序日志中看不到任何异常信息. 在Review源代码时发现,当catch到异常时只是输出了e.getMessage(),如下所示: l ...
- photoshop7.0 排版一寸照片、2寸照片
说明:必须先照一张一寸电子照片,否则是无法做成 1.本例同样采用photoshop CS5制作,其它版本通用,这里采用上一教程“PS照片处理教程-制作一寸照片并排版”的处理效果图进行排版,首先在PS中 ...