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

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

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

Struktura programu. Projekty złożone składają się zwykłe z różnych plików. Zawartość każdego pliku programista wyznacza zgodnie z jego przeznaczeniem.

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

Lab 9 Podstawy Programowania

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

Część 4 życie programu

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

Tablice, funkcje - wprowadzenie

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

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

Wskaźniki. Informatyka

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

Zmienne, stałe i operatory

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

1 Podstawy c++ w pigułce.

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

Argumenty wywołania programu, operacje na plikach

Język C, tablice i funkcje (laboratorium)

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

Uzupełnienie dot. przekazywania argumentów

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

main( ) main( void ) main( int argc, char argv[ ] ) int MAX ( int liczba_1, liczba_2, liczba_3 ) źle!

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

iii. b. Deklaracja zmiennej znakowej poprzez podanie znaku

> C++ dynamiczna alokacja/rezerwacja/przydział pamięci. Dane: Iwona Polak. Uniwersytet Śląski Instytut Informatyki

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

Podział programu na moduły

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

typ y y p y z łoż o on o e n - tab a lice c e w iel e owym m ar a o r we, e stru r kt k ury

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

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

Język C++ zajęcia nr 2

TABLICE W JĘZYKU C/C++ typ_elementu nazwa_tablicy [wymiar_1][wymiar_2]... [wymiar_n] ;

1 Podstawy c++ w pigułce.

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

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

Stałe, tablice dynamiczne i wielowymiarowe

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

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

typ_zwracanej_wartości nazwa_funkcji(lista deklaracji argumentów) { ciało(treść) funkcji return Val; //zwracana wartość }

Język C zajęcia nr 11. Funkcje

// Potrzebne do memset oraz memcpy, czyli kopiowania bloków

Materiał. Typy zmiennych Instrukcje warunkowe Pętle Tablice statyczne Funkcje Wskaźniki Referencje Tablice dynamiczne Typ string Przeładowania funkcji

Wymiar musi być wyrażeniem stałym typu całkowitego, tzn. takim, które może obliczyć kompilator. Przykłady:

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

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

1 Wskaźniki i zmienne dynamiczne, instrukcja przed zajęciami

typ_zwracanej_wartości nazwa_funkcji(lista deklaracji argumentów) { ciało(treść) funkcji return Val; //zwracana wartość }

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

Języki i metodyka programowania. Wprowadzenie do języka C

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

Wstęp do Programowania, laboratorium 02

Programowanie obiektowe W3

iii. b. Deklaracja zmiennej znakowej poprzez podanie znaku

Zmienne i struktury dynamiczne

Globalne / Lokalne. Wykład 15. Podstawy programowania (język C) Zmienne globalne / lokalne (1) Zmienne globalne / lokalne (2)

Wstęp do programowania

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

Podstawy informatyki. Informatyka stosowana - studia niestacjonarne. Grzegorz Smyk

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

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

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

2 Przygotował: mgr inż. Maciej Lasota

Podstawy Programowania C++

Język ludzki kod maszynowy

Podstawy programowania komputerów

DYNAMICZNE PRZYDZIELANIE PAMIECI

ZASADY PROGRAMOWANIA KOMPUTERÓW

Informacje wstępne #include <nazwa> - derektywa procesora umożliwiająca włączenie do programu pliku o podanej nazwie. Typy danych: char, signed char

Programowanie Proceduralne

IX. Wskaźniki.(3 godz.)

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

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

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

int f(); //f - funkcja zwracająca wartość typu int int (*f)(); //f - wskaźnik do funkcji zwracającej wartość typu int

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

Co nie powinno być umieszczane w plikach nagłówkowych:

Tablice i struktury. czyli złożone typy danych. Programowanie Proceduralne 1

Struktury. Przykład W8_1

Wskaźniki. Programowanie Proceduralne 1

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

wykład III uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C - zarządzanie pamięcią, struktury,

tablica: dane_liczbowe

Język C, tablice i funkcje (laboratorium, EE1-DI)

I - Microsoft Visual Studio C++

Wstęp do programowania 1

Tablicę 2-wymiarową można przedstawić jako pewien zestaw tablic 1-wymiarowych np.:

Podstawy programowania w języku C++

Podstawy programowania. Wykład: 5. Instrukcje sterujące c.d. Stałe, Typy zmiennych c.d. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

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

Zajęcia nr 2 Programowanie strukturalne. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

Tablice mgr Tomasz Xięski, Instytut Informatyki, Uniwersytet Śląski Katowice, 2011

2. Tablice. Tablice jednowymiarowe - wektory. Algorytmy i Struktury Danych

Języki programowania C i C++ Wykład: Typy zmiennych c.d. Operatory Funkcje. dr Artur Bartoszewski - Języki C i C++, sem.

Wstęp do programowania

Wskaźniki w C. Anna Gogolińska

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

LABORATORIUM 3 ALGORYTMY OBLICZENIOWE W ELEKTRONICE I TELEKOMUNIKACJI. Wprowadzenie do środowiska Matlab

Podstawy algorytmiki i programowania - wykład 2 Tablice dwuwymiarowe cd Funkcje rekurencyjne

Transkrypt:

Języki i paradygmaty programowania 1 studia niestacjonarne 2018/19 Lab 4. Program zapisany w kilku plikach. Pliki nagłówkowe (*h.). Słowa kluczowe static, const. Klasy pamięci (auto), static, extern. Tablice liczbowe. Operacje macierzowo-wektorowe, memcpy, memmove, memset. Wyrażenie warunkowe. Operacje na tablicach o dwóch indeksach. Dynamiczna alokacja pamięci dla tablic wielowymiarowych. 1. Projekty składają się zazwyczaj z wielu, różnych plików. Zawartość każdego pliku programista wyznacza zgodnie z jego przeznaczeniem. Bezpośredni dostęp do danych jest możliwy wyłącznie z tego pliku, w którym dane te są zdefiniowane. Dostęp do danych z innych plików nie jest wspierany w języku C. Aby tworzone programy były bezpieczne należy: a. podstawowe dane w pliku definiować, jako zmienne globalne z modyfikatorem static, który nie pozwala na udostępnianie tych zmiennych w innych plikach; b. prototypy funkcji interfejsowych umieścić w odpowiednim headerze (bez modyfikatora static); c. prototypy funkcji wewnętrznych umieścić w pliku, jako obiekty globalne z modyfikatorem static; d. dane globalne, które mogą być widoczne w innych plikach: i. udostępniać poprzez funkcje ii. Definiować bez modyfikatora static iii. Samo udostępnienie w innym pliku wprowadzić przy pomocy specyfikatora extern iv. Nie poleca się umieszczania tych danych w pliku nagłówkowym header. e. Dane pomocnicze (indeksy tablic, zmienne tymczasowe itd.) używać jako dane lokalne (auto). 2. Headery, czyli pliki nagłówkowe, są używane do deklaracji typów danych (struktur, unii, typedef), makr, dyrektyw kompilatora (pragma), prototypów funkcji itd., które mają być widoczne w różnych plikach projektu. 3. Każdy header musi zawierać tak zwane straże, które w projektach złożonych chronią przed duplikacją definicji umieszczanych w headerze. 4. Klasy pamięci dzielą się na: a. auto wszystkie zmienne i tablice zdefiniowane są w dowolnym bloku. Rezerwacja miejsca w pamięci następuje w momencie wejścia do bloku programu. Pamięć ta zostaje zwolniona w chwili wyjścia z bloku, w którym dana zmienna została zdefiniowana następuje utrata danych. Widoczność (zasięg deklaracji) zmiennej w klasie auto to tzw. blok programu. Czas życia zmiennej od momentu definicji do momentu wyjścia z bloku. Zmienne domyślnie nie są inicjowane - jeśli użytkownik nie przypisze im wartości, zawierają przypadkowe śmieci. b. static (zmienne i tablice zdefiniowane lokalnie wewnątrz bloku programu). Rezerwacja pamięci następuje na początku działania programu. Obszar widoczności zmiennych klasy static od miejsca definicji w bloku, w którym zostały zdefiniowane, do końca bloku. Czas życia zmiennej czas trwania całego programu. Oznacza to, że wartości zmiennych tej klasy pozostają chronione nawet po wyjściu z bloku i są aktualne przy kolejnym wejściu w blok. Zmienne domyślnie inicjalizowane są wartością: zero. Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 1

void fun() int a = 0; a++; pierwsze wejście: a = 0 przed wyjściem: a = 1 drugie wejście: a = 0 przed wyjściem: a = 1 void fun() static int a; a++; pierwsze wejście: a = 0 wyjście: a = 1 drugie wejście: a = 1 wyjście: a = 2 c. static (definicja globalna w pliku poza blokami). Rezerwacja pamięci dokonywana jest na początku działania programu. Obszar widoczności zmiennych od miejsca definicji do końca pliku. Czas życia zmiennej czas trwania całego programu. Zmienne domyślnie inicjalizowane są wartością: zero. Są dostępne tylko w podanym pliku. d. Zmienne zewnętrzne (globalne) (bez specyfikatora static). Rezerwacja pamięci dokonywana jest na początku działania programu. Obszar widoczności zmiennych globalnych od miejsca definicji do końca pliku. Czas życia zmiennej czas trwania całego programu. Zmienne domyślnie inicjalizowane są wartością: zero. Mogą być udostępnianie w innych plikach, jeśli zostaną w nich zadeklarowane, tzn. deklaracja typu zostanie poprzedzona słowem kluczowym extern. e. Klasa pamięci register oznacza, że dane zostaną umieszczone w rejestrze procesora, kiedy będzie to możliwe. f. Specyfikator static używany przy deklaracji funkcji, ogranicza widoczność tej funkcji obszarem pliku. Nie wolno umieszczać deklaracji funkcji statycznych w plikach nagłówkowych. 5. Do czego służą słowa kluczowe static i const? Czym się różnią? 6. Utwórz nowy projekt składający się z dwóch poniższych plików: plik_1.cpp, plik_2.cpp. Na podstawie informacji zawartych w pkt. 4 określ typ, klasę pamięci, obszar działania każdego występującego w programie identyfikatora. Przeanalizuj odwołania do różnych funkcji i znajdź te fragmenty programu, które na takie odwołania pozwalają. Sprawdź jakie teksty pojawią się na monitorze podczas wykonania programu. //*************************PLIK_1***************************** #include <stdio.h> double fun1(); static int fun2(); extern int fun3(); static int c = 5; double a, b = 10; char *xx[] = "mama","tato","stryjek",(char *)0; double aa[] = 1,2,3,4,5,6 ; int main() double x, y = 5; int i, j, k; static double aa[] = 11,12,13,14,15,16 ; printf("%lf %lf \n", aa[0], aa[1]); j = fun2(); k = fun3(); printf("j=%d, k= %d\n", j, k); double fun1(int x, int y) Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 2

static char *xx[] = "pies","kot","mysz",(char *)0 ; int i = 0; i++; char *xxxx[] = "zima","wiosna","lato",(char *)0 ; static int fun2() static int k = 0; puts("ppp fun2"); k++; return(k); //*************************PLIK_2***************************** #include <stdio.h> extern double fun1(); static double fun2(); int fun3(); static char *c[] = "slon","lew","pantera",(char *)0 ; extern char *xx[]; static double fun2() static char *zz[] = "krzeslo","szafa","tapczan",(char *)0 ; puts("qqq fun2"); return ((double) 2.0); int fun3() double ff; puts("qqq fun3"); ff = fun2(); return (5); 7. Wybierz jeden spośród Twoich programów (np. projekt nr 1 lub nr2) i podziel go na kilka plików, w taki sposób aby nie dzielić funkcjonalności, które tego nie wymagają. 8. Wektory i macierze: a. Przykład 1. Przechowywanie macierzy (tablicy jednowymiarowej) wiersz po wierszu. i numer wiersza, j numer kolumny, kolejność indeksowania: for (j = 0; j < n; j++) b. Przykład 2. Przechowywanie macierzy (tablicy jednowymiarowej) kolumna po kolumnie. i numer wiersza, j numer kolumny, kolejność indeksowania: for (j = 0; j < n; j++) Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 3

c. Przykład 3. Mnożenie macierzy przez macierz c ij=σk a ik b kj metodą: i. klasyczną, czyli wiersz po wierszu : for (i = 0; i < M; i++) for (j = 0; j < N; j++) for (k = 0; k < K; k++) C ij = C ij + A ik * B kj ii. Element macierzy C w pętli wewnętrznej nie zależy od indeksu k. Pobieranie elementów macierzy A następuje ciągle, bez skoków, natomiast elementy macierzy B pobierane są ze skokami. W związku z tym metoda ta nie jest skuteczna. Przyśpieszoną: for (i = 0; i < M; i++) for (k = 0; k < K; k++) for (j = 0; j < N; j++) C ij = C ij + A ik * B kj Elementy macierzy A w pętli wewnętrznej nie zależą od indeksu j. Pobieranie elementów macierzy C następuje ciągle, bez skoków, natomiast elementy macierzy B pobierane są ze skokami. W związku z tym metoda ta jest lepsza od poprzedniej. 9. Funkcje memcpy, memmove, memset znajdują się w bibliotece #include <memory.h>. void *memcpy(void *dest, const void *src, size_t count); funkcja kopiuje count bajtów z src do dest. Jako wynik zwraca wskaźnik do dest. Jeśli obszar pamięci src i dest pokrywa się działanie funkcji jest nieprzewidywalne. void *memmove(void *dest, const void *src, size_t count); funkcja kopiuje count bajtów z src do dest. Jeśli jakiś obszar pamięci src i dest pokrywa się funkcji gwarantuje, że bajty źródłowe w pokrywającym się regionie zostaną skopiowane zanim zostaną przepisane. void *memset(void *dest, int c, size_t count); Przypisuje symbol c pierwszym count symbolom tablicy dest. Zwraca wskaźnik do dest. 10. Utwórz nowy projekt, a następnie skopiuj i przeanalizuj poniższe przykłady użycia funkcji memcpy, memmove, memset. a) Przykład 1. #include <memory.h> #include <string.h> #include <stdio.h> char str1[7] = "aabbcc"; int main(void) printf("the string: %s\n", str1); //Pokrywający się region! Kopiowanie może nie być poprawne memcpy(str1 + 2, str1, 4); printf("new string: %s\n", str1); strcpy_s(str1, sizeof(str1), "aabbcc"); // reset string Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 4

printf("the string: %s\n", str1); //Pokrywający się region! Kopiowanie poprawne memmove(str1 + 2, str1, 4); printf("new string: %s\n", str1); b) Przykład 2. #include <memory.h> #include <stdio.h> int main(void) char buffer[] = "This is a test of the memset function"; printf("before: %s\n", buffer); memset(buffer, '*', 4); printf("after: %s\n", buffer); Wynik działania: Before: This is a test of the memset function After : **** is a test of the memset function c) Przykład 3. #include <memory.h> #include <stdio.h> int main(void) char str[256]; double aa[200]; double cc[10] = 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ; double dd[5] = 20, 30, 40, 50, 60 ; memset((void *)str, 0, 256 * sizeof(char)); //OK memset((void *)str, ' ', 256 * sizeof(char)); //!OK pisanie po pamięci memset((void *)str, ' ', 255 * sizeof(char)); //OK memset((void *)aa, 0, 200 * sizeof(double)); //OK memcpy((void *)&cc[3], (const void *)&dd[2], 2 * sizeof(double)); Wynik działania: cc: 1 2 3 40 50 6 7 8 9 10 11. Przykład. Napisz program, który dla danych dwóch wektorów, policzy: i. Sumę tych wektorów: = + ; ii. Iloczyn skalarny wektorów: = ; iii. Maksymalną współrzędną wektorów, //==============================PLIK_1=================================== #pragma warning (disable:4996) #include<stdio.h> #include<stdlib.h> #define LL 200 extern void error(int, char *); void argumenty(int, char **); int main(int argc, char *argv[]) double x[ll], y[ll], z[ll], s, mx, my; FILE *fw, *fd; int n, k; argumenty(argc, argv); if (!(fd = fopen(argv[1], "r"))) error(2, "dane"); if (!(fw = fopen(argv[2], "w"))) error(2, "wyniki"); fscanf(fd, "%d", &n); Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 5

for (k = 0; k < n; k++) fscanf(fd, "%lf", &x[k]); for (k = 0; k < n; k++) fscanf(fd, "%lf", &y[k]); s = 0; mx = x[0]; my = y[0]; for (k = 0; k < n; k++) z[k] = x[k] + y[k]; mx = x[k] > mx? x[k] : mx; my = y[k] > my? y[k] : my; s += x[k] * y[k]; for (k = 0; k < n; k++) fprintf(fw, "%lf ", z[k]); if (!((k + 1) % 5)) fprintf(fw, "\n"); fprintf(fw, "\nilocz.skal=%lf mx=%lf my=%lf\n", s, mx, my); void argumenty(int argc, char *argv[]) int len; char *usage; if (argc!= 3) len = strlen(argv[0]) + 19; if (!(usage = (char*)malloc((unsigned)len * sizeof(char)))) error(3, "tablica usage"); strcpy(usage, argv[0]); strcat(usage, " file_in file_out"); error(4, usage); /**************** plik util_1.c ******************************/ #include<stdio.h> #define MAX_ERR 5 static char *p[] = "", " zle dane", " otwarcie pliku", " brak pamieci", " Usage : ", " nieznany ", ; void error(int nr, char *str) int k; k = nr >= MAX_ERR? MAX_ERR : nr; fprintf(stderr, "Blad(%d) - %s %s\n", nr, p[k], str); system("pause"); exit(nr); 12. Wyrażenie warunkowe przyjmuje postać: wyrażenie1? wyrażenie2 : wyrażenie3 wartością wyrażenia warunkowego jest: Wartość wyrażenia2, o ile wyrażenie1 jest różne od zera, Wartość wyrażenia3, o ile wyrażenie1 jest równe zero. Operator pytajnik, dwukropek (?:) jest prawostronnie łączny i ma priorytet wyższy jedynie od operatorów przypisania i operatora przecinkowego. Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 6

13. Napisz procedurę, która korzystając z funkcji: srand, time, rand oraz operatora dzielenia modulo uzupełni przekazaną do niej tablicę typu int o losowe liczby z zakresu od 0 do 10. Tablica niech będzie przekazywana przez referencję. 14. Do poprzedniego programu dopisz procedurę, która będzie wyświetlać zawartość tablicy oraz informację ile razy funkcja była wywoływana (skorzystaj ze zmiennej statycznej). Tablica niech będzie przekazywana przez wskaźnik. 15. Operatorem sizeof sprawdź rozmiar tablicy w trzech miejscach (po jej deklaracji i w dwóch procedurach z powyższych zadań). Wytłumacz otrzymane wyniki. 16. Zadeklaruj i uzupełnij liczbami tablicę 5 elementową. Wypisz wartość 3 elementu BEZ KORZYSTANIA Z INDEKSÓW (złe rozwiązanie: printf("%d\n", tablica[2]);). 17. Zmodyfikuj program z przykładu w pkt.11 tak aby: Zamiast tablic zdefiniować zmienne typu double *; Zarezerwować dokładnie n miejsc na zmienne typu double (alokacja pamięci), np.: x = (double*)malloc((unsigned)n * sizeof(double)) 18. Algorytm z pkt.17 podziel na kilka funkcji: a) Alokacja pamięci dla tablicy: double *DajWekt(int n) b) Czytanie elementów tablicy z pliku: void CzytWekt(FILE *fd, double *we, int n) c) Pisanie elementów tablicy do pliku: void PiszWekt(FILE *fw, double *we, int n) d) Obliczanie sumy dwóch wektorów: void DodWekt(double *w1, double *w2, double *w3, int n) e) Obliczanie iloczynu skalarnego: double IloczynSkal(double *w1,double *w2,int n) f) Obliczanie maksymalnej współrzędnej wektora: double MaxElem(double *w, int n) Funkcje realizujące zadania a), b), c) zapisz w pliku util_2.cpp. Funkcje realizujące zadania d), e), f) zapisz w pliku util_3.cpp. 19. Dynamiczna alokacja pamięci dla tablic wielowymiarowych - Przykładowa tablica 10x5 o elementach typu double. Wersja 1. double **tab; int n = 10, m = 5; tab = (double **)malloc(sizeof(double *) * n); if (!tab) //błąd alokacji for (int i = 0; i < n; i++) tab[i] = (double *)malloc(sizeof(double) * m); if (!tab[i]) //błąd alokacji if (tab) for (int i = 0; i < n; i++) if (tab[i]) free(tab[i]); free(tab); tab = NULL; Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 7

Wersja 2. double **tab_a, *tab_b; int n = 10, m = 5; tab_b = (double *)malloc(sizeof(double) * n * m ); if (!tab_b) //błąd alokacji tab_a = (double **)malloc(sizeof(double *) * n); if (!tab_a) //błąd alokacji for (int i = 0; i < n; i++) tab_a[i] = &tab_b[ m * i ]; if (tab_b) free(tab_b); // free(tab_a[0]); tab_b = NULL; if (tab_a) free(tab_a); tab_a = NULL; 20. Przykład. Napisz program, który dla danych dwóch macierzy: =, = 0,1,2,, 1;! = 0,1,2,, " 1, #$ = %, = 0,1,2,, 1;! = 0,1,2,, " 1 oraz wektora = & ', = 0,1,2,, " 1, policzy: i. Sumę macierzy: ( = + #, ) *+ * = + % ; ii. Iloczyn macierzy przez wektor : = ; = -,,, ; = 0,1,2,, 1; Do kontroli poprawności obliczeń wykorzystaj funkcję error z pliku util_1.cpp (patrz lab. 8). Dane pobrać z pliku, wyniki zapisać do pliku, nazwy plików przekazać przez argumenty wywołania programu. //==============================PLIK_1=================================== #include "pch.h" #include<stdio.h> #include<stdlib.h> #include<string.h> #pragma warning(disable:4996) #define LL 20 FILE *fw, *fd; void argumenty(int, char **); extern void error(int, char *); int main(int argc, char *argv[]) double a[ll][ll], b[ll][ll], c[ll][ll], x[ll], y[ll], r; int i, j, k, n, m; argumenty(argc, argv); if (!(fd = fopen(argv[1], "r"))) error(2, "dane"); Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 8

if (!(fw = fopen(argv[2], "w"))) error(2, "wyniki"); fscanf(fd, "%d %d", &n, &m); for (j = 0; j < m; j++) fscanf(fd, "%lf", &a[i][j]); for (i = 0; i < m; i++) fscanf(fd, "%lf", &x[i]); for (j = 0; j < m; j++) fscanf(fd, "%lf", &b[i][j]); for (j = 0; j < m; j++) c[i][j] = a[i][j] + b[i][j]; r = 0; for (k = 0; k < m; k++) r += a[i][k] * x[k]; y[i] = r; for (j = 0; j < m; j++) fprintf(fw, "%lf ", c[i][j]); fprintf(fw, "\n"); fprintf(fw, "%lf ", y[i]); if (!((i + 1) % 5)) fprintf(fw, "\n"); system("pause"); return 0; void argumenty(int argc, char *argv[]) int len; char *usage; if (argc!= 3) len = strlen(argv[0]) + 19; if (!(usage = (char*)malloc((unsigned)len * sizeof(char)))) error(3, "tablica usage"); strcpy(usage, argv[0]); strcat(usage, " file_in file_out"); error(4, usage); /**************** plik util_1.cpp ******************************/ #include<stdio.h> #define MAX_ERR 5 static char *p[] = "", " zle dane", " otwarcie pliku", " brak pamieci", " Usage : ", " nieznany ", Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 9

; void error(int nr, char *str) int k; k = nr >= MAX_ERR? MAX_ERR : nr; fprintf(stderr, "Blad(%d) - %s %s\n", nr, p[k], str); system("pause"); exit(nr); 21. Zmodyfikuj program z powyższego przykładu tak aby: Zamiast tablic jednowymiarowych zdefiniować zmienne typu double *, zamiast tablic dwuwymiarowych zdefiniować zmienne typu double **; Zarezerwować dokładnie m miejsc na tablice jednowymiarowe typu double (alokacja pamięci), np.: x = (double*)malloc((unsigned)m * sizeof(double)); Zarezerwować dokładnie n*m miejsc na tablice dwuwymiarowe typu double (alokacja pamięci patrz pkt.1), np.: a = (double**)malloc((unsigned)n * sizeof(double*)); a[i] = (double*)malloc((unsigned)m * sizeof(double)); 22. Algorytm z pkt.20 podziel na kilka funkcji: g) Alokacja pamięci (dwie funkcje - wer.1 i wer.2 patrz pkt.19) : double **DajMac_1(int n, int m) double **DajMac_2(int n, int m) h) Zwolnienie pamięci (dwie funkcje): void ZwrocMac_1(double **ma, int n, int m) void ZwrocMac_2(double **ma, int n, int m) i) Czytanie elementów tablicy o dwóch indeksach z pliku: void CzytMac(FILE *fd, double **ma, int n, int m) int i, j; char *err; for (j = 0; j < m; j++) if (fscanf(fd, "%lf", &ma[i][j])!= 1) printf("blad - element nr %d %d\n", i, j); j) Pisanie elementów tablicy o dwóch indeksach do pliku: void PiszMac(FILE *fw, double **ma, int n, int m) k) Dodawanie macierzy: void DodMac(double **ma1, double **ma2, double **ma3, int n, int m) l) Mnożenie macierzy przez wektor: void Mac_x_Wekt(double **ma, double *we, double *wy, int n, int m) m) Napisz dodatkowo funkcję, która dla danych macierzy:.$ =, = 0,1,2,, 1;! = 0,1,2,, " 1, /$ =, = 0,1,2,, " 1;! = 0,1,2,, 0 1 policzy macierz 1 =./ $$$$ czyli - = 2,,, = 0,1,2,, 1,! = 0,1,2, 0 1, void Mac_x_Mac(double **x, double **y, double **z, int n, int m, int p) Funkcje realizujące zadania a), b), c), d) zapisz w pliku util_4.cpp. Funkcje realizujące zadania e), f), g) zapisz w pliku util_5.cpp. Wydział Fizyki, Matematyki i Informatyki Politechniki Krakowskiej 10

23. Zrealizuj zadania z powyższego przykładu (pkt.20 i następne) wykorzystując utworzone wcześniej funkcje zawarte w plikach util_2.cpp, util_3.cpp, util_4.cpp, util_5.cpp. Fragment programu: FILE *fw, *fd; extern void error(int, char*),piszwekt(file *, double *, int), CzytWekt(FILE *, double *, int),czytmac(file *, double **, int, int), PiszMac(FILE *, double **, int, int); extern double *DajWekt(int), **DajMac_1(int, int); extern void DodMac(double **, double **, double **, int, int), Mac_x_Wekt(double **, double *, double *, int, int); void argumenty(int argc, char *argv[]); int main(int argc, char *argv[]) double *x, *y; double **a, **b, **c; int n, m; argumenty(argc, argv); if (!(fd = fopen(argv[1], "r"))) error(2, "dane"); if (!(fw = fopen(argv[2], "w"))) error(2, "wyniki"); fscanf(fd, "%d %d", &n, &m); x = DajWekt(m); y = DajWekt(m); a = DajMac_1(n, m); b = DajMac_1(n, m); c = DajMac_1(n, m); CzytMac(fd, a, n, m); CzytMac(fd, b, n, m); CzytWekt(fd, x, m); DodMac(a, b, c, n, m); Mac_x_Wekt(a, x, y, n, m); printf("macierz\n"); PiszMac(stdout, c, n, m); fprintf(fw, "Macierz\n"); PiszMac(fw, c, n, m); printf("wektor\n"); PiszWekt(stdout, y, n); fprintf(fw, "Wektor\n"); PiszWekt(fw, y, n); Pliki util_2.cpp i util_3.cpp dostępne pod adresem: http:/http://riad.pk.edu.pl/~jwojtas/jipp/util_2.pdf http:/http://riad.pk.edu.pl/~jwojtas/jipp/util_3.pdf 24. Dana jest macierz kwadratowa B[n][n]. Znaleźć sumę elementów leżących poniżej głównej przekątnej i jednocześnie należących do zadanego przedziału [a,b]. 25. Dana jest macierz kwadratowa B[n][n]. Znaleźć sumę tych elementów leżących na obu przekątnych macierzy, które jednocześnie spełniają warunek (na głównej przekątnej j=i, na drugiej j=n-i): sin6#787!89 ; 0 <+ =+="=>ó@ Ałó@=! 0C=Dą>=! 0,5 <+ =+="=>ó@ <CGA=! 0C=Dą>=! 26. Przeanalizuj w trybie pracy krokowej przykłady do wykładu: 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 11