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