1、指针
指针这个东西,C中就有,指针就是存放变量在内存中的地址。
go语言中,指针不能运算,指针运算会报错。(PS:我觉得这点非常棒,我写C的时候有的时候也避免进行指针运算,不然容易出错,虽然指针运算也很方便,但是我是能不用就不用。)
package main
import "fmt"
func main() {
a:=100
fmt.Printf("%x\n",&a) //返回a 的地址c00000a0a8
var b *int=&a
fmt.Println(b) //返回 a 的地址0xc00000a0a8
fmt.Println(&b) //返回b的地址 0xc000006030
fmt.Println(*b) //返回b指向的a的值 100
}
复制代码
在go中,当声明了一个指针p指向的地址为NULL,则称这个指针为空指针,nil
sample1用指针交换变量
package main
import "fmt"
func swap(a,b *int) {
tmp:=*a
*a=*b
*b=tmp
}
func main() {
a:=100
b:=200
c :=&a
d:=&b
fmt.Println(*c,*d)
fmt.Println("-------------------")
swap(c,d)
fmt.Println(*c,*d)
}
/*返回
100 200
-------------------
200 100
*/
复制代码
1.1指针数组
指针数组也就是存放指针的数组。这个东西在C中有的时候特别有用,比如说临时在栈内存中创建一个指针数组当做队列或者栈来用。
sample利用指针数组遍历元素
package main
import "fmt"
const count int =4
func main() {
a:=[count] string {"abc","1","1.2","五六七"}
i:=0
//定义指针数组
var ptr[count]*string
//将每个元素地址赋值给指针数组
for i=0;i<count;i++{
ptr[i]=&a[i]
}
//用指针数组遍历元素
for i=0;i<count;i++{
fmt.Println(*ptr[i])
}
}
复制代码
1.2指针的指针
package main
import "fmt"
func main() {
a:=100 //创建一个int a=100
p:=&a //指针p存a的地址
pp:=&p //指针的指针存p的地址
fmt.Printf("%d,%d\n",&a,a) //打印a的地址,a的值
fmt.Printf("%d,%d\n",p,*p) //打印p存的地址,和p指向的值
fmt.Printf("%d,%d,%d\n",pp,*pp,**pp) //pp是pp的地址,*pp是pp指向的指针p的地址,**pp是pp->p->a的值
}
//一次输出的结果的值
/*
824633761960,100
824633761960,100
824633745448,824633761960,100
*/
复制代码
sample定义指针和指针的指针
a:=100
var ptr *int //定义一个指针
var pptr **int //定义一个指针的指针
ptr=&a //指针存放a的地址
pptr=&ptr //指针存放ptr的地址
fmt.Println(pptr) //打印ptr的地址
fmt.Println(ptr) //打印a的地址
复制代码
1.3参数传递
2、数组
2.1数组的定义
var a=[length]type{element1,element2}
var a=[2]int{1,2}
复制代码
go的数组和C中不太一样的就是C中的数组就是指针,也就是C中数组取地址会得到数组的第一个元素的地址。而go中你对数组取地址会得到整个数组元素,也因此go中无法通过指针运算来遍历数组
2.2数组的长度
go中获取数组的长度通过len()函数就可以获取了。
var a=[2]int{2,4};
fmt.Println(len(a)) //这里输出2
复制代码
2.3多维数组
//创建一个三行四列的二维数组
var a=[3][4]int
{
{1,2,3,4},
{2,3,4,5},
{3,4,5,6}
}
复制代码
go语言中数组是值类型。也就是说数组分配内存在栈中
3、切片重点
切片是指可变数组,有点像C++中的vector?切片结构可以理解为三个部分:1、指针ptr,指向切片的指定位置。2、长度len,切片的长度。3、容量cap,也就是切片从开始到最后的长度。slice的语法和数组很像,只是没有固定长度而已。
切片的数据结构
切片ptr指向第一个元素
//这里用C语言来实现一下slice的大致的结构体
typedef struct d{
int *ptr; //这里是一个指针,指向的是数组中的某一个数
int len; //这里是长度,切片的长度
int cap; //这里是切面的容量
}
复制代码
长度和容量的区别在于,长度是你存放了元素的部分,容量是你能存放多少?
切片和数组的关系,两者连定义都一样。
package main
import "fmt"
func main() {
months := []string{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
fmt.Println(months)
fmt.Println("Length:", len(months))
fmt.Println("Capacity:", cap(months))
}
复制代码
切片项(重点)
package main
import "fmt"
func main() {
months := []string{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}
quarter1 := months[0:3] //这里是切片1
quarter2 := months[3:6] //这里是切片2
quarter3 := months[6:9] //这里是切片3
quarter4 := months[9:12] //这里是切片4
fmt.Println(quarter1, len(quarter1), cap(quarter1))
fmt.Println(quarter2, len(quarter2), cap(quarter2))
fmt.Println(quarter3, len(quarter3), cap(quarter3))
fmt.Println(quarter4, len(quarter4), cap(quarter4))
}
复制代码
3.1切片的扩容(*)
切片的扩容可以说是非常值得关注的一个知识点。
package main
import "fmt"
func main() {
a:=[]int{1,3,5,7}
fmt.Printf("lena:%d\tcapa:%d\n",len(a),cap(a))
fmt.Println("-------------")
b:=append(a,1,2)
fmt.Printf("lenb:%d\tcapb:%d\n",len(b),cap(b)) //b这里扩容为原来的两倍
c:=append(a,2,4,5,6,7)
fmt.Printf("lenc:%d\tcapc:%d\n",len(c),cap(c)) //c这里由于扩容cap==8<len==9,所以cap==10
d:=append(a,1,2,3,4,5,6,7)
fmt.Printf("lend:%d\tcapd:%d\n",len(d),cap(d)) //这里和上面一样
}
/*
输出结果
lena:4 capa:4
-------------
lenb:6 capb:8
lenc:9 capc:10
lend:11 capd:12
*/
复制代码
sample逆置数组
package main
import "fmt"
func main() {
a:=[]int{1,3,5,7,9}
for i,j:=0,len(a)-1;i<j;i,j=i+1,j-1{
a[i],a[j]=a[j],a[i]
}
fmt.Println(a)
}
/*
返回结果
[9 7 5 3 1]
*/
复制代码
3.2 equal
利用equal来对两个切片进行比较
func equal(x, y []string) bool {
if len(x) != len(y) {
return false
}
for i := range x {
if x[i] != y[i] {
return false
}
}
return true
}
复制代码
切片没有自己的任何数据。它只是底层数组的一个引用。对切片所做的任何修改都将反映在底层数组中。数组是值类型,而切片是引用类型
3.3 copy和append
利用copy复制
package main
import (
"fmt"
)
func main() {
a:=[]int{1,3,5,7,9}
//b:=[]int{1,3,5,7,8}
b:=make([]int,len(a),cap(a)*2)
ret:=copy(b,a)
fmt.Printf("%x,%x\n",&a,&b)
fmt.Println(ret)
fmt.Println(b)
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END