Зачем нужны указатели в C++?

แชร์
ฝัง
  • เผยแพร่เมื่อ 23 ธ.ค. 2024

ความคิดเห็น • 77

  • @MihkailVoronov
    @MihkailVoronov 10 ชั่วโมงที่ผ่านมา

    Спасибо вам огромное! Ваш видеоурок очень познавателен и понятен, а ваш голос очень приятен! Очень надеюсь на дальнейший успех вашего канал!

  • @nikitos-mw9nb
    @nikitos-mw9nb 5 หลายเดือนก่อน +17

    Ты один из немногих людей которые могут понятно, кратко обьяснить материал. Большое тебе спасибо за работу!!!

  • @АндрейСоколов-п9я
    @АндрейСоколов-п9я 15 วันที่ผ่านมา +1

    Спасибо, наконец хоть понятно стало зачем их вообще придумали.

  • @randomcreations1079
    @randomcreations1079 4 หลายเดือนก่อน +7

    Очень доступно объяснил сложную для многих тему. Спасибо

  • @ServusSovereign
    @ServusSovereign 4 หลายเดือนก่อน +3

    Красавчег! Спасибо!

  • @stupnum8764
    @stupnum8764 5 หลายเดือนก่อน +23

    Дополню. Стек может быть каким угодно размером, все это настраивается, по умолчанию в динуксе 10мб, в винде 1мб. Еще важно, стек на самом деле принадлежит не процессу, а потоку, у каждого потока свой стек.

  • @megaspace-wy9mw
    @megaspace-wy9mw 6 หลายเดือนก่อน +10

    отлично рассказал, сохранил в плейлисте!

    • @Dima-Teplov
      @Dima-Teplov  6 หลายเดือนก่อน +3

      Спасибо!

    • @megaspace-wy9mw
      @megaspace-wy9mw 6 หลายเดือนก่อน +2

      @@Dima-Teplov быстро проверил другие видео и подписался

  • @mihail8159
    @mihail8159 5 หลายเดือนก่อน +5

    Спасибо , круто, по сути, коротко и ясно….

  • @qq-tn7bc
    @qq-tn7bc 5 หลายเดือนก่อน +5

    Спасибо большое, очень просто и понятно, идеально

    • @Dima-Teplov
      @Dima-Teplov  5 หลายเดือนก่อน +2

      Я рад, что понравилось, если что в описании есть ссылка на плейлист по указателям и пошаговый курс на степике.

  • @denis-dy4lo
    @denis-dy4lo 2 หลายเดือนก่อน +2

    В начале видео вы говорите: "когда вы обьявляете переменную, она автоматически размещается в стеке" и в конце видео, когда показываете примеры обьявляете те же переменные, но они вдруг размещаются в куче, несоответствие какое-то, и второй щепетильный момент- зачем нужен стек, если все данные можно сразу в кучу класть, да и почему нельзя в принципе увеличить размер стека до размеров кучи?

    • @Dima-Teplov
      @Dima-Teplov  2 หลายเดือนก่อน +4

      Здравствуйте, Денис! Это хорошие вопросы, спасибо! В конце видео я говорю о том, что есть возможность создавать переменные не в стеке, а в куче, просто я не показываю как.
      Насчет размера стека. Память - это общий ресурс для всех программ, стек - это сегмент памяти, который строго резервируется за этой конкретной программой (пока она работает). Если бы стек был размером 1 ГБ, то каждая программа при запуске «съедала» бы 1 ГБ минимум. Поэтому стек не делают таким большим. Куча устроена иначе: в ней память можно выделить, когда она вам нужна, и можно освободить, если она больше не нужна.
      Стек вообще очень важный сегмент памяти, он используется для вызова функций, передачи аргументов в функции и много еще для чего, кроме хранения переменных. И выделение памяти в стеке работает гораздо быстрее, чем в куче.
      Теперь немного с юмором. Стек - это холодильник у вас дома, куча - это магазин. Создать переменную в стеке - это как открыть холодильник и взять оттуда мороженое. Выделить память в куче - это как сходить в магазин за мороженым. Теперь я задам вам ваши же вопросы, а вы попробуйте на них ответить.
      1. «Зачем нужен холодильник, если сразу можно сходить в магазин»?
      2. «Почему нельзя в принципе сразу увеличить размер холодильника до размера магазина?»

    • @siyovushfurkati1642
      @siyovushfurkati1642 หลายเดือนก่อน

      @@Dima-Teplov все же непонятно одна вещь. Если переменные хранятся в куче то все таки зачем нужен указатель ?)))

    • @Dima-Teplov
      @Dima-Teplov  หลายเดือนก่อน +1

      @@siyovushfurkati1642 , данные можно хранить и в стеке и в куче. В стеке можно хранить небольшое количество данных, это удобно, у них есть имена. В куче у данных нет имен, поэтому для доступа к ним нужны указатели. Они хранят информацию о том, где именно в куче лежат нужные нам данные.

  • @viper_0097
    @viper_0097 6 หลายเดือนก่อน +7

    еще одно применение указателей - очень легко выбирать одну переменную между несколькими. Например, вам нужно менять картинки в зависимости от каких-либо событий. присваивать значение слишком дорого, зато можно сделать указатель на картинку. И в коде просто менять адрес указателя на нужную картинку и от указателя отрисовывать её. Это намного лучше, чем если бы писать какие-нибудь свичи с перечислениями картинок.

    • @brinza888
      @brinza888 5 หลายเดือนก่อน

      в C++ для этого есть ссылки, а голые указатели использовать категорически не рекомендуется

    • @viper_0097
      @viper_0097 5 หลายเดือนก่อน +1

      @@brinza888 эм, нет. Ссылку нельзя поменять, в отличие от указателей.

    • @brinza888
      @brinza888 5 หลายเดือนก่อน

      @@viper_0097 это все верно, но в вашем случае вместо «голых» указателей все же лучше использовать shared_ptr или unique_ptr.

    • @viper_0097
      @viper_0097 5 หลายเดือนก่อน

      @@brinza888 Ну... так они же для работы с кучей нужны, я же вам говорю; они вызывают ошибку, если им дать адрес на переменную в стеке.
      Я говорю именно про выборку между адресами каких-то переменных, чтобы упрощать код. Я сам использую и умные указатели, и обычные: первые, чтобы хранить в них ресурсы, вторые, чтобы делать то, что я писал выше: указывать.

    • @8olegator8
      @8olegator8 5 หลายเดือนก่อน +1

      @@brinza888 а что это такое за боязнь голых указателей? Они и без одежды хороши, если уметь ими пользоваться и корректно освобождать)

  • @проха_картоха
    @проха_картоха 6 หลายเดือนก่อน +3

    Очень хорошо обьяснили❤

  • @rikmorti4072
    @rikmorti4072 5 หลายเดือนก่อน +1

    Чувак продолжай, отличная подача. Лайк, подписка

  • @postoronny
    @postoronny 4 หลายเดือนก่อน +1

    Что такое "библиотека"?
    DLL?

  • @LithiumDeuteride-6
    @LithiumDeuteride-6 5 หลายเดือนก่อน +2

    Ещё надо про умные указатели.

    • @Dima-Teplov
      @Dima-Teplov  5 หลายเดือนก่อน

      Так как я записывал это изначально для школьников, то умные указатели сюда не вошли. Это, все таки, более сложная тема.

  • @tvsettv
    @tvsettv 4 หลายเดือนก่อน +1

    Указатели это как бы маркировка на ящике. Это Все что нужно знать об указателях. Маркировки могут быть разные, в зависимости, что лежит там.

  • @ted_res
    @ted_res 5 หลายเดือนก่อน +3

    Есть ещё одна важная особенность указателей. При передаче объекта в фукнцию в качестве параметра (допустим, по значению) он будет скопирован. То же самое касается возвращаемого значения: оно будет скопировано. Если вы работаете с объектом, размер которого 10КиБ, он постоянно будет копироваться в полном объёме, если его постоянно передавать между функциями, а это дополнительное время процессора. Если же передавать указатель на объект, сам объект остаётся там, где и был, а копируется только указатель на него.

    • @Dima-Teplov
      @Dima-Teplov  5 หลายเดือนก่อน +1

      Все верно! В плейлисте по указателям есть отдельный пример, который это демонстрирует. th-cam.com/video/r4tIRmRWPB0/w-d-xo.html

    • @f.linezkij
      @f.linezkij 4 หลายเดือนก่อน

      Вы говорите про то, как передать аргумент не по значению, а по ссылке: call-by-value vs. call-by-reference.
      Многие языки программирования не поддерживают указатели, но всё же поддерживают call-by-reference, например в Java это деоается с помощью амперсанта при имени передаваемой переменной, да и в C++ тоже. То есть это не объясняет, для чего вообще нужны указатели, если передавать аргумент по ссылке можно прекрасно и без них.

    • @ted_res
      @ted_res 4 หลายเดือนก่อน +1

      @@f.linezkij удачи вам вернуть значение из функции по ссылке.
      Говоря, что многие языки не поддерживают указатели, вы о каких именно языках говорите? Например в Java каждая переменная на экземпляр класса - это указатель под капотом. Часто о таком механизме говорят pass-by-object-reference, это не имеет отношения к pass-by-reference.
      Пишу на Java больше 15 лет, но первый раз слышу, что можно передавать значения по ссылке. Вероятно, вы спутали с С#.

  • @mihail8159
    @mihail8159 5 หลายเดือนก่อน +1

    ❤❤❤❤❤

  • @nicivanov5135
    @nicivanov5135 5 หลายเดือนก่อน

    Сейчас вышли новые процессоры с увеличенным L 1, L2 , L 3 хешем. Означаетли это, что стек будет больше у таких процессоров? Не 1 мб?
    Или нужно, что-то добовлять в код, чтобы получить плюшки от этого хеша?

    • @Dima-Teplov
      @Dima-Teplov  4 หลายเดือนก่อน

      Привет! Нет, стек - это понятие уровня программы, а не процессора. Когда из исходного кода на языка С++ собирается исполняемая программа, то используемая ей память организуется специальным образом. Каким именно - зависит от используемой операционной системы. Размер стека по-умолчанию различается в разных операционных системах, кроме того, некоторые IDE позволяют изменить размер стека программы в настройках линковщика. Однако суть от этого не меняется, размер стека фиксирован и не может быть изменен во время работы программы и, значит, он может переполниться.

  • @vvdvlas8397
    @vvdvlas8397 5 หลายเดือนก่อน

    Почему int x; будет размещен в стеке? Если он определен внутри функции - то да, в стеке. А если нет?

    • @alienhazzard7201
      @alienhazzard7201 4 หลายเดือนก่อน

      А если нет, тогда в сегменте данных.

    • @Happy-Gappy
      @Happy-Gappy 3 หลายเดือนก่อน

      Если это локальная переменна то на стеке, если глоабальная то в сегменте данных

  • @kosiak10851
    @kosiak10851 4 หลายเดือนก่อน +1

    Ну это как-то громко сказано, "указатели нужны для управления динамической памятью." Вообще-то какой угодно памятью. Захочу и на автоматические переменные буду указывать.

  • @ibnkhaleedone
    @ibnkhaleedone 5 หลายเดือนก่อน

    Четко

  • @alexeybaranov8869
    @alexeybaranov8869 5 หลายเดือนก่อน +1

    Еще можно endian менять :) short s = 0x0102; char* p = (char*)&s; *p = *p ^ *(p + 1); *(p+1) = *p ^ *(p + 1); *p = *p ^ *(p + 1);

  • @timbrazh8512
    @timbrazh8512 5 หลายเดือนก่อน

    Допустим. Но как программа "узнает" что одну переменную надо поместить в стек, а другую в кучу?

    • @Dima-Teplov
      @Dima-Teplov  5 หลายเดือนก่อน

      В языке С++ для того, чтобы программа создала переменную, объект или массив в куче программист должен сам ей об этом сказать. Для этого используются операторы new. Иначе все локальные переменные и массивы будут размещаться в стеке.

    • @adrew4
      @adrew4 5 หลายเดือนก่อน

      @@Dima-Teplov нет не все, только значимые типы будут размещены в стеке. Пишу на c# но и там и там string например - ссылочный тип. Есть еще некоторые примеры. Но на самом деле в ряде случаев оптимизации это не прибавит, должны выполнятся несколько условий чтобы ваш стек попал именно в кеш L3-L2, иначе особого смысла в этом мало с точки зрения оптимизации процессов.

    • @Dima-Teplov
      @Dima-Teplov  5 หลายเดือนก่อน

      @@adrew4 Здравствуйте! С++ это не С#, тут все немного по-другому... В С++ нет понятия "значимый тип". В С++ string - это не втроенный тип, а пользовательский класс (хоть и библиотечный). Сам объект типа string располагается в стеке, а вот содержимое строки действительно может размещаться в куче (для достаточно длинных строк), а может и в стеке (для коротких). Если вам интересно, то можете поэкспериментировать сами. Вот ссылочка на простой пример: onlinegdb.com/Sg32CX3W8

    • @adrew4
      @adrew4 5 หลายเดือนก่อน +1

      @@Dima-Teplov я не совсем понимаю как работает ваш скрипт по ссылке, но если данные строки фактически располагаются в куче, а на стеке находятся размер и указатель на эти данные, то в таком случае выражение о том что string будет находится на стеке не совсем справедливо. И если это работает так, значит это идентично языку C#, хоть и безусловно многие вещи отличаются, в том же интернировании. По логам судя по всему короткая строка находится где-то ближе к участку памяти на стеке. Насколько правдиво и правильно так оценивать фактическое быстродействие не возьмусь судить. В том смысле, не может ли среда вас обманывать говоря о том что переменная на стеке, а на самом деле там находится лишь указатель и это было сделано для оптимизации, чтобы среда думала что она работает с фактическими данными, например. Не знаю как практически это использовать, но такое предположение. Когда мы говорим о стеке и куче, это прежде всего об оптимизации, и если данные все равно находятся в куче, они уже ни при каких обстоятельствах не смогут попасть на кеш процессора, и тогда уже все равно в каком месте находится ссылка на эти данные. Чтобы взять их для работы придется потратить больше времени. Возможно я ошибаюсь, и если все именно так как вы описали, значит я не все процессы c++ понял. Просто это действительно любопытный вопрос.
      Меня просто смутила эта строчка из вики:
      "*Стек**: как и в C#, локальные переменные (включая объекты строк) могут храниться на стеке. Например, если вы создаете объект `std::string` в функции, он будет храниться на стеке. Однако сам объект `std::string` содержит только данные о строке (например, указатель на данные, длину и емкость). Фактические данные строки могут храниться в куче."
      В C# можно так же принудительно создать многие обьекты на стеке, но для этого необходимо обладать некоторыми фишками взаимодействия.

    • @Dima-Teplov
      @Dima-Teplov  5 หลายเดือนก่อน

      @@adrew4 Да, мне кажется, это вопрос терминологии. Когда я говорю о том, что объект или переменная класса находится в стеке, то я вовсе не имею ввиду, что все данные с которыми этот объект работает тоже находятся в стеке.
      Если в объекте есть указатели, то они могут указывать в любое место памяти - одни на стек, другие на кучу, третьи на статическую память или на сегменты кода. Поэтому в языке С++ нет никакого смысла говорить о том, что объект находится в куче, если часть данных с которыми он работает расположена в куче.
      В статье, то что касается С++ вроде все написано правильно. С# я не знаю, поэтому ничего не могу про него сказать.
      Насчет примера. Операция & (взятия адреса переменной) в С++ выполняется во время работы программы и возвращает реальный адрес объекта в оперативной памяти. Поэтому никакого обмана тут нет. По стандарту языка С++ все локальные переменные размещаются в стеке. При создании объекта пользовательского типа он может (в конструкторе) выделить память как в куче, так и в стеке. Что обычно и реализуется в классе std::string.
      Память под локальные переменные выделяется в стеке потому что это работает гораздо быстрее, чем выделение памяти в куче. Это оптимизация производительности.
      Насчет кэширования памяти, к сожалению, я не могу вам ответить. Логично, что стек будет кэшироваться "лучше", но, насколько я знаю, данные в "куче" тоже могут кэшироваться при частом доступе к ним. Думаю, что тут вы разбираетесь лучше меня.

  • @DeadnWoon
    @DeadnWoon 4 หลายเดือนก่อน +1

    Было бы очень неплохо, если бы кто-то (к примеру, Вы) сделали видео о том, как в теории можно было бы обойтись без указателей...

    • @Dima-Teplov
      @Dima-Teplov  4 หลายเดือนก่อน +1

      Боюсь, что тогда это будет видео не про С++. Конечно, в некоторых задачах можно "обойтись без указателей", например, вместо динамического выделения памяти под массив можно использовать готовый класс std::vector. Однако надо понимать, что внутри этого std::vector все равно используются указатели, он просто "прячет" их от программиста, но это не значит, что они не используются. Указатели связаны с архитектурой компьютера (это адреса данных в оперативной памяти), поэтому в итоге они всегда используются в любой программе. Их можно только "хорошенько спрятать", как, например, это делает Python. Поэтому, если вы не хотите работать с указателями, то просто используйте языки программирования, в которых они "спрятаны".
      Если вы хотите просто ездить на машине, то, наверное, знать внутреннее устройство машины не обязательно. Но если вы хотите быть профессиональным водителем, то полезно разобраться в том как эта машина устроена изнутри. С++ - это язык, которые требует не только навыков программирования, но и знания некоторых основ работы компьютера и операционных систем. Если, вдруг, вам это не нужно, то просто используйте другой язык программирования, например, Python.

    • @DeadnWoon
      @DeadnWoon 4 หลายเดือนก่อน +1

      Да, конечно, я имел в виду именно то, что язык мог бы быть достаточно низкоуровневым и при этом не использовать указатели как отдельное явление. Язык может, скажем, иметь некий спецификатор flexible, который подразумевает, что данная переменная может менять свой размер. Язык может иметь некий оператор вроде a?b, который выдаёт true, если по адресу a есть b незанятых последовательных байт. Размещать переменные по конкретному адресу можно с помощью некоего оператора at. При этом языку совсем необязательно иметь отдельное явление под названием указатель. По крайней мере, я так это вижу.

    • @Dima-Teplov
      @Dima-Teplov  4 หลายเดือนก่อน +1

      @@DeadnWoon Если переменная может менять свой размер, то под нее изначально надо выделять память самого большого размера, который она может занимать. То есть придется ввести какое-то ограничение по размеру, например, 1 Кб и тогда все переменные этого типа будут заниматься в памяти 1 Кб даже, если на самом деле там хранится 1 символ. Это уже выглядит не эффективно. Можно выделять память динамически по необходимости, но такое выделение памяти работает гораздо медленнее, чем выделение памяти в стеке, значит, это будет работать медленно. На мой взгляд эта одна из основных проблем такого подхода. Основной принцип языка С++ - это эффективность, поэтому такие варианты в нем не рассматриваются.
      Размещать переменные по какому-то конкретному адресу не достаточно, надо еще этот адрес где-то хранить и иметь возможность получать к нему доступ. Где он будет храниться? Кроме того, как в вашем языке можно описать такую структуру, как "связный список" без использования указателей?

    • @DeadnWoon
      @DeadnWoon 4 หลายเดือนก่อน

      @@Dima-Teplov Да, конечно, я имел в виду, что flexible и a?b работают с кучей. По поводу связного списка - надо подумать...

    • @alienhazzard7201
      @alienhazzard7201 4 หลายเดือนก่อน

      @@DeadnWoon /фейспалм/

  • @ВладиславГришин-ш7ш
    @ВладиславГришин-ш7ш 5 หลายเดือนก่อน +2

    можно вообще заглянуть - как устроен процессор, регистры, команды асма
    иии чудесным образом вопроса зачем не будет

  • @postoronny
    @postoronny 4 หลายเดือนก่อน +1

    Три ореха - это куча? (ц)

  • @ILYA1991RUS_Socratus
    @ILYA1991RUS_Socratus 4 หลายเดือนก่อน +1

    Это адрес.

  • @MSaidu-sj6vx
    @MSaidu-sj6vx 5 หลายเดือนก่อน +2

    Чтобы было понятно "твердолобым" показывайте на примере простенькой программы, можно еще дебаггером пройтись по адресам и носом ткнуть. Вот тогда "дойдет" точно. Указатели, структуры - сложная штука, с наскока не понимают многие ( еще и объяснить "зачем это надо", не каждый преподаватель доносит ).

    • @Dima-Teplov
      @Dima-Teplov  5 หลายเดือนก่อน

      Да, спасибо, все верно. Собственно я так и сделал в этом курсе: stepik.org/course/196036/promo
      Это просто один из видеоуроков оттуда.

  • @Варис-д3ш
    @Варис-д3ш 4 หลายเดือนก่อน

    Почему я не начал изучение языков с С+ а послушав советы взялся за Питон? С+ лучше дает понимание как работает железо

    • @Dima-Teplov
      @Dima-Teplov  4 หลายเดือนก่อน

      Да, такие языки как С и C++ действительно заставляют разбираться во внутренних механизмах работы программ. Однако Питон проще освоить и, если вам надо быстро что-то написать для себя, то это отличный вариант. С++ в основном используется там, где требуется скорость и эффективное использование ресурсов.

  • @tohoto2183
    @tohoto2183 5 หลายเดือนก่อน

    Если возникает такой вопрос,то вы начали изучать С++ сильно неправильно .

    • @Dima-Teplov
      @Dima-Teplov  5 หลายเดือนก่อน

      Согласен, но, тем не менее, вопрос возникает у многих.

    • @alienhazzard7201
      @alienhazzard7201 4 หลายเดือนก่อน

      Если возникает такой вопрос, то программирование вообще изучать не нужно. Это не ваше.

    • @ОлегСеверо-Двинский
      @ОлегСеверо-Двинский หลายเดือนก่อน

      Программистам уже лет 24 не важно какой размер стека и памяти.