User Tools

Site Tools


dydaktyka:cprog:2016:arrays

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
dydaktyka:cprog:2016:arrays [2016/12/06 08:26]
pkleczek
— (current)
Line 1: Line 1:
-====== Tablice ====== 
- 
-Tablica to ciąg wartości tego samego typu (np. liczb) przechowywanych obok siebie. 
- 
-===== Tablice jednowymiarowe ===== 
- 
- 
-==== Deklarowanie ==== 
- 
-Uogólniona deklaracja tablicy: 
-<​code>​ 
-typ_danych nazwa_tablicy[liczba_elementow];​ 
-</​code>​ 
-przy czym dostępne typy elementów są identyczne, jak dla "​zwykłych"​ zmiennych (''​int'',​ ''​float''​ itd.) 
- 
-Przykład: 
-<code c> 
-int tab[8]; // tablica osmiu wartosci typu calkowitego 
-</​code>​ 
- 
-==== Definiowanie ==== 
- 
-Definicja tablicy polega na przypisaniu do tablicy podanej w nawiasach klamrowych listy wartości kolejnych elementów (rozdzielonych przecinkami). 
- 
-Przykład: 
-<code c> 
-int tab[4] = {3, 2, 5, 1}; 
-</​code>​ 
- 
-W przypadku podania zbyt małej liczby wartości do inicjalizacji,​ pozostałe elementy tablicy otrzymują wartość 0. 
- 
-==== Dostęp do elementów ==== 
- 
-Dostęp do poszczególnych elementów tablicy można uzyskać za pomocą indeksu elementu, będącego zawsze liczbą naturalną, umieszczonego w nawiasach kwadratowych. 
- 
-:!: W języku C indeksowanie zaczyna się od zera  -- czyli aby uzyskać wartość pierwszego elementu piszemy ''​tab[0]''​! 
- 
-Przykład: 
-<code c> 
-int tab[] = {1, 2, 3, 4}; 
-int elem = tab[2]; ​ // przypisz zmiennej `elem` wartosc TRZECIEGO elementu tablicy `tab` 
-</​code>​ 
- 
-===== Jak wyświetlać tablicę? ===== 
- 
-Cóż... Niestety, język C nie pozwala na wyświetlanie tablicy jedną instrukcję. \\ 
-Tablicę trzeba wyświetlać element po elemencie. 
- 
-Podobnie w przypadku, gdy to użytkownik ma podawać wartości elementów tablicy, trzeba to zrobić element po elemencie (najlepiej -- w pętli!). 
- 
-==== Zadania ==== 
- 
-=== Zadanie SUM1D === 
- 
-Stwórz jednowymiarową tablicę wartości zmiennoprzecinkowych zainicjalizowaną wybranymi przez siebie wartościami,​ a następnie oblicz sumę jej elementów. 
- 
-//​Wskazówka:​ Skorzystaj z pętli ''​for''​.//​ 
- 
-=== Zadanie MAX1D === 
- 
-Napisz program, który wyznaczy największą wartość w jednowymiarowej tablicy liczb całkowitych. 
- 
- 
-===== Jak "​elastycznie"​ określać rozmiar tablicy? ===== 
- 
-Standard ANSI C __nie pozwala__ na używanie zmiennych bądź stałych do określania rozmiaru tablicy podczas deklaracji: 
-<code c> 
-int n = 3; 
-int tab[n]; ​ // blad 
-</​code>​ 
-<code c> 
-const int n = 3; 
-int tab[n]; ​ // blad 
-</​code>​ 
- 
-:!: Oznacza to więc, że **nie ma możliwości utworzenia (__statycznie__) tablicy o rozmiarze zadanym przez użytkownika**! -- Nie pobieraj od użytkownika rozmiaru tablicy.\\ 
-Można to zrobić korzystając z dynamicznej alokacji pamięci, ale to temat na jedno z ostatnich laboratoriów... 
- 
-Z pomocą przychodzą //stałe symboliczne//​. 
- 
-Stałą symboliczną tworzy się z użyciem //derektywy preprocesora//​ ''#​define'',​ na przykład: 
-<code c> 
-#define N   3 
-</​code>​ 
- 
-Preprocesor to program uruchamiany przed właściwą kompilacją (stąd jego nazwa: __pre__procesor),​ a zajmuje się on m.in. dołączaniem plików nagłówkowych (poprzez znaną Ci derektywę ''#​include''​). Derektywa ''#​define''​ mówi "​zamień w __tekście__ programu ciąg znaków po lewej stronie na ciąg znaków po prawej stronie"​. W tym przypadku -- ciąg znaków ''​N''​ na ciąg znaków ''​3''​. \\ 
-Zatem po tym, jak preprocesor skończy swoją robotę, kod 
-<code c> 
-#define N   3 
-... 
-int tab[N]; 
-</​code>​ 
-wygląda następująco (to widzi kompilator):​ 
-<code c> 
-int tab[3]; 
-</​code>​ 
- 
-Preprocesor działa więc momentami jak cenzor, którzy przed dostarczeniem listu do adresata zmienia to i owo -- coś wykreśla, coś dodaje... ;-) 
- 
-Derektywy ''#​define''​ umieszcza się na początku kodu programu, zaraz pod derektywami ''#​include''​. 
- 
-Można tworzyć wiele stałych symbolicznych -- każdą w osobnej linii programu: 
-<code c> 
-#define R   3 
-#define C   3 
-</​code>​ 
-(to będzie przydatne przy tworzeniu tablic wielowymiarowych) 
- 
-:!: Stosuj stałe symboliczne wszędzie tam, gdzie normalnie powinien występować rozmiar tablicy (tj. dany jej wymiar) -- w deklaracjach,​ w pętlach ''​for''​ itd. 
- 
-===== Dlaczego nie należy wychodzić poza zakres tablicy? ===== 
- 
-W poniższym przykładzie mimo, że tablica składa się z trzech elementów (a więc poprawne indeksy to 0, 1 i 2), możemy odwołać się do elementów spoza zakresu -- ani kompilator nie zgłosi błędów, ani (w tym przypadku) nie wystąpi błąd podczas wykonania programu: 
- 
-<code c> 
-#include <​stdio.h>​ 
- 
-int main() 
-{ 
-    int tab[3] = {1, 2, 3}; 
- 
-    printf("​%d\n",​ tab[-1]); 
-    printf("​%d\n",​ tab[3]); 
- 
-    return 0; 
-} 
-</​code>​ 
- 
-Tyle, że... wartości ''​tab[-1]''​ i ''​tab[3]''​ zawierają "​śmieci"​. W dodatku ta pamięć nie należy już do zmiennej ''​tab''​. \\ 
-W ogólnym przypadku odwoływanie się do nie-swojej pamięci może spowodować błąd działania programu. 
- 
-===== Operator "​sizeof"​ ===== 
- 
-Operator ''​sizeof''​ zwraca rozmiar operandu (w bajtach). Używa się go podobnie do wywołania funkcji, przy czym argumentem może być nazwa zmiennej lub typ danych: 
-<code c> 
-int s = sizeof(char); ​ // wartosc `s` to 1, bo tyle wynosi rozmiar typu '​char'​ 
-int s2 = sizeof(s); ​ // wartosc `s2` to (prawdopodobnie) 4 
-</​code>​ 
- 
-Operator ten można wykorzystać,​ aby otrzymać ilość elementów tablicy: 
-<code c> 
-int tab[5]; 
-int ilosc_elementow = sizeof(tab) / sizeof(int);​ 
-</​code>​ 
- 
-===== Przydatne operatory arytmetyczne ===== 
- 
-==== Arytmetyczne operatory przypisania ==== 
- 
-Język C udostępnia //​arytmetyczne operatory przypisania//​ ''<​op>​=''​ (gdzie ''<​op>''​ oznacza operator arytmetyczny:​ ''​+'',​ ''​-'',​ ''​*'',​ ''/''​ bądź ''​%''​):​ instrukcja ''​x <op>= y;''​ jest równoważna ''​x = x <op> (y);''​ 
- 
-Przykład: 
-<code c> 
-int a = 5; 
-int b = 2; 
-a *= 3;      // nowa wartosc `a` to 5 * 3 = 15 
-b *= 3 + 1;  // nowa wartosc `b` to 2 * (3 + 1) = 8 
-</​code>​ 
- 
-==== Inkrementacja i dekrementacja ==== 
- 
-Operatory inkrementacji (''​++''​) i dekrementacji (''​%%--%%''​) powodują odpowiednio zwiększenie bądź zmniejszenie wartości zmiennej o 1. 
- 
-Są one dostępne w dwóch trybach: 
-  * przedrostkowym (//​pre-incrementation//​) -- najpierw następuje zwiększenie wartości zmiennej, potem dalsze operacje na zwiększonej wartości; np. ''​++i''​ 
-  * przyrostkowym (//​post-incrementation//​) -- najpierw wykonywane są operacje (na pierwotnej wartości), a dopiero potem następuje zwiększenie wartości zmiennej; np. ''​i++''​ 
- 
-Przykład: 
-<code c> 
-int a1 = 3; 
-int a2 = 3; 
-int b_pre = 2 * ++a1;  //po wykonaniu instrukcji: b_pre = 6, a1 = 3 
-int b_post = 2 * a2++; //po wykonaniu instrukcji: b_post = 4, a2 = 3 
- 
-printf("​a = %d, b_pre = %d, b_post = %d\n", b_pre, b_post); 
-</​code>​ 
- 
-:!: Zwróć uwagę na to, że np. ''​i+1''​ to nie to samo co ''​i++'':​ 
-<code c> 
-int tab[3] = {1, 2, 3}; 
-int i = 0; 
-printf("​%d\n",​ tab[i++]); ​ // wypisz i-ty element ORAZ (nastepnie) zwieksz `i` o 1 
-// teraz `i` wynosi 1 
-printf("​%d\n",​ tab[i+1]); ​ // wypisz (i+1)-wszy element (ale nie zmnieniaj wartosci `i`) 
-// `i` nadal wynosi 1 
-</​code>​ 
- 
-Operatory inkrementacji i dekrementacji działają tylko dla zmiennych (a ściślej: dla modyfikowalnych l-wartości). Oznacza to, że instrukcja ''​int a = 6++;''​ jest błędna. 
- 
-Stosuj powyższe operatory ostrożnie -- zwiększają one zwięzłość kodu, lecz łatwo popełnić błąd w zapisie. 
- 
-==== "Co za dużo to niezdrowo!"​ ==== 
- 
-Nie łącz zbyt wielu operatorów w jednym wyrażeniu, nie rób "​optymalizacji"​ długości kodu kosztem czytelności -- w ten sposób unikniesz wielu błędów. W szczególności:​ 
-  * Nie stosuj operatora inkrementacji lub dekrementacji do zmiennej, która jest częścią więcej niż jednego argumentu funkcji. 
-  * Nie stosuj operatora inkrementacji lub dekrementacji do zmiennej, która w wyrażeniu pojawia się więcej niż jeden raz. 
- 
-Na przykład po wykonaniu kodu 
-<code c> 
-int n = 3; 
-int y = n++ + n++; 
-</​code>​ 
-''​y''​ może mieć albo wartość ''​6''​ -- jeśli kompilator dwukrotnie użyje starej wartości -- albo wartość ''​7''​ (''​3 + 4''​),​ jeśli zwiększenie nastąpi przed obliczeniem sumy. Standard języka C nie narzuca jednego słusznego sposobu obliczania takiego wyrażenia. 
- 
-===== Zadania podsumowujące ===== 
- 
-/* 
-==== Fotoszop ==== 
- 
-([size=10]poziom trudności:​[/​size] {{stars>​2/​4}} / {{stars>​3/​4}}) 
- 
-Wykonaj zadania w ramach polecenia [[dydaktyka:​cprog:​2015:​photoshop#​cwiczenia|Rozmycie obrazu]]. 
- 
-*/ 
- 
-==== Zadanie RAND-ARR ==== 
- 
-([size=10]poziom trudności:​[/​size] {{stars>​1/​4}}) 
- 
-Napisz program, który uzupełni tablicę typu ''​int''​ (o rozmiarze 10) losowymi wartościami z przedziału $\langle 0, 99 \rangle$. 
- 
-==== Zadanie REV ==== 
- 
-([size=10]poziom trudności:​[/​size] {{stars>​2/​4}}) 
- 
-Napisz program, który odwróci kolejność elementów tablicy "w miejscu",​ czyli bez deklarowania __tablicy__ pomocniczej. \\ 
-Przykład: ''​{1,​ 4, 3}''​ → ''​{3,​ 4, 1}''​. 
- 
-//​Wskazówka:​ Stosowanie "​zwykłej"​ zmiennej pomocniczej jest dozwolone!//​ 
  
dydaktyka/cprog/2016/arrays.1481009198.txt.gz · Last modified: 2020/03/25 11:46 (external edit)