值类型和应用类型
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
&
操作符会生成一个指向其操作数的指针。
扫描二维码关注公众号,回复:
1724886 查看本文章
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