funkcji Gramatyką formalną G zapisujemy w następujący sposób: { }nawias klamrowy *wykazuje początek i koniec instrukcji złożonej G=<N, V, P, S> ,przecinek *oddziela argumenty wywołania funkcji Gdzie: N-alfabet nieterminalny(zbiór symboli ;średnik *zakończenie instrukcji pomocniczych), V-alfabet terminalny(symbole, z którego :dwukropek *ciąg znaków określa etykietę tworzone są słowa języka), P-zbiór reguł produkcji, S-symbol … wielokropek *definicja funkcji o zmiennej liczbie parametrów startowy(wyróżniony symbol nieterminalny) *znak gwiazdki -znak mnożenia -deklaracja zmiennej Notacje BNF wskaźnikowej =znak równości *oddziela deklarację zmiennej od części ->Symbol początkowy (startowy): <zdanie>, inicjującej tę zmienną #znak hash *oznaczanie dyrektyw preprocesora ->Symbol pomocnicze(nieterminalne): STRUKTUTA programu w języku C: <zdanie>,<podmiot>,<orzeczenie> •program w języku C tworzą funkcje. ->Symbol końcowe(terminale):alfabet końcowy: samochód, •funkcja może posiadać parametry oraz określony typ pociąg, jedzie, stoi wartości, •w jednym i tylko w jednym z modułów musi wystąpić ->Metasymbole: <,>,::=,| funkcja main, od której rozpoczyna się wykonywanie programu, ->Produkcje -reguły, poprzez które można zdefiniować język, reguły gramatyki •moduł z funkcją main to moduł główny, •każda funkcja zwraca wartość. Gramatyka generująca liczbę binarną . G={N,V,P,S} Formatowanie: %d lub %i – Liczba całkowita ze znakiem.np int. N={<liczba binarna>,<cyfra>} %f -Liczba rzeczywista np. float. V={0,1} %u- Liczba całkowita bez znaku %o-Liczba w systemie ósemkowym/ %x(małe)%X(duże) P={<liczba binarna>::=<liczba binarna><cyfra> Liczba w systemie szesnastkowym. %c-Znak.np, zmienne typu char. <liczba binarna>::=<cyfra> %s-Łańcuch znaków zakończony „\0” np. Zmienne typu string <cyfra>::+0|1} <liczba binarna> TYPY DANYCH Data= dzień ‘’.’’ Miesiąc ‘’.’’ Rok | dzień ‘’-‘’ miesiąc ‘’-‘’ rok. *Typy proste: całkowite i rzeczywiste/ wskaźnikowe Dzień= cyfra| cyfra cyfra. *Typy złożone: tablice/struktury/unie Miesiąc= cyfra | cyfra cyfra. /* miesiąc=[‘’1’’] cyfra*/ Słowa kluczowe określające typy całkowity: Rok= cyfra cyfra | cyfra cyfra cyfra cyfra. CHAR-typ znakowy/ INT-typ całkowity/ LONG-typ tzw. Cyfra= ‘’0’’|’’1’’|’’2’’|’’3’’|’’4’’|’’5’’|’’6’’|’’7”|”8”|”9”. długich liczb całkowitych/ SIGNED-liczby ze znakiem/ SHORT-typ tzw. Krótkich liczb całkowitych/ UNSIGNED- Liczba=[znak-liczby] liczba-bez-znaku. liczny bez znaku/FLOAT-liczba zmiennopozycyjna Liczba=[‘’+’’,’’-‘’] cyfra{cyfra} pojedynczej precyzji/DOUBLE-liczba zmiennopozycyjna Znak-liczby= ‘’+”|”-‘’. podwójnej precyzji. Liczba=[‘’+’’,’’-‘’] {cyfra} PRINTF-wypisuje komunikat błędu na standardowy Liczbe-bez-znaku= cyfra{cyfra}. strumieniu wyjścia./SCANF- wczytuje dane różnego typu na podstawie sformatowanego tekstu. Cyfra=’’0’’|’’1’’|’’2’’|’’3’’. System binarny Komentarze w C = /* ciag-znakow */ cn∙ pn+ . . . + c2 ∙ p2+ c1 ∙ p1+ c0 ∙ p0 Podstawowe jednostki leksykalne języka C c –cyfra, p –podstawa. Identyfikatory c = {0,1} •małe i wielkie litery {A-Z, a-z} , cyfry {0-9}, znak p=2 podkreślenia _ 1 ∙ 27+ . . . + 1 ∙ 22+ 1 ∙ 21+ 1 ∙ 20 •pierwszy znak musi być literą lub znakiem podkreślenia_ Przykład *Znaki przestankowe 10110100 [ ]nawias kwadratowe 1∙27+0∙26+1∙25+1∙24+0∙23+1∙22+0∙21+0∙20=128+32+16+4= 180 System szesnastkowy /dziesiętny (p=10) Struktury składają się ze składowych różnych typów, umieszczonych w pamięci w kolejności deklaracji. Rozmiar c = {0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F} struktury jest równy sumie rozmiarów jej składowych. p=16 Struct identyfikator-typu-struktury szesnastkowy -dziesiętny { A –10 ,…, F –15 deklaracje-składowych Przykład: 009FA } [identyfikator-struktury=[inicjator], ….]; 0∙164+0∙163+9∙162+15∙161+10∙160=2304+240+10=2570 Struct punkt /*definicja struktury i typów*/ { Stałe znakowe :Stała znakowa –stała reprezentująca znak doublex,y; alfanumeryczny } p1 = {100.00,100.00}; char znak; albo char literaA= 65, char znak7c=’\x7c’; p1.x=150.00; /* Odwołanie się do elementów struktury – znak=’C’; (Zapis znaku do pamięci w postaci kodu.) zmiana wartości*/ znaki specjalne \-odwrotny ukośnik (Backslash) p1.y=150.00; \b –cofacz (Backspace) \f –nowa strona (Form feed) doubleXp=p1.x; \n –nowa linia (New line) \r –powrót karetki Unie składają się ze składowych różnych typów, (carriageReturn) przechowywanych się w tej samej komórce pamięci. \t –tabulator poziomy (Tabulator) \v –tabulator pionowy W danej chwili unia może zawierać tylko jedną użyteczną (Verticaltabulator) wartość zdefiniowanego typu. char zs=’\n’; Rozmiar unii jest równy rozmiarowi największej składowej. Kompilacja- przepisanie kodu źródłowego na komputerowy Union identyfikator-typu-unii Konsolidacja- łączenie plików w celu utworzenia { wynikowego deklaracje-składowych Kompilacja jest przed konsolidacją Może być } [unia[=inicjator], ….]; if /* gggg*/ (wyrażenie) Nie może być if //ggg Unio nunia (wyrażenie) Iiteracja { Najpierw biblioteka później zmienne stałe Switch może być char znak; intem (chyba że literki, co są zapisywane kodami asci) intliczba1; Algorytmy Argumenty to to co podajemy w nawiasach doubleliczba2; Literały tekstowe- np. nazwy zmiennych Program nie jest } jednoznacznym odwzorowaniem algorytmu Int i =0, j =0; unia unia1={'a'}; poprawne unia1.liczba1=12; Najpierw matematyczne a później porównawcze 5/2 zwraca unia1.liczba2=234.89; 2 !!!!!!! 5.0/2.0 zwraca 2.5 !!!!! X++ i ++x nie są tożsame Zasięg deklaracji i widoczność zmiennych Dzielenie jest pierwsze później mnożenie Czas życia obiektu –okres od momentu, gdy zostaje on # define Pi 4.14 dobrze zdefiniowany (definicja przydziela miejsce w pamięci) do #define Pi= 3.14 źle momentu, gdy przestaje istnieć (zostaje zwolnione miejsce Scanf stdin Scanf zawsze z & While(i<10) i*=2; i++; pomija w pamięci) i++ bo nie jest jakby w wąsach Okres ważności nazwy obiektu–to część programu, w której Cechy zmiennych: nazwa obiektu jest znana (obiekt jest dostępny poprzez a) nazwa -poprawny identyfikator, który różni się od słów odwołanie do jego nazwy) kluczowych, W pewnym momencie wykonywania programu obiekt b) typ -określa, jakie informacje będą przechowywane w może istnieć, ale nie jest dostępny poprzez odwołanie do zmiennej; jego nazwy, ponieważ znajduje się poza zakresem ważności c) aktualna wartość, jego nazwy. d) alokacja -miejsce w pamięci, gdzie ma być Zmienna globalna –zasięg zmiennej obejmuje cały plik kodu przechowywana wartość zmiennej, źródłowego, począwszy do miejsca deklaracji. Zmienna e) zakres -miejsce w programie, gdzie można odwoływać się zlokalizowana poza wszystkimi blokami programu do Blok programu –część kodu zawarta w nawiasach zmiennej, klamrowych { blok programu} f) czas trwania -czas, w jakim mogą wystąpić odwołania do Zmienna lokalna –zasięg zmiennej obejmuje blok programu zmiennej. int np; zmienna globalna widoczna w obrębie całego Operacje na zmiennych pliku Operacje matematyczne: dodawanie x=x+y -> x+=y; …. odejmowanie x=x-y->x-=y; mnożenie x=x*y->x*y; dzielenie doublesuma(doublea, doubleb) x=x/y->x/=y; reszta z dzielenie x=x%y-> x%y; != jest różne { od; i && iloczyn logiczny, lub || suma logiczna, negacja ! double p; zmienna lokalna widoczna w obrębie zanegowanie wartości. funkcji "suma" INKREMENTACJA -> zwiększenie wartości zmiennej o jeden p=a+b; np. zmienna +=1; DEKREMENTACJA -> zmniejszenie return p; wartości zmiennej o jeden np. zmienna -=1 } int main( ) zmienna lokalna widoczna w obrębie Operatory -priorytet i wiązanie x + y -z ,operatory "+" i "-" funkcji "main" mają w języku C równy priorytet / (x + y)-z -> wiązanie { operatów następuje od lewej do prawej !/ x+(y-z) - double s; >wiązanie operatów następuje od prawej do lewej. double c=2; zmienne lokalne widoczna w obrębie OPERATOR INKREMENTACJA: ++O, O++(przy) funkcji "main” DEKREMENTACJA: --O,O—(*o. przyrostkowy działa po double d=3; obliczeniu wartości całego wyrażenia, natomiast s=suma(c,d); przedrostkowy przed). && koniunkcja, || alternatywa, … !negacja. return 0; OPERATOR BITOWE: AND &, OR |, XOR ^, NOT ~. } OPERATOR PRZYPISANIA: =, i+=4 Oznacza i=i+4 …; Zmienne i zarządzanie pamięcią sizeof(identyfikator-typu) -rozmiar w bajtach typu Zmienne automatyczne : auto –przyjmowany domyślnie dla określonego przez wskazany identyfikator zmiennych zadeklarowanych lokalnie/ register – sizeof(double) specyfikator informuje kompilator, że deklarowana sizeof O –rozmiar pamięci zajmowany przez operand O zmienna powinna być przechowywana w rejestrze sizeof(structpunkt) procesora. INSTRUKCJE Zmienne statyczne: istnieją od momentu rozpoczęcia *INSTRUKCJA WARUNKOWA IF /typ, który można poddać wykonywania programu do jego zakończenia. porównaniu/ Atrybuty stałości -const / Const double e=2.7182; if(warunek){instrukcja1;} Atrybuty ulotności –volatile zmienna nie może być if(warunek){instrukcja1;} przechowywana w rejestrze/zmienna może zmieniać wartość nie tylko w wyniku działania programu, ale również else{instrukcja2;} na skutek operacji wykonywanych przez inne elementy if(i>0) a=2; systemu volatile double b; if(i>0) a=2; Specyfikator typedef if(i==0 || i<0) a=0; deklaracja typu /zastąpienie nazw standardowych typów else a=0; własnymi oraz uproszczenie złożonych deklaracji, Zagnieżdżanie typedf unsigned int if(warunek_1) liczba; *Wybór wielowariantowy liczba licz { 1=102. if(warunek_1){instrukcja1;} Operator i wyrażenia/ wyrażeniem jest ciągiem operatów i if(warunek_2) znaków przestankowych określających sposób wykonania else if(warunek_2){instrukcja2;} danego obliczenia. PRIORYTET OPERATÓW: stanowi o { kolejności wykonania działań określonych przez else if(warunek_3){instrukcja3;} poszczególne operatory/WIĄZANIE: sposób łączenia } operatora z operandami/ OPERATOR UNARNY: o. else{ } jednoargumentowy- jest wiązany tylko z jednym } operandem, np. ++a; /OPERATOR BINARNY: o. else{ dwuargumentowy- jest wiązany z dwoma operandami, np.: } a=b+c; I-WARTOŚĆ: wyrażenie identyfikujące obszar Instrukcja switch / Podejmowanie pamięci(zmienną)MODYFIKOWANA I WARTOŚĆ: w. i. o. p., wielowariantowych decyzji / typ całkowity/ którego wartość może być zmienna. Cost double e= ….- switch(zmienna) wartosc niemodyfikowalna. {case w_1: operacja odniesienia może być po prawej stronie operatora //polecenie "=" break; wa= *wskaznik; case w_2: lub po lewej stronie operatora //polecenie *wskaźnik=28; Break; /kończy wykonywanie instrukcji switch/nie jest l-wartość (l-value) –wyrażenie, które może stać po lewej obowiązkowy- brak powoduje wykonanie kolejnych instrukcji case/ stronie operatora przypisania //... r-wartość (r-value) –wyrażenie, które może stać po prawej case w_n: stronie operatora przypisania //polecenie l-wartość jest też r-wartością, ale nie odwrotnie break; Przykłady default: /gdy wartość wyrażenia warunkowego ni zgadza się z żadną z wartości podanych przy etykietach j=28; case wykonywane są instrukcje po etykiecie default / Brak etykiety 28=j;28 nie może być l-wartością powoduje opuszczenie instrukcji switch i wykonywanie kolejnych instrukcji Jeśli wskaźnik wpokazuje na zmienną zto zapisy po switch/ z=28; i *w=28; //polecenie intk; break;} k=z; k=*w; Instrukcja for są równoważne for (wyrażenie-inicjujące; wyrażenie-warunkowe; Goto: goto etykieta; etykieta –nazwa, po której występuje wyrażenie-zwiększjące) dwukropek instrukcja Instrukcja umożliwia wykonanie operacji opuszczenia kilku int i; poziomów pętli naraz.Stosować tylko w uzasadnionych i double suma=0; wyjątkowych przypadkach !!! for( i= 1; i <= 10; i++ ){ FUNKCJE suma= suma+i; /*Powtarzane instrukcje */ Składnia funkcji } <typ> identyfikator-funkcji (lista-deklaracji-parametrów) Np. Obliczenie potęgi liczby a do n { Double potega (double a, double n) { deklaracja } { { instrukcja } Unsigned i; } Double wynik=1; Deklaracja funkcji Prototypy for (i=0;i<n;++i) Deklaracja funkcji –stanowi deklarację dla kompilatora, że { funkcja o określonej nazwie, typie wartości oraz wynik*=a; /* wynik=wynik*a */ parametrów może zostać użyta w danym module } programu. return wynik; <typ>identyfikator-funkcji (lista-deklaracji-parametrów); } np. Instrukcja while voidfun1 (void); /* bezparametrowa funkcja bez zwracania while(wyrażenie warunkowe) instrukcja; wartości*/ int n=0; fun2 (int); /* funkcja o wartościach typy int–jeżeli typ nie while(n<9){ jest zdefiniowany to domyślnie int*/ n=n+1; doublefun3 (doubledb1, doubledb2); /* funkcja o /* powtarzane polecenia …*/ parametrach i wartości typu double*/ }; Instrukcja jest wykonywana do Deklaracja funkcji momentu, kiedy wyrażenie warunkowe osiągnie wartość 0 Prototypy (fałsz) Typ określa wartość funkcji -dozwolone są wszystkie typy z wyjątkiem tablic i funkcji. Instrukcja do … while Lista deklaracji parametrów składa się z nazw typów parametrów. do Identyfikatory parametrów mogą wystąpić opcjonalnie. instrukcja Dopuszczalne jest użycie specyfikatorów dla : while(wyrażenie-warunkowe); const–używany do zagwarantowania niezmienności zmiennych int n=0; wskazywanych danym parametrem do { intstr_length(constchar*C); n=n+1; */powtarzane polecenia …*/ register i volatile–zastosowanie jak w deklaracji zmiennych } while(n<9); Zastosowanie prototypów: Instrukcja jest wykonywana do momentu, gdy wyrażenie- •dokumentowanie kodu programu lub biblioteki (np. zbiory nagłówkowe bibliotek standardowych), warunkowe osiągnie wartość zero (fałsz). Instrukcja stosowana zamiast while, gdy konieczne jest •kontroli poprawności wywołań funkcji. wykonanie chociaż jednej iteracji. Definicja funkcji Definicja funkcji –określa działanie. Stanowi zapis algorytmu lub Instrukcje sterujące przebiegiem programu break(Użycie jego części. jest dopuszczalne w instrukcjach for, while, do ..while, Elementy definicji funkcji: switch.) typ wartości funkcji (z wyłączeniem funkcji i tablic) –reguły Jeżeli instrukcję break stosujemy w zagnieżdżonych pętlach, identyczne, co w przypadku deklaracji funkcji. Dozwolony jest to instrukcja break powoduje przerwanie tylko jej pętli, w wskaźnik funkcji oraz specyfikator void, który umożliwia której bezpośrednio się znajduje. definiowanie funkcji nie zwracających wartości. identyfikator Continue Instrukcja używana tylko wewnątrz instrukcji (nazwy) funkcji –stosowane są zasady obowiązujące przy iteracyjnych: identyfikatorach zmiennych. W języku C nazwy funkcji nie mogą •whilei do … while–przeniesienie sterowania z wnętrza pętli się powtarzać w obrębie danego modułu. lista deklaracji parametrów –deklaracja parametrów rozdzielonych przecinkami do wyrażenia warunkowego, które zostaje obliczone, analogicznie do deklaracji zmiennej. Lista deklaracji może być •for–przeniesienie sterowania do wyrażenia zwiększającego pusta dla funkcji bezparametrowej. Zaleca się jednak używanie liczniki pętli, słowa kluczowego void. ciało funkcji zbudowane jest z instrukcji •przy wielokrotnym zagnieżdżeniu pętli instrukcja jest ujętych w nawiasy klamrowe. wiązana z najbliższą instrukcją iteracyjną. unsignedi=0; Definicja funkcji while ( i<=5) Definicja funkcji –określa działanie. Stanowi zapis algorytmu lub { jego części. i++; Elementy definicji funkcji: if ( x<3) typ wartości funkcji (z wyłączeniem funkcji i tablic) –reguły continue; identyczne, co w przypadku deklaracji funkcji. Dozwolony jest doubley=y+x; wskaźnik funkcji oraz specyfikator void, który umożliwia } definiowanie funkcji nie zwracających wartości, identyfikator (nazwy) funkcji –stosowane są zasady obowiązujące przy void *-wskaźnikowy typ danych reprezentujący czyste identyfikatorach zmiennych. W języku C nazwy funkcji nie mogą adresy. się powtarzać w obrębie danego modułu, lista deklaracji Wskaźniki mogą być argumentami funkcji–przekazywanie parametrów –deklaracja parametrów rozdzielonych przecinkami argumentów przez wskaźnik. analogicznie do deklaracji zmiennej. Lista deklaracji może być Tablica to ciąg obiektów tego samego typu pusta dla funkcji bezparametrowej. Zaleca się jednak używanie słowa kluczowego void, ciało funkcji zbudowane jest z instrukcji int tablica[5]; /*deklaracja tablicy*/ ujętych w nawiasy tablica[0]=4; numeracja elementów tablicy zaczyna się od klamrowe. zera Wskaźniki–zmienne zawierające adresy innych zmiennych. tablica[1]=2; Jeżeli w jest wskaźnikiem to *w oznacza referencje do …… zmiennej, której adres jest wartością w (zmienna pod tablica[4]=56; adresem w). Jeżeli w jest wskaźnikiem, to *w może Nazwa tablicy reprezentuje położenie jej początkowego zastępować nazwę zmiennej: *po lewej stronie operatorów (zerowego) elementu./Nazwa tablicy jest wskaźnikiem na ten element./Nazwa tablicy jest jednocześnie adresem zerowego jej przypisania i modyfikacji. Wskaźnikom przypisywane są elementu. typy danych, na które wskazują, ale mają jednakowe Tablica +4 –element 4 rozmiary. Tablica [4] -element 4 int *w –definicja wskaźnika wskazującego na obiekty typu &Tablica[4] –adres elementu 4 int Znak & (ampersand) operator oznaczający uzyskiwanie adresu *w–zmienna typu określonego przez typ danych danego obiektu. zdefiniowanego wskaźnika w znajdującego się pod adresem *Tablica = 2; /* wprowadzenie wartości elementu 0 */ w *(Tablica+4) = 3; /* wprowadzenie wartości elementu 4 */ double* wd –definicja wskaźnika wskazującego na obiekty Elementy tablicy mogą być wskazywane przez zmienne wskaźnikowe. typu double. int *wt; /* wt jest wskaźnikiem do obiektu typu int */ Int liczba; // definicja zmiennej wt = Tablica; /* wt wskazuje na na 0 element */ int*w1;//definicja wskaźnika wt = &Tablica[0]; /* równoważne powyższemu */ w1=&liczba;// ustawienie wskaźnika w1, aby pokazywał na int V; obiekt liczba; V = *wt; /* wartość Tablica[0] zostaje skopiowana do V */ int*w1 = &liczba; V = *(wt+1)/* wartość Tablica[1] zostaje skopiowana do V */ *w1=23; //podstawienie wartości V = *(++wt) /* wartość Tablica[1] zostaje skopiowana do V, wt inta=*w1; //podstawienie wartości do innej zmiennej typu pokazuje na Tablica[1] */ integer Wskaźnik nie pokazuje raz na zawsze na ten sam obiekt Do obiektu można od nosić się na dwa sposoby: •przez jego nazwę, •przez wskaźnik, który na ten obiekt pokaże. Np. int*d; … Błąd –brak ustawienia wskaźnika na zmienną *d=34; Int b; Int c; int*d=&b; *d=20 -*d; d=20 -*d; *&b=24; Wskaźnik służący do pokazywania na obiekty jednego typu nie nadaje się do pokazywania na obiekty innego typu. int *w_int1; int *w_int2; double *w_double; w_int1=w_int2; Inicjacja zmiennych typów int i long w_double=w_int1; //błąd Stałe dziesiętne int a= 100; unsigned k = 121; Operator rzutowania / reinterpret_cast UWAGA: int j= 010; wartość dziesiętna zmiennej j wyniesie 8 cyfra w_double=(double*)w_int1; //stary styl 0 na początku oznacza zapis w systemie ósemkowym, k=0 wartość Wskaźnik typu void -Wskaźnik to adres miejsca w pamięci + dziesiętna k wyniesie 0. wiedza o typie obiektu, na który wskazuje Stałe ósemkowe ; int m= 012357; inicjacja wartości ósemkowej void *w_void; 123457(cyfry z zakresu 0-7) int l=0123578; cyfra poza zakresem int * w_int; przedziału (0-7) double * w_d; w_void=w_d; //przypisanie do wskaźnika w_void bez rzutowania w_void=w_int; //przypisanie do wskaźnika w_void bez rzutowania