这是我参与「第五届青训营 」伴学笔记创作活动的第3天
1.Go的基础语法(续)
(1). Go的指针
Golang是基于C++的,也有类似于C++的指针机制,有了指针可以非常方便的对变量进行操作。
首先Golang中的地址也是通过取地址符&得到的:
var x int = 1
fmt.Printf("Address: %x\n", &x)
指针的定义和赋值也类似,其中,输出xPoint存储的地址得到x的地址,输出*xPoint得到x的值:
var int x = 10
var xPoint *int
xPoint = &x
Golang的空指针类似于NULL、nullptr、null,为nil,若要判空 xPoint != nil 即可。
指向指针的指针可以类似于以下定义,可以顺次指针的指针的指针等操作:
var xPointP **int //该指针存储某个指针的地址
前面总结过,swap函数的引用传递中,函数的形参实际上是指针参数,接受实参地址。
func swap(x *int, y *int){
*x, *y = *y, *x
}
指针应用到数组上,需要依次赋值:
var point [N]*int;
num := []int{1,2,3}
for i := 0; i < N; i++ {
point[i] = &num[i]
}
(2). Go的数组
数组是数据结构中顺序表的物理实现,和其他高级语言类似,Golang中的数组也具有类似的性质和语法。
数组声明后初始化方式有很多种,一维数组的相关内容如下代码所示:
/* 一维数组声明 */
var num1 [20] int
/* 一维数组初始化 */
var num2 = [5]float64{2.4343, 1.323, 5.6565, 43.56, 12.98} //普通初始化 不可以var
num3 := [5]float64{2.4343, 1.323, 5.6565, 43.56, 12.98} //快速初始化
var num4 = [...]float64{2.4343, 1.323, 5.6565, 43.56, 12.98} //不定长普通初始化
num5 := [...]float64{2.4343, 1.323, 5.6565, 43.56, 12.98} //不定长快速初始化
num6 := [5]float64{1:3.14, 4:2.71828} //指定位置初始化,相当于num6[1], num6[4] = 3.14, 2.71828
对于二维数组,相关内容如下。
二维数组的声明方式:
var num1 [3][4] int
二维数组的初始化方式:
/* 二维数组初始化 */
num2 := [][]int{} //一个空二维数组
num3 := [3][2]int{
{0, 1},
{2, 3},
{4, 5}, //逗号不可省略
}
num4 := [3][2]int{
{0, 1},
{2, 3},
{4, 5}) //没有逗号
num5 := [...][]int{
{1, 2, 3, 4},
{10, 20, 30, 40}, //使用...不定长行数
}
二维数组的赋值方式:
num6 := [][]int{}
r1 := []int{1, 2}
r2 := []int{3, 4}
num6 = append(num6, r1)
num6 = append(num6, r2) //num5为一个2行2列的二维数组
s := [2][2]string{}
s[0][0] = "aa"
s[0][1] = "bb"
s[1][0] = "cc"
s[1][1] = "dd" //依次赋值,可以用循环输入方式
二维数组的遍历方式:
//使用range
for i := range num {
for j := range num[i] {
fmt.Println(num[i][j])
}
}
//使用普通for循环
for i:=0 ; i<n; i++ {
for j:=0 ; j<m; j++ {
fmt.Println(num[i][j])
}
}
对于多维数组,其语法和操作类似于二维数组。
对于不定维数组,可以通过append函数依次添加元素数量不同的一维数组达到效果。
数组在函数参数传递上的状况,大致分为三种,数组参数、指针参数、切片参数: 数组作为函数参数时,为值传递,不会改变数组的值:
func change1(nums [3]int) {
nums[0] = 2
}
指针参数,引用传递,会改变值:
func change2(nums *[3]int) {
nums[0] = 2
}
Go 语言中对数组的处理,一般采用切片,切片包含对底层数组内容的引用,作为函数参数时,类似上面那种指针传递,会修改值,这种参数只能用于切片([]内没有数字的数组):
func change3(nums []int) {
nums[0] = 2
}
这种切片不会改变值,因为a长度已经改变,之后的操作都不起作用:
func change4(nums []int) {
nums = append(nums, 1, 2, 3, 4)
nums[0] = 10
}
这样result的值才能是真正修改的结果:
result := [][]int{}
func change5(a []int){
a = append(a, 1, 2, 3, 4)
a[0] = 10
temp := make([]int, len(a))
copy(temp, a)
result = append(result,temp)
}
func main() {
var nums1 = [3]int{1, 2, 3}
var nums2 = []int{1, 2, 3}
change1(nums1)
fmt.Println(nums1) //[1 2 3]
change2(&nums1)
fmt.Println(nums1) //[2 2 3]
change3(nums2)
fmt.Println(nums2) //[2 2 3]
change4(nums2)
fmt.Println(nums2) //[2 2 3]
change5(nums2)
fmt.Println(result) //[10 2 1 2 3 4]
}
(3). Go的算法竞赛数据输入
值得注意的是,Golang不允许自增/自减运算符作为作为赋值语句的值。
(4). Go的结构体
值得注意的是,Golang不允许自增/自减运算符作为作为赋值语句的值。
(5). Go的切片
值得注意的是,Golang不允许自增/自减运算符作为作为赋值语句的值。
(6). Go的范围
值得注意的是,Golang不允许自增/自减运算符作为作为赋值语句的值。
(7). Go的集合
值得注意的是,Golang不允许自增/自减运算符作为作为赋值语句的值。
(8). Go的接口
值得注意的是,Golang不允许自增/自减运算符作为作为赋值语句的值。