[C++]Zabezpieczenie przed wpisaniem liter - nie działa


(Wojtek7878) #1

Według tego co znalazłem w internecie powinno działać a nie działa, zapętla się w nieskończoność:

do

{ 

cout<<"Podaj poczatkowa stawke: ";

cin>>stawka;


cout<<"Podaj liczbe kolejek: ";

cin>>kolejki;

cout<
}while (!(cin>>zmienna));

(system) #2
bool *fx = new bool;

cin >> liczba;

if(!cin){

  *fx = false; 

}

//Użycie zmienej dynamicznej *fx w celach X

delete fx; // zmienne dynamiczne należy usuwać, gdy nie są nam potrzebne, w dalszej części :)

Dalej już myślę, że wiadomo


([alex]) #3

Protected_48 , ależ zamąciłeś !!

while(true)

(system) #4


([alex]) #5

Ja mówiłem o:

bool *fx=new bool;fx=true;fx=...;fx) ...delete fx; [/code]



czemu nie zrobić tego po ludzku:


[code=php]bool fx=true;fx=...;fx) ...

(system) #6

Pytanie odnoszące się bardziej, co to przyzwyczajenia.

Dlatego, że zapewnia to elastyczność pozwalającą dostosować się do aktualnych potrzeb w programie


([alex]) #7

Elastyczność?! Ktoś ci tak mózg wyprał?

Marnowanie pamięci (12 bajt zamiast 1 bajta) oraz mocy obliczeniowej komputera (dodatkowe niepotrzebne new + delete) dające najwyżej dodatkową szansę popełnienia błędu nazywasz elastycznością?

Powiedz mi jak to marnotrawstwo pozwoli ci dostosować się do potrzeb w programie?


(system) #8

Masz przypływ zbyt dużej pewności siebie pisząc te zdanie.

Nie rozumiem tego zdania, gdzie tutaj marnuję pamięć? Teraz zostajemy przy mocy obliczeniowej a tutaj już chyba sobie żartujesz, naprawdę strasznie obciążam komputer.

Czy zmienna o której mowa, potrzebujemy cały czas? Zakładając, że w normalnym przypadku program nie będzie się kończył przy sprawdzeniu poprawności wprowadzonej liczby.


(Sawyer47) #9

Przepraszam że się wtrącam do offtopu, ale naprawdę, Protected_48, dynamiczna alokacja jednej zmiennej bool to czyste marnotrastwo i pamięci i czasu. Argumentacja, że ta zmienna potrzebna jest tylko tymczasowo jest głupia, bo w tym samym zakresie leksykalnym masz wksaźnik, który praktycznie na pewno waży więcej niż zmienna typu bool - można użyć tej samej argumentacji i zapytać czy potrzebujesz tego wskaźnika cały czas. Do tego new i delete jest - uwaga, strzelam wartością wyssaną z palca - kilkadziesiąt razy wolniejsze.


(system) #10

Ok, wiadome jest że operatora new powinno używać się przykładowo przy 200 elementowej tablicy. Ale ta dyskusja schodzi na typ :

Dlaczego for a nie przypadkiem while. Bo w końcu można zastąpić między sobą w niektórych przypadkach. Chyba nie sądzicie, że nie starczy przy obecnych komputerach pamięci, ponadto różnica w wykorzystaniu pamięci przez program jest nieznaczna.

Czasy wykonywania mogę być bardzo nieznaczne i naprawdę małe, ideone różnicy między wykorzystaniem new i delete nie zauważa w stosunku, co to statycznych zmiennych. Ponadto jeżeli zrobiłem, według was aż taki karygodny błąd. To, jak to się ma w stosunku do C#? Bo z tego, co mi wychodzi programy konsolowe w C# mają dłuższy czas wykonania i program ma zapotrzebowanie na więcej pamięci , to jest na pewno uwarunkowane od algorytmu, ale chociażby w przypadku prostego dodawania różnice są.


([alex]) #11

Co do tego przypadku, to każdy komu nie wyprano mózgu ze mną się zgodzi.

No rzeczywiście trochę wyssana z palca. W rzeczywistości kilkaset razy wolniejsze, jako dowód:

   clock_t tm=clock();   for(unsigned i=0;i10000000;++i)     {      bool a=true;      bool b=false;      bool c=true;      bool d=false;      bool e=true;      bool f=false;      bool g=true;      if(a^b^c^d^e^f^g) break;     }   cout(clock()-tm)endl;   tm=clock();   for(unsigned i=0;i10000000;++i)     {      bool *a=new bool; *a=true;      bool *b=new bool; *b=false;      bool *c=new bool; *c=true;      bool *d=new bool; *d=false;      bool *e=new bool; *e=true;      bool *f=new bool; *f=false;      bool *g=new bool; *g=true;      if(*a^*b^*c^*d^*e^*f^*g) break;      delete a;      delete b;      delete c;      delete d;      delete e;      delete f;      delete g;     }   cout(clock()-tm)endl;[/code]




[quote="Protected_48"]

Nie rozumiem tego zdania, gdzie tutaj marnuję pamięć? Teraz zostajemy przy mocy obliczeniowej a tutaj już chyba sobie żartujesz, naprawdę strasznie obciążam komputer.
[/quote]


Zamiast jednego bajtu na zmienną typu bool, używasz wskaźnika który zajmuje 4 bajty (dla 32 bitowego kodu), do tego przydzielasz pamięć która przydzielana jest 8 bajtowymi porcjami.(co najmniej) czyli w sumie używasz co najmniej 12 bajtów pamięci, Oraz zwiększasz defragmentację pamięci. Na dodatek spowalniasz cały kod. W sumie bezwzględna różnica może i nie jest strasznie duża - kilka milisekund, zaś stosunkowo to jest spowolnienie kilkaset razy. Ba nie zapominaj że przydzielenie pamięci jest synchronizowane co najmniej z głównym wątkiem programu (bo pula pamięci jest wspólna). Wiec jak zrobisz taką "elastyczność" w wątkach a tych wątków będzie ze 100 to należy spodziewać się względnej różnicy w prędkości wykonania nawet 10000 razy (tu strzelam - nr47, mam nadzieje że się zemścisz i udowodnisz że się mylę ;P o zero w którąś stronę, nie chcę mi się sprawdzać).

(system) #12

[alex]

Jedynie, co udowodniłeś to, że totalną abstrakcją użycia tych zmiennych można opóźnić wykonanie. W normalnych wykorzystaniu różnice będą właśnie minimalne, o czym wspomniałeś.

Używając właśnie tych zmiennych, którymi "wyprano" mi mózg ma się większą kontrolę nad sposobem użycia pamięci w programie, i to jest dla mnie elastyczność.


([alex]) #13

Owszem operacja przydzielania pamięci na zmienną typu bool wraz ze zwalnianiem (na moim komputerze) wynosi około 10 mikrosekund, czyli niby prawie nic. Tylko że to jest 250 razy wolniej niż bezpośrednie użycie bool. A teraz pomyśl czy warto spowalniać program 250 razy nawet jeżeli to daje jakąś tam elastyczność.

Nadal nie wyjaśniłeś na czym polega ta twoja "elastyczność"?

A tak a propos, aby nie używać tego typu bool cały czas to zrobiłeś wskaźnik i przydzielasz pod niego pamięć ale teraz używasz przez cały czas wskaźnika, więc aby jego nie używać czas to trza na niego też przydzielić pamięć, no i załóżmy tak z trzy razy. Więc:

bool  ***f=new bool** ;f=new bool*;f=new bool;f=true;

(system) #14

Czyli przyznajesz, że komentujesz coś czego nie rozumiesz?

Gdzie napisałem o elastyczności kodu? Czyli tak rozumiem, że jesteś pesymistycznie nastawiony do new i delete oraz ogólnie do wskaźników?


([alex]) #15

Wiem czym jest elastyczność ale takie nieuzasadnione użycie wskaźników nie daje żadnej elastyczności. Więc moje pytanie właśnie brzmi: Na czym polega ta twoja "elastyczność"? Dla tego słowo elastyczny wziąłem w cudzysłowy bo oznacza zupełnie coś innego niż to ogólnie przyjęte w programowaniu.

Po pierwsze unikasz odpowiedzi i nie powiedziałeś czy ten przedstawiony kod jest wg ciebie bardziej "elastyczny". Po drugie widzę że masz też na pieńku z logiką. Bez wskaźników nie ma dynamicznego przydzielania pamięci a bez tego nic oprócz dydaktycznych przykładów nie napiszesz. Więc bardzo lubię wskaźniki, lecz nie oznacza to że pcham ich wszędzie gdzie to się uda. Tak a propos w twoim kodzie są też zmienne

int liczba, licz;

Czemu dla "elastyczności" nie zrobiłeś z nich wskaźniki ?


(system) #16

To jest pewien problem. Ponieważ wg książki to w tym przypadku się mylisz. Rozumiem, że mam cytować?

Co napisałem tutaj :

Bo odnosimy się właśnie to tych operatorów, ty natomiast próbujesz odwracać co można w maksymalny sposób interpretując to całkowicie pod siebie.


(Fiołek) #17

Ale masz świadomość, że ten wskaźnik też trzeba trzymać w pamięci i też trzeba się do niego jakoś dobrać(co więcej, na 32-bitowych maszynach i w większości kompilatorów sizeof(bool) przeważnie będzie równe sizeof(bool*))?

Z tego co zdążyłem zauważyć, Ty starasz się uogólniać, dając nietrafiony przykład(nie oszukujmy się, używanie 8B i dwóch "warstw" zamiast 4B i jednej "warstwy" lepsze nie jest), a [alex] i inni odnoszą się ciągle do TEGO wątku i Twojego użycia wskaźnika.


([alex]) #18

Owszem, ale czytać trza ze zrozumieniem. Zwiększa się elastyczność kiedy to w programie potrzebuje tabliczki od 2 elementów do 1000 elementów to przy alokacji automatycznej lub statycznej będę musiał przydzielić tablice na 1000 elementów co "zeżre" mi natychmiast sporo pamięci. Dynamicznie przydzielę tyle ile akurat potrzebuje co prawda o 4 bajty więcej bo sam wskaźnik tyle zajmuje ale średnio jednak się "opłaca". Na tym polega elastyczność, a nie na tym że wszystko co się da przydzielać dynamicznie.


(system) #19

Ale nie musisz mi robić wykładów. Bo po prostu tak zechciało się mi tego użyć i tyle. Oczywiście, co tutaj jest normą, to robienie ze mnie, jak największego idioty. Zrobiłem błąd, nie nadaje się, starczy wam?


(Krecik17) #20

nie jestem pewien ale autorowi postu chyba chodziło o coś takiego

#include 

bool czyDobrze; int menu; 

cout << "Prosze podac liczbe: "; 

cin >> menu; czyDobrze = cin.good(); cin.clear(); cin.ignore(1000, '\n');

                        if ((czyDobrze==0))

                         {

                            do

                            {cout << "Prosze podać liczbe ponownie!\n" << "Prosze podać liczbe: ";

                             cin >> menu;czyDobrze = cin.good(); cin.clear(); cin.ignore(1000, '\n');

                            }while ((czyDobrze==0));

                         }else if (!((czyDobrze==0)));

cout << "Podałeś liczbe: " << menu << " \n";

Mam nadzieje że pomogłem :slight_smile: