Що таке "коротке замикання" на мовах, подібних до мови С?


15

Я чув, що термін "коротке замикання" вживається в C, C ++, C #, Java та багатьох інших. Що це означає і в якому сценарії воно буде використовуватися?


6
Стаття у Вікіпедії про поняття: en.wikipedia.org/wiki/Short-circuit_evaluation Це оптимізація в оцінці &&оператора.
wirrbel

1
@wirrbel Я вважаю, що це стосується ||і ... принаймні, так і повинно.
Radu Murzea

1
@RaduMurzea Дійсно. Контраст ||і &&до &і, |щоб побачити тонку різницю. Попросіть просту програму оцінити 1 || printf("yay");проти 0 || printf("yay");і 1 | printf("yay");проти, 0 | printf("yay");щоб побачити
різниці

Відповіді:


36

Коротке замикання на C - це те, коли логічний оператор не оцінює всі його аргументи.

Візьмемо для прикладу і &&, цілком очевидно, що 0 && WhoCaresце буде помилково незалежно від того, що WhoCaresє. Через це C просто пропускає оцінку WhoCares. Те саме стосується 1 || WhoCares, це завжди буде правдою. Через це ми можемо писати подібний код

CanFireMissiles && FireMissiles()

Таким чином ми уникаємо робити якісь потенційно неможливі операції. Якщо ми не можемо вистрілити ракети, ми, звичайно, не хочемо намагатися. Це зазвичай використовується вказівниками, особливо файловими вказівниками.

 bool isN(int* ptr, int n){
     return ptr && *ptr == n;
 }

Це є безліччю інших корисних способів уникнути зайвих обчислень

 isFileReady() || getFileReady()

Це дозволяє уникнути зайвої роботи, якщо нам цього не потрібно.


1
У будь-який час, якщо я відповів на ваше запитання, ви можете встановити прапорець біля нього, щоб позначити ваше запитання як відповідь
Daniel Gratzer

7
Я не люблю CanFireMissiles && FireMissiles(), оскільки змушує мене підозрювати, що ви зловживаєте коротким замиканням, щоб викликати побічні ефекти. Я відчуваю, що ти приховуєш дії умовно. Такий код краще писати як if(CanFireMissiles){FireMissiles();}або if(CanFireMissles){didFireMissiles = TryFireMissiles(); if(didFireMissiles){...}}.
Брайан

2
Я б стверджував, що єдине використання - приховати побічні ефекти. Зазвичай не сорт "Вибуху міста", але такі речі, як перенаправлення покажчика або використання системних ресурсів, також робляться таким чином на C досить часто. Дивіться сторінку вікіпедії, весь розділ, що використовується, є "Приховування побічних ефектів"
Даніель Гратцер

2
@jozefg ви також можете використовувати його для запобігання виконанню дорогих операцій, наприклад IsInCache(value) || IsInDatabase(value), де IsInDatabase може зайняти час (особливо, якщо використання мобільного пристрою та затримки в мережі є проблемою).
mgw854

4

"Коротке замикання", як правило, відноситься до " Оцінки короткого замикання ", що є загальною концепцією, а не лише специфікою C.

Булева оцінка операторів зліва направо, тому будь-які умови, які роблять інші умови непотрібними, корисні. Таким чином, ви можете перевірити стан, який виключає інші умови згодом, тим самим дозволяючи часткову оцінку логічних операцій, а не оцінювати всю справу.

Приклад:

while((x && y) == 1) {
    //This bit will not execute if x is 0 or y is 0 but y won't even be 
    //evaluated due to short circuit evaluation if x is 0.
}

Більш складний приклад:

if((a || b || c || d || e || f || g || h || i || j || k) == 1) {
    /* If any of these are equal to 1 the whole expression is equal to 1,
     * thus doesn't it make sense to short circuit evaluate this?
     * Saves a bunch of time.
     */
}

8
Коротке замикання менше заощаджує час, але більше не оцінюється. Функція, що не оцінюється, також не матиме побічного ефекту, якби вона була оцінена.
Пітер Б

Ви знаєте, == 0це не тільки не потрібно, це може насправді заплутати деяких людей.
Дедуплікатор

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.