Указатели на GO

Указатели на GO

#GO


Указатели на языке программирования Go или Golang — это переменная, которая используется для хранения адреса памяти другой переменной. Указатели на Голанг также называются специальными переменными. Переменные используются для хранения некоторых данных по определенному адресу памяти в системе. Адрес памяти всегда находится в шестнадцатеричном формате.


Какая потребность в указателях?

Чтобы понять эту потребность, во-первых, мы должны понять концепцию переменных. Переменные — это имена, данные в ячейке памяти, где хранятся фактические данные. Для доступа к хранимым данным нам нужен адрес этой конкретной ячейки памяти. Запоминать все адреса памяти (шестнадцатеричный формат) вручную — непростая задача, поэтому мы используем переменные для хранения данных, и к переменным можно обращаться, просто используя их имя.

Golang также позволяет сохранять шестнадцатеричное число в переменной, используя буквальное выражение, то есть число, начинающееся с 0x, является шестнадцатеричным числом.

Пример: в приведенной ниже программе мы сохраняем шестнадцатеричное число в переменной. Но вы можете видеть, что тип значений int и сохраняется как десятичное число, или вы можете сказать, что десятичное значение типа int хранит. Но основной смысл объяснения этого примера заключается в том, что мы храним шестнадцатеричное значение (считайте его адресом памяти), но это не указатель, поскольку он не указывает на какое-либо другое место в памяти другой переменной. Это просто пользовательская переменная. Так что возникает необходимость в указателях.


// Программа Голанг для демонстрации переменных

// сохраняем шестнадцатеричные значения

package main

  

import "fmt"

  

func main() {

  

    // сохраняем шестнадцатеричное

    // значения в переменных

    x := 0xFF

    y := 0x9C

      

    // Отображение значений

    fmt.Printf("Type of variable x is %T\n", x)

    fmt.Printf("Value of x in hexdecimal is %X\n", x)

    fmt.Printf("Value of x in decimal is %v\n", x)

      

    fmt.Printf("Type of variable y is %T\n", y)

    fmt.Printf("Value of y in hexdecimal is %X\n", y)

    fmt.Printf("Value of y in decimal is %v\n", y)    

      

}

Выход:

Type of variable x is int
Value of x in hexdecimal is FF
Value of x in decimal is 255
Type of variable y is int
Value of y in hexdecimal is 9C
Value of y in decimal is 156

Указатель — это особая переменная, которая используется не только для хранения адресов памяти других переменных, но также указывает, где находится память, и предоставляет способы для определения значения, хранящегося в этой ячейке памяти. Обычно он называется «Специальный тип переменной», потому что он почти объявлен как переменная, но с * (оператор разыменования).

Декларация и инициализация указателей

Прежде чем мы начнем, есть два важных оператора, которые мы будем использовать в указателях.

Оператор также называется оператором разыменования, используемым для объявления переменной указателя и доступа к значению, сохраненному в адресе.

Оператор & называется оператором адреса, который используется для возврата адреса переменной или для доступа к адресу переменной для указателя.

Объявление указателя :

var pointer_name *Data_Type

Пример: ниже указатель типа string, который может хранить только адреса памяти строковых переменных.

var s *string

Инициализация указателя: для этого вам нужно инициализировать указатель с адресом памяти другой переменной, используя оператор адреса, как показано в следующем примере:

// normal variable declaration
var a = 45

// Initialization of pointer s with 
// memory address of variable a
var s *int = &a

Пример:


// Программа Голанг для демонстрации декларации

// и инициализация указателей

package main

  

import "fmt"

  

func main() {

  

    // берём нормальную переменную

    var x int = 5748

      

    // объявление указателя

    var p *int

      

    // инициализация указателя

    p = &x

  

        // отображение результата

    fmt.Println("Value stored in x = ", x)

    fmt.Println("Address of x = ", &x)

    fmt.Println("Value stored in variable p = ", p)

}

Выход:

Value stored in x =  5748
Address of x =  0x414020
Value stored in variable p =  0x414020

Важные моменты:

  • Значение по умолчанию или нулевое значение указателя всегда равно нулю . Или вы можете сказать, что неинициализированный указатель всегда будет иметь значение nil.

Пример:


  • // Программа Голанг для демонстрации
  • // нулевое значение указателя
  • package main
  •   
  • import "fmt"
  •   
  • func main() {
  •   
  •         // берём указатель
  •     var s *int
  •       
  •     // отображение результата
  •     fmt.Println("s = ", s)
  • }
  • Выход:
s =  <nil>
  • Объявление и инициализация указателей может быть сделано в одну строку.

Пример:

var s *int = &a
  • Если вы указываете тип данных вместе с объявлением указателя, то указатель сможет обработать адрес памяти этой указанной переменной типа данных. Например, если вы берете указатель строкового типа, то адрес переменной, которую вы дадите указателю, будет только строковой переменной типа данных, а не любого другого типа.
  • Чтобы преодолеть вышеуказанную проблему, вы можете использовать концепцию определения типа ключевого слова var . Нет необходимости указывать тип данных во время объявления. Тип переменной-указателя также может быть определен компилятором как обычная переменная. Здесь мы не будем использовать оператор *. Он будет внутренне определяться компилятором, когда мы инициализируем переменную с адресом другой переменной.Пример:

  • // Программа Голанг для демонстрации
  • // использование вывода типа в
  • // переменные указателя
  • package main
  •   
  • import "fmt"
  •   
  • func main() {
  •   
  •     // используя ключевое слово var
  •     // мы не определяем
  •     // любой тип с переменной
  •     var y = 458
  •       
  •     // берём указатель на переменную используя
  •     // ключевое слово var без указания
  •     // тип
  •     var p = &y
  •   
  •     fmt.Println("Value stored in y = ", y)
  •     fmt.Println("Address of y = ", &y)
  •     fmt.Println("Value stored in pointer variable p = ", p)
  • }
  • Выход:
Value stored in y =  458
Address of y =  0x414020
Value stored in pointer variable p =  0x414020
  • Вы также можете использовать сокращенный синтаксис (: =) для объявления и инициализации переменных-указателей. Компилятор сам определит, что переменная является переменной-указателем, если мы передаем адрес переменной с помощью оператора & (address) .Пример:

  • // Программа Голанг для демонстрации
  • // использование сокращенного синтаксиса в
  • // переменные указателя
  • package main
  •   
  • import "fmt"
  •   
  • func main() {
  •   
  •     // используя оператор: = для объявления
  •     // и инициализируем переменную
  •     y := 458
  •       
  •     // берём указатель на переменную используя
  •     //: = присваивая его с
  •     // адрес переменной y
  •     p := &y
  •   
  •     fmt.Println("Value stored in y = ", y)
  •     fmt.Println("Address of y = ", &y)
  •     fmt.Println("Value stored in pointer variable p = ", p)
  • }
  • Выход:
Value stored in y =  458
Address of y =  0x414020
Value stored in pointer variable p =  0x414020

Разыменование указателя

Как мы знаем, оператор * также называется оператором разыменования. Он не только используется для объявления переменной указателя, но также используется для доступа к значению, хранящемуся в переменной, на которую указывает указатель, и которая обычно называется косвенной или разыменованной . * Оператор также называется значением по адресу . Давайте рассмотрим пример, чтобы лучше понять эту концепцию:

Пример:


// Программа Голанг для иллюстрации

// концепция разыменования указателя

package main

   

import "fmt"

   

func main() {

   

    // используя ключевое слово var

    // мы не определяем

    // любой тип с переменной

    var y = 458

       

    // берём указатель на переменную используя

    // ключевое слово var без указания

    // тип

    var p = &y

   

    fmt.Println("Value stored in y = ", y)

    fmt.Println("Address of y = ", &y)

    fmt.Println("Value stored in pointer variable p = ", p)

  

    // это разыменование указателя

    // использование оператора * перед указателем

    // переменная для доступа к сохраненному значению

    // на переменную, на которую он указывает

    fmt.Println("Value stored in y(*p) = ", *p)

  

}

Выход:

Value stored in y =  458
Address of y =  0x414020
Value stored in pointer variable p =  0x414020
Value stored in y(*p) =  458

Вы также можете изменить значение указателя или в ячейке памяти вместо назначения нового значения переменной.

Пример:


// Программа Голанг для иллюстрации

// вышеупомянутая концепция

package main

   

import "fmt"

   

func main() {

   

    // используя ключевое слово var

    // мы не определяем

    // любой тип с переменной

    var y = 458

       

    // берём указатель на переменную используя

    // ключевое слово var без указания

    // тип

    var p = &y

   

    fmt.Println("Value stored in y before changing = ", y)

    fmt.Println("Address of y = ", &y)

    fmt.Println("Value stored in pointer variable p = ", p)

  

    // это разыменование указателя

    // использование оператора * перед указателем

    // переменная для доступа к сохраненному значению

    // на переменную, на которую он указывает

    fmt.Println("Value stored in y(*p) Before Changing = ", *p)

  

    // меняем значение y, присваивая

    // новое значение для указателя

    *p = 500

  

     fmt.Println("Value stored in y(*p) after Changing = ",y)

  

}

Выход:

Value stored in y before changing =  458
Address of y =  0x414020
Value stored in pointer variable p =  0x414020
Value stored in y(*p) Before Changing =  458
Value stored in y(*p) after Changing =  500


Report Page