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