Tablice wielowymiarowe Przykład – tablica 2-wymiarowa
Transkrypt
Tablice wielowymiarowe Przykład – tablica 2-wymiarowa
Tablice wielowymiarowe ● Tak naprawdę nie istnieją w C! ● C i Java dopuszczają tworzenie „tablic tablic” ● Przykład – tablica 2-wymiarowa ● Rozważmy tablicę o rozmiarze 3x2 1 2 – tablica 2-wymiarowa = tablica (zwykłych) tablic – tablica 3-wymiarowa = tablica tablic wymiaru 2 – ... ● – tablica (n+1)-wymiarowa = tablica tablic wymiaru n ● Każdy wymiar oznaczamy parą nawiasów ([]) 3 5 4 6 C pamięta ją w sposób liniowy: 1 2 3 4 5 6 Kompilator zinterpretuje ją jako 3-elementową tablicę tablic 2-elementowych int a[][][]; 3-wymiarowa tablica liczb całkowitych ● 1 Inicjalizując używamy zagnieżdżonych list wartości 2 3 4 5 6 a[1][0] 156 157 Przykład Przykład 3-wymiarowy ● /* wypisz.c */ #include <stdio.h> int main() { int a[][2] = {{1,2}, {3,4}, {5,6}}; int i,j; for (i = 0; i < 3; ++i) { printf("* "); for (j = 0; j < 2; ++j) printf("%d ", a[i][j]); putchar('*'); } putchar('\n'); return 0; } Program na następnym slajdzie tworzy i przegląda następującą tablicę 3-wymiarową a[0] == 1 2 3 5 4 6 a[1] == 7 8 9 1 0 2 * 1 2 ** 3 4 ** 5 6 * 158 159 Przykład 3D c.d. Napisy – łańcuchy znaków /* wypisz3d.c */ #include <stdio.h> int main() { int a[][3][2] = {{{1,2}, {3,4}, {5,6}}, {{7,8}, {9,0}, {1,2}}}; int i, j, k; for (i = 0; i < 2; ++i) { printf("* "); for (j = 0; j < 3; ++j) { for (k = 0; k <2; ++k) printf("%d ", a[i][j][k]); putchar('*'); } } putchar('\n'); return 0; } * 1 2 *3 4 *5 6 ** 7 8 *9 0 *1 2 * ● ● ● ● Napisy to tablice znaków W języku Java występuje osobny typ/klasa String o większych możliwościach Ostatnim elementem w tablicy reprezentującej napis jest zawsze znak o kodzie 0 – „null” Literały napisowe automatycznie uzupełniają napis o „terminator” w postaci znaku null "Ahoj!" 'A' 'h' 'o' 'j' '!' '\0' 160 161 Nagłówek <string.h> Napisy – przykład /* napisy.c */ #include <stdio.h> #include <string.h> ● int main() { char imie[] = {'R', 'o', 'm', 'a', 'n', '\0'}; char nazw[] = "Nowakowski"; printf("Imię: %s\n", imie); printf("Nazwisko: %s\n", nazw); printf("Imię ma: %d znaków\n", strlen(imie)); printf("Nazwisko ma: %d znaków\n", strlen(nazw)); return 0; } Imię: Roman Nazwisko: Nowakowski Imię ma: 5 znaków Nazwisko ma: 10 znaków ● Zawiera dwie grupy funkcji – pozwalające na analizowanie i manipulowanie ciągami znaków – funkcje o nazwach str... – wykonujące operacje na pamięci w bardziej ogólny sposób – funkcje o nazwach mem... Dostępne grupy operacji – kopiowanie i łączenie: ● – porównywanie ● – – strcmp, strcmp, memcmp, memcmp, ... wyszukiwanie ● 162 strcpy, strcpy, strcat, strcat, memcpy, memcpy, ... strchr, strchr, memchr, memchr, strrchr, strrchr, strstr, strstr, strtok, strtok, ... inne: np. strlen, strlen, strerror, strerror, ... 163 Formatowane przetwarzanie napisów Formatowane przetwarzanie napisów /* ilustracja funkcji sprintf/sscanf */ #include <stdio.h> /* ilustracja funkcji sprintf/sscanf */ #include <stdio.h> int main() { int n = 1; float x = 2.0; char s[] = "ahoj"; char lancuch[BUFSIZ]; sprintf(lancuch,"%d %f A%s!", n+1, x+2, s+1); puts(lancuch); sscanf(lancuch,"%d %f %s", &n, &x, s); printf("n: %d, x: %f, s: %s\n", n, x, s); return 0; } int main() { Błąd – chociaż „zadziałało”! int n = 1; float x = 2.0; char s[] = "ahoj"; char lancuch[BUFSIZ]; sprintf(lancuch,"%d %f A%s!", n+1, x+2, s+1); puts(lancuch); sscanf(lancuch,"%d %f %s", &n, &x, s); printf("n: %d, x: %f, s: %s\n", n, x, s); return 0; } 2 4.000000 Ahoj! n: 2, x: 4.000000, s: Ahoj! 2 4.000000 Ahoj! n: 2, x: 4.000000, s: Ahoj! 164 165 Tablice mają statyczny rozmiar Struktury w ANSI C /* ilustracja funkcji sprintf/sscanf */ #include <stdio.h> ● int main() { 'a' 'h' 'o' 'j' '\0' int n = 1; float x = 2.0; char s[] = "ahoj"; s[5]='X'; char lancuch[BUFSIZ]; printf("%dB, %x, %x\n",sizeof(s),s[4],s[5]); sprintf(lancuch,"%d %f A%s!", n+1, x+2, s+1); sscanf(lancuch,"%d %f %s", &n, &x, s); printf("%dB, %x, %x\n",sizeof(s),s[4],s[5]); return 0; } '\0' ● ● ● Struktura – uporządkowany zbiór zmiennych – „składowych” – składowe mogą mieć różne typy Do definiowania służy słowo kluczowe struct Do odwoływania się do składowych struktury służy operator „.” Struktury to punkt wyjścia dla pojęcia obiektu – składowe to „atrybuty” obiektu 'A' 'h' 'o' 'j' '!' 5B, 0, 58 5B, 21, 0 166 167 Struktury – przykład Struktury – przykład 2 #include <stdio.h> #include <string.h> #include <stdio.h> #include <string.h> struct Towar { char nazwa[20]; float cena; }; // Średnik jest tu niezbędny!!! #define MAX 10 struct Towar { char nazwa[20]; float cena; }; int main() { struct Towar t1 = {"Rower", 799.99}; struct Towar t2; t2 = t1; t2.cena += 200.0; strcat(t2.nazwa, " Wagant"); printf("%s: %f.2\n", t1.nazwa, t1.cena); printf("%s: %f.2\n", t2.nazwa, t2.cena); return 0; } Rower: 799.99 zł Rower Wagant: 999.99 zł struct Oferta { struct Towar lista[MAX]; int liczba; }; 168 169 Struktury – przykład 2 c.d. Łańcuchy i przypisanie int main() { struct Oferta mo; int i; mo.liczba = 0; /* wstaw pierwszy towar */ strcpy(mo.lista[mo.liczba].nazwa, "Rower"); mo.lista[mo.liczba++].cena = 799.99; /* wstaw drugi towar */ strcpy(mo.lista[mo.liczba].nazwa, "Torba"); mo.lista[mo.liczba++].cena = 29.99; /* wydrukuj listę towarów */ for (i = 0; i < mo.liczba; ++i) printf("%s: %.2f\n", mo.lista[i].nazwa, mo.lista[i].cena); return 0; } Rower: 799.99 Torba: 29.99 170 ● Język C dopuszcza inicjalizację char a[] = "Ahoj przygodo!"; ● W sytuacji char a[14]; a = "Ahoj przygodo!"; kompilator sygnalizuje błąd. Dlaczego? ● Łańcuchy znaków to tablice, a język C nie dopuszcza bezpośredniego przypisywania wartości tablicowych. Należy w takiej sytuacji użyć funkcji strcpy char a[14]; strcpy(a, "Ahoj przygodo!"); 171 Złożone typy danych – podsumowanie ● ● ● ● ● ● ● ● ANSI C – funkcje Deklaracja/inicjalizacja tablicy ustala jednolity typ wszystkich jej elementów oraz niezmienny rozmiar ● Wprowadzenie – programowanie proceduralne Indeksowanie tablic rozpoczyna się od zera – argumenty i wynik funkcji Tablice wielowymiarowe to „tablice tablic” – prototypy funkcji – zasięg – zmienne automatyczne, statyczne i globalne Napisy (łańcuchy) to tablice znaków; „koniec łańcucha” wyznacza znak null (o kodzie 0) Do tablic nie można stosować operatora przypisania Struktury pozwalają na łączenie danych różnych typów w całość Do struktur można stosować operator przypisania Struktury i tablice mogą być inicjalizowane za pomocą list elementów ujętych w nawiasy klamrowe 172 Funkcje w ANSI C – wprowadzenie ● ● Przykład Rola funkcji – 173 /* Prosty przykład wykorzystania funkcji */ #include <stdio.h> pomagają podzielić kod programu na mniejsze, logicznie wydzielone zadania – ukrywają szczegóły pewnych operacji tam, gdzie ich znajomość nie jest niezbędna – zwiększają przejrzystość kodu programu i ułatwiają wprowadzanie w nim zmian Funkcja – podstawowe cechy – posiada unikatową nazwę – składa się z ciągu instrukcji implementującego dobrze określoną operację/zadanie – może być zależna od argumentów i zwracać wynik 174 float avg(int n, int m) { return (n + m) / 2.0; } int main() { int x,y; printf("Podaj pierwszą liczbę: "); scanf("%d", &x); printf("Podaj drugą liczbę: "); scanf("%d", &y); printf("Średnia: %.2f\n", avg(x,y)); return 0; } 175 Definicja funkcji – postać ogólna Uwagi typ_wyniku nazwa ( lista_parametrów ) { ● deklaracje ● instrukcje } ● ● Lista parametrów jest listą par postaci – typ nazwa_parametru oddzielonych przecinkami ● Jeśli funkcja ma zwracać pewną wartość, to musi ona być zgodna z zadeklarowanym typem_wyniku Parametry funkcji pełnią rolę „zmiennych lokalnych” w kodzie funkcji Wartość parametrów ustalana jest w momencie wywołania funkcji Do zwracania wyniku funkcji służy instrukcja postaci: return wyrażenie; – wyrażenie może być ujęte w nawiasy – jeśli funkcja nie ma zwracać wyniku, to aby „przekazać sterowanie” z powrotem do programu wywołującego można użyć pustego wyrażenia, tzn. instrukcji return ; return ; – jeśli w funkcji nie występuje instrukcja return, return, to sterowanie wraca do programu wywołującego po napotkaniu zamykającego nawiasu } 176 177 Słowo kluczowe void ● Funkcja main, ANSI C i void Użyte jako typ wyniku funkcji – ● wskazuje, że funkcja nie zwraca żadnej wartości main() { ... } void f(int x, float y) { ... } ● ● Użyte w miejscu listy parametrów funkcji – W „tradycyjnym” C można było napisać: int main(void) { mówi, że funkcja nie akceptuje żadnych argumentów void komunikat(void) { puts("Witaj w ..."); } ... komunikat(); W języku ANSI C powyższe należy zamienić na: ... } ● ANSI C dopuszcza jeszcze inny formę main: int main(int argc, char *argv[]) { ... } 178 179