Tablice w języku C++
Transkrypt
Tablice w języku C++
TABLICE W JĘZYKU C++ Aby pracować z tablicą, musimy najpierw ją zadeklarować, tak jak kaŜdą zmienną w programie. Deklaracja tablicy ma postać: typ_elementow nazwa_tablicy [liczba_elementów] Stosowane oznaczenia: typ_elementow - naleŜy podać nazwę typu elementów w tablicy nazwa_tablicy -jest dowolną nazwą (podlega tym samym regułom poprawności, co nazwa kaŜdej innej zmiennej); liczba_elementow - w nawiasie kwadratowym naleŜy podać liczbę elementów tablicy; musi to być liczba podana wprost (tak zwany literał na przykład 7, lub stałą typu całkowitego (zdefiniowana wcześniej) Ogólna postać definicji tablicy: typ_elementu np. int tablica [ 10 ]; nazwa_tablicy [wymiar_1][wymiar_2] . . . [wymiar_N] ; // 10-cio elementowa tablica liczb całkowitych char tekst [ 255 ]; float macierz [ 5 ] [ 2 ]; // 255-cio elementowa tablica znaków // dwuwymiarowa tablica: 5 wierszy po 2 kolumny, UWAGA: ⇒ w języku C++ tablice są zawsze indeksowane od zera np. pierwszym elementem tablicy «macierz» jest: macierz[ 0 ][ 0 ] a ostatnim elementem jest:macierz[ wymiar_1 − 1 ][wymiar_2 − 1] tzn. macierz[ 4 ][ 1 ] ⇒ w języku C++ nie jest sprawdzana zgodność indeksu z wymiarami tablicy !!! często jest to przyczyną trudnych do wykrycia błędów. np. odwołanie: macierz[ 1 ][ 2 ] zwróci w rzeczywistości wartość pierwszego elementu z trzeciego wiersza tzn. macierz[ 2 ][ 0 ] 0,0 0,1 1,0 1,1 2,0 2,1 3,0 3,1 4,0 4,1 1,2 reprezentacja tej macierzy ↓ w pamięci komputera 0,0 0,1 1,0 1,1 2 ,0 2,1 3,0 3,1 4,0 4 ,1 ↑ macierz[ 1 ][ 2 ] 1 ⇒ Obszar pamięci zajmowany przez tablicę musi być mniejszy od 64 kB W implementacji C++ firmy Borland to ograniczenie moŜna obejść uŜywając przy definicji tablicy słowo kluczowe huge . np. definicja: long double huge tab[ 20000 ]; jest poprawna, chociaŜ tablica «tab» zajmuje 200 000 bajtów ≈ 196 kB Definicję tablicy moŜna połączyć z inicjacją jej zawartości: int int char float float tab[ 10 ]; // ← sama definicja bez inicjacji tab_inicjowana[ 10 ] = { 20, -3, 12, 1, 0, 7, -5, 100, 2, 5 }; tab_znakow[ 5 ] = { ‘a’, ‘B’, ‘\n’, ‘1’, ‘\0’ }; macierz_A[ 3 ][ 2 ] = { {1,1}, {3.5,7.0}, {-15,100} }; macierz_B[ 3 ][ 2 ] = { 1, 1, 3.5, 7.0, -15, 100 }; ⇒ Kolejne „inicjatory” zawsze wstawiane są do kolejnych (w związku z tym moŜna pominąć wewnętrzne nawiasy klamrowe). „komórek” tablicy ⇒ JeŜeli lista inicjatorów jest krótsza niŜ ilość elementów tablicy to pozostałe elementy są uzupełniane zerami lub wskaźnikami NULL np. definicja: int tab[ 10 ] = { 20, -3, 12, 1 }; jest równowaŜna: int tab[ 10 ] = { 20, -3, 12, 1, 0, 0, 0, 0, 0, 0 }; a definicja: float macierz[ 3 ][ 2 ] = { {1}, {3.5,7.0} }; jest równowaŜna: float macierz[ 3 ][ 2 ] = { {1,0}, {3.5,7.0}, {0,0} }; lub: float macierz[ 3 ][ 2 ] = { 1, 0, 3.5, 7.0, 0, 0 }; ⇒ W języku C inicjatorami muszą być stałe, natomiast w języku C++ inicjatorami mogą być zarówno stałe jak i zmienne. Wykorzystanie stałych do definiowania ilości elementów tablicy: int tablica [ 100 ] ; // rozmiar zadany bezpośrednio const ROZMIAR = 100 ; // definicja stałej w stylu języka C++ int tablica [ ROZMIAR] ; 2 Do wypełnienia tablicy podczas wykonywania programu uŜywać będziemy najczęściej sposobu iteracyjnego, przedstawionego na schemacie blokowym (ryc. 5.3). Schemat przedstawia wypełnianie tablicy o nazwie tab, która ma n elementów (gdzie n oraz zmienna pomocnicza i są dodatnimi liczbami całkowitymi). Schemat blokowy wypełniania tablicy jednowymiarowej Zmienna i jest licznikową zmienną pomocniczą, która przyjmując wartości indeksów kolejnych elementów tablicy, pozwala przypisać elementom tablicy pobrane z zewnątrz wartości. Przypominam, Ŝe jeśli tablica o nazwie tab ma n elementów, to jej elementami są: tab [0], tab [1],. .., tab [ n-1 ]. Indeksami tablicy są liczby ze zbioru {0,..., n - 1}. Odwołanie się do elementu o indeksie innym aniŜeli liczba z tego zbioru nazywamy przekroczeniem zakresu tablicy (lub wyjściem poza zakres tablicy). Przekroczenie zakresu, na przykład przy wypełnianiu tablicy, spowoduje zapis poza obszarem pamięci przeznaczonym na zdeklarowaną tablicę. W obszarze tym mogą się znajdować inne zmienne tego programu lub nawet dane innych programów. Wpisanie tam nieprawidłowych wartości grozi więc błędem w programie, zawieszeniem uruchomionego programu lub nawet całego systemu. Wypełnianie tablicy : for (int i=0; i<n; i++) { cout«"Podaj wartość elementu"; cin» tab[i]; } Jeśli w programie chcemy wypełnić kilka tablic, to wygodniejsze będzie umieszczenie powyŜszego kodu w funkcji, którą nazwiemy wypełnij. Wówczas parametrami przekazywanymi do funkcji będą: tablica , którą chcemy wypełnić, oraz liczba elementów tablicy do wypełnienia. Funkcja, otrzymując tablicę jako argument, ma pełen dostęp do zawartości komórek, w których przechowywane są elementy tablicy - działa bezpośrednio na tablicy. Nie jest więc potrzebne odwołanie przez referencję, aby z wnętrza funkcji modyfikować wartości elementów tablicy. 3 W celu sprawdzenia efektów działania funkcji wypełnij zdefiniowaliśmy funkcję wyświetl, która wyświetli nam na ekranie i na tablice: #include <iostream.h> #include <conio.h> void wypełnij (int tab[8]) { for (int i=0; i<8; i++) { cout«"Podaj wartość elementu"; cin» tab[i]; } } void wyświetl(int tab[8]) { for (int i=0; i<8; i++) cout«tab[i]«" "; cout«endl; } /*************** początek funkcji głównej programu *************/ main () { int tablica1[8],tablica2[8]; wypełnij(tablical); //wywołanie funkcji wypełnij dla tablica1 wypełnij(tablica2); //wywołanie funkcji wypełnij dla tablica2 wyświetl(tablical); //wywołanie funkcji wyświetl dla tablica1 wyświetl(tablica2); //wywołanie funkcji wyświetl dla tablica2 getch(); } Drugi przykład wypełniania tablicy jednowymiarowej o wymiarze podanym przez uŜytkownika, pod zmienna typu int ile. #include <iostream.h> #include <conio.h> void wypelnij(int tab[],int n) { for (int i=0; i<n; i++) { cout<<"Podaj wartosc elementu :"; cin>>tab[i]; } 4 } void wyswietl(int tab[],int n) { for (int i=0; i<n; i++) cout<<tab[i]<<" "; cout<<endl; } /*************** początek funkcji głównej programu *************/ main () { int tablica1[100],ile; cout<<"Jaki wymiar tablicy? : "; cin>>ile; //pod zmienna ile wczytujemy podany przez uŜytkownika rozmiar tablicy wypelnij(tablica1,ile); //wywołanie funkcji wypełnij dla tablica1 wyswietl(tablica1,ile); //wywołanie funkcji wyświetl dla tablica1 getch(); } Tablice wielowymiarowe Funkcja wypełnij dla tablicy dwuwymiarowej : void wypelnij (float tab[4][3]) { for (int i=0; i<4; i++) { for (int j=0; j<3; j++) { cout<<”Podaj wartosc elementu ”; cin>>tab[i][j]; } } } 5 Program z funkcją wypelnij I wyswietl dla tablicy 2-wymiarowej #include <iostream.h> #include <conio.h> #include <iomanip.h> void wypelnij (float tab[5][7]) { for (int i=0; i<5; i++) { for (int j=0; j<7; j++) { cout<<”Podaj wartosc elementu: “; cin>>tab[i][j]; } } } void wyswietl (float tab[5][7]) { for (int i=0; i<5; i++) { for (int j=0; j<7; j++) { cout<<setw(4)<<tab[i][j] //na zapis zmiennej przeznaczamy 4 miejsca } cout<<endl; // aby kazdy nastepny wiersz pojawil // sie w nowej linii } } main () { float tab1[5][7],tab2[5][7]; wypelnij (tab1); wypelnij (tab2); cout<<endl; wyswietl (tab1); wyswietl (tab2); getch (); } 6 Program dla tablicy dwuwymiarowej, gdzie uŜytkownik podaje ilośc wierszy i kolumn. #include <iostream.h> #include <conio.h> #include <iomanip.h> //biblioteka do opcjii setw(x) #pragma argsused int tablica1[100][100]; void wypelnij(int tab[100][100],int w,int k) { for (int i=0;i<w; i++) for(int j=0;j<k;j++) { cout<<"Podaj wartosc elementu "<<i<<j<<" : "; cin>>tab[i][j]; } }; void wyswietl(int tab[100][100],int w,int k) { for (int i=0;i<w; i++) { for(int j=0;j<k;j++) cout<<setw(5)<<tab[i][j];cout<<"\n"; } } /*************** początek funkcji głównej programu *************/ main () { int w,k; cout<<"Ile wierszy tablicy? : "; cin>>w; cout<<"Ile kolumn tablicy? : "; cin>>k; wypelnij(tablica1,w,k); //wywołanie funkcji wypełnij dla tablica1 wyswietl(tablica1,w,k); //wywołanie funkcji wyświetl dla tablica1 getch(); } 7 Przykładowe zadanie : Napisz program, który wprowadzi do tablicy dwuwymiarowej oceny końcoworoczne uczniów z kilku przedmiotów, wypisze najlepszego ucznia(czyli tego, który uzyskał najwyŜszą średnią) jego średnią, a takŜe przedmiot, z którego uczniowie uzyskali średnią, wraz z podaniem tej wartości. #include <iostream.h> #include <iomanip.h> #include <conio.h> const int w = 8; //liczba uczniow const int k = 5; //liczba przedmiotow void wypelnij (int tab[w][k]) { for (int i=0; i<w; i++) { cout<<”Podaj oceny ucznia: uczen”<<(i+1)<<endl; cout<<”w kolejnosci: j.pol. j.ang. matem. biol. inf.”<<endl; for (int j=0; j<k; j++) cin>>tab[i][j]; } } void wyswietl (int tab[w][k]) { for (int i=0; i<w; i++) { cout<<”u”<<(i+1)<<” “; for (int j=0; j<k; j++) cout<<setw(7)<<tab[i][j]; cout<<endl; } } void max_srednia_ucznia (int tab[w][k]) { float srednia_ucznia, max_srednia=0; int i,j,nr_ucznia; for (i=0; i<w; i++) { srednia_ucznia=0; for (j=0;j<k;j++) 8 { srednia_ucznia=srednia_ucznia+tab[i][j]; } srednia_ucznia=(float)srednia_ucznia/k; if (srednia_ucznia>max_srednia) { max_srednia = srednia_ucznia; nr_ucznia=(i+1); } } cout<<endl<<”Najwyzsza srednia ucznia to: “<<max_srednia; cout<<”Osiagnal ja uczen u”<<nr_ucznia; } void max_srednia_przedmiot (int tab[w][k]) { float srednia_przedmiot, max_srednia=0; int i,j,nr_przedmiotu; for (j=0; j<k; j++) { srednia_przedmiot=0; for (i=0; i<w; i++) srednia_przedmiot=srednia_przedmiot+tab[i][j]; srednia_przedmiot=(float)srednia_przedmiot/w; if (srednia_przedmiot>max_srednia) { max_srednia = srednia_przedmiot; nr_przedmiotu=j; } } cout<<endl<<”Najwyzsza srednia z przedmiotu: “<<max_srednia; cout<<” Jest to “; switch(nr_przedmiotu) { case 0: cout<<”j.pol.”; break; case 1: cout<<”j.ang.”; break; case 2: cout<<”matem.”; break; case 3: cout<<”biol.”; break; case 4: cout<<”inf.”; break; } } 9 main () { int oceny[w][k]; wypelnij (oceny); cout<<” j.pol. j.ang. matem. biol. inf.”<<endl; wyswietl (oceny); max_srednia_ucznia (oceny); cout<<endl; max_srednia_przedmiot(oceny); getch (); } 10