值类型和应用类型
1、值类型:变量直接存储值,内存通常在栈中分配
基本数据类型int、float、bool、string以及数组和struct。如果在函数里面修改了,函数外不变
2、引用类型:变量存储的是一个地址,这个地址存储最终的值。内存通常在堆上分配。通过GC回收。
指针、slice、map、chan等都是引用类型。如果在函数里面修改了,函数外面也会变
例一
package main
import "fmt"
func modify(a int) {
a = 10
}
func modify1(a *int) {
*a = 10
}
func main() {
var a = 100
var b chan int = make(chan int,1)
fmt.Println("a=",a)
fmt.Println("b=",b)
modify(a)
fmt.Println(a)
modify1(&a)
fmt.Println(a)
}
输出
a= 100 b= 0xc0420140e0 100 10
指针
Go 拥有指针。指针保存了值的内存地址。
类型 *T 是指向 T 类型值的指针。其零值为 nil。
var p *int
& 操作符会生成一个指向其操作数的指针。
i := 42 p = &i //设置p的内存地址
* 操作符表示指针指向的底层值。
fmt.Println(*p) // 通过指针 p 读取 i *p = 21 // 通过指针 p 设置 i
这也就是通常所说的“间接引用”或“重定向”。
与 C 不同,Go 没有指针运算。
例一
package main
import "fmt"
func swap(a, b int) {
tmp := a
a = b
b = tmp
}
func main() {
first := 10
second := 20
swap(first, second) //这里执行的时候相当于传入了first1=10,second1=20,这个first1与first的内存地址不同,但是值相同,因为10为值类型,second1同理
fmt.Println("first=", first)
fmt.Println("second=", second)
}
输出
first= 10 second= 20
例二
package main
import "fmt"
func swap(a, b *int) {
tmp := *a
*a = *b //交换a,b的指针的值
*b = tmp
}
func main() {
first := 10
second := 20
swap(&first, &second) //传入指针
fmt.Println("first=", first)
fmt.Println("second=", second)
}
输出
first= 20 second= 10
变量的作用域
1、在函数内部声明的变量叫局部变量,生命周期仅限于函数内部。
2、在函数外部声明的变量叫全局变量,声明周期作用于整个包,如果是大写的,则作用于整个程序
例一
package main
import "fmt"
var a = "G"
func n() {
fmt.Println(a)
}
func m() {
a := "O" //重新声明一个变量a
fmt.Println(a)
}
func main() {
n()
m()
n()
}
输出
G O G
例二
package main
import "fmt"
var a = "G"
func n() {
fmt.Println(a)
}
func m() {
a = "O" //对全局变量a重新赋值
fmt.Println(a)
}
func main() {
n()
m()
n()
}
输出
G O O
例三
package main
import "fmt"
var a string
func f1() {
a := "O"
fmt.Println(a)
f2()
}
func f2() {
fmt.Println(a)
}
func main() {
a = "G"
fmt.Print(a)
f1()
}
输出
G O G
数据类型和操作符
1、字符串表示两种方式:
1)""
2)'' //byte类型
3)`` //完全按照输入来输出
例一
package main
import "fmt"
func main() {
var a byte ='c'
var str string = "hello \nworld"
var str2 string = `
fdsfdsf,
hello world \n
hello world
`
fmt.Printf("%c\n",a)
fmt.Println(str)
fmt.Println(str2)
}
输出
99 hello world fdsfdsf, hello world \n hello world
练习
1、判断101-200之间有多少个素数,并输出所有素数
package main
import (
"math"
"fmt"
)
func prime(n int) (res int) {
var list []int
var flag int
for i := 2; float64(i) <= math.Sqrt(float64(n)); i ++ {
flag ++
k := n % i
if k == 0 {
res = 0
break
}else {
list = append(list, i)
}
}
if len(list) == flag {
res = 1
}
return res
}
func main() {
var count int
for j :=101; j <= 200; j++ {
res := prime(j)
if res == 1 {
fmt.Println(j)
count++
}
}
fmt.Printf("总数:%v个\n",count)
}
输出
101 103 107 109 113 127 131 137 139 149 151 157 163 167 173 179 181 191 193 197 199 总数:21个
2. 打印出100-999中所有的“水仙花数”,所谓“水仙花数”是指一个三位数,其各位数字
立方和等于该数本身。例如:153 是一个“水仙花数”,因为 153=1 的三次
方+5 的三次方+3 的三次方。
package main
import (
"fmt"
"strconv"
)
func flower(n int) (sum int) {
a := fmt.Sprintf("%v", n)
for i := 0; i < len(a); i ++ {
b := fmt.Sprintf("%c", a[i])
s, err := strconv.Atoi(b)
if err != nil {
fmt.Println("字符串转换成整数失败")
}
sum += s*s*s
}
return sum
}
func main() {
for i :=100; i < 999; i ++ {
if flower(i) == i{
fmt.Println(flower(i))
}
}
}
输出
153 370 371 407
3. 对于一个数n,求n的阶乘之和,即: 1! + 2! + 3!+…n!
package main
import "fmt"
func step(n int) (res int) {
if n == 0 {
res = 1
}else {
res = n*step(n-1)
}
return res
}
func main() {
n := 3
var sum int
for i := 1; i <= n; i++ {
sum += step(i)
}
fmt.Println("sum=",sum)
}
输出
sum= 9

浙公网安备 33010602011771号