Politechnika Białostocka Wydział Elektryczny Katedra Elektrotechniki Teoretycznej i Metrologii Instrukcja do pracowni specjalistycznej z przedmiotu Informatyka 1 Kod przedmiotu: EZ1C200 010 (studia niestacjonarne) JĘZYK C - TABLICE DWUWYMIAROWE, OPERACJE NA TABLICACH, ŁAŃCUCHY ZNAKÓW Spis treści 1. Opis stanowiska... 3 1.1. Stosowana aparatura... 3 1.2. Oprogramowanie... 3 2. Wiadomości teoretyczne... 3 2.1. Deklaracja tablicy dwuwymiarowej... 3 2.2. Inicjalizacja elementów tablicy... 4 2.3. Podstawowe operacje na macierzach... 5 2.4. Łańcuchy znaków... 7 2.5. Inicjalizacja łańcucha znaków... 8 2.6. Stała znakowa... 10 2.7. Funkcje do wprowadzania i wyprowadzania znaków... 10 2.8. Funkcje z pliku nagłówkowego string.h... 11 3. Przebieg ćwiczenia... 14 4. Literatura... 17 Numer ćwiczenia INF06Z 5. Zagadnienia na zaliczenie... 17 6. Wymagania BHP... 18 Materiały dydaktyczne przeznaczone dla studentów Wydziału Elektrycznego PB. Autor: dr inż. Jarosław Forenc Białystok 2013 Wydział Elektryczny, Politechnika Białostocka, 2013 Wszelkie prawa zastrzeżone. Żadna część tej publikacji nie może być kopiowana i odtwarzana w jakiejkolwiek formie i przy użyciu jakichkolwiek środków bez zgody posiadacza praw autorskich. Informatyka 1 2 z 19 Instrukcja INF06Z
1. Opis stanowiska Odczytanie wartości z tablicy: x = tab[1][2]; 1.1. Stosowana aparatura Podczas zajęć wykorzystywany jest komputer klasy PC z systemem operacyjnym Microsoft Windows (XP/Vista/7). 1.2. Oprogramowanie Na komputerach zainstalowane jest środowisko programistyczne Microsoft Visual Studio 2008 Standard Edition lub Microsoft Visual Studio 2008 Express Edition zawierające kompilator Microsoft Visual C++ 2008. 2. Wiadomości teoretyczne 2.1. Deklaracja tablicy dwuwymiarowej Deklaracja tablicy dwuwymiarowej (macierzy) wymaga podania liczby wierszy i liczby kolumn, z których będzie składała się tablica. float tab[3][4]; średnik liczba kolumn tablicy liczba wierszy tablicy nazwa tablicy typ elementów tablicy Powyższa deklaracja definiuje tablicę dwunastu elementów typu float, składającą się z trzech wierszy i czterech kolumn (Rys. 1). Odwołując się do elementów tablicy dwuwymiarowej musimy podać dwa indeksy: numer wiersza i numer kolumny, na przecięciu których znajduje się dany element. Zapisanie wartości do tablicy: tab[1][2] = 10; 2.2. Inicjalizacja elementów tablicy Rys. 1. Tablica o rozmiarze 3 4. Po zadeklarowaniu tablicy, wartość jej elementów jest nieokreślona. Inicjalizacja polega na umieszczeniu w deklaracji po znaku równości, ujętej w nawiasy klamrowe, listy wartości kolejnych jej elementów. Poszczególne elementy tablicy umieszczone są w nawiasach klamrowych i oddzielone od siebie przecinkami. Deklaracja: int b[2][3] = 3,6,2},4,1,0}}; powoduje wypełnienie tablicy w następujący sposób: 0 1 0 3 1 2 6 2 4 1 0 Poszczególne wiersze tablicy wyróżnione są nawiasami klamrowymi. Nawiasy te można pominąć. int b[2][3] = 3,6,2,4,1,0}; Informatyka 1 3 z 19 Instrukcja INF06Z Informatyka 1 4 z 19 Instrukcja INF06Z
Druga postać inicjalizacji pokazuje w jaki sposób są przechowywane tablice w pamięci komputera. Jeśli wartości podanych w trakcie inicjalizacji jest mniej niż wynosi rozmiar tablicy, to pozostałe elementy tablicy wypełniane są zerami, np. int b[2][3] = 3,6,2,4}; #define N 3 /* liczba wierszy */ #define M 3 /* liczba kolumn */ int main() int tab[n][m]; int i, j, max, suma, suma1, suma2; float srednia; /* generowanie pseudolosowe elementow macierzy */ srand(time(null)); tab[i][j] = rand() % 10; /* wyswietlenie elementow macierzy */ Inicjalizacja tablicy, w powiązaniu z wypełnianiem pominiętych elementów tablicy zerami, pozwala zapisać w bardzo prosty sposób wypełnienie całej tablicy wartością zero. int b[2][3] = 0}; Podajemy wartość tylko pierwszego elementu tablicy (zero), zaś pozostałym elementom automatycznie zostanie także przypisana taka sama wartość. 2.3. Podstawowe operacje na macierzach W poniższym programie przedstawiono często wykonywane operacje na macierzach. Program wykonujący wybrane operacje na macierzy liczb całkowitych. #include <stdio.h> #include <stdlib.h> #include <time.h> printf("%3d",tab[i][j]); printf("\n"); } printf("\n"); /* poszukiwanie elementu o wartosci maksymalnej */ max = tab[0][0]; if (tab[i][j] > max) max = tab[i][j]; printf("wartosc max: %d\n\n",max); /* suma i srednia arytmetyczna elementow */ suma = 0; suma = suma + tab[i][j]; srednia = (float) suma/(n*m); printf("suma elementow: %d\n",suma); printf("srednia arytmetyczna: %f\n\n",srednia); Informatyka 1 5 z 19 Instrukcja INF06Z Informatyka 1 6 z 19 Instrukcja INF06Z
} /* sumy elementow w poszczegolnych wierszach */ suma = 0; suma = suma + tab[i][j]; printf("suma wiersza %d = %d\n",i,suma); } printf("\n"); /* sumy elementow w poszczegolnych kolumnach */ suma = 0; suma = suma + tab[i][j]; printf("suma kolumny %d = %d\n",j,suma); } printf("\n"); /* sumy elementow nad, na i ponizej przekatnej */ suma = suma1 = suma2 = 0; if (i < j) suma1+=tab[i][j]; /* nad */ if (i > j) suma2+=tab[i][j]; /* pod */ if (i == j) suma+=tab[i][j]; /* na */ } printf("suma nad przekatna: %d\n",suma1); printf("suma na przekatnej: %d\n",suma); printf("suma pod przekatna: %d\n",suma2); return 0; "napis" Znaki cudzysłowu nie są częścią napisu, służą jedynie do określenia jego granic. W rzeczywistości łańcuch znaków jest tablicą, której elementami są pojedyncze znaki (tablica elementów typu char). Ostatnim elementem tablicy jest znak o kodzie 0 (stała liczbowa 0 lub stała znakowa \0 ), oznaczający koniec napisu (Rys. 2). Większość funkcji standardowych języka C dodaje automatycznie na końcu ten znak. "Pies" P i e s \0 Rys. 2. Tablica znaków. Rozmiar fizycznej pamięci przeznaczonej na napis musi być o jeden większy niż liczba znaków zawartych między znakami cudzysłowu. Deklaracja zmiennej mogącej przechowywać napis jest podobna do deklaracji zwykłej tablicy: typ zmienna[rozmiar]; Deklaracja tablicy, w której można przechowywać napisy o maksymalnej długości do 19 znaków: char txt[20]; 2.5. Inicjalizacja łańcucha znaków Deklarując łańcuch znaków możemy nadać mu wartość początkową, np. 2.4. Łańcuchy znaków char txt[10] = "pies"; Łańcuch znaków (napis, stała napisowa) jest to ciąg złożony z zera lub większej liczby znaków zawartych między znakami cudzysłowu, np. Informatyka 1 7 z 19 Instrukcja INF06Z Informatyka 1 8 z 19 Instrukcja INF06Z
2.6. Stała znakowa Stała znakowa jest to liczba całkowita. Taką stałą tworzy jeden znak ujęty w apostrofy, np. x. Wartością stałej znakowej jest wartość kodu ASCII (Tabela 1). Rys. 3. Deklaracja i inicjalizacja tablicy znaków. To samo można uzyskać podając pojedyncze litery umieszczone w apostrofach, np. char txt[10] = 'P','i','e','s'}; Deklarując napis można nie określać jego długości, kompilator przydzieli wtedy automatycznie odpowiedni rozmiar pamięci (uwzględniając ostatni znak \0 ): lub char *txt = "To jest napis"; char txt[] = "To jest napis"; W powyższy sposób można nadawać wartość łańcuchowi znaków tylko przy jego deklaracji. Zatem błędnym jest poniższy zapis: char txt[10]; txt = "Pies"; Prawidłowy zapis wymaga wykorzystania funkcji strcpy() z pliku nagłówkowego string.h: char txt[10]; strcpy(txt,"pies"); Tabela 1. Wybrane kody ASCII. kod ASCII znak kod ASCII znak kod ASCII znak 48 0 65 A 97 a 49 1 66 B 98 b 50 2 67 C 99 c.................. 57 9 90 Z 122 z Pewne znaki niegraficzne mogą być reprezentowane w stałych znakowych przez sekwencje specjalne, które wyglądają jak dwa znaki, ale reprezentują tylko jeden znak: '\n' nowy wiersz '\t' tabulator poziomy '\v' tabulator pionowy '\a' alarm '\\' \ (ang. backslash) '\'' apostrof '\"' cudzysłów '\?' znak zapytania Zapis A oznacza jeden znak, natomiast zapis A - dwa znaki, gdyż jest to napis kończący się znakiem \0. 2.7. Funkcje do wprowadzania i wyprowadzania znaków printf() Nagłówek: int printf(const char *format,...); - w funkcji printf() do wyświetlenia łańcucha znaków używamy: %s, zaś pojedynczego znaku - %c; scanf() Nagłówek: int scanf(const char *format,...); Informatyka 1 9 z 19 Instrukcja INF06Z Informatyka 1 10 z 19 Instrukcja INF06Z
- w funkcji scanf() do wczytania łańcucha znaków używamy: %s, zaś pojedynczego znaku - %c; strcat() Nagłówek: char *strcat(char *s1, const char *s2); - funkcja strcat() dołącza do łańcucha s1 łańcuch s2; gets() Nagłówek: char *gets(char *s); strchr() Nagłówek: char *strchr(const char *s, int c); - funkcja gets() wprowadza wiersz (ciąg znaków zakończony \n ) ze strumienia stdin (klawiatura) i umieszcza w obszarze pamięci wskazywanym przez wskaźnik s zastępując \n znakiem \0 ; - zwraca wskaźnik do początku wypełnianego obszaru, np. - funkcja strchr() przeszukuje łańcuch s w celu znalezienia pierwszego wystąpienia znaku c; - zwraca wskaźnik do znalezionego znaku lub NULL, jeśli znak nie został znaleziony; char bufor[80]; gets(bufor); strcmp() Nagłówek: int strcmp(const char *s1, const char *s2); puts() Nagłówek: int puts(const char *s); - funkcja puts() wypisuje na stdout (ekran) zawartość łańcucha znakowego (ciąg znaków zakończony znakiem \0 ), zastępując znak \0 znakiem \n, np. char bufor[80] = "to jest tekst"; puts(bufor); 2.8. Funkcje z pliku nagłówkowego string.h - funkcja strcmp() porównuje łańcuchy s1 i s2 z rozróżnianiem wielkości liter, - zwraca 0, gdy s1=s2, wartość mniejszą od zera, gdy s1<s2 i wartość większą od zera, gdy s1>s2; strcmpi() Nagłówek: int strcmpi(const char *s1, const char *s2); - funkcja strcmpi() działa jak strcmp(), ale bez rozróżniania wielkości liter; strlwr() Nagłówek: char *strlwr(char *s); - funkcja strlwr() zamienia w łańcuchu s duże litery na małe; strlen() Nagłówek: size_t strlen(const char *s); strrev() Nagłówek: char *strrev(char *s); - funkcja strlen() zwraca długość łańcucha znaków; - nie bierze pod uwagę znaku \0 ; strcpy() Nagłówek: char *strcpy(char *s1, const char *s2); - funkcja strcpy() kopiuje łańcuch s2 do łańcucha s1; - funkcja strrev() odwraca kolejność znaków w łańcuchu s; strset() Nagłówek: char *strset(char *s, int c); - funkcja strset() wypełnia łańcuch s znakiem c; Informatyka 1 11 z 19 Instrukcja INF06Z Informatyka 1 12 z 19 Instrukcja INF06Z
strstr() Nagłówek: char *strstr(const char *s1, const char *s2); - funkcja strstr() przeszukuje łańcuch s1 w celu odnalezienia podłańcucha s2 zwracając wskazanie do elementu łańcucha s1, od którego zaczynają się znaki takie same jak w łańcuchu s2, lub NULL, gdy s2 nie występuje w s1; strupr() Nagłówek: char *strupr(char *s); - funkcja strupr() zamienia w łańcuchu s litery małe na duże. Poniższy program pokazuje przykładowe wykorzystanie funkcji z pliku nagłówkowego string.h. Przykładowe operacje na łańcuchu znaków. #include <stdio.h> #include <string.h> int main() char napis1[] = "tekst w buforze"; char napis2[20]; int dlugosc; } printf("napis1: %s \n",napis1); dlugosc = strlen(napis1); printf("liczba znakow w napis1: %d \n",dlugosc); strupr(napis1); printf("napis1 (duze litery): %s \n",napis1); strlwr(napis1); printf("napis1 (male litery): %s \n",napis1); strcpy(napis2,napis1); printf("napis2: %s \n",napis2); strrev(napis2); printf("napis2 (odwrocony): %s \n",napis2); return 0; W wyniku uruchomienia powyższego programu na ekranie pojawi się: napis1: tekst w buforze liczba znakow w napis1: 15 napis1 (duze litery): TEKST W BUFORZE napis1 (male litery): tekst w buforze napis2: tekst w buforze napis2 (odwrocony): ezrofub w tsket 3. Przebieg ćwiczenia Na pracowni specjalistycznej należy wykonać wybrane zadania wskazane przez prowadzącego zajęcia. W różnych grupach mogą być wykonywane różne zadania. 1. Tablica P przechowuje wyniki 100 pomiarów wartości chwilowych napięcia (pierwszy wiersz tablicy) i prądu (drugi wiersz tablicy) na pewnym dwójniku RLC. Napisz program, który: - zapisze do trzeciego wiersza tablicy wartości chwilowe mocy (p = u i), - wypisze wartości średnie napięcia, prądu i mocy, - wypisze numer pomiaru, dla którego wartość napięcia była największa oraz numer pomiaru, w którym wartość prądu była największa, - wypisze liczbę pomiarów, dla których moc chwilowa była dodatnia i liczbę pomiarów, dla których moc chwilowa była ujemna. Wartości napięcia: Wartości prądu: 10.0*sin((i+10.0)/15.0) i = 0..99 (1) 5.0*sin(i/15.0) i = 0..99 (2) 2. Tablica REK przechowuje informacje dotyczące rekrutacji na studia wyższe. W tablicy znajduje się N wierszy i 4 kolumny. Każdy wiersz zawiera informacje o jednym kandydacie. W pierwszych trzech kolumnach umieszczone są oceny kandydatów. Na studia przyjmowane są osoby, których średnia arytmetyczna Informatyka 1 13 z 19 Instrukcja INF06Z Informatyka 1 14 z 19 Instrukcja INF06Z
trzech ocen jest większa lub równa średniej arytmetycznej wszystkich ocen wszystkich kandydatów. Napisz program który: - zapisze do tablicy wygenerowane losowo oceny wszystkich kandydatów (dopuszczalne oceny to: 2, 3, 4, 5, 6), - umieści w czwartej kolumnie średnie arytmetyczne ocen poszczególnych kandydatów, - obliczy średnią arytmetyczną wszystkich ocen kandydatów, - wyświetli numery kandydatów przyjętych na studia (numer kandydata jest jednocześnie numerem wiersza w tablicy REK) oraz średnie arytmetyczne ich ocen. 3. Napisz program realizujący mnożenie macierzy N M - elementowej przez macierz M K - elementową. Elementy macierzy wygeneruj pseudolosowo. 4. Napisz program, który dla N M - elementowej tablicy liczb całkowitych wygeneruje losowo liczby z zakresu 0, 10, a następnie odnajdzie taki element tablicy, którego suma sąsiadów jest największa. Jako sąsiadów należy rozumieć elementy znajdujące się po lewej stronie, po prawej stronie, powyżej i poniżej danego elementu. Wyświetl zawartość tablicy i indeksy odnalezionego elementu. 5. Napisz program, który dla N N - elementowej tablicy liczb całkowitych wygeneruje pseudolosowo elementy tablicy z zakresu 0, 10, a następnie obliczy sumę elementów znajdujących się na brzegach tablicy i na jej głównych przekątnych (elementy zaznaczone na szaro na poniższym rysunku). 6. Napisz program, który dla N M - elementowej tablicy liczb całkowitych wygeneruje pseudolosowo elementy tablicy z zakresu 0, 10. Następnie wyświetli zawartość tablicy z podziałem na wiersze i kolumny oraz obliczy ile razy każda liczba występuje w tablicy, wyświetlając tylko te liczby, których ilość jest różna od zera. 7. Napisz program wyświetlający tablicę kodów ASCII (od 30 do 254). W jednym wierszu umieść 9 kodów ASCII. Na ekranie ma być wyświetlona informacja w postaci: kod znak, np. 97 - a. 8. Napisz program zamieniający liczbę dwójkową na liczbę dziesiętną. Liczbę dwójkową wczytaj z klawiatury jako napis. 9. Napisz program, który podaną przez użytkownika dodatnią liczbę całkowitą wyświetli w postaci liczby dwójkowej. 10. Napisz program wyświetlający dla zadanego x (całkowitego, dodatniego) wszystkie liczby od 0 do x w kodzie dwójkowym w postaci: 0 --> 0 1 --> 1 2 --> 10 3 --> 11 4 --> 100... 11. Napisz program, który wczytuje do łańcucha znaków tekst z klawiatury (jeden wiersz), a następnie usuwa wszystkie znaki spacji znajdujące się na początku tekstu i na jego końcu, np. " Ala ma kota " "Ala ma kota " 12. Napisz program wczytujący z klawiatury do 10 linii tekstu. Wczytywanie zostaje zakończone po wczytaniu 10 linii lub po wprowadzeniu pustego łańcucha (naciśnięcie klawisza ENTER). Wyświetl wczytane linie w kolejności od ostatniej do pierwszej. Informatyka 1 15 z 19 Instrukcja INF06Z Informatyka 1 16 z 19 Instrukcja INF06Z
13. Napisz program, który będzie wczytywał, wyświetlał i zliczał znaki dopóki nie zostanie wczytany znak @. Wyświetl na koniec liczbę wczytanych znaków. 14. Napisz program, który będzie wczytywał ciąg znaków składający się z zer i jedynek. Następnie program powinien wyznaczyć liczbę serii w ciągu. Seria w ciągu, to podciąg złożony z takich samych znaków. Przykład wywołania programu: Podaj ciag: 0011101010011 Liczba serii: 8 4. Literatura [1] Kernighan B.W., Ritchie D.M.: Język ANSI C. Programowanie. Wydanie II. Helion, Gliwice, 2010. [2] Prata S.: Język C. Szkoła programowania. Wydanie V. Helion, Gliwice, 2006. [3] King K.N.: Język C. Nowoczesne programowanie. Wydanie II. Helion, Gliwice, 2011. [4] Summit S.: Programowanie w języku C. FAQ. Helion, Gliwice, 2003. [5] Wileczek R.: Microsoft Visual C++ 2008. Tworzenie aplikacji dla Windows. Helion, Gliwice, 2009. 5. Zagadnienia na zaliczenie 1. Omów sposób deklaracji tablic dwuwymiarowych (macierzy) w języku C oraz odwoływania się do elementów tych tablic. 2. Opisz inicjalizację elementów tablicy dwuwymiarowej. 3. Opisz sposób przechowywania napisów (tekstów) w języku C. 4. Przedstaw sposoby inicjalizacji tablicy znaków. 5. Scharakteryzuj funkcje znajdujące się w pliku nagłówkowym string.h. 6. Wymagania BHP Warunkiem przystąpienia do praktycznej realizacji ćwiczenia jest zapoznanie się z instrukcją BHP i instrukcją przeciw pożarową oraz przestrzeganie zasad w nich zawartych. W trakcie zajęć laboratoryjnych należy przestrzegać następujących zasad. - Sprawdzić, czy urządzenia dostępne na stanowisku laboratoryjnym są w stanie kompletnym, nie wskazującym na fizyczne uszkodzenie. - Jeżeli istnieje taka możliwość, należy dostosować warunki stanowiska do własnych potrzeb, ze względu na ergonomię. Monitor komputera ustawić w sposób zapewniający stałą i wygodną obserwację dla wszystkich członków zespołu. - Sprawdzić prawidłowość połączeń urządzeń. - Załączenie komputera może nastąpić po wyrażeniu zgody przez prowadzącego. - W trakcie pracy z komputerem zabronione jest spożywanie posiłków i picie napojów. - W przypadku zakończenia pracy należy zakończyć sesję przez wydanie polecenia wylogowania. Zamknięcie systemu operacyjnego może się odbywać tylko na wyraźne polecenie prowadzącego. - Zabronione jest dokonywanie jakichkolwiek przełączeń oraz wymiana elementów składowych stanowiska. - Zabroniona jest zmiana konfiguracji komputera, w tym systemu operacyjnego i programów użytkowych, która nie wynika z programu zajęć i nie jest wykonywana w porozumieniu z prowadzącym zajęcia. - W przypadku zaniku napięcia zasilającego należy niezwłocznie wyłączyć wszystkie urządzenia. - Stwierdzone wszelkie braki w wyposażeniu stanowiska oraz nieprawidłowości w funkcjonowaniu sprzętu należy przekazywać prowadzącemu zajęcia. Informatyka 1 17 z 19 Instrukcja INF06Z Informatyka 1 18 z 19 Instrukcja INF06Z
- Zabrania się samodzielnego włączania, manipulowania i korzystania z urządzeń nie należących do danego ćwiczenia. - W przypadku wystąpienia porażenia prądem elektrycznym należy niezwłocznie wyłączyć zasilanie stanowiska. Przed odłączeniem napięcia nie dotykać porażonego. Informatyka 1 19 z 19 Instrukcja INF06Z