Step 10 (S-11062)

From Stepik Wiki
Jump to: navigation, search

Step on Stepik: https://stepik.org/lesson/558/step/10

Step 10 (S-11062) 1.png

[00:00 - 00:16] все + есть 3 перегружаемых оператора который создает особый порядок вычислений это операторы логического и логическую или а также оператор запятая что значит что оператор создает особый порядок вычислений давайте посмотрим на примере начнем с логических операторов


[00:16 - 00:31] пусть на добавлено 2 переменные целочисленную типа альба и нам будет важно что а равно 0 и рассмотрим вычисления следующие выражения логическая и следующих утверждений


[00:31 - 00:49] а не равно 0 и б равно бы поделить на 1 выражение то логическое выражение его значение имеет и был 2 выражение арифметическое выражение его значение это значение переменной бы


Step 10 (S-11062) 2.png

[00:49 - 01:05] после то присваивание и после этого она будет образовано к логическому типу следующим образом таким образом преобразуется все стройно числовые типы 0 преобразуется в false


[01:05 - 01:21] а все оставшееся то есть то что не равно 0 преобразуется в труд но нам ведь это не особенно важно просто на будущее да то есть все чтобы тема преобразуются типа bool


[01:21 - 01:39] да довольно простым преобразовать 0 преобразуется фолс все что не 0 образуется по знаю как это выражение будет вычисляться если бы это было выражение без специального логического оператора например место оператора


[01:39 - 01:56] и здесь то я в оператор + то вычисление выражений происходил бы следующем порядке сначала вы числились обе скобки при этом в каком конкретно порядке они сами вычислялись не определено то есть для выражений не указан в таком порядке


[01:56 - 02:14] это может решаться компилятор но важно что обе скобки были вычислены до того как вызвался бы оператор + но это естественно для того чтобы увидеть оператора + надо знать значение обоих операндов


[02:14 - 02:30] но так как у нас не оператор + оператор логического и то вычисления будет происходить в другом порядке сначала всегда сначала будет вычислен 1 скобка то гарантирует сначала начинается значения 1 операнда


[02:30 - 02:47] если значение 1 ранда true то вычисляется 2 почему так происходит потому что если вдруг значение 1 равно false как например нашем случае в нашем случае действительно


[02:47 - 03:03] значение 1 равно false а не равно 0 а действительность это утверждение неверно 1 и теперь вне зависимости от значения 2 аргумента то есть независимо от того что там будет true или false то есть


Step 10 (S-11062) 3.png

[03:03 - 03:23] независимо от того что какой то на что нибудь 2 скобки все равно оператор и вернет false если хотя бы 1 из 2 аргументов то или иное как 1 уже falls мы вычислили то вычисления 2 аргумента


Step 10 (S-11062) 4.png

[03:23 - 03:38] не требуют такой вычисления логических операторов называется short circuit лоджик по английски


Step 10 (S-11062) 5.png

[03:38 - 03:53] так и по русски называется навязывают ленивые вычисления числа операторов ты лезешь лезешь есть важно что стандарт гарантирует


[03:53 - 04:11] что при вычислении такого рода поражений сначала будет вычислен 1 операнд и только в том случае если 1 операнд окажется through будет поселятся 2 противном случае он сейчас нибудь это очень важно потому что


[04:11 - 04:28] в нашем случае например если бы 2 операнд все таки вычислил что то мы получили ошибку у нас здесь произошло бы деление на 0 то есть вот он и прямоугольник часть кода выдает ошибку мы пытаемся поделить на 0


Step 10 (S-11062) 6.png

Step 10 (S-11062) 7.png

[04:28 - 04:43] но так как нам гарантировать что 2 операнд читаться не будет то мы здесь защитились от ошибки мы 400 и даже не проверив а равенство 0 а логично поведения задаете для оператора или


Step 10 (S-11062) 8.png

Step 10 (S-11062) 9.png

[04:43 - 04:58] можно посмотреть на следующий пример здесь так такой же логическое выражение такое с оператором или и в 1 скобки мы вместо неравенство 0 проверяем на равенство так как 1 скобка


[04:58 - 05:16] проверка а на равенство 0 вернет true то 2 скобку читать уже не нужно то есть 2 операнд никак не повлияет на результат операции или или вернет нам true если хотя бы 1 из операндов тру но так как


Step 10 (S-11062) 10.png

Step 10 (S-11062) 11.png

[05:16 - 05:34] 1 оператор true мы уже на 1 операнд ру уже нашли то значение 2 операнда никак не повлияет важно не то что она никак не повлияет а важно то что компилятор гарантируются чтобы вычисления 2 2 операнда


Step 10 (S-11062) 12.png

[05:34 - 05:49] оно не будет происходить в том случае если 1 операнд оказался равным и соответственно мы точно также как и в случае с и здесь защитились от ошибки мы проверили сначала она равен 0


Step 10 (S-11062) 13.png

Step 10 (S-11062) 14.png

[05:49 - 06:04] если а оказалось равно 0 то мы не будем выделить на это очень важно что именно гарантирует то что можно делать а именно этот гарантирован и можно писать код опираясь на так играть


Step 10 (S-11062) 15.png

[06:04 - 06:20] еще раз отмечу что если бы здесь место оператора логического или логическую и стояли бы какие то другие операторы там оператора умножить поделить + бинарный и или бинарный или


Step 10 (S-11062) 16.png

Step 10 (S-11062) 17.png

[06:20 - 06:40] побитовое то есть побитовой и побитовой или это обычно оператор они работают целыми числами а логические игры логические лет они работают с типом так вот если бы такой другой оператор то при вычислении смогу оператора сначала вычисли значения


[06:40 - 06:57] обоих его верандой и после этого хочется до значения самого оператора такое поведение это особенность логических операторов и можно проверить это например при помощи следующих выражений то есть


Step 10 (S-11062) 18.png

[06:57 - 07:16] создать 2 функции foobar и если функция foo будут возвращать какой то значение которое приводится к фолс то функция бар вот здесь вот зацени будет ну и соответственно если вы будете возвращать ненулевой этом числовое значение или просто потрясающее отношение бол


Step 10 (S-11062) 19.png

[07:16 - 07:35] true то будет вызываться вот по этой строчке еще 1 оператор который дает питания порядок вычисления это оператор запятая оператор запятая позволяет гарантировать порядок вычисления для 2 поставить на поражение


Step 10 (S-11062) 20.png

Step 10 (S-11062) 21.png

[07:35 - 07:53] иногда используется для того чтобы аккуратно записать какой нибудь цикл коротко но в хорошем стоит избегать этого оператора так как он такой довольно редко используемый и малоизвестных есть человек который может дать ваш код может не понять что вы имеете в виду


[07:53 - 08:11] оператор запятая гарантирует что при вычислении данные выражения сначала будет вычислена 1 операнд то есть то что до запятой а после это будет вычислим 2 при этом если я напишу тебе какую то переменную то


Step 10 (S-11062) 22.png

[08:11 - 08:27] а равняется то значение которое будет после выполнения этой строчке это будет значение которое вернулся из 2 фронт то есть вот это значение будет


Step 10 (S-11062) 23.png

Step 10 (S-11062) 24.png

[08:27 - 08:44] присвоено значение который вернулся с 1 функции оно будет проигнорирован вот важно что в данном случае мы в любом случае выполним оба операнда но в отличие от обычных операторов


Step 10 (S-11062) 25.png

Step 10 (S-11062) 26.png

[08:44 - 09:03] для оператора запятой гарантирует что сначала будет вычислена 1 часть выражения а потом мы разобрали что значит особый порядок вычисления теперь почему нам это важно а важно то потому что при перегрузке этих операторов этот особый порядок вычисления


Step 10 (S-11062) 27.png

[09:03 - 09:22] уже не будет гарантировать то есть перегружена операторы будут вести себя как обычные операторы если я например для какого нибудь класса реализующего например плойку с 3 значениями трибун


[09:22 - 09:37] если для такого класса перегрузить оператор логического и то данный оператор будет вести себя как любой другой перегруженный оператор то есть так как данный оператор реализуется при помощи


Step 10 (S-11062) 28.png

[09:37 - 09:53] функция а для вычисления функции нужно сначала вычислить значение всех аргументов то в отличие от встроенного биологического и для данного оператора будет гарантироваться что оба него


Step 10 (S-11062) 29.png

Step 10 (S-11062) 30.png

[09:53 - 10:09] операнда вот всегда вычтены до того как будет если назначения собственно оператора то есть если у логического и для типа есть строгий порядок вычисления при этом если 1 значение


Step 10 (S-11062) 31.png

[10:09 - 10:25] окажется для оператора и false то 2 значения не будет вычислена при перегрузке нас получается все по другому у нас порядок вычисления операндов не задом но гарантируется что


Step 10 (S-11062) 32.png

Step 10 (S-11062) 33.png

[10:25 - 10:41] оба варианта будут вычислены до того как будет вызван собсно перегруженный оператор и алогично происходит с или просто оператора или и при перегрузки оператора запятая все точно также


Step 10 (S-11062) 34.png

[10:41 - 10:56] то есть перегружен оператор запятая уже не гарантирует порядок вычисления в этом кроется проблема перегрузки этих операторов при перегрузке этих операторов вы теряете


Step 10 (S-11062) 35.png

Step 10 (S-11062) 36.png

[10:56 - 11:13] те свойства которые есть в оригинальных операторов это может привести к неприятностям к непониманию в коде то есть человек который будет будет недоумевать почему же вы здесь используете логический оператор и и вроде бы


Step 10 (S-11062) 37.png

[11:13 - 11:24] 2 аргумент не должен вычисляться в некоторых случаях ну или меня вычислять поэтому нужно очень аккуратно переиграть оператор по хорошему избегать их перегрузки


Step 10 (S-11062) 38.png