Система ( «пауза»); - Почему это не так?


131

Вот вопрос, который я не совсем понимаю:

Эта команда system("pause");преподается новым программистам как способ приостановить программу и дождаться продолжения ввода с клавиатуры. Однако многие опытные программисты, похоже, не одобряют это, как то, что не следует делать в той или иной степени.

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

Я сам новый программист без формального обучения программированию. Я использую его, потому что меня научили им пользоваться. Чего я не понимаю, так это того, что если это не то, что нужно использовать, то почему меня учили этим пользоваться? Или, с другой стороны, все-таки не так уж и плохо?

Что вы думаете по этому поводу?



5
Очевидно, людям нравится, когда их призывы ставятся на паузу, чтобы быть действительно эффективными. Другими словами, «Торопитесь и остановитесь!»
Ли Лувьер

63
Вас учили, потому что обычно учителя плохие программисты
которым

Прочтите этот совет о том, как задавать хорошие вопросы: [ Как задать вопрос ], [Написание идеального вопроса ].
Ади Инбар

9
@wich полная чушь.
Майкл Чурдакис

Ответы:


85

Это не одобряется, потому что это специфический для платформы взлом, который не имеет ничего общего с фактическим обучением программированию, а вместо этого позволяет обойти особенность IDE / OS - окно консоли, запущенное из Visual Studio, закрывается, когда программа завершает выполнение, и поэтому новый пользователь не видит вывода своей новой программы.

Bodging in System («пауза») запускает программу «паузы» в командной строке Windows и ожидает ее завершения, прежде чем продолжить выполнение программы - окно консоли остается открытым, чтобы вы могли прочитать вывод.

Лучшей идеей было бы поставить точку останова в конце и отладить ее, но здесь снова есть проблемы.


6
Visual Studio может запускать программу в двух режимах: с отладкой или без нее. При запуске в режиме отладки он остановится на первой точке останова. Если у вас его нет, он запустит программу и закроет консоль. Итак, если вы хотите, чтобы консольная программа остановилась, просто установите точку останова или, что еще лучше, запустите ее без отладки! Это запустит программу и остановит консоль.
Иван Месич

Это не только функция Visual Studio - если вы запускаете консольную программу из Windows (т. Е. Вместо загрузки командной строки и запуска ее оттуда), она также закроется, когда завершит выполнение.
JBentley

2
-1 Re «окно консоли, запущенное из Visual Studio, закрывается, когда программа завершает выполнение», нет, только тогда, когда программа запускается в отладчике. Повторно «запускает программу паузы в командной строке Windows», нет такой ( pauseэто внутренняя команда в cmd.exe). Список лучших идей также сильно отсутствует.
ура и hth. - Alf

Я думаю, что этот ответ - единственный, который касается того аспекта, что это обходной путь. Он работает с поведением конкретной среды выполнения, которая закрывает окно терминала, прежде чем вы сможете прочитать вывод программы. Что вам следует сделать, так это исправить эту среду. Если это невозможно, используйте этот обходной путь, возможно, только если он IsDebuggerPresent()возвращает true, и должным образом задокументируйте этот обходной путь («почему здесь этот код?»).
Ульрих Экхардт

43

Это медленно. Это зависит от платформы. Это небезопасно.

Во-первых: что он делает. Вызов «система» буквально похож на ввод команды в командной строке Windows. Чтобы ваше приложение совершило такой вызов, требуется множество настроек и демонтажа, а накладные расходы просто смехотворны.

Что, если программа под названием «пауза» была помещена в пользовательский PATH? Просто вызов системы («пауза») гарантирует только выполнение программы с именем «пауза» (надеюсь, что у вас нет исполняемого файла с именем «пауза»!)

Просто напишите свою собственную функцию «Pause ()», которая использует _getch. Хорошо, конечно, _getch также зависит от платформы (примечание: он определен в "conio.h") - но он намного лучше, чем system()если бы вы разрабатываете в Windows, и имеет тот же эффект (хотя вы обязаны предоставить текст с cout или около того).

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


61
Тем, кто жалуется на зависимость от платформы, это кажется странным _getch, особенно когда это предусмотрено стандартным C ++ getchar.
paxdiablo

33
я чувствую некоторую иронию в подсчете накладных расходов на взаимодействие с человеком)
ШПавель

1
@Spagpants: Возможно , вы не понимаете разницу между получать информацию от человека, и генерации изображений и звуков на человека.
yzt

1
@ Cheersandhth.-Альф - Хм? Когда я писал это 8 лет назад, я только что закончил отладку проблемы, которая была вызвана «системой (« пауза »)», потому что исполняемое имя проекта называлось «пауза», и он переходил в бесконечный цикл. Моя точка зрения все еще в силе, я не уверен, почему вы говорите, что я был неправ.

2
@paxdiablo getchar требует ввода и нажатия клавиши Enter. _getch требует простого нажатия клавиши независимо от того, какая это клавиша. Чтобы эмулировать _getch в Linux, вам понадобится 5-6 строк кода, чтобы изменить режим консоли, а затем вернуть его к значениям по умолчанию. Это не то же самое, это разные вещи. getchar не заменяет _getch.
Barnack

29
  • медленно: он должен перепрыгивать через много ненужного кода Windows и отдельную программу для простой операции
  • не переносится: зависит от программы паузы
  • плохой стиль: делать Системный вызов следует только тогда, когда это действительно необходимо
  • больше ввода: System ("пауза") длиннее, чем getchar ()

простой getchar () подойдет.


26

Использование system("pause");- это Ungood Practice ™, потому что

  • Это совершенно не нужно .
    Чтобы окно откройте консоль программы в конце , когда вы запускаете его из Visual Studio, использование Ctrl+ , F5чтобы запустить его без отладки, или другое место , точку останова в последней правой фигурной скобкой }в main. Итак, в Visual Studio проблем нет. И, конечно же, никаких проблем при запуске из командной строки.

  • Это проблематично и раздражает,
    когда вы запускаете программу из командной строки. Для интерактивного выполнения вы должны нажимать клавишу в конце без какой-либо цели. И для использования в автоматизации некоторых задач, которые pauseочень нежелательны!

  • Это не переносно.
    Unix-land не имеет стандартной pauseкоманды.

Это pauseвнутренняя cmd.exeкоманда, и ее нельзя переопределить, поскольку это ошибочно заявлено как минимум в одном другом ответе. Т.е. это не угроза безопасности, и утверждение о том, что антивирусные программы диагностируют его как таковое, столь же сомнительно, как и утверждение о переопределении команды (в конце концов, вызываемая программа на C ++ systemможет делать все, что может делать интерпретатор команд, и Больше). Кроме того, хотя этот способ приостановки крайне неэффективен по обычным стандартам программирования на C ++, это не имеет никакого значения в конце программы для новичка.

Итак, утверждения в толпе ответов перед этим неверны, и основная причина, по которой вы не должны использовать system("pause") или любую другую команду ожидания в конце вашего main, - это первый пункт выше: это совершенно не нужно, это абсолютно бесполезно , это просто очень глупо.


1
Иногда для быстрых тестов необходима Ungood Practice ™ .... то, что мы называем «быстрым и грязным»
Майкл Хефрати

22

Таким образом, он должен приостанавливать выполнение программ и выполнять системный вызов и выделять ненужные ресурсы, когда вы могли бы использовать что-то столь же простое, как cin.get (). Люди используют Систему («ПАУЗА»), потому что они хотят, чтобы программа ждала, пока они нажмут ввод, чтобы они могли видеть свой вывод. Если вы хотите, чтобы программа ждала ввода, для этого есть встроенные функции, которые также являются кросс-платформенными и менее требовательными.

Дальнейшее объяснение в этой статье.


Ух ты снова! Вы живете здесь? lol В любом случае, спасибо, я почитаю. А пока что ВАШИ мысли по этому поводу?
Faken

У меня был тот же вопрос, когда я впервые начал писать C несколько лет назад, и мне указали на ту же статью. Я лично использую getchar ().
John T

Хо, вау ... Я не занимался C ++ какое-то время, но да ... Есть определенно лучшие способы достичь тех же результатов
Newtopian

16

Вы можете использовать std::cin.get()с iostream:

#include <iostream> // std::cout, std::cin
using namespace std;

int main() {
   do {
     cout << '\n' << "Press the Enter key to continue.";
   } while (cin.get() != '\n');

   return 0;
}

Кроме того, system('pause')идет медленно, и включает в себя файл , который вы , вероятно , не нужно: stdlib.h. Он зависит от платформы и фактически вызывает «виртуальную» ОС.


3
Меня учили использовать System("pause")на первом курсе программирования, но я хотел иметь возможность запускать свои программы на моем Mac, поэтому мне пришлось узнать об этом cin.get().
daviewales

10

Потому что он не переносится.

pause

это программа только для Windows / DOS, поэтому ваш код не будет работать в Linux. Кроме того, как systemправило , не рассматривается как очень хороший способ , чтобы вызвать другую программу - это, как правило , лучше использовать CreateProcessили forkили что - то подобное.


4

Как указано в других ответах, есть много причин, по которым вы можете избежать этого. Все сводится к одной причине, которая делает остальное спорным. System()Функция небезопасна / ненадежная, и не должна быть введена в программу без необходимости.

Для студенческого задания это условие никогда не выполнялось, и по этой причине я бы провалил задание, даже не запустив программу, если бы присутствовал вызов этого метода. (Это было ясно с самого начала.)


4

Для меня вообще не имеет смысла ждать перед выходом без причины. Программа, которая выполнила свою работу, должна просто завершить работу и передать свои ресурсы ее создателю.

Также не стоит молча ждать в темном углу после рабочего дня, ожидая, когда кто-то опрокинет плечо.


7
Это глупый ответ. Часть программы, «выполняющей свою работу», отображает результаты своей работы пользователю. Поэтому он не должен заканчиваться, пока пользователь не сообщит ему, что он закончил с ним. Программа, которая исчезает с экрана пользователя через наносекунду после отображения результатов, бесполезна.
JBentley

1
@JBentley: Я рассказал о ситуации после отображения результатов, если они есть. Для отображения результатов существуют соответствующие шаблоны, такие как сигналы, прерывания, таймеры, прокрутка в вашем терминале, файлы. system("pause")сам по себе ничего не отображает. Программа интерфейса командной строки, которая вызывается не из командной строки и закрывается слишком рано, вызывается неправильно и с неправильными параметрами, и использование system("pause")для обхода неправильно запущенной программы на самом деле не является правильным.
Себастьян Мах

1
Я имею в виду, только представьте себе cat, less, vi, OpenOffice, Mathematica, GNU Octave, что , если бы они используют system("pause")? Это было бы неприятно.
Себастьян Мах

2
Да, это было бы неприятно, но сейчас вы конкретно говорите о проблемах system("pause"), тогда как ваш ответ говорит о «подождать перед выходом», что является гораздо более обобщенной концепцией. Многие из приведенных вами примеров на самом деле «ждут перед выходом», пока пользователь не сообщит программе, что он хочет, чтобы она завершилась. Я согласен, что system("pause")это не лучший способ добиться этого и что есть решения лучше, но ваш ответ не об этом.
JBentley

1
@JBentley О, конечно: если задержка / ожидание / приглашение является частью семантики программы, pauseпрочь!
Гонки

3
system("pause");  

неверно, потому что это часть Windows API и поэтому не будет работать в других операционных системах.

Вам следует попробовать использовать только объекты из стандартной библиотеки C ++. Лучшим решением будет написать:

cin.get();
return 0;

Но это также вызовет проблемы, если cinв вашем коде есть другие s. Потому что после каждого cinвы нажимаете Enterили, \nкоторый является символом пробела. cinигнорирует этот символ и оставляет его в буферной зоне, но cin.get()получает оставшийся символ. Таким образом, управление программой достигает линии, return 0и консоль закрывается, прежде чем вы сможете увидеть результаты.
Чтобы решить эту проблему, мы пишем следующий код:

cin.ignore();  
cin.get();  
return 0;

Это немного вводит в заблуждение. system()является стандартным и не относится к MS Windows. Однако команда pauseоболочки является наследием DOS и обычно встречается только там.
Ульрих Экхардт

1

Вот одна из причин, по которой вы не должны его использовать: это вызовет раздражение у большинства антивирусных программ, работающих в Windows, если вы передадите программу другому компьютеру, потому что это угроза безопасности. Даже если ваша программа состоит только из простой cout << "hello world\n"; system("pause"); ресурсоемкой программы, и программа получает доступ к команде cmd, которую антивирусы считают угрозой.


-1

плюсы к использованию системы («ПАУЗА»); а создание небольших частей вашей программы предназначено для ее самостоятельной отладки. если вы используете его для получения результатов переменных до и после каждого используемого вами процесса, чтобы убедиться, что они работают правильно.

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

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


-3

Все дело в стиле. Это полезно для отладки, но в остальном его не следует использовать в окончательной версии программы. На самом деле это не имеет значения по поводу памяти, потому что я уверен, что те ребята, которые изобрели систему («пауза»), ожидали, что она будет часто использоваться. С другой стороны, компьютеры в любом случае ограничивают свою память для всего, что мы используем на компьютере, и это не представляет прямой угрозы, такой как динамическое выделение памяти, поэтому я бы рекомендовал его для отладки кода, но не более того.


6
Это действительно не имеет значения по поводу памяти, потому что я уверен, что те ребята, которые изобрели систему ("пауза"), ожидали, что она будет использоваться часто, на самом деле не имеет никакого смысла. Никто этого не «изобрел», он pauseбыл разработан для использования в пакетных программах DOS, он никогда не предназначался для использования таким образом. Кроме того, существовали гораздо лучшие альтернативы, прежде чем кто-либо стал настолько сумасшедшим, чтобы напечатать фразу system("pause");.
которым
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.