一、指针类型

1、普通类型,变量存的就是值,也叫值类型。指针类型存的是地址

2、获取变量的地址,用&,比如:var a int, 获取a的地址 &a

3、指针类型,变量存的是一个地址,这个地址存的才是值

4、获取指针类型所指向的值,使用:* ,比如:var p *int,使用*p获取p指向的变量的值

var a int = 5

var p *int = &a   0xefefefe 指向变量a的值是 5

5、指针类型的变量初始话有两种:

5.1、直接给指针赋值其他变量的地址

func test3(){
    var p *int  //默认初始化nil
    var a int
    p = &a
    *p = 200
    fmt.Println(a)
}

5.2、使用new分配

func test4(){
    var p *int
    p = new(int)
    *p = 2000
    fmt.Println(*p)
}

6、练习题

6.1、练习1:写一个程序,获取一个变量的地址,并打印到终端

package main
import (
    "fmt"
)
func test1(){
    var a int = 5
    var p *int = &a
    fmt.Printf("a的地址是:%p\n",p)
    fmt.Printf("a的值是:%d",*p)
}
func main(){
    test1()
}
运行打印的结果如下:

6.2、练习2:写一个函数,传入一个int类型的指针,并在函数中修改所指向的值

func modify(x *int){         //传入的变量x类型是指针 *int代表指针是整形的指针
    *x = 200                      //给x指针指向的值重新赋值为200
}
func test2(){
    var a int = 5             //定义一个整形的变量a,初始值是5
    var p *int = &a           //定义一个指针p,指向的是a
    fmt.Println("变量a的初始值是",a)   //打印a的初始值
    modify(p)                  //修改p指针指向的a的值
    fmt.Println("p指针指向的a变量的改变值是",a)   //打印a的值改变的结果
}
func main(){
    test2()
}
 
执行打印的结果如下:

二、内置函数

1、close:主要用来关闭channel

2、len:用来求长度,比如string、array、slice、map、channel

3、new:用来分配内存,主要用来分配值类型,比如int、struct。返回的是指针。示例可以看上面一的5.2,

4、make:用来分配内存,主要用来分配引用类型,比如channel、map、slice

5、append:用来追加元素到数组、slice中

6、panic和recover:用来做错误处理

7、new和make的区别

7.1、内建函数 new 用来分配内存,它的第一个参数是一个类型,不是一个值,它的返回值是一个指向新分配类型零值的指针

7.2、内建函数 make 用来为 slice,map 或 chan 类型分配内存和初始化一个对象(注意:只能用在这三种类型上),跟 new 类似,第一个参数也是一个类型而不是一个值,跟 new 不同的是,make 返回类型的引用而不是指针,而返回值也依赖于具体传入的类型,具体说明如下:

  Slice: 第二个参数 size 指定了它的长度,它的容量和长度相同。
你可以传入第三个参数来指定不同的容量值,但必须不能比长度值小。
比如 make([]int, 0, 10)

  Map: 根据 size 大小来初始化分配内存,不过分配后的 map 长度为 0,如果 size 被忽略了,那么会在初始化分配内存时分配一个小尺寸的内存

  Channel: 管道缓冲区依据缓冲区容量被初始化。如果容量为 0 或者忽略容量,管道是没有缓冲区的

7.3、总结:

  new 的作用是初始化一个指向类型的指针(*T),make 的作用是为 slice,map 或 chan 初始化并返回引用(T)。

三、函数

1、声明语法:func 函数名(参数列表)[(返回值列表)]{}

  func add(){

  }

  func add(a int,b int){

  }

  func add(a int, b int) int {

  }

  func add(a int, b int) (int , int){

  }

  func add(a , b int) (int , int){

  }

2、golang函数的特点:

  a、不支持重载,一个包不能有两个名字一样的函数;

  b、函数是一等公民,函数也是一种类型,函数也可以赋值给变量

  c、匿名函数

  d、多返回值

  示例: 

  type add_func func(int, int)int

  func oprator(op add_func,a int,b int)int {
      //使用传进来的函数op,进行操作
      return op(a,b)
  }
  func add(a,b int) int {
      return a + b
  }  
  func main(){
      c:=add
      fmt.Println(c)
      sum := oprator(c,100,200)
      fmt.Println(sum)

 
  }
3、函数参数传递方式:
  3.1、值传递
  3.2、引用传递
  注意1:无论是值传递,还是引用传递,传递给函数的都是变量的副本。值传递是值的拷贝,一般来说地址拷贝更高效。值拷贝取决于拷贝的对象的大小,对象越大,性能越低。
  注意2:map、slice、channel、指针、interface默认以引用的方式传递
4、命名返回值的名字

//重命名一个返回值
func reduce(a , b int)(c int){
    c = a - b
    return
}
//重命名多个返回值
func calc(a,b int)(sum int,avg int){
    sum = a + b
    avg = sum/2
    return
}
// _ 忽略返回值
func main(){
    sum,_ := calc(100,200)
}
5、可变参数:
多个参数
func test11(arg...int) int{
}

一个或多个参数

func test11(a int ,arg...int) int{
}

二个或多个参数

func test11(a int,b int ,arg...int) int{
}

注意:其中arg是一个slice,我们可以通过arg[index]来获取多个参数

通过len(arg)来判断传递参数的个数

6、练习题示例

package main
import (
    "fmt"
)
//练习题一:写一个函数add,支持1个或多个int相加,并返回结果
func add(a int,arg...int)int{
    var sum int
    //当只有一个参数时
    if len(arg)==0{
        sum = a
    }
    //当参数大于一个时
    if len(arg)>0{
        for i:=0;i<len(arg);i++{
            //注意这里但arg里面只有一个参数时,i是等于0即arg[0]
            if i == 0 {
                sum = a + arg[0]
            }
            //当arg参数大于一个时
            if i >0 {
                sum+=arg[i]
            }
        }
    }
    return sum
}
//练习题二:写一个函数concat,支持1个或多个string相拼接,并返回结果
func concat(a string,arg...string)string{
    var str string
    if len(arg)==0{
        str = a
    }
    if len(arg)>0{
        for i:=0;i<len(arg);i++{
            if i == 0 {
                str = a + arg[0]
            }
            if i >0 {
                str+=arg[i]
            }
        }
    }
    return str
}
func main(){
    fmt.Println(add(-22,23,555))
    fmt.Println(concat("aaa","bbbbb","ccccccc"))
}
 
7、defer的特点和用途
7.1、当函数返回时,执行defer语句。因此可以用来做资源清理
7.2、多个defer语句,按先进后出的方式执行
示例:
func a(){
    fmt.Println("defer from a")
    i:=0
    defer fmt.Println(i)   //defer语句中的变量,在defer声明时就决定
    i++ 
}
func f(){
    fmt.Println("defer from f")
    for i:=0;i<5;i++{
        defer fmt.Println(i)
    }   
}
func main(){
    //练习三
    a()
    f()
}
打印的结果:
7.3、defer语句中的变量,在defer声明时就决定了
7.4、defer用途:关闭文件句柄,锁资源释放,数据库连接释放
 
四、递归函数
1、一个函数调用自己,就叫递归函数
2、斐波那契数
//斐波那契数列示例:
func fb( n int)int{
    if n <=1{
        return 1
    }
    return fb(n-1)+fb(n-2)
}
func main(){
    for i:=0;i<10;i++{
        n := fb(i)
        fmt.Println(n)
    }
}
3、递归的设计原则
3.1、一个大问题能够分解成相似的小问题
3.2、定义好出口条件(即结束递归循环的条件)
 
五、闭包
一个函数和与其相关的引用环境的组合成的实体
//示例一:
func Adder() func(int)int{
    var x int
    return func(delta int)int{
        x +=delta
        return x
    }
}
//示例2:
func makeSuffixFunc(suffix string) func(string)string{
    return func(name string)string{
        if !strings.HasSuffix(name ,suffix){
            return name + suffix
        }
        return name
    }
}
func main(){
    //练习五:闭包
    //示例1:
    // var f = Adder()
    // fmt.Println(f(1))
    // fmt.Println(f(10))
    // fmt.Println(f(100))
    //示例2:
    func1 := makeSuffixFunc(".jpg")
    func2 := makeSuffixFunc(".txt")
    fmt.Println(func1(func1("test")))
    fmt.Println(func2("test"))
}
 
六、数组和切片
1.1、排序和查找操作
  排序操作主要都在sort包中,导入就可以使用
  sort.Ints对整数进行排序, sort.Strings对字符串串进⾏行行排序, sort.Float64s对 浮点数进⾏行行排序.
  sort.SearchInts(a []int, b int) 从数组a中查找b,前提是a 必须有序
   sort.SearchFloats(a []float64, b float64) 从数组a中查找b,前提是a 必须有序
  sort.SearchStrings(a []string, b string) 从数组a中查找b,前提是a 必须有序

GO-指针与函数的更多相关文章

  1. 12-返回指针的函数&&指向函数的指针

    前言 接下来我只讲指针的最常见用法,比如这一章的内容----返回指针的函数 与 指向函数的指针   一.返回指针的函数 指针也是C语言中的一种数据类型,因此一个函数的返回值肯定可以是指针类型的. 返回 ...

  2. 我的c++学习(12)指针作为函数参数

    ◆ 引用调用与指针传值调用C++中函数的参数的基本使用方法是传值.为了弥补单纯传值的不足,以引用作为函数的参数,从逻辑上讲引用是别名,在函数中对参数的操作,就是对实参的操作,而在物理上是传实参的地址. ...

  3. C#委托与C语言函数指针及函数指针数组

    C#委托与C语言函数指针及函数指针数组 在使用C#时总会为委托而感到疑惑,但现在总新温习了一遍C语言后,才真正理解的委托. 其实委托就类似于C/C++里的函数指针,在函数传参时传递的是函数指针,在调用 ...

  4. 【C语言】14-返回指针的函数与指向函数的指针

    前言 前面我们花了接近3个章节学习指针,应该都感受到指针的强大了吧.指针可以根据地址直接操作内存中的数据,使用得当的话,不仅能使代码量变少,还能优化内存管理.提升程序性能.关于指针的内容还非常多,比如 ...

  5. C/C++ 一段代码区分数组指针|指针数组|函数指针|函数指针数组

    #include<stdio.h> #include<stdlib.h> #include<windows.h> /* 举列子说明什么是函数指针 */ //以一个加 ...

  6. 【学习笔记】【C语言】返回指针的函数

    函数如果带*的返回的就是指针 char *test(){ } #include <stdio.h> char *test(); /* 返回指针的函数 */ int main() { cha ...

  7. C++ 二维数组(双重指针作为函数参数)

    本文的学习内容参考:http://blog.csdn.net/yunyun1886358/article/details/5659851 http://blog.csdn.net/xudongdong ...

  8. Delphi 函数指针(函数可以当参数)

    首先学习: 指向非对象(一般的)函数/过程的函数指针 Pascal 中的过程类型与C语言中的函数指针相似,为了统一说法,以下称函数指针.函数指针的声明只需要参数列表:如果是函数,再加个返回值.例如声明 ...

  9. C语言中的声明解析规则——数组,指针与函数

    摘要:C语言的申明存在的最大问题是:你无法以一种人们所习惯的自然方式和从左向右阅读一个声明,在引入voliatile和const关键字以后,情况更加糟糕了.由于这些关键字只能出现在声明中,是的声明形式 ...

  10. C语言的本质(12)——指针与函数

    往往,我们一提到指针函数和函数指针的时候,就有很多人弄不懂.下面详细为大家介绍C语言中指针函数和函数指针. 1.指针函数 当一个函数声明其返回值为一个指针时,实际上就是返回一个地址给调用函数,以用于需 ...

随机推荐

  1. EF中Json序列化对象时检测到循环引用的解决办法

    MVC4 EF中将数据表外键引用的是自身,转换成Json时,总是提示错误:“序列化类型为....的对象时检测到循环引用.”: 解决办法: 把要序列化的对象转为匿名对象去掉导航属性,如下 :本来是var ...

  2. Collections带有的排序方法 传入的元素类型 需是子类或者这个类的实例

  3. luogu 1360 阵容均衡(前缀和+差分+hash)

    要求一段最大的区间里每个能力的增长值是一样的. 我们首先求一遍前缀和,发现,如果区间内[l,r]每个能力的增长值是一样的话,那么前缀和[r]和[l-1]的差分也应该是一样的. 那么我们把前缀和的差分h ...

  4. AtCoder Regular Contest 083 D: Restoring Road Network

    题意 有一张无向带权连通图(点数<=300),给出任意两点i,j之间的最短路长度dis[i][j].问是否存在一张这样的无向图.如果不存在输出-1.如果存在输出所有这样的无向图中边权和最小的一张 ...

  5. QT模态对话框及非模态对话框

    QT模态对话框及非模态对话框 模态对话框(Modal Dialog)与非模态对话框(Modeless Dialog)的概念不是Qt所独有的,在各种不同的平台下都存在.又有叫法是称为模式对话框,无模式对 ...

  6. [SCOI2016]幸运数字 线性基

    题面 题面 题解 题面意思非常明确:求树上一条链的最大异或和. 我们用倍增的思想. 将这条链分成2部分:x ---> lca , lca ---> y 分别求出这2个部分的线性基,然后合并 ...

  7. redis安全性 添加访问密码

    设置客户端连接访问redis服务器必须进行身份验证. vi打开编辑redis配置文件:[root@martin etc]# vi /usr/local/redis/etc/redis.conf 在约1 ...

  8. bzoj4569: [Scoi2016]萌萌哒(ST表+并查集)

    好喵喵的题 将一个要求用ST表分割成logn个要求,如果把f[i][j]和f[u][v]在同一个集合,那么f[i][j-1]和f[u][v-1],f[i+2^(j-1)][j-1]和f[u][u+2^ ...

  9. CF1100E

    i207M给的题 省选前-小题解合集 给定一张有向图,每条边有边权.你可以花费边权的代价反转一条边,使得原图中没有环.最小化反转的边权的最大值. 首先二分,然后考虑判定. 转化为有些边可以翻转,有些边 ...

  10. 【分块,莫队】【P4396】【AHOI2013】作业

    传送门 Description 此时己是凌晨两点,刚刚做了Codeforces的小A掏出了英语试卷.英语作业其实不算多,一个小时刚好可以做完.然后是一个小时可以做完的数学作业,接下来是分别都是一个小时 ...