О как же ответсвенен АВТОР , он действительно хочет нас научить , а не просто хвастается своими умениями.
@AllEXE784 жыл бұрын
Когда const и * "скачут" туда сюда меня это иногда вводит в ступор. Вот совет с хабра, который поможет разобраться: "_Существует мнемоническое правило, позволяющее легко запомнить, к чему относится const. Надо провести черту через "*", если const слева, то оно относится к значению данных; если справа - к значению указателя_"
@stilljunior17643 жыл бұрын
благодарю;)
@camradsamka44273 жыл бұрын
+
@parvizinoyatov80093 жыл бұрын
+ thanks
@vladimirsagabalk13643 жыл бұрын
есть еще один способ, который кажется более простым: читать конструкцию справа налево: const int *px - тут px указатель на int константный (константное значение) int *const px - тут px константный указатель на int (константный указатель)
@vladimirsagabalk13643 жыл бұрын
и добавлю, в первом варианте, если понимать разницу между разыменованием и указателем, то логичнее *px, где * - операция разыменования. Т.е. мы работаем со значением. И там неважно, как мы укажем int const *px или const int *px, но читаться будет привычнее - указатель на константный инт. А во втором варианте, все же правильнее, как мне кажется, из логики синтаксиса записать int* const px (внимание на пробел), так понятнее, что мы работаем с интовым указателем (указателем на целое, на int). Для компилятора пробелы рядом с "*" не важны, а для понимания написанного, нам, человекам удобнее и понятнее. Это я сейчас, как-то для себя вывел. Поправьте, если я не прав.
Блин! Забил я на программирование на месяца два) Жаль конечно, но всякой жести много в жизне произошло, но тут пересматриваю чтобы освежить память что вообще происходит! Блин, как же круто! Такие мелкие детали, но такие полезные.
@user-vo8mf2xw6f5 ай бұрын
не останавливайся только!
@std40427 жыл бұрын
Спасибо большое.)
@ФиламентАфтер5 ай бұрын
Спасибо большое за это видео! ❤Очень было приятно узнать про это
@outcast-cr5yy6 жыл бұрын
Спасибо за урок
@lossofsoul36938 ай бұрын
О, спасибо! Этой фишки не знал. Видел, но не понимал что это значит
@ГлебДомрачев-ь7э4 жыл бұрын
Большое спасибо за уроки, Сергей! Думаю, это фишка очень поможет избежать всяких синтаксических ошибок. К примеру, на злосчастных инкрементах и декрементах. А если какую-то собственную операцию в функции использовать, то тем более
@Ms001man6 жыл бұрын
Сергей, спасибо большое за урок!
@amd3s7 жыл бұрын
Спасибо!
@ГусейнСалахов5 жыл бұрын
Спасибо за урок))
@alexandrprodan87944 жыл бұрын
Классная фишка, спасибо!
@mykhailomorhal21817 жыл бұрын
Спасибо)
@archiechellaut94833 жыл бұрын
Большое спасибо вам за урок и прекрасное пояснение, Сергей!
@nikitazubat9825 жыл бұрын
посмотрев этот урок решил сделать такое дз:из прошлого урока сделать функцию заполнения массива и функцию его вывода.Теперь иду смотреть дальше
@ОлегС-ь7и5 жыл бұрын
5:40 Потерять в функции указатель на выделенную в main() область памяти можно, только передавая в функцию указатель как ссылку: void FillArray(int *&arr, int size=1) { arr = new int; }
@ДмитрийНормов-ю6ц2 жыл бұрын
@@anoname10 как твои успехи в С++ ?
@abkl28497 жыл бұрын
спасибо
@temirlantolegenov56253 жыл бұрын
очень ответственный подход, благодарю
@dualsense73234 ай бұрын
если кто сюда дошел, и не понимает, что конкретно защищает const в двух видах записи (перед или после указателя). То как бы вот: Т.к указатель может принимать в себя адрес какой либо переменной, мы можем через указатель менять значение этой переменной. const ПЕРЕД указателем защищает значение, на которое ссылается указатель. то есть по записи ||const int* a = что-то||, мы не сможем сделать ||*a = что-то_другое||, const-анируется значение, менять его нельзя, но записью ||a = &что-то_еще|| мы переадресовываем указатель, теперь указывает на новое значение (и это новое значение мы также не можем менять. const ПОСЛЕ указателя защищает сам адрес, тут уже наоборот мы можем через указатель изменить значение, но не можем переадресовать указатель: ||*a = что-то_другое|| - можно, ||a = &что-то_еще|| - нельзя. и тут уже как бы сами решайте, что защищать - адрес или значение, или оба.
@maksstepanov809813 күн бұрын
а разве то ,что мы размер делаем константным , не мешает сделать нам этот массив динамическим? не подскажешь? я имею вв виду еже на этапе компиляции мы ведь не сможем вводить размер массива?
@dualsense732313 күн бұрын
@maksstepanov8098 в плане: const int size = 10; int *a = new int[size]; ? сам size да, менять нельзя, но массив всё также динамичен, просто чтобы использовать его динамичность придется идти окольными путями. Например в функцию меняющую размер массива параметром может быть копия константной size, и эта копия сама константой не является, размер массива можно менять.
@alexeymi26186 жыл бұрын
Спасибульки
@gagikarakelyan60144 жыл бұрын
. Спасибо
@ВікторіяДобридень-ц5х3 жыл бұрын
Сергей, скажите пожалуйста, в чем разница между int* const и const int* const?
@incrazyble85843 жыл бұрын
int* const - это константный указатель на int, т. е. сами значения в массиве мы можем изменять, а указателю не можем присвоить, например, nullptr. const int* const - это константный указатель на константные int, здесь мы гарантируем, что не сможем внутри функции поменять как указатель, так и сами значения.
@aviator1472 Жыл бұрын
@@incrazyble8584 а зачем вообще в функцию писать int* const arr?
@russiantutorials4763 Жыл бұрын
@@aviator1472 в уроке было сказано это и человек уже ответил на этот вопрос выше. Чтобы указатель на массив в функции было никак нельзя изменить, к примеру приписать nullptr, чтобы затереть адрес. Это может не гарантировать правильность выполнения функции, однако предохраняет программистов от вмешательства в указатель (чтобы нельзя было его изменить), так как компилятор выведет ошибку в таком случае и грамотный программист все поймет.
@aviator1472 Жыл бұрын
@@russiantutorials4763 спасибо
@romastyle78233 жыл бұрын
Спасибо
@krouvy4694 жыл бұрын
Не подскажите правильно ли написана функция для очистки памяти из под двумерного динамического массива? void del(int** const arr, const int row, const int col) { for (int i = 0; i < row; i++) { for (int j = 0; j < row; j++) { delete[] arr[j]; } delete[] arr[i]; /// Мне кажется, что эта или } delete[] arr; //// эта строчка лишние. Но не знаю какая. Но думаю, что та, что выше. Ведь i это указатель на указатель } // а j это уже колонки в которых хранится массив.
@krouvy4694 жыл бұрын
Ааа.. забудьте это я от недосыпа. Также как раньше, ничего не изменилось, надо было так оставить: void del(int** const arr, const int row) { for (int i = 0; i < row; i++) { delete[] arr[i]; } delete[] arr; }
@furjis-dev4 жыл бұрын
Глянь в предыдущем видео как это реализовано. Должно быть в точности также. Когда ты пишешь arr[i][j] то ты работаешь со значениями внутренних массивов. Сначала должен удалить внутренние массивы (блягодаря вот этим скобкам delete [] ... компилятор понимает, что ты чистишь массив. Поэтому удаляется всё, что связано с массивом. Запись arr[i] и запись arr[j] одинаковы. Это всего лишь счётчики. Они не привязаны к столбцам или строкам. Проход по строкам и столбцам реализуется засчёт структуры вложеннего массива.(строка меняется только после того как ты полностью по ней прошёлся). Поэтому запись delete arr[i] и delete arr[j] одинаковы и не требуют вложенного массива. Короче говоря, запись удаления двумерного динамического массива должна выглядеть так: for (int i=0;i
@furjis-dev4 жыл бұрын
не увидел
@krouvy4694 жыл бұрын
@@furjis-dev Все равно спасибо) У меня от недосыпа часты переписки с самим собой)
@wasony.1264 жыл бұрын
7:41😂😂😂😂
@havemerc4 жыл бұрын
Интересно, а в конце списка будут приложения с графическим интерфейсом создаваться? Хочу именно по порядку идти, просто интересно
@daps9516 Жыл бұрын
А как будучи сторонним разработчиком поковыряться в чужой функции? Используя только IDE и библиотеку. Хотяб посмотреть как реализованы функции sizeof, sqrt, max и т.д, т.п.
@ОлександрШульга4 жыл бұрын
Первый раз посмотрел и показалось все понятно , но заметил , что я не понимаю "int* arr" , поскольку как я понимаю создаётся массив указателей , а не интов , получается какой-то бред
@паносниглайдер4 жыл бұрын
int* arr означает что ты передаёт указатель на массив типа int
@2912kar3 жыл бұрын
ХМ, это конечно классно, что в функцию можно принимать значения и обрабатывать их там как константное. Но как быть если умник сделал *.dll файл например и в теле функции написал к примеру так (int size1 = size + 1;) и на цикл подставил не константу size а замену size1? Я понимаю это выглядит нелепо но все-же!
@ВиталийСахно-ъ1р5 жыл бұрын
А как корректно сделать процедуру освобождения памяти? Попробовал сам на основе предыдущего урока - не получилось: void FreeArrey(int* const arr, const int size) { // очистка памяти for (int i = 0; i < size; i++) { delete [] arr[i]; // (выводит красным arr и пишет "Выражение должно быть указателем на полный тип объекта" } delete[] arr; arr = nullptr; // и здесь arr красный и пишет "выражение должно быть допустимым для изменения левосторонним значением" - если убираю первый "const" в передаваемом значении в функцию - то ругаться перестает. А вот в "delete [] arr[i];" по прежнему ругается! }
@theyandwe90475 жыл бұрын
Зачем ты по строкам идешь? Ведь их нет у тебя. delete[] arr; Этого вполне достаточно.
@panda93035 жыл бұрын
Чтобы правильно удалить динамический массив, нужно в функцию передавать указатель по ссылке. , типа int* &pArr. Иначе ты память не освободишь, так как в функцию передается копия указателя, имеющая другой адрес в памяти, именно адрес расположения указателя в памяти. В твоем случае ты получишь утечку памяти все равно. Delete не сработает как ты от него ожидаешь, так как ему нужен первоначальный адрес указателя по которому была выделена память в куче.
@TGrod4 жыл бұрын
я так понимаю, что уже отвечать не надо, но может кому-то понадобится))) Когда ты удаляешь по строчкам в массиве, ты пытаешься удалить не указатель, а интовый объект. У тебя массив не двумерный, а одномерный. Т.е. когда ты пишешь delete arr[i] компилятор думает, что ты хочешь в динамическом массиве arr удалить динамический массив с индексом i. Но у тебя там находятся интовые объекты. Вот у тебя и выдало "Выражение должно быть указателем...", так как delete можно применить только к указателям. Когда ты пишешь arr = nullptr, ты пытаешься задать указателю arr нулевой указатель (или как он там называется), но ты в аргументах функции сам написал int* const arr, что означает, что ты указатель arr в этой функции изменить не можешь. Ты пытаешься ему присвоить nullptr. Надеюсь, что понятно объяснил и это кому-то понадобится) Ещё раз говорю, что это не для человека, который оставил коментарий с просьбой помочь (так как ему уже думаю помощь не нужна), а для новичков))))
@geoleb81062 жыл бұрын
почему мы в первом параметре функции FillArray указали arr без квадратных скобочек впереди?
@wasony.1264 жыл бұрын
👍👍👍
@ИНФОРМАЦИЯДЛЯУСПЕШНЫХ5 жыл бұрын
Спсб
@simongreyse41716 жыл бұрын
почему слово const в аргументах функции стоит в разных местах? А иногда одновременно в двух.
@ПользовательИнтернета-э6г5 жыл бұрын
Тупа по преколу
@TheWladberlin5 жыл бұрын
смотри внимательней 6:40
@adiletastana27816 жыл бұрын
слишком много константы, тема указателей, динамических массивов довольно сложная, я думаю это нужно было потом как нибудь добавить как дополнительный материал. Незнаю как у других, но у меня в голове образовалась каша от всего этого
@voltamper966 жыл бұрын
Давай видео твоем исполнение))) я тож уже потерялся в этих указательях и массивах
@obolochka15375 жыл бұрын
Да указатели еще та ересть
@codingposture4 жыл бұрын
Незн норм
@sympathies17694 жыл бұрын
Помогите мне пожалуйста, я кое-что не понял. Почему когда мы передаем обычный массив в функцию (arr, size); а ф-я принимает (int arr, const int size); а когда передаем динамический, то функция принимает (int* arr, const int size); , но передаём мы в него все ровно (arr, size); ?
@priest_21523 жыл бұрын
Потому что добавляя звездочку и конст мы указываем, что это указатель, кол-во ячеек которого нельзя изменить. А в стат. массиве конст не нужен т.к. он в принципе то и не может менять свой размер. Только, конечно, если нужно чтобы он был только читаемым.
@Mishanya00 Жыл бұрын
ф-я принимает (int *arr, const int size) или (int arr[], const int size). (int arr, const int size) вы просто передаете число int, а не указатель на начало массива. То есть динамический и статический массивы передаются одинаково, просто указатель на первый элемент
@mihas11065 жыл бұрын
это одномерный масив?
@TheWladberlin5 жыл бұрын
Да, один аргумент дынных и один размер массива
@mihas11064 жыл бұрын
@@dusk-a-stone-throw понял
@ДмитрийНормов-ю6ц2 жыл бұрын
@@dusk-a-stone-throw ну ты загнул)))
@Viamsupervadetvadens7 жыл бұрын
up
@relaxingspeedmusic12692 жыл бұрын
А где можно попрактиковать свои умения?
@MrNichosik7 ай бұрын
Codewars
@nosferatu27996 жыл бұрын
Непонятно только, кто дизы ставит... конкуренция?)
@8lxckcxt4 жыл бұрын
хейтеры какие-то бестолковые)
@roockeet34603 жыл бұрын
просто 4 человека случайно поставили вместо лайка диз
@samvelvardanyan60856 жыл бұрын
В чём разница между int * const var и const int * var ? А так спасибо за урок.
@samvelvardanyan60856 жыл бұрын
Я не понял.
@samvelvardanyan60856 жыл бұрын
Спасибо большое. Вот теперь я понял.
@pilot-jx4zp4 жыл бұрын
читаем справа налево. 1-ое : var это неизменяемый указатель на целое число и 2-ое : var это указатель на целое число, которое нельзя менять.
@pilot-jx4zp Жыл бұрын
@@horhegarsia4221Честно говоря давно занимался и не практикую посему могу соврать. Но исходя из ранее мною написанного надо буквально читать справа на лево. int*const - где " const " читаем первым (неизменяемый), " * " читаем вторым (указатель), " int " читаем третьим (на целое число). В ваших рассуждениях "var" читать вообще не надо, так как это название указателя и может быть любым (int * const ptichki) и к смыслу выражения отношения не имеет.
@ivan_kirsanov Жыл бұрын
Был не в курсе, но получилось :-) void FillArray(int** const arr, const int * rows, const int cols) { for (int i = 0; i < *rows; ++i) { arr[i] = new int [cols]; } for (int i = 0; i < *rows; ++i) { for (int j = 0; j < cols; ++j) arr[i][j] = rand() % 100; } } void ShowArray(int** const arr, const int* rows, const int cols) { for (int i = 0; i < *rows; ++i) { for (int j = 0; j < cols; ++j) cout
@Sooderone6 ай бұрын
🧠
@temirlansafargaliyev88736 жыл бұрын
осталась непонятной разница между int* const arr и const int* const arr в параметрах первой и второй функций
@camradsamka44276 жыл бұрын
ну, во второй функции нам же не надо изменять содержимое массива, поэтому его тоже сделали const, что бы мифический второй разработчик, который использует эту мифическую dll не ссался за свои данные, а по принимаемым параметрам видел, что с ними ничего не случится. Как я это понял.
@pashakkaa6 жыл бұрын
int* const arr - нельзя сделать так, чтобы указатель *arr указывал на какие-то другие данные. Но, значения данных, на которые указывает *arr, можно изменять. То есть, мы не можем написать: arr = new int(135), но можем написать: arr[0] = 135. const int* const arr - нельзя сделать так, чтобы указатель *arr указывал на какие-то другие данные и нельзя изменять значения данных, на которые указывает *arr. То есть, мы не можем написать: arr = new int(135) и не можем написать: arr[0] = 135.
@qymb49916 жыл бұрын
Pasha, спасибо тебе большое!
@TheWladberlin5 жыл бұрын
смотри внимательней 6:40
@boyjak72052 жыл бұрын
Здравствуете, подскажите почему при изменении переменой size компилятор считает ее константой, но если указать ее в качестве размера массива создаваемого внутри функции(int a[size];), то компилятор пишет что size должен быть константой? Означает ли это то, что на момент старта программы компилятор резервирует место в памяти для всех данных используемых в функциях, даже если некоторые функции могут быть не вызваны?
@maksstepanov809813 күн бұрын
а разве то ,что мы размер делаем константным , не мешает сделать нам этот размер динамическим?
@obolochka15375 жыл бұрын
правильно ли я понял в примере с int* const arr - это указатель на массив в котором нельзя задать другое количество элементов (если передал arr[8], то кол-во элементов всегда будет 8 штук). Но можно изменять сами значения этих элементов , к например значение второй элемента масива было 12 но можем изменить на 19 (arr[8] = {4, 12, 25, 65, 26, 6, 7 ,12} --> arr[8] = {4, *19* , 25, 65, 26, 6, 7 ,12} ) ??
@TheWladberlin5 жыл бұрын
Как я понял, прежде чем вызвать эту функцию с новыми параметрами - т.е. имя и размер, ты должен позаботиться об очистке. А далее уже эта функция для того и сделана, чтобы заполнять новыми данными при каждом обращении к ней.
@Artyomuchch5 жыл бұрын
Как я понял, int* const arr - это указатель, адрес которого нельзя изменить.
@obolochka15375 жыл бұрын
Artyomuchch думаю это указатель на постоянный масив с целыми числами
@sleepyNovember_project11 ай бұрын
"const int* const arr" эт пипец :D
@johnconstantine63312 жыл бұрын
1) Если пользователь видит параметр конст это как-то гарантирует, что функция написана правильно? Бредятина полная. 2) С точки зрения боязни, что функция что-то неожиданно поменяет в данных пользователя - так в данном примере size передается по значению. И там, откуда функция вызвана с size ничего не может случиться. 3) Более того, с указателем тоже ничего не может случиться. Сам указатель передается по значению. Если внутри функции его переприсвоить, ничего "во внешнем мире" не изменится с точки зрения пользователя, а утечка памяти все равно будет, если в функции использовано "new" без "delete[]". Итого: абсолютно непонятно, зачем эти все const нужны за исключением единственного применения: указывать ключевое слово перед типом массива, чтобы функция гарантировано его не изменяла. Тем более что по значению массив передать невозможно (на сколько мне известно)