LEKCJA 13. Jak tworzy� w programie p�tle i rozga��zienia. _______________________________________________________________ W trakcie tej lekcji: 1. Dowiesz si� znacznie wi�cej o p�tlach. 2. Przeanalizujemy instrukcje warunkowe i formu�owanie warunk�w. _______________________________________________________________ Zaczniemy t� lekcj� nietypowo - od s�ownika, poniewa� dobrze jest rozumie� dok�adnie co si� pisze. Tym razem s�ownik jest troch� obszerniejszy. Pozwalam sobie przytoczy� niekt�re s�owa powt�rnie - dla przypomnienia i Twojej wygody. Do organizacji p�tli b�d� nam potrzebne nast�puj�ce s�owa: [S!] conditional expressions - wyra�enia warunkowe structural loops - p�tle strukturalne ________________________________________________________________ if - je�eli (poprzedza warunek do sprawdzenia); else - a je�li nie, to (w przeciwnym wypadku...); for - dla; while - dop�ki (dop�ki nie spe�nimy warunku); do - wykonaj, wykonuj; break - przerwij (wykonanie p�tli); switch - prze��cz; case - przypadek, wariant (jedna z mo�liwo�ci); goto - id� do... default - domy�lny, (automatyczny, pozosta�y); continue - kontynuuj (p�tl�); ________________________________________________________________ UWAGA: W C/C++ nie stosuje si� s�owa THEN. P�TLA TYPU for. Og�lna posta� p�tli for jest nast�puj�ca: for (W_inicjuj�ce; W_logiczne; W_kroku) Instrukcja; gdzie skr�t W_ oznacza wyra�enie. Ka�de z tych wyra�e� mo�e zosta� pomini�te (patrz --> for(;;)). Wykonanie p�tli for przebiega nast�puj�co: 1. Wykonanie JEDEN raz WYRA�ENIA INICJUJ�CEGO. 2. Obliczenie warto�ci LOGICZNEJ wyra�enia logicznego. 3. Je�li W_logiczne ma warto�� PRAWDA (TRUE) nast�pi wykonanie Instrukcji. 4. Obliczenie wyra�enia kroku. 5. Powt�rne sprawdzenie warunku - czy wyra�enie logiczne ma warto�� r�n� od zera. Je�li wyra�enie logiczne ma warto�� zero, nast�pi zako�czenie p�tli. Warunek jest testowany PRZED wykonaniem instrukcji. Je�li zatem nie zostanie spe�niony warunek, instrukcja mo�e nie wykona� si� ANI RAZ. Instrukcja mo�e by� INSTRUKCJ� GRUPUJ�C�, sk�adaj�c� si� z instrukcji prostych, deklaracji i definicji zmiennych lokalnych: { ci�g deklaracji lub definicji; ci�g instrukcji; } Ogromnie wa�ny jest fakt, �e C++ ocenia warto�� logiczn� wyra�enia wed�ug zasady: 0 - FALSE, FA�SZ, inaczej ZERO LOGICZNE je�li WYRA�ENIE == 0 lub jest fa�szywe w znaczeniu logicznym; 1 - TRUE, PRAWDA, JEDYNKA LOGICZNA, je�li wyra�enie ma DOWOLN� WARTO�� NUMERYCZN� RӯN� OD ZERA (!) lub jest prawdziwe w sensie logicznym. Przyk�ad: "Klasycznie" zastosowana p�tla for oblicza pierwiastki kwadratowe kolejnych liczb ca�kowitych. #include <math.h> #include <stdio.h> void main() { int n; for (n=0; n<=100; n++) printf("%f\t", sqrt(n)); getch(); } Wyra�enie inicjuj�ce mo�e zosta� pomini�te. Innymi s�owy zmienna mo�e zosta� zainicjowana na zewn�trz p�tli, a p�tla przejmie j� tak� jaka jest w danym momencie. Przyk�adowo: ..... { float n; n=(2*3)/(3*n*n - 1.234); ...... for (; n<=100; n++) printf("%f4.4\t", sqrt(n)); Przyk�ad: Warunek przerwania p�tli mo�e mie� tak�e inny charakter. W przyk�adzie p�tla zostanie przerwana, je�li r�nica pomi�dzy kolejnymi pierwiastkami przekroczy 3.0. void main() { float y=0, n=0; for (; (sqrt(n)-y)<=3.0; n++) �����{ y=sqrt(n); ����� printf("%f2.3\t", y); �����} getch(); } UWAGA: Sprawd�, czy nawias (sqrt(n)-y)<=3 mo�na pomin��? Jaki jest priorytet operator�w w wyra�eniach: (sqrt(n)-y)<=3.0 i sqrt(n)-y<=3.0 Jaki b�dzie wynik? Dlaczego? Przyk�ad: Instrukcja stanowi�ca cia�o p�tli mo�e by� instrukcj� pust� a wszystkie istotne czynno�ci mog� zosta� wykonane w ramach samego "szkieletu" for. Program przyk�adowy sprawdza ile kolejnych liczb ca�kowitych trzeba zsumowa� by uzyska� sum� nie mniejsz� ni� tysi�c. void main() { float SUMA=0, n=0; for (; SUMA < 1000; SUMA+=(++n)); printf("%f", n); getch(); } [???] CZY NIE MO�NA JA�NIEJ ??? ________________________________________________________________ Mo�na, ale po nabraniu wprawy takie skr�ty pozwol� Ci przyspieszy� tworzenie program�w. Zmniejszenie wielko�ci pliku tekstowego jest w dzisiejszych czasach mniej istotne. Rozszyfrujmy zapis SUMA+=(++n). Preinkrementacja nast�puje PRZED u�yciem zmiennej n, wi�c: 1. Najpierw ++n, czyli n=n+1. 2. Potem SUMA=SUMA+ (n+1). Dla wyja�nienia przedstawiam dwie wersje (obie z p�tl� for): void main() { void main() float SUMA=0; { float SUMA=0, n=0; int n; for (; SUMA < 1000; SUMA+=(++n)); } clrscr(); for (n=0; SUMA<=1000; n++) { SUMA=SUMA+n; } } ________________________________________________________________ To jeszcze nie koniec pokazu elastyczno�ci C/C++. W p�tli for wolno nam umie�ci� wi�cej ni� jedno wyra�enie inicjuj�ce i wi�cej ni� jedno wyra�enie kroku oddzielaj�c je przecinkami. flat a, b, c; const float d=1.2345; void main() { for (a=5,b=3.14,c=10; c; ++a,b*=d,c--) printf("\n%f\t%f\t%f", a,b,c); getch(); } Zwr�� uwag�, �e zapisy warunku: if (c)...; i if (c != 0)...; s� w C++ r�wnowa�ne. Przyk�ad: Program b�dzie pisa� kropki a� do naci�ni�cia dowolnego klawisza, co wykryje funkcja kbhit(), b�d�ca odpowiednikem KeyPressed w Pascalu. Zapis !kbhit() oznacza "NIE NACI�NI�TO KLAWISZA", czyli w buforze klawiatury nie oczekuje znak. Zwr�� uwag�, �e funkcja getch() mo�e oczekiwa� na klawisz w niesko�czono��. Aby unikn�� k�opotliwych sytuacji, czasem znacznie wygodniej jest zastosowa� kbhit(), szczeg�lnie, je�li czekamy na DOWOLNY klawisz. void main() { for (; !kbhit(); printf(".")); } Przyk�ad: Wska�nik w charakterze zmiennej roboczej w p�tli typu for. P�tla powoduje wypisanie napisu. char *Ptr = "Jakis napis"; void main() { for (; (*Ptr) ;) printf("%c",*Pt++); getch(); } AUTOMATYCZNE GENEROWANIE TABLIC W P�TLI for Na dyskietce znajdziesz jeszcze kilka przyk�ad�w FORxx.CPP u�ycia p�tli. A teraz, zanim b�dziemy kontynuowa� nauk� - przyk�adowy program do zabawy. P�tla for s�u�y do wykrywania zgodno�ci klawisza z elementami tablicy TABL[]. W tablicy D[] umieszczone zosta�y cz�stotliwo�ci kolejnych d�wi�k�w, kt�re program oblicza sam, wykorzystuj�c przybli�ony wsp�czynnik. [P030.CPP] # include "conio.h" # include "dos.h" # include "math.h" # include "stdio.h" char TABL[27]={"zsxdcvgbhnjm,ZSXDCVGBHNJM<"}; char k; float D[26]; int i; void main() { clrscr(); printf("[A]- KONIEC, dostepne klawisze: \n"); printf(" ZSXDCVGBHNJM,i [Shift]"); D[0]=200.0; for(i=1; i<26; i++) D[i]=D[i-1]*1.0577; for (;;) //patrz przyklad {*} { k = getch(); for(i=0; i<27; i++) { if (k==TABL[i]) { sound(D[i]); delay(100); nosound(); } }; if (k=='a'|| k=='A') break; //Wyj�cie z p�tli. k = '0'; }; } Po uruchomieniu programu klawisze dzia�aj� w spos�b przypominaj�cy prosty klawiszowy instrument muzyczny. Automatyczne zainicjowanie tablicy wielowymiarowej mo�emy pozostawi� C++. Wielko�� tablicy mo�e by� znana na etapie kompilacji programu, lub okre�lona w ruchu programu. C++ traktuje sta�� (const) jako szczeg�lny przypadek wyra�enia sta�owarto�ciowego (ang. true constant expression). Je�li zadeklarowali�my zmienn� wymiar jako sta��, mo�emy zastosowa� j� np. do zwymiarowania tablicy TAB[]. Przyk�ad poni�ej przedstawia takie w�a�nie zastosowanie sta�ych w C++. [P031.CPP] /* Inicjowanie tablicy przy pomocy sta�ej */ # include <iostream.h> main() { const int wymiar = 7; //Deklaracja sta�ej char TAB[wymiar]; //Deklaracja tablicy cout << "\n Wielkosc tablicy TAB[] wynosi: " << sizeof TAB; cout << " bajtow."; return 0; } Umo�liwia to dynamiczne inicjowanie tablic pod warunkiem rygorystycznego przestrzegania zasady, �e do zainicjowana sta�ej mo�emy zastosowa� wy��cznie wyra�enie sta�owarto�ciowe. . [S] sizeof - wielko�� w bajtach. DANE PREDEFINIOWANE. Dla u�atwienia �ycia programi�cie producenci kompilator�w C++ stosuj� sta�e predefiniowane w plikach nag��wkowych, np.: _stklen - wielko�� stosu, O_RDONLY - tryb otwarcia pliku "tylko do odczytu", GREEN - numer koloru w palecie, itp., itp. Predefiniowanych sta�ych mo�emy u�ywa� do deklarowania indeks�w/rozmiar�w tablic. P�TLA TYPU while. P�tl� typu while stosuje si� na og� "do skutku", tj. do momentu spe�nienia warunku, zwykle wtedy, gdy nie jeste�my w stanie przewidzie� potrzebnej ilo�ci cykli. Konstrukcja p�tli while wygl�da nast�puj�co: while (Wyra�enie_logiczne) Instrukcja; Je�li Wyra�enie_logiczne ma warto�� r�n� od zera, to zostanie wykonana Instrukcja. Sprawdzenie nast�puje PRZED wykonaniem Instrukcji, tote� Instrukcja mo�e nie zosta� wykonana ANI RAZU. Instrukcja mo�e by� INSTRUKCJ� GRUPUJ�C�. Przyk�ad Stosujemy p�tl� while do programu pisz�cego kropki (patrz wy�ej). void main() { while (!kbhit()) printf("."); } Przyk�ad Stosujemy p�tl� while w programie obliczaj�cym sum�. void main(){ float SUMA=0, n=0; clrscr(); while (SUMA<1000) SUMA+=(++n); printf("SUMA: %4.0f ostatnia liczba: %3.0f", SUMA, n); getch(); } [P032.CPP] char *Pointer1="Koniec napisu ...
ZAZZY