sistemi ( “duraklama”); - Neden yanlış?


131

İşte tam olarak anlamadığım bir soru:

Komut, system("pause");yeni programcılara bir programı duraklatmanın ve klavye girişinin devam etmesini beklemenin bir yolu olarak öğretilir. Bununla birlikte, birçok deneyimli programcı tarafından çeşitli derecelerde yapılmaması gereken bir şey olarak kabul edilmiyor gibi görünüyor.

Bazı insanlar kullanmanın iyi olduğunu söylüyor. Bazıları bunun sadece odanızda kilitli olduğunuzda ve kimse izlemediğinde kullanılacağını söylüyor. Bazıları kişisel olarak evinize gelip kullanırsanız sizi öldüreceklerini söylüyor.

Ben, resmi programlama eğitimi olmayan yeni bir programcıyım. Kullanıyorum çünkü kullanmam öğretildi. Anlamadığım şey, kullanılacak bir şey değilse, neden onu kullanmam öğretildi? Ya da diğer taraftan, gerçekten o kadar da kötü değil mi?

Bu konuda düşünceleriniz nelerdir?



5
Görünüşe göre insanlar gerçekten verimli olmak için çağrılarının duraklatılmasını seviyorlar. Başka bir deyişle, "Acele et ve dur!"
Lee Louviere

63
Size öğretildi çünkü genellikle öğretmenler kötü programcılardır
hangi

Lütfen iyi sorular sormak için şu tavsiyeyi okuyun: [ Nasıl Sorulur ], [Mükemmel soruyu yazma ].
Adi Inbar

9
@wich tamamen saçma.
Michael Chourdakis

Yanıtlar:


85

Aslında programlamayı öğrenmekle hiçbir ilgisi olmayan platforma özgü bir hack, bunun yerine IDE / OS'nin bir özelliğini dolaşmak için - Visual Studio'dan başlatılan konsol penceresi, programın yürütülmesi bittiğinde kapanır ve bu yüzden yeni kullanıcı, yeni programının çıktısını göremez.

Sistemde Bodging ("pause"), Windows komut satırı "duraklatma" programını çalıştırır ve programın yürütülmesine devam etmeden önce bunun sona ermesini bekler - çıktıyı okuyabilmeniz için konsol penceresi açık kalır.

Daha iyi bir fikir, sonuna bir kesme noktası koymak ve hatalarını ayıklamak olabilir, ancak bunun yine sorunları var.


6
Visual Studio programı iki modda çalıştırabilir: hata ayıklama ile veya hata ayıklama olmadan. Hata ayıklama modunda çalıştırıldığında, ilk kırılma noktasında duracaktır. Tanımlı bir taneniz yoksa, programı çalıştıracak ve konsolu kapatacaktır. Dolayısıyla, konsol programının durmasını istiyorsanız, sadece bir kesme noktası ayarlayın veya daha da iyisi, hata ayıklamadan çalıştırın! Bu, programı çalıştıracak ve konsolu durduracaktır.
Ivan Mesic

Bu yalnızca Visual Studio'nun bir özelliği değildir - Windows'tan bir konsol programı çalıştırırsanız (yani bir komut istemini yükleyip oradan çalıştırmanın aksine), yürütme bittiğinde de kapanır.
JBentley

2
−1 Re "Visual Studio'dan başlatılan konsol penceresi, program yürütmeyi bitirdiğinde kapanır", hayır, yalnızca program hata ayıklayıcıda çalıştırıldığında geçerlidir. Yeniden "Windows komut satırı" duraklatma "programını çalıştırır, böyle bir şey yoktur ( pausedahili bir komuttur cmd.exe). Daha iyi fikirlerin listesi de ciddi şekilde eksik.
Şerefe ve hth. - Alf

Sanırım bu yanıt, bunun geçici bir çözüm olduğu yönüne değinen tek cevap. Program çıktısını okumadan önce bir terminal penceresini kapatan belirli bir yürütme ortamının davranışı etrafında çalışır. Yapmanız gereken, o ortamı düzeltmek. Bu yapılamıyorsa, bu geçici çözümü kullanın, muhtemelen yalnızca IsDebuggerPresent()doğru döndürüyorsa ve bu geçici çözümü doğru şekilde belgeleyin ("bu kod neden burada?").
Ulrich Eckhardt

43

Yavaş. Platforma bağlıdır. Güvensiz.

Birincisi: Ne işe yarar? "Sistem" i çağırmak, kelimenin tam anlamıyla Windows komut istemine bir komut yazmaya benzer. Uygulamanızın böyle bir arama yapması için bir ton kurulum ve sökme var - ve ek yük çok saçma.

Ya "duraklatma" adlı bir program kullanıcının PATH'ına yerleştirildiyse? Sadece sistemi çağırmak ("duraklat"), yalnızca "duraklat" adlı bir programın yürütülmesini garanti eder (umarız, "duraklat" adlı yürütülebilir dosyanızın olmaması!)

_Getch kullanan kendi "Pause ()" işlevinizi yazmanız yeterlidir. Tamam, elbette, _getch de platforma bağımlıdır (not: "conio.h" içinde tanımlanmıştır) - ancak system()Windows üzerinde geliştirme yapmaktan çok daha iyidir ve aynı etkiye sahiptir (ancak metni sağlamak sizin sorumluluğunuzdur cout ya da öylesine).

Temel olarak: Basitçe iki satır kod ekleyebildiğinizde ve biri çok daha esnek bir mekanizma ekleyebildiğinizde neden bu kadar çok potansiyel sorunu ortaya çıkarasınız?


61
Platform bağımlılığından şikayet eden biri için _getch, özellikle standart C ++ sağladığında bunu önermek kesinlikle tuhaf görünüyor getchar.
paxdiablo

33
bir insanla etkileşim için ek yükü hesaplarken biraz ironi hissediyorum)
ShPavel

1
@Spagpants: Belki bir insan girdi almak ve görüntü ve sesleri üreten arasındaki farkı anlayamıyorum de bir insan.
yzt

1
@ Cheersandhth.-Alf - Hm? Bunu 8 yıl önce yazdığımda, 'system ("pause")' den kaynaklanan bir sorunu hata ayıklamayı yeni bitirmiştim çünkü projenin yürütülebilir adı "duraklama" olarak adlandırılıyordu ve sonsuz bir döngüye girecekti. Demek istediğim hala geçerli, neden hatalı olduğumu söylediğinden emin değilim.

2
@paxdiablo getchar bir giriş gerektirir ve ardından enter tuşuna basılmalıdır. _getch, anahtar ne olursa olsun sadece bir tuşa basmayı gerektirir. _Getch'i linux üzerinde taklit etmek için konsol modunu değiştirmek için 5-6 satır koda ihtiyacınız var ve sonra onu varsayılana geri döndürmelisiniz. Aynı değil, farklı şeyler yapıyor. getchar, _getch yerine geçmez.
Barnack

29
  • yavaş: basit bir işlem için birçok gereksiz Windows kodundan ve ayrı bir programdan geçmesi gerekir
  • taşınabilir değil: duraklatma programına bağlıdır
  • iyi bir tarz değil: bir Sistem çağrısı yapmak yalnızca gerçekten gerekli olduğunda yapılmalıdır
  • daha fazla yazma: Sistem ("duraklatma") getchar () 'dan daha uzun

basit bir getchar () yeterli olacaktır.


26

Kullanmak İyi system("pause");Değildir ™ çünkü

  • Tamamen gereksiz .
    Visual Studio, kullanımdan çalıştırdığınızda sonunda programın konsol penceresini açık tutmak için Ctrl+ F5ayıklama olmadan çalıştırmak için, ya da başka bir yerde son Sağ parantez bir kesme noktası }arasında main. Yani, Visual Studio'da sorun yok. Ve tabii ki komut satırından çalıştırdığınızda hiç sorun değil.


  • Programı komut satırından çalıştırdığınızda sorunlu ve can sıkıcı . Etkileşimli yürütme için, herhangi bir amaç olmaksızın sonunda bir tuşa basmanız gerekir. Ve pauseçok istenmeyen bazı görevlerin otomasyonunda kullanmak için !

  • Taşınabilir değil.
    Unix-land'in standart bir pausekomutu yoktur .

pauseKomut bir iç olduğunu cmd.exeyanlışlıkla en azından bir başka cevap iddia edildiği gibi, komuta ve geçersiz kılınan olamaz. Yani bu bir güvenlik riski değildir ve AV programlarının bunu bu şekilde teşhis ettiği iddiası, komutu geçersiz kılma iddiası kadar şüphelidir (sonuçta, bir C ++ programısystem komut yorumlayıcısının yapabildiği her şeyi kendi başına yapacak konumdadır ve Daha). Ayrıca, bu tür bir duraklatma, C ++ programlamanın olağan standartlarına göre son derece verimsiz olsa da, aceminin programının sonunda hiç önemi yoktur.

Bu nedenle, bundan önceki cevaplar ordusundaki iddialar doğru değildir ve kullanmamanız gereken ana sebep system("pause") veya sonundaki herhangi bir başka bekleme komutu , mainyukarıdaki ilk noktadır: tamamen gereksizdir, kesinlikle hiçbir amaca hizmet etmez. , bu çok aptalca.


1
Bazen hızlı testler için bir İyi Olmayan Uygulama ™ gerekir .... "hızlı ve kirli" dediğimiz şey
Michael Haephrati

22

Özetle, cin.get () kadar basit bir şey kullanırken, programların çalışmasını duraklatmalı ve bir sistem çağrısı yapmalı ve gereksiz kaynakları tahsis etmelidir. İnsanlar Sistem'i ("DURAKLAT") kullanır çünkü programın çıktılarını görebilmek için enter tuşuna basana kadar beklemesini ister. Bir programın girdi beklemesini istiyorsanız, platformlar arası ve daha az talepkar olanlar için yerleşik işlevler vardır.

Bu makalede daha fazla açıklama .


Vay canına, yine sen! burada mı yaşıyorsun? lol Neyse, teşekkürler, biraz okuma yapacağım. Bu arada, bu konudaki düşünceleriniz nelerdir?
Faken

Birkaç yıl önce C'ye ilk başladığımda da aynı soruyu sormuştum ve aynı makaleye işaret edilmiştim. Kişisel olarak getchar () kullanıyorum.
John T

Vay canına ... Bir süredir C ++ yapmadım ama evet .. aynı sonuçları elde etmenin kesinlikle daha iyi yolları var
Newtopian

16

Sen kullanabilirsiniz std::cin.get()den 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;
}

Ayrıca, system('pause')yavaş ve muhtemelen gerekmez bir dosya içerir: stdlib.h. Platforma bağlıdır ve aslında 'sanal' bir işletim sistemi çağırır.


3
System("pause")İlk yıl programlama kursunda kullanmam öğretildi , ancak programlarımı Mac'imde çalıştırabilmek istedim, bu yüzden öğrenmem gerekiyordu cin.get().
daviewales

10

Çünkü taşınabilir değil.

pause

sadece windows / dos programıdır, bu yüzden bu kodunuz linux üzerinde çalışmayacaktır. Ayrıca, systemgenellikle başka bir programı çağırmanın çok iyi bir yolu olarak görülmez - genellikle kullanmak CreateProcessveya forkbenzeri bir şey kullanmak daha iyidir .


4

Diğer yanıtlarda listelendiği gibi, bundan kaçınmak için bulabileceğiniz birçok neden vardır. Her şey, gerisini tartışmalı hale getiren tek bir nedene indirgeniyor. System()Fonksiyon nedeniyle güvenli / güvenilir olmayan ve gerekmedikçe bir program içine edilmemelidir.

Bir öğrenci ödevi için bu koşul hiçbir zaman karşılanmadı ve bu nedenle, bu yönteme bir çağrı varsa, programı çalıştırmadan bile bir ödevde başarısız olurdum. (Bu, en baştan netleştirildi.)


4

Benim için genel olarak sebepsiz yere çıkmadan önce beklemek mantıklı değil. İşini yapmış bir program, sadece bitmeli ve kaynaklarını yaratıcısına geri vermelidir.

Kişi ayrıca bir iş gününden sonra karanlık bir köşede birinin omzunu devirmesini bekleyerek sessizce beklemez.


7
Bu aptalca bir cevap. "İşini yapan" bir programın bir kısmı, çalışmasının sonuçlarını kullanıcıya göstermektir. Bu nedenle, kullanıcı işin bittiğini bildirene kadar bitmemelidir. Sonuçlarını gösterdikten bir nanosaniye sonra kullanıcının ekranından kaybolan bir program işe yaramaz.
JBentley

1
@JBentley: Varsa sonuçları gösterdikten sonra durum hakkında konuştum . Sonuçları görüntülemek için sinyaller, kesintiler, zamanlayıcılar, terminalinizde geri kaydırma, dosyalar gibi uygun modeller vardır. system("pause")kendi başına hiçbir şey göstermez. Komut satırından başlatılmayan ve çok erken kapanan bir komut satırı arayüz programı yanlış bir şekilde ve yanlış seçeneklerle çalıştırılır ve system("pause")yanlış başlatılmış bir programı atlatmak için kullanmak gerçekten yapılacak doğru şey değildir.
Sebastian Mach

1
Ben sadece hayal demek cat, less, vi, OpenOffice, Mathematica, GNU Octave, ne kullanmayı tercih ederseniz system("pause")? Bu can sıkıcı olur.
Sebastian Mach

2
Evet, bu can sıkıcı olurdu, ama şimdi özellikle sorunlarından bahsediyorsunuz system("pause"), oysa cevabınız çok daha genel bir kavram olan "çıkmadan önce bekleyin" den bahsediyor. Verdiğiniz örneklerin çoğu aslında, kullanıcı programdan çıkmak istediğini söyleyene kadar "çıkmadan önce bekleyin". Bunun system("pause"), bunu başarmanın iyi bir yolu olmadığını ve daha iyi çözümler olduğunu kabul ediyorum , ancak cevabınız bu değil.
JBentley

1
@JBentley Oh, kesinlikle: Eğer bir gecikme / bekleme / istemi programın anlambiliminin bir parçasıysa, pauseuzaklaş!
Orbit'te Hafiflik Yarışları

3
system("pause");  

Windows API'nin bir parçası olduğu için yanlıştır ve bu nedenle diğer işletim sistemlerinde çalışmayacaktır.

Sadece C ++ standart kitaplığındaki nesneleri kullanmayı denemelisiniz. Daha iyi bir çözüm yazmak olacaktır:

cin.get();
return 0;

Ancak cinkodunuzda başka e- postaların olması da sorunlara neden olacaktır . Çünkü her birinden sonra cinbir Enterveya \nbir beyaz boşluk karakterine dokunacaksınız. cinbu karakteri yok sayar ve tampon bölgede bırakır cin.get(), ancak bu kalan karakteri alır. Böylece programın kontrolü hatta ulaşır return 0ve sonuçları görmenize izin vermeden konsol kapanır.
Bunu çözmek için kodu şu şekilde yazıyoruz:

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

Bu biraz yanıltıcı. system()standarttır ve MS Windows'a özgü değildir. Bununla birlikte, pausekabuk komutu bir DOS mirasıdır ve genellikle yalnızca orada bulunur.
Ulrich Eckhardt

1

İşte onu kullanmamanız için bir neden: eğer programı başka bir makineye geçirirseniz, Windows üzerinde çalışan çoğu anti-virüs programını sinirlendirecektir çünkü bu bir güvenlik tehdididir. Programınız yalnızca basit bir cout << "hello world\n"; system("pause"); Kaynak ağırlığından oluşsa bile ve program, anti virüslerin tehdit olarak gördüğü cmd komutuna erişebilir.


-1

profesyonellerin sistemi kullanması ("DURAKLAT"); programınızın küçük bölümlerini oluştururken kendi başınıza hata ayıklamak içindir. her işlem sırasında ve sonrasında değişkenlerin sonuçlarını almak için kullanırsanız, düzgün çalıştıklarından emin olmak için kullanırsınız.

Test ettikten ve çözümün geri kalanıyla tüm hızıyla hareket ettirdikten sonra bu hatları kaldırmalısınız. Kullanıcı tanımlı bir algoritmayı test etmek ve istediğiniz sonuçlar için işleri doğru sırada yaptığınızdan emin olmak gerçekten iyidir.

Bunu test ettikten ve düzgün çalıştığından emin olduktan sonra hiçbir şekilde bir uygulamada kullanmak istemezsiniz. Ancak, gerçekleşirken olup biten her şeyi takip etmenize izin verir. Son Kullanıcı uygulamaları için kesinlikle kullanmayın.


-3

Hepsi bir stil meselesi. Hata ayıklama için kullanışlıdır, ancak aksi takdirde programın son sürümünde kullanılmamalıdır. Hafıza konusunda gerçekten önemli değil çünkü sistemi icat edenlerin ("duraklama") sık sık kullanılacağını tahmin ettiğinden eminim. Başka bir bakış açısıyla, bilgisayarlar zaten bilgisayarda kullandığımız diğer her şey için hafızalarında kısılıyor ve dinamik bellek tahsisi gibi doğrudan bir tehdit oluşturmuyor, bu yüzden kodu hata ayıklama için tavsiye ederim, ancak başka hiçbir şey yapmaz.


6
Hafıza sorunu için gerçekten önemli değil çünkü sistemi icat edenlerin ("duraklama"), sistemin sık sık kullanılacağını tahmin ettiklerinden eminim, gerçekten hiçbir anlam ifade etmiyor. Kimse bunu "icat pauseetmedi", DOS toplu iş programlarında kullanılmak üzere tasarlandı, asla böyle bir şekilde kullanılması amaçlanmadı. Dahası, kimse bu ifadeyi yazacak kadar çılgın olmadan önce çok daha iyi alternatifler vardı system("pause");.
wich
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.