iii. b. Deklaracja zmiennej znakowej poprzez podanie znaku

Podobne dokumenty
4. Tablica dwuwymiarowa to jednowymiarowa tablica wskaźników do jednowymiarowych tablic danego typu.

iii. b. Deklaracja zmiennej znakowej poprzez podanie znaku

Stałe i zmienne znakowe. Stała znakowa: znak

Języki i paradygmaty programowania 1 studia stacjonarne 2018/19. Lab 9. Tablice liczbowe cd,. Operacje na tablicach o dwóch indeksach.

Tablice w argumentach funkcji. Tablicy nie są przekazywane po wartości Tablicy są przekazywane przez referencje lub po wskaźniku

Lab 8. Tablice liczbowe cd,. Operacje macierzowo-wektorowe, memcpy, memmove, memset. Wyrażenie warunkowe.

Wskaźniki. Informatyka

Lab 9 Podstawy Programowania

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 26 marca kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 40

Co to jest sterta? Sterta (ang. heap) to obszar pamięci udostępniany przez system operacyjny wszystkim działającym programom (procesom).

Podstawy Programowania C++

int tab[5]; tab[1]; ciągły obszar pamięci, w którym umieszczone są elementy tego samego typu macierz [ ] - dwuargumentowy operator indeksowania

Wskaźniki. Przemysław Gawroński D-10, p marca Wykład 2. (Wykład 2) Wskaźniki 8 marca / 17

Katedra Elektrotechniki Teoretycznej i Informatyki. wykład 9 - sem.iii. Dr inż. M. Czyżak

Języki programowania obiektowego Nieobiektowe elementy języka C++

Tablice, funkcje - wprowadzenie

Katedra Elektrotechniki Teoretycznej i Informatyki. wykład 7- sem.iii. M. Czyżak

Podstawy programowania w języku C++

Podstawy programowania skrót z wykładów:

Tablice (jedno i wielowymiarowe), łańcuchy znaków

Wstęp do programowania INP003203L rok akademicki 2018/19 semestr zimowy. Laboratorium 2. Karol Tarnowski A-1 p.

Języki programowania. Przetwarzanie tablic znaków. Część druga. Autorzy Tomasz Xięski Roman Simiński

Ćwiczenie nr 6. Poprawne deklaracje takich zmiennych tekstowych mogą wyglądać tak:

Podstawy programowania. Wykład 6 Wskaźniki. Krzysztof Banaś Podstawy programowania 1

Powyższe wyrażenie alokuje 200 lub 400 w zależności od rozmiaru int w danym systemie. Wskaźnik wskazuje na adres pierwszego bajtu pamięci.

ISO/ANSI C - funkcje. Funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje

Część 4 życie programu

Podstawy programowania

wykład II uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C - funkcje, tablice i wskaźniki wykład II dr Jarosław Mederski Spis

Tablice deklaracja, reprezentacja wewnętrzna

Podstawy programowania. Wykład Pętle. Tablice. Krzysztof Banaś Podstawy programowania 1

Wskaźniki i dynamiczna alokacja pamięci. Spotkanie 4. Wskaźniki. Dynamiczna alokacja pamięci. Przykłady

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Podstawy programowania 1

Materiał Typy zmiennych Instrukcje warunkowe Pętle Tablice statyczne Wskaźniki Tablice dynamiczne Referencje Funkcje

Języki i paradygmaty programowania 1 studia stacjonarne 2018/19

Stałe, znaki, łańcuchy znaków, wejście i wyjście sformatowane

Tablice. Monika Wrzosek (IM UG) Podstawy Programowania 96 / 119

Wskaźniki. nie są konieczne, ale dają językowi siłę i elastyczność są języki w których nie używa się wskaźników typ wskaźnikowy typ pochodny:

Podstawy programowania w języku C++

Wskaźniki w C. Anna Gogolińska

Temat: Dynamiczne przydzielanie i zwalnianie pamięci. Struktura listy operacje wstawiania, wyszukiwania oraz usuwania danych.

Laboratorium 3: Tablice, tablice znaków i funkcje operujące na ciągach znaków. dr inż. Arkadiusz Chrobot dr inż. Grzegorz Łukawski

Podstawy programowania w języku C++

Podstawy programowania komputerów

Wstęp do programowania INP001213Wcl rok akademicki 2017/18 semestr zimowy. Wykład 12. Karol Tarnowski A-1 p.

część 8 wskaźniki - podstawy Jarosław Gramacki Instytut Informatyki i Elektroniki Podstawowe pojęcia

Programowanie Proceduralne

Wprowadzenie do programowania w języku C

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

ZASADY PROGRAMOWANIA KOMPUTERÓW

Podstawy Programowania

Ćwiczenie 4. Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1.

utworz tworzącą w pamięci dynamicznej tablicę dwuwymiarową liczb rzeczywistych, a następnie zerującą jej wszystkie elementy,

DANE TEKSTOWE W JĘZYKU C/C++ - TABLICE ZNAKOWE

Inicjacja tablicy jednowymiarowej

Wskaźniki. Programowanie Proceduralne 1

Zmienne, stałe i operatory

Podstawy programowania. Wykład 7 Tablice wielowymiarowe, SOA, AOS, itp. Krzysztof Banaś Podstawy programowania 1

Stałe, tablice dynamiczne i wielowymiarowe

Obsługa plików. Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Laboratorium Podstaw Informatyki Strona 1. Kraków 2013

Laboratorium 6: Ciągi znaków. mgr inż. Leszek Ciopiński dr inż. Arkadiusz Chrobot dr inż. Grzegorz Łukawski

ŁAŃCUCHY W JĘZYKU C/C++

Języki programowania. Przetwarzanie plików amorficznych Konwencja języka C. Część siódma. Autorzy Tomasz Xięski Roman Simiński

Pliki w C/C++ Przykłady na podstawie materiałów dr T. Jeleniewskiego

Wstęp do wskaźników w języku ANSI C

1 Podstawy c++ w pigułce.

1 Podstawy c++ w pigułce.

Lab 10. Funkcje w argumentach funkcji metoda Newtona. Synonimy nazw typów danych. Struktury. Tablice struktur.

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

Wykład IV PASCAL - łańcuch znaków, - procedury i funkcje, - sortowanie bąbelkowe

Wstęp do programowania INP001213Wcl rok akademicki 2018/19 semestr zimowy. Wykład 4. Karol Tarnowski A-1 p.

Argumenty wywołania programu, operacje na plikach

Programowanie w języku C++

Biblioteka standardowa - operacje wejścia/wyjścia

Tablice, funkcje, wskaźniki - wprowadzenie

Języki i paradygmaty programowania 1 studia niestacjonarne 2018/19

Programowanie proceduralne INP001210WL rok akademicki 2015/16 semestr letni. Wykład 6. Karol Tarnowski A-1 p.

dr inż. Jarosław Forenc

Pętle i tablice. Spotkanie 3. Pętle: for, while, do while. Tablice. Przykłady

Podstawy informatyki. Informatyka stosowana - studia niestacjonarne. Grzegorz Smyk. Wydział Inżynierii Metali i Informatyki Przemysłowej

// Liczy srednie w wierszach i kolumnach tablicy "dwuwymiarowej" // Elementy tablicy są generowane losowo #include <stdio.h> #include <stdlib.

KURS C/C++ WYKŁAD 6. Wskaźniki

Informatyka 1. Plan dzisiejszych zajęć. zajęcia nr 11. Elektrotechnika, semestr II rok akademicki 2008/2009

Tablice wielowymiarowe. Przykład tablica 2-wymiarowa. Przykład. Przykład 3-wymiarowy. Tak naprawdę nie istnieją w C! Rozważmy tablicę o rozmiarze 3x2

Uzupełnienie dot. przekazywania argumentów

DYNAMICZNE PRZYDZIELANIE PAMIECI

Pliki. Informacje ogólne. Obsługa plików w języku C

Pliki. Informacje ogólne. Obsługa plików w języku C

Elementy języka C. ACprogramislikeafastdanceonanewlywaxeddancefloorbypeople carrying razors.

Wstęp do programowania

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

ISO/ANSI C - funkcje. Funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje. ISO/ANSI C - funkcje

//zmienne globalne int *pa, *pb; //wskaźniki globalne void main(void) { clrscr(); printf("\n podaj wartosc liczby a\n"); scanf("%d",&a); pa=&a;

Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)

Wykład VII. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik

Programowanie Proceduralne

Zasady programowania Dokumentacja

dynamiczny przydział pamięci calloc() memset() memcpy( ) (wskaźniki!! )

Język C++ zajęcia nr 2

Transkrypt:

Języki i paradygmaty programowania 1 studia stacjonarne 2018/19 Lab 3. Stałe i zmienne znakowe. Tablice. Wskaźniki do tablic. Operacje na wskaźnikach. Instrukcja switch, case. Wyrażenie przecinkowe. Funkcje tekstowe. Tablice znakowe o dwóch indeksach, przekazywanie tablic do funkcji, dynamiczna alokacja pamięci, funkcje przetwarzające ciągi znakowe. Projekt nr 2. 1. char jest to typ znakowy, umożliwiający zapis znaków ASCII. Może też być traktowany jako liczba z zakresu 0..255 (Oznacza to, że każdy znak jest reprezentowany w pamięci przez swój kod. Kody znaków alfanumerycznych to liczby z przedziału *32 127+ pozostałe liczby są również kodami znaków, ale mogą być one różnie definiowane nie odpowiadają standardowi ASCII). Znaki zapisujemy w pojedynczych cudzysłowach (czasami nazywanymi apostrofami), by odróżnić je od łańcuchów tekstowych (pisanych w podwójnych cudzysłowach). Np. 'a';'7';'!'; '$'. i. Stała znakowa ma postać: 'znak' ii. Deklaracja zmiennej znakowej poprzez podanie kodu znaku spacji char i = 32; // i znak spacji iii. b. Deklaracja zmiennej znakowej poprzez podanie znaku char i = ' '; // i znak spacji //Zmienne znakowe wyprowadzanie znaków, ++i /* Kody ASCII */ int i = 32; /* int i=' '; jest poprawne */ while (++i < 128) printf("%3d %c ", i, i); if (!((i - 32) % 4)) printf("\n"); printf("\n"); //Zmienne znakowe wyprowadzanie znaków, i++ /* Kody ASCII */ char i = ' '; /* char i=32; jest poprawne */ while (i++ < 127) printf("%3d %c ", i, i); if (!((i - 32) % 4)) printf("\n"); printf("\n"); 2. Typ char to zwykły typ liczbowy i można go używać tak samo jak typu int (zazwyczaj ma jednak mniejszy zakres). Co więcej literały znakowe (np. 'a') są traktowane jak liczby i w języku C są typu int (w języku C++ są typu char). 3. Stała tekstowa dowolny ciąg znaków, zapisany w postaci: to jest stała tekstowa. Jeśli w stałej chcemy umieścić cudzysłów należy wtedy poprzedzić znak znakiem \ tzn. umieścić w tekście sekwencję \. Kompilator umieszcza tekst w odpowiedniej grupie bajtów (1B na symbol). Na końcu stałej tekstowej dopisywany jest znak o kodzie zero, czyli symbol \0. to jest stała tekstowa = 22 znaki łącznie ze spacjami. W pamięci komputera stała ta zajmie 23B razem ze znakiem \0. 4. Tablice znakowe używane są do zapisu ciągu znaków w pamięci komputera. Ciąg znaków (wiersz tekstowy) jest umieszczany w kolejnych bajtach pamięci. Każdy znak tego ciągu to odpowiedni element tablicy znakowej. Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 1

Definicja tablicy znakowej: char tekst[num]; gdzie: tekst to nazwa (identyfikator) tablicy, num maksymalna liczba znaków minus jeden tzw. rozmiar tablicy; musi być zdefiniowany jako stała. Elementy tablicy numerowane są od 0 do n-1 (numery elementów to tzw. indeksy tablicy) tekst[0], tekst[1],, tekst[n-2], tekst[n-1] przy czym tekst[n-1] -> '\0', pamięć zarezerwowana na num elementów: num >= n. Odwołanie do elementu tablicy o indeksie i następuje poprzez użycie operatora [ ] np.: tekst[i], a w każdym elemencie można zapisać tylko jeden znak np. : tekst[1]= 'a'. //Liczba powtórzeń litery a (1)-tablice tekstowe /*Ile razy litera a powtarza sie w tekscie*/ char d[max_line], b; int k, l; k = 0; l = 0; gets(d); while ((b = d[k])!= '\0') if (b == 'a') l++; k++; printf("%s\n%d\n", d, l); //Liczba powtórzeń litery a (2) - tablice tekstowe /*Ile razy litera a powtarza sie w tekscie*/ char d[max_line], b; int k = 0, l = 0; gets(d); while ((b = d[k++])!= '\0') if (b == 'a') l++; printf("%s\n%d\n", d, l); 5. Funkcja gets() - czyta linię ze standardowego wejścia (usuwa ją stamtąd) i umieszcza ją w tablicy znakowej wskazywanej przez str. Ostatni znak linii (znak nowego wiersza - '\n') zastępuje zerem (znakiem '\0'). Wartością zwracaną funkcji jest str (wskaźnik do tekstu) w przypadku sukcesu lub NULL w przypadku błędu lub natrafienia na koniec pliku. Funkcja nie sprawdza, czy jest miejsce do zapisu w tablicy str. Deklaracja: char *gets(char *str); 6. Wskaźnik do tablicy definicja tablicy rezerwuje odpowiednią grupę bajtów w pamięci i przypisuje nazwie (identyfikatorowi) tekst adres zerowego elementu. Nie wolno zmieniać wartości tekst jest to stała, wskaźnik początku tablicy. Dodatkowo identyfikator tekst nie jest L-value, tzn. że nie można go używać po lewej stronie instrukcji przypisania. Przykład 1: char str1[] = "abcde"; //debuger information: str1 = 0x0012fe44 "abcde" //str1[0] = 97 a, &str1[0] 0x0012fe44 "abcde" //str1[1] = 98 b &str1[1] 0x0012fe45 "bcde" Przykład 2: char str[256]; char *ptr = NULL; ptr = gets(str); //Przy wyjściu z gets str zawiera ciąg znaków, //wprowadzonych z monitora, ptr to jest wskaźnik do str: str 0x0012fe60 "abcdef" char[256] ptr 0x0012fe60 "abcdef" char * Przykład 3: Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 2

char *ptr = NULL; //ptr 0x00000000 ptr = "abcdefg"; //ptr 0x0041563c "abcdefg" char * //Uwaga! Pamięć pozostała wydzielona w obszarze roboczym. Ta informacja nie będzie chroniona. //Kod poprawny: ptr = (char *)malloc(256 * sizeof(char)); //dynamiczne wydzielenie pamięci w stercie (heap) if (!ptr) printf("błąd \n"); exit(1); sprintf(ptr, "abcdefg"); //... //jeżeli ptr jest już nie potrzebne zwolnij pamięć! if (ptr) free(ptr); ptr = NULL; //Liczba powtórzeń litery a (3) - tablice a wskaźniki /*Ile razy litera a powtarza sie w tekscie*/ char d[max_line], *dd; int l; l = 0; dd = gets(d); while (*dd!= '\0') if (*dd == 'a') l++; dd++; printf("%s\n%d\n", d, l); //Liczba powtórzeń litery a (4) - krótko /*Ile razy litera a powtarza sie w tekscie*/ char d[max_line], *dd; int l; l = 0; dd = gets(d); while (*dd) if (*dd++ == 'a') l++; printf("%s\n%d\n", d, l); 7. Instrukcja switch, case - tzw. warunek wielokrotnego wyboru lub przełącznik. Dzięki tej instrukcji możemy wykonywać decyzje tylko i wyłącznie na podstawie wartości jednej zmiennej. Możliwości instrukcji switch są nieporównywalnie mniejsze od możliwości funkcji if, jednak używanie jej w niektórych przypadkach jest znacznie korzystniejsze dla szybkości działania programu i estetyki kodu niż użycie funkcji if. Składnia: switch (zmienna) case wartosc_1: //jakiś kod case wartosc_2: //jakiś kod //... case wartosc_n: //jakiś kod default: //jakiś kod Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 3

Algorytm działania: 1. Obliczenie wartości zmienna 2. Jeśli zmienna == wartosc_i - wykonanie ciągu instrukcji (i + 1).ciąg instrukcji n, goto 3; jeśli zmienna!= wartosc_i - ciąg instrukcji default, goto 3 ; 3. Pierwszy operator poza blokiem switch W przypadku gdy operator default jest pominięty w deklaracji instrukcji switch: 1. Obliczenie wartości zmienna 2. Jeśli zmienna == wartosc_i - wykonanie ciągu instrukcji (i + 1).ciąg instrukcji n; pierwszy operator poza blokiem switch Ostatnim operatorem ciągu instrukcji i może być - przerywa on działanie switch i przekazuje sterowanie do pierwszego operatora poza blokiem switch. switch (i) case -1: n++; case 0: z++; case 1: p++; 8. Przykład: liczba wystąpień liter a, b oraz liter od b do y. //Instrukcje switch, case, break, continue /* Liczba wystąpień liter a, b oraz liter od b do y */ char d[max_line], *dd, b; int l, k, m; l = k = m = 0; dd = gets(d); while (b = *dd++, b!= '\0') if (!(b >= 'a' && b <= 'y')) continue; switch (b) case 'a': l++; case 'b': k++; default: m++; printf("%d %d %d\n", l, k, m); Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 4

9. Operator przecinkowy, wyrażenie przecinkowe. Operator przecinkowy jest operatorem o najniższym priorytecie i jest lewostronnie łączny. Wyrażenie przecinkowe to wrażenie postaci: wyrazenie_1, wyrazenie_2 Wartością wyrażenia przecinkowego jest wartość wyrazenie_2. 10. Przykład: liczba słów w jednej linii tekstu. //Liczba słów w linii tekstu (1) char d[max_line], *dd, p = ' ', b; dd = gets(d); printf("%s\n", dd); /* Tu zostanie wyprowadzony cały wczytany tekst */ while ((b = *dd)!= '\0') if (b!= ' ') if (p == ' ') l++; p = b; dd++; /* A tu zostanie wyprowadzony pusty tekst */ printf("%s\n", dd); 11. Przykład: liczba słów w jednej linii tekstu tablice w argumentach funkcji. //Liczba słów w linii tekstu (2) - tablice w argumentach funkcji int ile_slow_1(char *), ile_slow_2(char *), ile_slow_3(char *), ile_slow(char *); char d[max_line], *dd; int l; dd = gets(d); /* Tu zostanie wyprowadzony caly wczytany tekst */ printf("%s\n", dd); l = ile_slow_1(d); l = ile_slow_2(dd); /* I tu zostanie wyprowadzony caly wczytany tekst */ printf("%s\n", dd); l = ile_slow_3(d); Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 5

l = ile_slow(dd); int ile_slow_1(char te[]) /* Ile jest slow w linii tekstu. Tablice w argumentach funkcji*/ char p = ' ', b; int l = 0, i = 0; while (b = te[i++]) if (b!= ' ') if (p == ' ') l++; p = b; return l; int ile_slow_2(char *te) /* Ile jest slow w linii tekstu. Wskaźniki w argumentach funkcji*/ char p = ' ', b; while (b = *te) if (b!= ' ') if (p == ' ') l++; p = b; te++; return l; int ile_slow_3(char *te) /* Ile jest slow w linii tekstu. Elementy tablic == wskazanie pośrednie*/ char p = ' ', b; int l = 0, i = 0; while (b = te[i]) if (b!= ' ') if (p == ' ') l++; p = b; i++; return l; int ile_slow(char *te) char p, b = ' '; while (p = b, b = *te++) if (b!= ' ' && p == ' ') l++; return(l); 12. Operacje na tekstach wybrane funkcje. Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 6

Funkcja strcpy() Funkcja kopiuje łańcuch znaków (src) do tablicy znaków (dest). Funkcja nie sprawdza czy łańcuch kopiowany zmieści się w tablicy docelowej. Nie istnieje wartość, która wskazywałaby na błędne wykonanie. Deklaracja: char * strcpy(char * dest, const char * src); Funkcja strcat() Dopisuje ciąg znaków (string) strfrom na końcu bufora (string) strto i zamyka symbolem końca \0. Zachowanie funkcji jest nieokreślone, jeśli bufory strto oraz strfrom wzajemnie się pokrywają. Funkcja zwraca wskaźnik do strto. Nie istnieje wartość, która wskazywałaby na błędne wykonanie. Deklaracja: char * strcat(char * strto, const char * strfrom); Funkcja strcmp() (znajduje się w bibliotece <string.h>) Porównuje ciągi znaków string1 i string2. Zwraca wartość (RetVal) typu int. RetVal: < 0 string1 < string2 = 0 string1 == string2 jeśli każdy znak ze string1 jest równy odpowiedniemu znakowi ze string2 > 0 string1 > string2 Deklaracja: int strcmp(const char * string1, const char * string2); Relacja nierówności: w języku C przyjęto, że string1 > string2, jeśli kod pierwszego symbolu ze string1 jest większy od kodu pierwszego symbolu ze string2. Jeśli pierwsze znaki są równe, porównujemy drugie itd. Funkcja strlen() (<string.h>) - oblicza długość łańcucha str. Jej działanie polega na zliczaniu znaków aż do napotkania 0 (znaku '\0'). 0 nie jest wliczane do długości. W przypadku łańcuchów nie zakończonych 0 jej działanie jest nieokreślone. Zwraca długość łańcucha str. Deklaracja: int strlen(char *str); Funkcja getchar() - czyta znak ze standardowego wejścia i go stamtąd usuwa. Wywołanie getchar() jest równoważne wywołaniu getc(stdin). Deklaracja: int getchar(void); Funkcja putchar ( ) - wysyła znak na standardowe wyjście. Wywołanie putchar ( c ) jest równoważne wywołaniu putc(c, stdout). Deklaracja: int putchar(int c); 13. Znajdź pozycję wybranego znaku w tekście. 14. Usuń z tekstu pierwsze wystąpienie wybranego znaku. 15. Zamień każde wystąpienie wybranego znaku na inny znak. 16. Dołącz tekst do innego tekstu. 17. Dołącz tekst od znaku o podanej pozycji na koniec innego teksu. 18. Zaproponuj i zaimplementuj algorytm, który przesunie zawartość N-elementowej tablicy cyklicznie o jedną pozycję w górę. (tzn. pierwszy element na miejsce drugiego, drugi na trzeci,..., ostatni na pierwszy). Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 7

19. Tablice możemy deklarować na kilka sposobów. W przypadku alokacji statycznej możemy je zadeklarować m.in. następująco: int tab1[5]; int tab2[5] = 2, 5, 3, 2, 5 ; int tab3[5] = 2, 2, 1 ; int tab4[5] = 0; int tab5[] = 1, 2, 3, 4, 5 ; Czym różnią (jeśli się różnią) powyższe sposoby? Zadeklaruj tablicę statyczną (bez inicjalizacji jej wartości - pierwszy sposób), podobnie tablicę globalną - jakie wartości przyjmują poszczególne elementy tablicy? Język C pozwala w sposób analogiczny na deklarację tablic wielowymiarowych. Przykłady tablic dwuwymiarowych: int matrix1[2][2]; int matrix2[2][2] = 1, 2, 3, 4 ; int matrix3[2][2] = 0; Czym jest nazwa tablicy - jaką przyjmuje wartość? Udowodnij swoją odpowiedź krótkim przykładem. 20. Tablice mogą być przekazywane do funkcji na dwa sposoby: poprzez referencję lub poprzez wskaźnik. Oznacza to, że przekazując tablicę nie jest tworzona jej kopia, a działania są wykonywane bezpośrednio na oryginalnej tablicy. Przekazywanie przez wartość jest niemożliwe. void myfun(int *tab) void myfun(int tab[]) 21. Tablica dwuwymiarowa to jednowymiarowa tablica wskaźników do jednowymiarowych tablic danego typu. char d[200][256]; rezerwuje miejsce w pamięci dla 200*256 zmiennych typu char; identyfikator d jest stałą o wartości równej adresowi elementu d[0][0]; wartość d[0] wskazuje na element d[0][0], wartość d[1] wskazuje na element d[1][0], itd.; wartości d, d[0], &d[0][0] są takie same. d, d[0], d[1], d[2], są stałymi nie wolno zmieniać ich wartości. Przykład: //Liczba słów w wielu liniach tekstu (1) - tablice o dwóch indeksach #pragma warning (disable: 4996) #include <string.h> #define MAX_LINES 200 FILE *fd = NULL; int ile_slow(char *); char d[max_lines][max_line]; int i, l; if (!(fd = fopen("dane.txt", "r"))) printf("blad otwarcia zbioru\n"); exit(2); Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 8

i = 0; l = 0; while (i < MAX_LINES && fgets(d[i], MAX_LINE, fd)!= (char*)null) l += ile_slow(d[i]); i++; fclose(fd); fd = NULL; /* TU funkcja ile_slow */ int ile_slow(char *te) char p, b = ' '; while (p = b, b = *te++) if (b!= ' ' && p == ' ') l++; return(l); 22. Funkcja fgets() czyta kolejne znaki ze strumienia stream i umieszcza je w tablicy znakowej wskazywanej przez str. Czytanie przerywa, gdy przeczyta size - 1 znaków, natrafi na koniec pliku lub znak końca linii (znak ten jest zapisywany do str). Na końcu fgets() dopisuje znak '\0'. W przypadku błędu lub natrafienia na koniec pliku wartością funkcji jest NULL. Deklaracja: char *fgets(char *str, int size, FILE *stream); 23. Dynamiczna alokacja pamięci - tworząc aplikacje zazwyczaj nie znamy z góry rozmiarów tablic jakie będą nam potrzebne. Często pamięć zarezerwowana przez stos jest niewystarczająca. Możemy wtedy skorzystać z dynamicznej alokacji pamięci. Język C dostarcza w tym celu funkcję malloc, która jako argument przyjmuje rozmiar bloku pamięci, który ma zaalokować, natomiast zwraca wskaźnik do zaalokowanej pamięci lub NULL w przypadku błędu. Przykładowo alokację 10 elementowej tablicy typu double możemy zapisać następująco: double *tab; tab = (double *)malloc(sizeof(double) * 10); if (!tab) //błąd alokacji Język C nie posiada mechanizmów automatycznego "odśmiecania pamięci" (tzw. garbage collecting). Procedura zarówno alokacji jak i dealokacji spoczywa na programiście. W celu zwolnienia pamięci korzystamy w funkcji free. Zwolnienie może być wykonane tylko raz. Pamiętajmy, aby po każdym użyciu funkcji free "zniszczyć" wskaźnik poprzez przypisanie wartości NULL. if (tab) free(tab); tab = NULL; Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 9

24. W przypadku tablic wielowymiarowych ich przekazywanie do funkcji znacznie się komplikuje. Aby przekazać tablicę wielowymiarową w sposób podobny do tablic jednowymiarowych musimy z góry znać stały rozmiar tablicy: void myfun(int tab[2][2]) void myfun(int (*tab)[2]) Rozwiązaniem powyższego problemu może być zapis tablicy dwuwymiarowej w jednym wymiarze - jednak nie zawsze jest to pożądane rozwiązanie. 25. Dynamiczna alokacja pamięci dla tablic wielowymiarowych - cały proces wygląda analogicznie do alokacji tablic jednowymiarowych - należy jedynie pamiętać, że musimy zaalokować każdy wiersz z osobna (podobnie w przypadku zwalniania pamięci). Przykładowa tablica 10x5 o elementach typu double: double **tab; tab = (double **)malloc(sizeof(double) * 10); if (!tab) //błąd alokacji for (int i = 0; i < 10; i++) tab[i] = (double *)malloc(sizeof(double) * 5); if (!tab[i]) //błąd alokacji if (tab) for (int i = 0; i < 10; i++) if (tab[i]) free(tab[i]); free(tab); tab = NULL; 26. Przykład dla tablic tekstowych: //Liczba słów w wielu liniach tekstu (2) - alokacja pamięci #pragma warning (disable: 4996) #include <string.h> #define MAX_LINES 200 FILE *fd = NULL; int ile_slow(char *); /* Ile slow w wielu liniach tekstu, alokacja pamieci */ char *d[max_lines], bufor[max_line]; int len, i, l; if (!(fd = fopen("dane.txt", "r"))) Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 10

printf("blad otwarcia zbioru\n"); exit(2); i = 0; l = 0; while (i < MAX_LINES && fgets(bufor, MAX_LINE, fd)) len = strlen(bufor); bufor[len - 1] = '\0'; if ((d[i] = (char *)malloc((unsigned)len)) == (char*)null) printf("brak pamieci\n"); exit(3); strcpy(d[i], bufor); l += ile_slow(d[i]); i++; fclose(fd); fd = NULL; /* Tekst w pamięci, tablica d przechowuje wskaźniki do linii tekstu */ int ile_slow(char *te) char p, b = ' '; while (p = b, b = *te++) if (b!= ' ' && p == ' ') l++; return(l); 27. Czym różnią się funkcje: malloc, calloc, realloc? 28. Korzystając z funkcji fgets napisz program, który będzie zaczytywał linia po linii tekst zapisany w pliku tekstowym, a następnie wyświetlał numer linii, liczbę dużych liter, liczbę małych liter i liczbę pozostałych znaków. Dla uproszczenia załóżmy, że tekst nie zawiera polskich znaków oraz maksymalna liczba znaków w pojedynczej linii wynosi 256. 29. Biblioteka stdlib.h dostarcza funkcji konwertujących ciąg znaków na liczbę (atoi, atof, atol, atoll) oraz liczby na ciąg znaków (itoa, _ecvt, _fcvt) - więcej informacji w dokumentacji MSDN oraz na wykładzie. 30. Tablice dwuwymiarowe w argumentach funkcji. Zmodyfikuj program z przykładu nr 26 tak, by algorytm liczenia liczby słów nie był zapisany w funkcji main() ale w funkcji o nazwie licz_slowa_1. W której zostanie wykorzystana funkcja ile_slow. Do funkcji licz_slowa_1 winien być przekazany cały przeczytany tekst przekażemy jedynie tablice wskaźników do poszczególnych linii tekstu. //Liczba słów w wielu liniach tekstu (3) - tablice 2-indeksowe w argumentach - argumenty funkcji main() #pragma warning (disable: 4996) #include <string.h> #define MAX_LINES 200 FILE *fd; Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 11

int ile_slow(char *), licz_slowa(char **), licz_slowa_1(char **); int main(int argc, char **argv) /* Ile slow w ielu liniach tekstu */ char *d[max_lines], bufor[max_line]; int len, i, l; if (argc!= 2) printf("zła liczba argumentów\n"); exit(1); if (!(fd = fopen(argv[1], "r"))) printf("blad otwarcia zbioru\n"); exit(2); i = 0; l = 0; while (i < MAX_LINES && fgets(bufor, MAX_LINE, fd)) len = strlen(bufor); bufor[len - 1] = '\0'; if (!(d[i] = (char*)malloc((unsigned)len))) printf("brak pamieci\n"); exit(3); strcpy(d[i], bufor); i++; d[i] = (char *)0; //znacznik końca tablicy wskaźników l = licz_slowa_1(d); /* Tekst w pamieci, tablica d - wskazniki do linii tekstu */ /* Tu funkcja ile_slow */ int ile_slow(char *te) char p, b = ' '; while (p = b, b = *te++) if (b!= ' ' && p == ' ') l++; return(l); int licz_slowa_1(char *te[]) int i, l = 0; i = 0; while (te[i]!= (char *)0) l += ile_slow(te[i]); i++; return l; Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 12

31. Przekazywanie tablic dwuindeksowych sprowadza się do przekazywania jednoindeksowej tablicy wskaźników do jej wierszy, czyli adresu początkowego elementu tablicy wskaźników. Poniższa funkcja licz_slowa jest modyfikacją funkcji licz_slowa_1. Deklaracje identyfikatora te w obu wersjach funkcji są w pełni równoważne. Bez względu na sposób deklarowania można odwoływać się do tekstów przez elementy tablic lub przez wskazanie pośrednie. int licz_slowa(char **te) while (*te) l += ile_slow(*te++); return l; 32. Zamień miejscami tekst z dwóch wybranych linii. 33. Wybierz z tekstu składającego się z wielu linii te linie, w których na początku znajduje się wybrany tekst. 34. Wstaw jedną linię teksu po linii o numerze n. 35. Wybierz z teksu słowo o podanej pozycji. Załóż, że ogranicznikiem słowa jest dwukropek. 36. Napisz program kodujący i dekodujący dowolne teksty posługując się alfabetem Morse a. W rozwiązaniu możesz wykorzystać poniższe tablice. char litery[] = 'a',165,'b','c',134,'d','e',169,'f','g','h','i','j','k','l',136, 'm','n',228,'o',162,'p','q','r','s',152,'t','u','v','w','x','y','z',190,1 71,'A',164,'B','C',143,'D','E',168,'F','G','H','I','J','K','L',157,'M','N ',227,'O',224,'P','Q','R','S',151,'T','U','V','W','X','Y','Z',189,141,' ','.',',','?',':','-','0','1','2','3','4','5','6','7','8','9','!','\0' ; char *mors[] = ".-",".-.-","-...","-.-.","-.-..","-..",".","..-..","..-.","--.","...","..",".---","-.-",".-..",".-..-","--","-.","--.--","---","---.",".--.","--.-",".-.","...","...-...","-","..-","...-",".--","-..-","-.- -","--..","--..-","--",".-",".-.-","-...","-.-.","-.-..","-..",".","..-..","..-.","--.","...","..",".---","-.-",".-..",".-..-","--","-.","--.-- ","---","---.",".--.","--.-",".-.", "...","...-...","-","..-","...-",".-- ","-..-","-.--","--..","--..-","--"," ",".-.-.-","--..--","..--..","---...","-...-","-----",".----","..---","...--","...-","...","-...","--...","---..","----.","!",0 ; 37. Przeanalizuj w trybie pracy krokowej następujące przykłady do wykładu 3: Wszystkie przykłady dostępne pod adresem: http://torus.uck.pk.edu.pl/~fialko/text/cc/przykl/ *Treści oznaczone kursywą pochodzą z różnych źródeł internetowych. Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 13