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.

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

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

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

Struktury. Przykład W8_1

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

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

Tablice, funkcje - wprowadzenie

Wprowadzenie w dziedziczenie. Klasa D dziedziczy klasę B: Klasa B klasa bazowa (base class), klasa D klasa pochodna (derived class).

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

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

Podstawy programowania komputerów

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

W2 Wprowadzenie do klas C++ Klasa najważniejsze pojęcie C++. To jest mechanizm do tworzenia obiektów. Deklaracje klasy :

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

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

Uzupełnienie dot. przekazywania argumentów

Wykład 8: klasy cz. 4

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

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

Język C zajęcia nr 11. Funkcje

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

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

Lab 9 Podstawy Programowania

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

Zmienne, stałe i operatory

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

Wskaźniki. Informatyka

Stałe, tablice dynamiczne i wielowymiarowe

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

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

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

Wykład 4: Klasy i Metody

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

Wskaźniki w C. Anna Gogolińska

PARADYGMATY PROGRAMOWANIA Wykład 3

Wstęp do programowania 1

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

Szablony klas, zastosowanie szablonów w programach

Przeciążenie operatorów

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU

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

Programowanie obiektowe Wykład 3. Dariusz Wardowski. dr Dariusz Wardowski, Katedra Analizy Nieliniowej, WMiI UŁ 1/21

Wprowadzenie do programowania w języku C

Język C++ zajęcia nr 2

Podstawy Programowania. Zmienne dynamiczne, struktury, moduły programowe

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

Podział programu na moduły

2 Przygotował: mgr inż. Maciej Lasota

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

Funkcja, argumenty funkcji

Programowanie Proceduralne

DYNAMICZNE PRZYDZIELANIE PAMIECI

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

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

KURS C/C++ WYKŁAD 8. Deklaracja funkcji informuje komplilator jaką wartość funkcja będzie zwracała i jakiego typu są jej argumenty.

1 Podstawy c++ w pigułce.

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

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

Programowanie obiektowe W3

1 Podstawy c++ w pigułce.

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

Obsługa wyjątków. Język C++ WW12

Spis treści WSKAŹNIKI. DYNAMICZNY PRZYDZIAŁ PAMIĘCI W JĘZYKU C. Informatyka 2. Instrukcja do pracowni specjalistycznej z przedmiotu

Programowanie w C++ Wykład 14. Katarzyna Grzelak. 3 czerwca K.Grzelak (Wykład 14) Programowanie w C++ 1 / 27

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

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

Argumenty wywołania programu, operacje na plikach

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

Języki i metody programowania I

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie?

ISO/ANSI C dostęp do plików ISO/ANSI C. ISO/ANSI C dostęp do plików. ISO/ANSI C dostęp do plików. ISO/ANSI C dostęp do plików

Wskaznik. Przekazywanie wyniku funkcji przez return. Typy i zmienne wskaznikowe. Zmienna wskazywana. typ * nazwa_wkaznika

Pola i metody statyczne

ZASADY PROGRAMOWANIA KOMPUTERÓW

Wykład Wskaźniki a tablice jednowymiarowe Arytmetyka wskaźników Dostęp do elementów tablic

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

Wykład 1. Program przedmiotu. Programowanie (język C++) Literatura. Program przedmiotu c.d.:

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU

Wykład 1_2 Algorytmy sortowania tablic Sortowanie bąbelkowe

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

Operator przypisania. Jest czym innym niż konstruktor kopiujący!

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

Programowanie obiektowe w języku C++ dr inż. Jarosław Forenc

Funkcja (podprogram) void

Programowanie strukturalne i obiektowe

Funkcje przeciążone, konstruktory kopiujące, argumenty domyślne

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

Tablice deklaracja, reprezentacja wewnętrzna

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

Dla każdej operacji łącznie tworzenia danych i zapisu ich do pliku przeprowadzić pomiar czasu wykonania polecenia. Wyniki przedstawić w tabelce.

Functionalization. Funkcje w C. Marcin Makowski. 30 listopada Zak lad Chemii Teoretycznej UJ

PARADYGMATY PROGRAMOWANIA Wykład 4

Programowanie obiektowe. Dr hab. Inż. Marta Gładysiewicz-Kudrawiec Pokój 229 A1 Operatory new delete pliki-odczyt

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

Język ludzki kod maszynowy

Wstęp do programowania

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

Laboratorium nr 10. Temat: Funkcje cz.2.

Wykład 3 Składnia języka C# (cz. 2)

Transkrypt:

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. W ostatnich latach najbardziej używanym stylem oprogramowania jest podejście obiektowe. Język C bezpośrednio nie ma narzędzi do oprogramowania obiektowego, przecież nadaje możliwość wytrzymać pewne cechę stylu oprogramowania obiektowego. W podstawie tego stylu leżą dane i metodę (funkcji - C), które tworzą te dane, alokują pamięć, zmieniają dane, usuwają ich, zwalniają pamięć, a również wykonują dowolne działania nad danymi. Bezpośredni dostęp do danych jest możliwy wyłącznie z tego pliku, w którym te dana są zdefiniowane. Z innych plików programy bezpośredni dostęp do danych nie jest popierany.

Do programisty należy: Podjęć decyzje jak rozdzielić dane na grupy, przy czym każda grupa danych będzie umieszczona w swój plik i będzie obsługiwana swoimi funkcjami. Dla każdej grupy danych rozdzielić funkcji obsługi na funkcje wewnętrzne, wykonujące działania nad danymi tylko w obszarze pliku, w którym dane są zdefiniowane, i na funkcje interfejsowe, jakie udostępniają działania nad danymi w innych plikach. Dla tego, żeby zabezpieczyć ten styl oprogramowania, należy (przykład W7_3): podstawowe dane w pliku definiować jako zmienne globalne z modyfikatorem static, który nie nadaje możliwości ich bezpośredniego udostępniania w innych plikach.

Prototypy funkcji interfejsowych umieścić w odpowiednim headerze (bez modyfikatora static). Prototypy funkcji wewnętrznych umieścić w pliku jako obiekty globalne z modyfikatorem static. Dane globalne, które nie są docelowo udostępniać przez funkcje, definiować bez modyfikatora static, a udostępnienie w innych plikach wprowadzić z specyfikatorem extern. Nie warto umieszczać te dane w headerze. Dane pomocnicze (indeksy tablic, tymczasowe zmienne i inne) używać jako dane lokalne (auto).

Headery (pliki nagłówkowe ) są używane dla deklaracji typów danych (struktur, unij, typedef), pragm kompilatorów, makrosów, prototypów funkcji, które muszą być widoczne w różnych plikach projektu. Każdy header musi mieścić tak zwane straże, które w projektach złożonych chronią przed duplikacją definicji, umieszczonych w headerze. Klasy pamięci auto wszystkie zmienne i tablicy, zdefiniowane w dowolnym bloku. Rezerwacja miejsca w pamięci następuje przy wejściu w blok. Pamięć ta pozostaje zwolniona przy wyjściu z bloku, w którym była zdefiniowana ta zmienna. Dane pozostają utracone. Obszar działania (widoczności, zasiąg deklaracji) blok. Czas życia od momentu definicji i do momentu wyjścia z bloku. Domyślnie zmienne nie są inicjowane, zawierają śmieci.

static (definicja lokalna wewnątrz bloku) rezerwacja pamięci jest dokonywana na początku wykonania programu. Obszar widoczności zmiennych i tablic klasy static od miejsca definicji w bloku, w którym oni pozostali zdefiniowane, do końca bloku. Czas życia czas wykonania całego programu. Oznacza to, że wartości zmiennych klasy pamięci static pozostają chronione nawet po wyjściu z bloku i są aktualne po następnemu wejściu w blok. Przy braku jawnej inicjalizacji zmienne klasy static są inicjowane jako zero. Przykład: void fun() { static int a; a++; } pierwsze wejście a = 0 wyjście a = 1 drugie wejście a = 1 wyjście a = 2 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

Statyczna składowa struktury: struct MY_STRUCT {.. static int a; }; //konieczne jest inicjowanie jako zmiennej globalnej: int MY_STRUCT :: a = 0; //Wszystkie obiekty MY_STRUCT rozdzielają tą samą zmienną a: MY_STRUCT A, B; A.a i B.a mają tą samą wartość. A.a = 10; printf( %d\n, B.a); //B.a = 10

MY_STRUCT tab[5]; tab[0].a, tab[1].a,, mają tą samą wartość. tab[0].a = 10; printf( %d\n, tab[1].a); //10 Funkcja zwraca wskaźnik do obiektu: int *fun() { int i = 10; return &i; } //!OK int *fun() { int *pi = (int *)malloc(sizeof(int)); *pi = 10; return pi; } //OK int *fun() { static int i = 10; return &i; } //OK int i; int *fun() { i = 10; return &i; } //OK

static (definicja globalna w pliku poza blokami) rezerwacja pamięci jest dokonywana na początku wykonania programu. Obszar widoczności zmiennych i tablic klasy pamięci static od miejsca definicji do końca pliku. Czas życia czas wykonania całego programu. Przy braku jawnej inicjalizacji zmienne są inicjowane jako zero. Są dostępne tylko w podanym pliku. Zmienne globalne (bez specyfikatora static) - rezerwacja pamięci jest dokonywana na początku wykonania programu. Obszar widoczności zmiennych i tablic globalnych od miejsca definicji do końca pliku. Czas życia czas wykonania całego programu. Przy braku jawnej inicjalizacji zmienne są inicjowane jako zero. Mogą być udostępnione w innych plikach. Klasa pamięci register oznacza, że dane, gdy to będzie możliwe, pozostaną umieszczone w rejestrze procesora. Specyfikator static, używany przy prototypie funkcji, ogranicza działalność tej funkcji obszarem pliku. Nie wolno umieszczać deklaracji funkcji statycznych w headerzach.

Wektory i macierzy Podstawowe działania algebry liniowej 1. Iloczyn skalarny dwóch wektorów: scalar = x T y. Przykład W7_4. 2. Mnożenie macierzy przez wektor: y=ax. Przykład W7_5. 3. Mnożenie macierzy przez macierz: C = C + A*B. Przykład W7_6. 4. Faktoryzacja macierzy kwadratowej: A = L*U, A = L*L T

Przechowywanie macierzy (tablicy jednowymiarowej) wierz-po-wiersze i numer wiersza, j numer kolumny, kolejność zmiany indeksów: for(i=0; i<n; i++) for(j=0; j<n; j++) Indeks ij ij=n*i+j 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 a a a a a a a a a a a a a a a a 11 12 13 14 21 22 23 24 31 32 33 34 41 42 43 44 Przechowywanie macierzy (tablicy jednowymiarowej) kolumna-pokolumnie i numer wiersza, j numer kolumny, kolejność zmiany indeksów: for(j=0; j<n; i++) for(i=0; i<n; i++) Indeks ij ij=n*j+i 0 4 8 12 1 5 9 13 2 6 10 14 3 7 11 15 a a a a a a a a a a a a a a a a 11 12 13 14 21 22 23 24 31 32 33 34 41 42 43 44

Mnożenie macierzy przez macierz Wzór matematyczny: c ij = k a ik b kj c00 c01 c02 c03 a00 a01 a02 a03 b00 b01 b02 b03 c10 c11 c12 c13 a10 a11 a12 a13 b10 b11 b12 b13 c20 c21 c22 c 23 a20 a21 a 22 a 23 b20 b21 b22 b 23 c c c c a a a a b b b b 30 31 32 33 30 31 32 33 30 31 32 33 j k j N N K i M C = i M A k K B

Metoda klasyczna przechowywanie macierzy wiersz po wiersze 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 Element macierzy C w pętli wewnętrznej nie zależy od indeksu k. Pobieranie elementów macierzy A idzie ciągłe, bez skoków. Pobieranie elementów macierzy B idzie ze skokami. Dla tego ta metoda nie skuteczna 0 1 2 3 0 1 2 3 0 1 2 3 4 5 6 7 4 5 6 7 4 5 6 7 8 9 10 11 8 9 10 11 8 9 10 11 12 13 14 15 12 13 14 15 12 13 14 15 C A B

Metoda przyspieszona przechowywanie macierzy wiersz po wiersze 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 nie zależą od indeksu j pętli wewnętrznej. Pobieranie elementów macierzy C idzie ciągłe, bez skoków. Pobieranie elementów macierzy B idzie ciągłe, bez skoków. Dla tego ta metoda jest lepsza od poprzedniej 0 1 2 3 0 1 2 3 0 1 2 3 4 5 6 7 4 5 6 7 4 5 6 7 8 9 10 11 8 9 10 11 8 9 10 11 12 13 14 15 12 13 14 15 12 13 14 15 C A B

Rozdzielenie macierzy na bloki Mnożenie blokowe przykład Mulm A a11 a 12 : a13 a14 0 1 : 2 3 a21 a 22 : a23 a 24 4 5 : 6 7 a a 1,1 1,2 a a 2,1 2,2 a31 a 32 : a33 a34 8 9 : 10 11 a41 a 42 : a43 a 44 12 13 : 14 15

#include <memory.h> void *memcpy( void *dest, const void *src, size_t count ); Kopiuje count bajtów z src do dest. Zwraca wskaźnik do dest. Działanie nie jest przewidywane, jeśli obszary pamięci src i dest przekrywają się. void *memmove( void *dest, const void *src, size_t count ); Kopiuje count bajtów z src do dest. Zwraca wskaźnik do dest. Jeśli jakieś obszary pamięci przekrywają się, funkcja gwarantuje, że oryginalne bajty źródłowe w przekrywającym się regionie będą skopiowany przed tym, jak pozostaną przepisane. void *memset( void *dest, int c, size_t count ); Przypisuje symbol c pierwszym count symbolom tablicy dest. Zwraca wskaźnik do dest.

#include <memory.h> #include <string.h> #include <stdio.h> char str1[7] = "aabbcc"; int main( void ) { printf( "The string: %s\n", str1 ); //Przekrywający się region! Kopiowanie może być nie poprawne memcpy( str1 + 2, str1, 4 ); printf( "New string: %s\n", str1 ); } strcpy_s( str1, sizeof(str1), "aabbcc" ); // reset string printf( "The string: %s\n", str1 ); //Przekrywający się region! Kopiowanie poprawne memmove( str1 + 2, str1, 4 ); printf( "New string: %s\n", str1 );

#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 ); } Before: This is a test of the memset function After : **** is a test of the memset function

Przykład 2. 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)); memset((void *)str,, 256*sizeof(char)); memset((void *)str,, 255*sizeof(char)); memset((void *)aa, 0, 200*sizeof(double)); //OK //!OK pisanie po pamięci //OK //OK memcpy((void *)&cc[3], (const void *)&dd[2], 2*sizeof(double)); //cc: 1 2 3 40 50 6 7 8 9 10