Что будет выведено в результате исполнения этого кода?

Сообщения
1 471
Реакции
271
Сайт
tehadm.ru
C-подобный:
package main

import "fmt"

func main() {
    v := 5
    p := &v
    fmt.Print(*p, " ")
    changePointer(p)
    fmt.Print(*p)
}

func changePointer(p *int) {
    v := 3
    p = &v
}

C-подобный:
package main

import "fmt"

func main() {
    v := 5 //Переменную v инициализировали со значением 5. Теперь там лежит 5.
    p := &v //Нашли адрес в памяти для переменной v, и записали его в переменную р. Теперь р - это указатель, и там лежит адрес v. Адрес области памяти выглядит примерно так: 0х000012. Переменная р не знает, что лежит в v, но знает ее адрес. Легко запомнить: амперсанд напоминает слово "адрес". Пэ инициализируем как адрес вэ.
    fmt.Print(*p, " ") //Звездочку просто запомнить как глазок в двери, когда мы приходим по адресу типа 0х000012 и берем то, что там лежит. А лежит там v, все с тем же значением. Печатаем его, потом пробел.
    changePointer(p) //Берем копию р (там лежит какой-то адрес по-прежнему) и передаем его в функцию. Го в свои функции передает всегда копию переменной, а оригинал остается в мейн, это важно. Идем и смотрим что происходит в функции...
    fmt.Print(*p) //Функция нам ничего не вернула, мы пришли ни с чем, поэтому пошли по старому адресу р, увидели глазок, открыли дверь и взяли там то же самое, что и в прошлый раз. Теперь вы знаете, как это работает. )))
}

func changePointer(p *int) { //Функция принимает копию адреса, но ничего не возвращает. Здесь звездочка путает нас тем, что стоит перед типом. Но мы все равно представляем глазок. Мы в функции, стоим перед дверью по адресу р, нам осталось открыть ее, и взять то что там лежит (а там по-прежнему v с неизменным значением).
    v := 3 //Но что это? Мы не открываем дверь, а инициализируем абсолютно новую переменную v в этой функции. В main про эту v ничего не известно. Это совсем другой Сережа (v).
    p = &v //А вот тут интересно! Мы берем эту р (копию той р, которая осталась в мейне), и говорим: взять адрес v и положить его в р. У нас здесь другая v, значит и адрес в р будет другим. Но кто об этом в курсе? В функцию мейн ничего не передается, ("все осталось в Вегасе"). Функция завершает работу.
}

C-подобный:
v := 5
   //в переменной лежит значение 5
   fmt.Println("адрес V", &v)
   p := &v
   //в переменную р положили указатель на переменную v, &v - значит взять адрес v и положить этот адрес в p
   //р - становится типом указатель, * и лежит там теперь адрес типа - 0х000002 (например)
   //fmt.Print(*p, " ")
   //печатаем *р - то есть пойдем по адресу который там лежит и напечатаем то что есть по этому адресу
   //попробуйте в этом месте напечатать просто р, типа так
   fmt.Println("адрес который лежит в Р", p)
   //он напечатает именно адрес, который лежит в р и он будет такой же, который мы печатали раннее со строкой "адрес V"
   changePointer(p)
   //fmt.Print(*p)
   fmt.Println("адрес который лежит в Р после функции", p)
   // поэтому тут указатель все на ту же v которая 5
   // !!!!!!ВАЖНО!!!!!!  Если вы хотите повыводить что в какой переменной лежит. Если это указатель как Р, то нужно выводить просто Р
   // А если вы хотите вывести именно адрес переменной то &p. Потому что Р это указатель конкретно тут в main и печатая Р вы напечатаете
   // ТО ЧТО ЛЕЖИТ ВНУТРИ Р(адрес V), а если вы напечатаете &P, то он выведет адрес САМОЙ ЭТОЙ Р.
}

func changePointer(p *int) {
   v := 3
   // мы в другой функции, инициализируем ДРУГУЮ v под которую выделен ДРУГОЙ адрес. Потому что мы в ДРУГОЙ функции
   // можно на каждую переменную что в main, что тут, написать
   fmt.Println("адрес переменной V в changePointer", &v)
   // и посмотреть что адрес v в main и тут разные
   p = &v
   fmt.Println("адрес переменной Р в changePointer", &p)
   // тут тоже самое мы в ДРУГОЙ функции инициализировали р, точно так же можно вывести принтом адрес той р в main и этой р и они будут разные
   // и в этом случае мы переменной р в ЭТОЙ функции присвоили адрес v которая тоже в ЭТОЙ функции
   // если написать *р = v, мы пойдем по адресу, который в р, придем в переменную v = 5 и ТУДА положим 3, значение которое у нас в v этой функции
   // то есть мы изменим изначальную v
   // и второй раз fmt.Print(*p) после функции выведет 3, все по тому же адресу.
}
 
Назад
Верх Низ