首页 > 其他分享 >指针

指针

时间:2024-02-26 17:01:41浏览次数:18  
标签:int fmt 数组 90 main 指针

目录

一、什么是指针

  • 指针也是一种变量,但是它的功能只是用来存储变量内存地址(Memory Address),即指针变量的值为其他变量的内存地址

  • 指针是变量,所以它本身也有内存地址

  • 内存地址都是属于 int 类型的值

  • Go中的指针是不支持运算的(有些语言可以,如C语言)

    • package main
      
      func main() {  
          b := [...]int{109, 110, 111}
          p := &b
          p++  // 不能进行运算,会报错 main.go:6: invalid operation: p++ (non-numeric type *[3]int)
      }
      

二、指针的定义

  • 最关键的两个符合

    • & 表示取变量的内存地址,* 表示通过地址找到值
  • 指针变量的类型为 *T,T为数据类型

  • 指针的空值为nil

1. 指针的声明
var d *string  // 声明了一个指针类型的字符串,恒等于 nil
var f *[3]int  // 声明了一个指针类型的数组,恒等于 nil
var g *[]int  // 声明了一个指针类型的切片,恒等于 nil

package main  
import (  
    "fmt"
)

2. 指针实例

func main() {  
    b := 255
    a := &b  // & 表示取变量的内存地址
    fmt.Println("address of b is", a)
    fmt.Println("value of b is", *a)  //  * 表示取指针的指向的值
}

/*
打印结果:

address of b is 0x1040a124  
value of b is 255
*/

三、向函数传递指针参数

  • 分为三种类型的指针参数
    • 数字、字符串类型的指针
    • 数组类型的指针(不推荐,推荐替换为直接传切片)
    • 切片类型(切片类型无需传递其指针,用来替代数组类型指针)

1. 传入字符串类型的指针

package main

import (  
    "fmt"
)

func change(val *int) {  
    *val = 55
}
func main() {  
    a := 58
    fmt.Println("value of a before function call is", a)
    b := &a
    change(b)
    fmt.Println("value of a after function call is", a)
}


/*
value of a before function call is 58  
value of a after function call is 55

可以看到,在函数中修改了传入的参数,但是,在函数外,a的值也同步被修改了
若不用指针,直接将a传入函数,则最后打印的a 仍是 58
*/

2. 传入数组类型的指针

  • 假如我们想在函数内部修改一个数组,并希望函数外部的数组也同步修改,有两种方式
    • 一种解决方案是把一个指向数组的指针传递给这个函数
    • 另一种是传递该数组的切片(因为切片的结构就包括底层数组的指针,其本身没有值)
  • 且传递数组类型的指针时,在函数内部,无需用符号 * 进行取值,可直接将参数当数组使用
package main

import (  
    "fmt"
)

func modify(arr *[3]int) {  // 接收 数组类型的指针 参数
    arr[0] = 90  // 本来应该写成  (*arr)[0] = 90 ,但是 go对数组指针做个处理
}

func main() {  
    a := [3]int{89, 90, 91}
    modify(&a)
    fmt.Println(a)  // [90 90 91] ,可以看到数组a的第一个元素也被修改为90了
}

3. 传入切片

  • 传入切片类型,能使得代码更加简洁,且更符合Go语言的习惯
package main

import (  
    "fmt"
)

func modify(sls []int) {  // 接收 切片类型 参数
    sls[0] = 90
}

func main() {  
    a := [3]int{89, 90, 91}
    modify(a[:])
    fmt.Println(a)  // [90 90 91] ,传切片时,数组a的第一个元素也被修改为90了
}

标签:int,fmt,数组,90,main,指针
From: https://www.cnblogs.com/Mcoming/p/18034715

相关文章

  • 掌握C语言指针,轻松解锁代码高效性与灵活性(下)
    ✨✨欢迎大家来到贝蒂大讲堂✨✨......
  • 掌握C语言指针,轻松解锁代码高效性与灵活性
    ✨✨欢迎大家来到贝蒂大讲堂✨✨......
  • Rust 智能指针
    本文在原文基础上有删减,原文参考Rust智能指针目录使用Box指向堆上的数据使用Box在堆上储存数据Box允许创建递归类型conslist的更多内容计算非递归类型的大小使用Box<T>给递归类型一个已知的大小通过Dereftrait将智能指针当作常规引用处理追踪指针的值像引用一样使用B......
  • C++ 第四节课 C和C++指针的区别 C的宏函数和C++内联函数的优缺点
    #include<iostream>//定义一个宏函数#defineADD(x,y)x+y;//宏函数具有速度快等特点但是写代码有些业务比较繁琐,所以C++中使用了内联函数优化//在定义函数前面添加一个inline把这个函数变成内联函数inlineintmax(intx,inty){returnx>y?x:y;}usi......
  • c++ 通过一个临时的空的智能指针(裸指针),交换两个智能指针(裸指针)的值,注意是交换值!!!!
    #include<iostream>#include<memory>usingnamespacestd;structParenTask//父亲{stringname{};};typedefshared_ptr<ParenTask>ParenTaskPtr;structSubTask:ParenTask//孩子{intuid{};};typedefshared_ptr<SubTask&g......
  • C++ 第三节课 指针的使用
    #include<iostream>usingnamespacestd;voidshow(){cout<<"全局函数"<<endl;}structStu{inta;voidwrite_code(){cout<<"成员函数"<<endl;}};intmain(){cout<<......
  • C++智能指针
    C++智能指针目录C++智能指针unique_ptr简单示例构造方法释放和重置shared_ptr构造方法常用函数构造重置和析构获得原始指针注意事项weak_ptr构造方法常用函数解决循环引用参考资料在C++中,内存的分配和释放都是由开发者手动实现的。这种方式虽然很灵活,但也十分容易出错,比如忘记释......
  • golang指针和结构体
    指针指针操作指针包括指针地址、指针类型和指针取值&:&符号放在变量前面进行取地址操作**:*放在变量前面根据地址进行取值指针地址:funcmain(){ varaint=1 //a的值是1--类型是int--,地址是0xc0000120c0,&是地址符号 fmt.Printf("a的值是%v--类型是%T--,地......
  • c++类开发的第三篇(讲明白友元函数和this指针)
    friend_function成员变量和函数的存储c++实现了封装,数据和处理数据的操作(函数)是分开存储的。c++中的非静态数据成员直接内含在类对象中,就像c语言的struct一样。成员函数并不会出现在对象中,而是作为类的一部分存储在代码段中,需要通过对象或对象指针进行调用。成员函数可......
  • C++ 以指针(*)作为参数和以指针引用(*&)作为参数的区别
    首先说结论,传入指针只能更改指针所指向的那一块内存的数据,传入指针引用既能修改指针本身的地址也能修改指针所指向的内存。假设现在有这样一个功能:传入一个数组指针,并将另一个数组的地址赋值给被传入的指针,以完成数据更新功能。定义两个函数,分别以指针和指针引用为参数://数组......