User Tools

Site Tools


dydaktyka:cprog:2016:arrays-adv

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-adv [2016/12/12 11:51]
pkleczek [Zadania]
— (current)
Line 1: Line 1:
-~~NOTRANS~~ 
- 
-====== Tablice – zaawansowane ====== 
- 
-===== Tablice wielowymiarowe ===== 
- 
-==== Deklarowanie ==== 
- 
-Uogólniona deklaracja tablicy wielowymiarowej:​ 
-<​code>​ 
-typ_danych nazwa_tablicy[rozmiar_1][rozmiar_2]...[rozmiar_n];​ 
-</​code>​ 
- 
-na przykładzie dwuwymiarowym:​ 
-<​code>​ 
-typ_danych nazwa_tablicy[ilosc_wierszy][ilosc_kolumn];​ 
-</​code>​ 
- 
-Przykład: 
-<code c> 
-int tab[8][3]; // tablica o osmiu wierszach i trzech kolumnach, wartosci typu calkowitego 
-</​code>​ 
- 
-Komputer przechowuje w pamięci taką tablicę dwuwymiarową liniowo, jako kilka następujących po sobie tablic jednowymiarowych. 
- 
-==== Definiowanie ==== 
- 
-Tablicę wielowymiarową można zdefiniować na dwa sposoby: 
-  * używając "​zagnieżdżonych"​ klamer (pierwszy zestaw -> piewszy rząd, drugi zestaw -> drugi rząd itd.) 
-  * stosując "​płaską"​ definicją -- wszystkie wartości znajdują się w jednych klamrach, przypisywane są do kolejnych elementów wierszami (najpierw całkowicie zapełniany jest pierwszy wiersz, potem drugi itd.) 
- 
-Przykład sposobu z "​zagnieżdżaniem"​ klamer: 
-<code c> 
-int tab[2][3] = { 
-        {3, 2, 6}, 
-        {5, 1, 9} 
-    }; 
-</​code>​ 
- 
-Przykład sposobu "​płaskiego":​ 
-<code c> 
-int tab[2][3] = {3, 2, 6, 5, 1, 9};  // zdecydowanie mniej czytelne, 
-                                     // w miare mozliwosci unikac! 
-</​code>​ 
- 
- 
-==== Dostęp do elementów ==== 
- 
-Podobnie jak w przypadku tablicy jednowymiarowej,​ dostęp uzyskuje się przez podanie w nawiasach kwadratowych numerów pozycji dla kolejnych wymiarów. \\ 
-Dla przypadku dwuwymiarowego,​ podaje się najpierw numer wiersza, a potem numer kolumny. 
- 
-Przykład: 
-<code c> 
-int tab[3][2]; 
-tab[2][0] = 5;  // przypisz wartosc elementowi w 3. wierszu w 1. kolumnie 
-</​code>​ 
- 
-Poniższy rysunek pomoże Ci załapać tę zasadę:\\ 
-{{:​dydaktyka:​cprog:​2015:​2d-array_indexing.png?​nolink|}} 
- 
-==== Zadania ==== 
- 
-=== Zadanie SUM2D === 
- 
-Zadeklaruj tablicę dwuwymiarową $A_{N \times M}$. Przypisz do każdego z jej elementów $a(i,j)$ wartość $i + 2 \cdot j$, gdzie $i$ -- numer wiersza, a $j$ -- numer kolumny. Oblicz sumę elementów leżących w co drugim wierszu, zaczynając od pierwszego wiersza. 
- 
-//​Wskazówka 1: Użyj zagnieżdżonych pętli ''​for''​ zarówno do inicjalizacji elementów tablicy, jak i do obliczenia sumy elementów.//​ \\ 
-//​Wskazówka 2: Zastosuj osobny zestaw pętli dla inicjalizacji i osobny dla sumowania.//​ 
- 
-===== Tablice bezwymiarowe ===== 
- 
-Różnica w tworzeniu tablic "​bezwymiarowych"​ w przypadku tablicy o wymiarze większym niż 1 jest następująca:​ 
- 
-:!: Kompilator jest w stanie obliczyć tylko jeden wymiar tablicy -- pierwszy od lewej. Pozostałe wymiary muszą zostać określone przez programistę:​ 
-<code c> 
-int tab[][2] = {{1,2}, {3,4}, {5,​6}}; ​ // OK 
-int tab[][] = {{1,2}, {3,​4}}; ​ // blad 
-</​code>​ 
- 
-===== Jak "​elastycznie"​ określać rozmiar tablicy? – Derektywa #define ===== 
- 
-Jak wspomniano w poprzednim laboratorium o tablicach, 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>​ 
- 
-Taki mechanizm jest przydatny właśnie podczas tworzenia wielowymiarowych tablic, szczególnie w przypadku gdy jeden z wymiarów ma być określony automatycznie. 
- 
-:!: Stosuj stałe symboliczne (bądź ilość elementów obliczoną z użyciem ''​sizeof''​) wszędzie tam, gdzie normalnie powinien występować rozmiar tablicy (tj. dany jej wymiar) -- w deklaracjach,​ w pętlach ''​for''​ itd. 
- 
-===== Łańcuchy znaków ===== 
- 
-Język C nie posiada specjalnego typu łańcuchowego. Zamiast tego, łańcuchy przechowywane są w tablicach elementów typu ''​char''​. Kolejne znaki, z których składa się łańcuch, znajdują się w kolejnych komórkach pamięci, a na ich końcu znajduje się **znak zerowy** (//null character//​). 
- 
-Znak zerowy nie jest cyfrą zero, tylko znakiem niedrukowanym o kodzie ASCII równym 0. Łańcuchy w języku C są przechowywane razem z tym znakiem. Oznacza to, że tablica musi mieć długość przynajmniej o jedną komórkę większą niż długość zapisanego w niej łańcucha. \\ 
-Literał znaku zerowego to ''​%%'​\0'​%%''​. 
- 
-Przykład -- łańcuch znaków ''​%%"​Hello"​%%'':​ \\ 
-{{:​dydaktyka:​cprog:​2015:​string.png?​nolink|}} 
- 
-:!: Znaki cudzysłowu nie są częścią łańcucha. Informują one jedynie kompilator, że to, co znajduje się pomiędzy nimi, jest łańcuchem -- podobnie jak apostrofy sygnalizują stałą znakową. 
- 
- 
-==== Wyświetlanie i wczytywanie ==== 
- 
-Do wyświetlania łańcuchów znaków służy specyfikator konwersji ''​%s'':​ 
-<code c> 
-printf("​Miasto:​ %s\n", "​Krakow"​);​ 
-</​code>​ 
- 
-Do wczytywania łańcuchów znaków najwygodniej wykorzystać funkcję [[http://​www.cplusplus.com/​reference/​cstdio/​gets/?​kw=gets|gets()]],​ która odczytuje znaki do momentu napotkania znaku końca linii (ENTER) i zapisuje je jako łańcuch w tablicy znaków -- sam znak końca linii nie jest kopiowany. Funkcja automatycznie dołącza do wczytanych znaków znak zerowy, tworząc tym samym łańcuch znaków. 
-<code c> 
-char imie[15]; 
-printf("​Podaj swoje imie: "); 
-gets(imie); 
-</​code>​ 
- 
-Oczywiście możesz też użyć funkcji ''​scanf()''​ ze specyfikatorem konwersji ''​%s'':​ 
-<code c> 
-char imie[15]; 
-printf("​Podaj swoje imie: "); 
-scanf("​%s",​ imie); ​ // `imie` to tablica, a nazwa tablicy to rownoczesnie ADRES jej  
-                    // pierwszego elementu - nie trzeba zatem dodawac '&'​ przed nazwa tablicy 
-</​code>​ 
- 
-:!: Pamiętaj, żeby wczytywać znaki do wystarczająco dużej tablicy (aby zmieściły się wszystkie znaki i jeszcze znak zerowy)! 
- 
- 
-==== Przydatne funkcje ==== 
- 
-Do badania długości łańcucha znaków -- czyli ilości znaków faktycznie tworzących łańcuch, z pominięciem znaku zerowego -- służy funkcja [[http://​www.cplusplus.com/​reference/​cstring/​strlen/?​kw=strlen|strlen()]]. \\ 
-Zwróć uwagę, że ''​sizeof''​ i ''​strlen''​ zwracają różne wartości dla tablicy przechowującej łańcuch znaków, gdyż łańcuch może nie zajmować całej tablicy (uruchom poniższy program): 
-<code c> 
-#include <​stdio.h>​ 
-#include <​stdlib.h>​ 
-#include <​string.h>​ 
- 
-int main () 
-{ 
-    char str[10] = "​ABC";​ // lancuch zajmuje 4 elementy tablicy 
- 
-    printf("​sizeof = %d , strlen = %d\n", sizeof(str),​ strlen(str));​ 
- 
-    return 0; 
-} 
-</​code>​ 
- 
-Aby określić typ znaku (np. czy dany znak jest cyfrą) warto skorzystać z biblioteki [[http://​www.cplusplus.com/​reference/​cctype/​|ctype.h]]. 
- 
-==== Zadania ==== 
- 
-=== Zadanie IDL === 
- 
-Napisz program, który pobiera imię i nazwisko użytkownika (używając jednego wywołania funkcji ''​scanf()''​),​ a następnie wyświetla: w pierwszym wierszu imię i nazwisko, a w drugim liczbę liter w imieniu oraz liczbę liter w nazwisku. 
- 
-Na przykład: 
-<code c> 
-Podaj imie i nazwisko: Jan Nowak 
- 
-Jan Nowak 
-3 5 
-</​code>​ 
- 
-//​Wskazówka:​ Przechowuj imię i nazwisko w osobnych tablicach.//​ 
- 
-=== Zadanie PAL === 
- 
-Napisz program, który sprawdzi czy dany łańcuch znaków jest [[http://​sjp.pwn.pl/​sjp/​palindrom;​2497635.html|palindromem]]. 
- 
-Na przykład ''​kajak''​ jest palindromem,​ natomiast ''​rower''​ już nie ;-) 
  
dydaktyka/cprog/2016/arrays-adv.1481539912.txt.gz · Last modified: 2020/03/25 11:46 (external edit)