MATERIAŁY POMOCNICZE NR 6 DO PRACOWNII Z PRZEMIOTU
Transkrypt
MATERIAŁY POMOCNICZE NR 6 DO PRACOWNII Z PRZEMIOTU
MATERIAŁY POMOCNICZE NR 6 DO PRACOWNII Z PRZEMIOTU „INFORMATYKA 1” int tab[5]; - deklaracja tablicy, tab[5] = 10; - błąd !!!, nie istnieje element o indeksie 5, ale kompilator nie zasygnalizuje błędu, tylko w obszarze za tablicą zapisze wartość 10. Tablica elementów Przy odwołaniach do elementów tablicy kompilator nie sprawdza, czy piszemy lub czytamy poza obszarem pamięci przydzielonej na tablicę, np. Tablica elementów jest ciągłym obszarem pamięci, w którym te elementy są umieszczone. Operacje na tablicach wykonywane są najczęściej przy wykorzystaniu pętli for. Załóżmy, że chcemy 5-elementową tablicę liczb całkowitych wypełnić wartością 10. Kod realizujący taką operację może mieć następującą postać: Głównym celem stosowania tablic jest zastąpienie wielu zmiennych tego samego typu jedną tablicą. Deklarując tablicę musimy podać: typ elementów, nazwę tablicy, liczbę elementów, np. int tab[5]; int tab[5]; tab[0] tab[1] tab[2] tab[3] tab[4] średnik rozmiar tablicy nazwa tablicy typ elementów tablicy Wyrażenie podane w nawiasach kwadratowych, określające rozmiar tablicy, musi w wyniku dawać dodatnią stałą całkowitoliczbową, a ponadto musi to być wartość znana już w fazie kompilacji (nie może to być zmienna). Powyższa deklaracja definiuje tablicę pięciu elementów typu int. Jest to tablica jednowymiarowa, czyli tzw. wektor. 0 1 2 3 = = = = = 10; 10; 10; 10; 10; Można to samo zrobić znacznie prościej, stosując pętlę for: int tab[5], i; for (i=0; i<5; i++) tab[i] = 10; 4 W powyższym fragmencie programu zmienna i przyjmuje wartości od 0 do 4 czyli takie same jak kolejne indeksy elementów tablicy. tab[0] tab[1] tab[2] tab[3] tab[4] Każdy element tablicy ma swój numer zwany indeksem, element zerowy (znajdujący się na początku tablicy) ma indeks 0 (zero), zaś ostatni N-1, gdzie N - rozmiar tablicy. Wartość indeksu pokazuje o ile elementów jest dany element odległy od początku tablicy. Jako indeks może występować wyrażenie, ale w wyniku musi ono dawać liczbę całkowitą. Nazwa tablicy jest adresem jej zerowego elementu (o indeksie 0) w pamięci komputera. Odwołania do elementów tablicy (odczytanie lub zapisanie wartości) wykonuje się za pomocą dwuargumentowego operatora indeksowania [ ], np. tab[1] - odwołanie do elementu tablicy o indeksie 1 indeks elementu (drugi argument operatora indeksowania) nazwa tablicy (pierwszy argument operatora indeksowania) tab[1] = 5; - zapisanie wartości 5 do elementu tablicy tab o indeksie 1 x = tab[1]; - odczytanie elementu tablicy tab o indeksie 1 i przypisanie jego wartości zmiennej x Informatyka 1 - Pracownia Strona 1 z 7 © 2011 Jarosław Forenc Przykład nr 6.1 Program wykonujący wybrane operacje na wektorze liczb całkowitych. #include <stdio.h> #include <conio.h> #define N 5 int main() { int tab[N]; int i,min,max; /* wczytanie elementow tablicy */ for (i=0; i<N; i++) { printf("Podaj liczbe nr %d: ",i+1); scanf("%d",&tab[i]); } Informatyka 1 - Pracownia Strona 2 z 7 © 2011 Jarosław Forenc for (i=0; i<N; i++) printf("%d ", tab[i]); /* wyswietlenie elementow tablicy */ printf("Elementy tablicy: "); for (i=0; i<N; i++) printf("%d ", tab[i]); printf("\n"); o printf("Elementy tablicy w odwrotnej kolejnosci: for (i=N-1; i>=0; i--) printf("%d ", tab[i]); /* wyswietlenie elementow tablicy w odwrotnej kolejnosci*/ printf("Elementy tablicy w odwrotnej kolejnosci: for (i=N-1; i>=0; i--) printf("%d ", tab[i]); printf("\n"); o wyszukanie elementu o najmniejszej wartości - zakładamy, że zerowy element tablicy jest najmniejszy (min = tab[0]); przeglądamy pozostałe elementy tablicy; jeśli kolejny z elementów tablicy (tab[i]) jest mniejszy od najmniejszego (min), to element ten staje się najmniejszym (min = tab[i]): min = tab[0]; for (i=1; i<N; i++) if (tab[i]<min) min = tab[i]; printf("Wartosc elementu najmniejszego: %d\n",min); min = tab[0]; for (i=1; i<N; i++) if (tab[i]<min) min = tab[i]; printf("Wartosc elementu najmniejszego: %d\n",min); o /* wyszukanie elementu o najwiekszej wartosci */ max = tab[0]; for (i=1; i<N; i++) if (tab[i]>max) max = tab[i]; printf("Wartosc elementu najwiekszego: %d\n",max); wyszukanie elementu o największej wartości - odbywa się na takiej samej zasadzie jak wyszukanie elementu najmniejszego: max = tab[0]; for (i=1; i<N; i++) if (tab[i]>max) max = tab[i]; printf("Wartosc elementu najwiekszego: %d\n",max); getch(); return 0; Generowanie pseudolosowe elementów tablicy } Elementy tablicy mogą być wygenerowane pseudolosowo, co pokazuje Przykład nr 6.2. W powyższym programie rozmiar tablicy określany został przy użyciu dyrektywy preprocesora #define: Przykład nr 6.2 Generowanie pseudolosowe elementów tablicy. #define N 5 dzięki czemu zmiana rozmiaru tablicy będzie wymagała tylko zmiany wartości w tej dyrektywie, a nie w każdym innym miejscu programu, gdzie pojawia się rozmiar tablicy. Dotyczy to zwłaszcza warunków w pętlach for. #include #include #include #include W programie wykonywane są następujące operacje na tablicy: int main() { int tab[10], i; o wczytanie elementów tablicy - w pętli for wyświetlamy komunikat „Podaj liczbę nr …”, a następnie funkcją scanf() wczytujemy liczbę: wyświetlenie elementów tablicy: printf("Elementy tablicy: Informatyka 1 - Pracownia <stdio.h> <conio.h> <stdlib.h> <time.h> srand(time(NULL)); for (i=0; i<10; i++) { tab[i] = rand(); printf("%d ",tab[i]); } getch(); return 0; for (i=0; i<N; i++) { printf("Podaj liczbe nr %d: ",i+1); scanf("%d",&tab[i]); } o "); "); /* wyszukanie elementu o najmniejszej wartosci */ wyświetlenie elementów tablicy w odwrotnej kolejności - zmieniamy wyrażenia w pętli for, zmienna i będzie przyjmowała wartości od N-1 (ostatni element tablicy) do 0 (zerowy element tablicy): } "); Strona 3 z 7 © 2011 Jarosław Forenc Informatyka 1 - Pracownia Strona 4 z 7 © 2011 Jarosław Forenc Do generowania liczb pseudolosowych zastosowana została funkcja rand(): tab[i] = rand(); Funkcja ta zwraca pseudolosową liczbę całkowitą z zakresu: 0 … RAND_MAX (32767). Zastosowanie jej w programie wymaga dołączenia pliku nagłówkowego stdlib.h. Przed użyciem funkcji rand() należy zainicjalizować generator liczb pseudolosowych wywołując funkcję srand(): srand(time(NULL)); do której przekazywana jest liczba inicjalizująca generator. Aby zapewnić unikalność generowania kolejnych liczb do funkcji srand() przekazywana jest wartość zwracana przez funkcję time(). Zastosowanie funkcji time() wymaga dołączenia pliku nagłówkowego time.h. tab[1][2] = 10; - zapisanie wartości do tablicy, x = tab[1][2]; - odczytanie wartości z tablicy. Inicjalizacja elementów tablicy Po zadeklarowaniu tablicy wartość jej elementów jest nieokreślona. Inicjalizacja elementów tablicy jest to nadanie wartości jej elementom od razu przy deklaracji. Inicjalizacja taka polega na umieszczeniu w deklaracji po znaku równości, ujętej w nawiasy klamrowe, listy wartości kolejnych jej elementów (lista ta może zawierać również wyrażenia), np. Do zmiany zakresu generowanych liczb najprostszym jest zastosowanie dzielenia modulo. Jeśli chcemy otrzymać liczby całkowite z zakresu 0 … 10, to wystarczy wartość zwracaną przez funkcję rand() podzielić modulo 11: int x; x = rand() % 11; Odwołując się do elementów tablicy dwuwymiarowej musimy podać dwa indeksy: numer wiersza i numer kolumny, na przecięciu których znajduje się dany element, np. int a[3] = { 5, 7, 1 }; Pseudolosową liczbę całkowitą z przedziału a … b otrzymamy używając funkcji rand() w następujący sposób: int x; x = rand() % (b – a + 1) + a; 0 1 2 5 7 1 Poszczególne elementy tablicy umieszczone są w nawiasach klamrowych i oddzielone od siebie przecinkami. int b[2][3] = { { 3, 6, 2 } , { 4, 1, 0 } }; int b[2][3] = { 3, 6, 2, 4, 1, 0 }; 0 1 2 0 3 6 2 1 4 1 0 Deklaracja tablicy dwuwymiarowej Deklaracja tablicy dwuwymiarowej (macierzy) wymaga podania liczby wierszy i liczby kolumn, z których będzie składała się tablica. Obie powyższe deklaracje oznaczają to samo. Poszczególne wiersze macierzy można wyróżnić dodatkowymi nawiasami klamrowymi (pierwsza postać). float tab[3][4]; Druga postać inicjalizacji pokazuje w jaki sposób przechowywane są tablice w pamięci komputera. Tablice można inicjalizować tylko przy deklaracji. Jeśli wartości podanych w trakcie inicjalizacji jest mniej niż wynosi rozmiar tablicy, to pozostałe elementy tablicy wypełniane są zerami, np. średnik liczba kolumn tablicy liczba wierszy tablicy nazwa tablicy typ elementów tablicy Powyższa deklaracja definiuje tablicę dwunastu elementów typu float, składającą się z trzech wierszy i czterech kolumn. 0 1 2 3 0 1 2 0 3 6 2 1 4 0 0 int b[2][3] = { 3, 6, 2, 4 }; indeksy kolumn 0 elementy uzupełnione zerami 1 tab[1][2] 2 tab[2][3] int b[2][3] = { 0 }; tab[2][2] indeksy wierszy Informatyka 1 - Pracownia Tablica zadeklarowana bez podania rozmiaru, a zainicjowana ma liczbę elementów równą ilości inicjatorów, np. int a[] = { 2, 3, 1, 4 }; Strona 5 z 7 © 2011 Jarosław Forenc - wypełnienie całej tablicy zerami. Informatyka 1 - Pracownia jest równoważne int a[4] = { 2, 3, 1, 4 }; Strona 6 z 7 © 2011 Jarosław Forenc Przykład nr 6.3 Program generujący N niepowtarzających się liczb całkowitych. #include #include #include #include <stdio.h> <stdlib.h> <time.h> <conio.h> #define #define N 6 ZAKRES 49 int main() { int lotto[N]; int i,j,x,powt; srand(time(NULL)); for (i=0; i<N; i++) { do { powt = 0; x = rand() % ZAKRES + 1; for (j=0; j<i; j++) if (lotto[j]==x) powt = 1; } while (powt==1); lotto[i] = x; } printf("Wylosowane liczby: "); for (i=0; i<N; i++) printf("%3d, ",lotto[i]); getch(); return 0; } Informatyka 1 - Pracownia Strona 7 z 7 © 2011 Jarosław Forenc