Wprowadzenie do programowania w języku C



Podobne dokumenty
Podstawy programowania w języku C i C++

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

Podstawy programowania w języku C++

/* dołączenie pliku nagłówkowego zawierającego deklaracje symboli dla wykorzystywanego mikrokontrolera */ #include <aduc834.h>

Dr inż. Grażyna KRUPIŃSKA. D-10 pokój 227 WYKŁAD 7 WSTĘP DO INFORMATYKI

Podstawy programowania w języku C++

Instrukcja do ćwiczeń nr 4 typy i rodzaje zmiennych w języku C dla AVR, oraz ich deklarowanie, oraz podstawowe operatory

Języki i metodyka programowania. Typy, operatory, wyrażenia. Wejście i wyjście.

2 Przygotował: mgr inż. Maciej Lasota

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

Programowanie strukturalne i obiektowe

Wprowadzenie do programowania w języku C

1. Brian W. Kernighan, Dennis M. Ritchie, Język ANSI C, WNT, Warszawa 1998.

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

Programowanie strukturalne język C - wprowadzenie

Program w C. wer. 10 z drobnymi modyfikacjami! Wojciech Myszka :28:

Programowanie w C++ Wykład 2. Katarzyna Grzelak. 4 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 44

Podstawy programowania w języku C++

Podstawy programowania. Wykład Co jeszcze... Przypomnienia, uzupełnienia. Krzysztof Banaś Podstawy programowania 1

Język ludzki kod maszynowy

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

1 Podstawy c++ w pigułce.

Zmienne, stałe i operatory

Powtórka algorytmów. Wprowadzenie do języka Java.

Operatory. Operatory bitowe i uzupełnienie informacji o pozostałych operatorach. Programowanie Proceduralne 1

Program w C. wer. 12 z drobnymi modyfikacjami! Wojciech Myszka :59:

Temat 1: Podstawowe pojęcia: program, kompilacja, kod

Programowanie C++ Wykład 2 - podstawy języka C++ dr inż. Jakub Możaryn. Warszawa, Instytut Automatyki i Robotyki

Wykład 15. Literatura. Kompilatory. Elementarne różnice. Preprocesor. Słowa kluczowe

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

Podstawy programowania

Język C zajęcia nr 11. Funkcje

Języki programowania - podstawy

Jak napisać program obliczający pola powierzchni różnych figur płaskich?

Proste typy zmiennych języka C++ *) Zapis 3.4 e-38 jest równoważny zapisowi 3,

Powtórka algorytmów. Wprowadzenie do języka Java.

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

Podstawy Programowania Podstawowa składnia języka C++

Wstęp do programowania

Podstawy programowania w języku C++

Programowanie strukturalne. Opis ogólny programu w Turbo Pascalu

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

Typy złożone. Struktury, pola bitowe i unie. Programowanie Proceduralne 1

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 języka C++ Marek Pudełko

Podstawy programowania w języku C

Informatyka I. Typy danych. Operacje arytmetyczne. Konwersje typów. Zmienne. Wczytywanie danych z klawiatury. dr hab. inż. Andrzej Czerepicki

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

Na ekranie monitora zostaną wyświetlone w dwu liniach teksty Pierwsza linia Druga linia

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

Powtórka algorytmów. Wprowadzenie do języka Java.

1 Podstawy c++ w pigułce.

Podstawy programowania

Informatyka, Ćwiczenie Uruchomienie Microsoft Visual C++ Politechnika Rzeszowska, Wojciech Szydełko. I. ZałoŜenie nowego projektu

Podstawy programowania w języku C++

Zadanie 04 Ktory z ponizszych typow danych w jezyku ANSI C jest typem zmiennoprzecinkowym pojedynczej precyzji?

Podstawy i języki programowania

Programowanie w C++ Wykład 2. Katarzyna Grzelak. 5 marca K.Grzelak (Wykład 1) Programowanie w C++ 1 / 41

Języki C i C++ Wykład: 2. Wstęp Instrukcje sterujące. dr Artur Bartoszewski - Języki C i C++, sem. 1I- WYKŁAD

MATERIAŁY DO ZAJĘĆ II

Wprowadzenie do programowania w języku C

Języki i metody programowania. Omówienie języków C, C++ i Java

4 Standardy reprezentacji znaków. 5 Przechowywanie danych w pamięci. 6 Literatura

1. Wprowadzanie danych z klawiatury funkcja scanf

Programowanie obiektowe

Ogólny schemat prostego formularza: A może lepiej zamiast przycisku opartego o input tak:

Języki i paradygmaty programowania

OPERACJE WEJŚCIA / WYJŚCIA. wysyła sformatowane dane do standardowego strumienia wyjściowego (stdout)

ARCHITEKTURA SYSTEMÓW KOMPUTEROWYCH

Laboratorium Podstaw Informatyki. Kierunek Elektrotechnika. Ćwiczenie 1. Podstawy. Wprowadzenie do programowania w języku C. Katedra Metrologii AGH

Odczyt danych z klawiatury Operatory w Javie

Algorytmy i struktury danych. wykład 1

Materiały pomocnicze do wykładu 3 - Elementy języka Java

Podstawy programowania. Wykład 2 Zmienne i obsługa wejścia/wyjścia. Krzysztof Banaś Podstawy programowania 1

Pascal typy danych. Typy pascalowe. Zmienna i typ. Podział typów danych:

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

Strona główna. Strona tytułowa. Programowanie. Spis treści. Sobera Jolanta Strona 1 z 26. Powrót. Full Screen. Zamknij.

( wykł. dr Marek Piasecki )

Microsoft IT Academy kurs programowania

Tablice deklaracja, reprezentacja wewnętrzna

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

Język C - podstawowe informacje

Bardzo szybkie podsumowanie: wykład 1 wer. 6 z drobnymi modyfikacjami!

Podstawy programowania

Operacje wykonywane są na operandach (argumentach operatorów). Przy operacji dodawania: argumentami operatora dodawania + są dwa operandy 2 i 5.

Typ użyty w deklaracji zmiennej decyduje o rodzaju informacji, a nazwa zmiennej symbolicznie opisuje wartość.

1 P roste e t ypy p d a d n a ych c - c ąg ą g d a d l a szy 2 T y T py p z ł z o ł żo ż ne e d a d n a ych c : T BLICE

Podstawy Programowania C++

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

Wstęp do informatyki- wykład 4 Deklaracja zmiennych Typy

Podstawy programowania w języku C++

Laboratorium 03: Podstawowe konstrukcje w języku Java [2h]

WPROWADZENIE DO JĘZYKA C++

Wstęp do programowania 1

Różności w C++ Marek Pudełko

Podstawy programowania w języku C++

dr inż. Jarosław Forenc

Wykład 1. Proponowany termin kolokwium zaliczeniowego ostatni wykład w semestrze letnim

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

Transkrypt:

Wprowadzenie do programowania w języku C Część czwarta Autor Roman Simiński Kontakt siminski@us.edu.pl www.us.edu.pl/~siminski Niniejsze opracowanie zawiera skrót treści wykładu, lektura tych materiałów nie zastąpi uważnego w nim uczestnictwa. Opracowanie to jest chronione prawem autorskim. Wykorzystywanie jakiegokolwiek fragmentu w celach innych niż nauka własna jest nielegalne. Dystrybuowanie tego opracowania lub jakiejkolwiek jego części oraz wykorzystywanie zarobkowe bez zgody autora jest zabronione.

Typy proste w języku C Typy proste w języku C dzielimy następująco: 1. Typy arytmetyczne: całkowite: char znakowy, int całkowity, wyliczeniowe; zmiennopozycyjne: float pojedyncza precyzja, double podwójna precyzja. 2. Typ void. 3. Typy wskaźnikowe. Copyright Roman Simiński Strona : 2

Typy proste w języku C Typ znakowy char Zmienne zadeklarowane jako znakowe char są dostatecznie duże aby pomieścić dowolny element zbioru znaków dla danej maszyny bądź systemu operacyjnego. Wartość zmiennej znakowej to liczba całkowita równa kodowi danego znaku. Zmienna typu char jest zatem krótką liczbą całkowitą i tak może być traktowana, można zmiennych tego typu używać w wyrażeniach. char c = 'A'; /* Stała 'A' ma wartość kodu litery A, w ASCII to 65 */ char d; d = c + 1; putchar( c ); /* Wyprowadza liter ę A */ putchar( d ); /* Wyprowadza liter ę B */ Pascal owe kombinacje z typem Char nie są w C potrzebne! Ord( A ) 65 Chr( 65 ) A Copyright Roman Simiński Strona : 3

Typy proste w języku C Typ znakowy char, cd.... Zwyczajowo dane typu char reprezentowany jest na jednym bajcie i służą do reprezentowania znaków kodowanych wg. ASCII. Do przechowywania kodów znaków wg. kodowania międzynarodowego wykorzystuje się typ wchar_t. Uporządkowanie liter i cyfr w kodzie ASCII Znak: spójne obszary kodowe Cyfry Duże litery Małe litery... 0 1... 9... A B... Z... a b... z........................ Kod: 0 48 49 57 65 66 90 97 98 122 255 Mimo możliwości wykorzystania typu char do realizacji obliczeń arytmetycznych na małych wartościach, zwyczajowo wykorzystuje się do tego typ int, co jest naturalniejsze i niejednokrotnie... szybsze! Copyright Roman Simiński Strona : 4

Typy proste w języku C Typ całkowity int Zmienne typu całkowitego int mają zwykle naturalny rozmiar wynikający z architektury maszyny lub środowiska systemowego. Zwykle w środowiskach 16-bitowych rozmiar danej typu int to dwa bajty, w środowiskach 32-bitowych to 4 bajty. Typy zmiennopozycyjne float i double Standard nie określa wewnętrznej reprezentacji danych zmiennopozycyjnych, zwykle implementacje są zgodne z formatem IEEE dotyczącym takich liczb. Typ void float to typ przeznaczony do reprezentowania liczb rzeczywistych pojedynczej precyzji. double to typ przeznaczony jest do reprezentowania liczb rzeczywistych w podwójnej precyzji. Wystąpienie typu void w deklaracji oznacza brak wartości. W zależności od kontekstu interpretacja zapisu void może się nieznacznie zmieniać, zawsze jednak jest to sygnał, że w danym miejscu nie przewiduje się wystąpienia żadnej konkretnej wartości lub konkretnego typu. Copyright Roman Simiński Strona : 5

Typy proste w języku C Typ void,cd.... Wystąpienie typu void w deklaracji oznacza brak wartości. W zależności od kontekstu interpretacja zapisu void może się nieznacznie zmieniać, zawsze jednak jest to sygnał, że w danym miejscu nie przewiduje się wystąpienia żadnej konkretnej wartości lub konkretnego typu. Funkcja bezparametrowa: int func( void ); Funkcja nie udostępniająca rezultatu: void fun( int i ); Bezparametrowa funkcja, nie udostępniająca rezultatu: void fun( void ); Rzutowanie rezultatu funkcji na typ void rezultat funkcji jest nieistotny ( void )sin( 0 ); /* Mało sensowne ale to przykład */ ( void )getchar(); /* Znacznie częściej wykorzystywane */ Copyright Roman Simiński Strona : 6

Typy proste w języku C Typy pochodne typów całkowitych modyfikatory unsigned i signed Modyfikatory signed i unsigned mogą być stosowane do typów char i int. Zmieniają one sposób traktowania najstarszego bitu liczby. Modyfikatory pozwalają na tworzenie specyfikacji typów pochodnych: unsigned int typ całkowity służący do reprezentacji liczb całkowitych bez znaku. Najstarszy bit liczby jest uznawany za jeden z bitów wartości. signed int - typ całkowity służący do reprezentacji liczb całkowitych ze znakiem. Najstarszy bit liczby jest bitem przechowującym informację o znaku liczby, nie wchodzi do bitów wartości. unsigned char i signed char analogicznie jak dla typu int. Copyright Roman Simiński Strona : 7

Typy proste w języku C Signed, unsigned o co chodzi? Liczba 8-mio bitowa ze znakiem 7 6 5 4 3 2 1 0 Bit znaku Bity określające wartość liczby Liczba 8-mio bitowa bez znaku 7 6 5 4 3 2 1 0 Bity określające wartość liczby -1 Jako liczba ze znakiem 255 Jako liczba bez znaku Copyright Roman Simiński Strona : 8

Typy proste w języku C Signed, unsigned ważne, nieważne? Ten sam układ bitów, różna interpretacja: signed char sc = 0xff; unsigned char uc = 0xff; printf( "%d %d", sc, uc ); -1 255 Zapis szesnastkowy: ffh Czym grozi nieznajomość zagadnienia signed a unsigned? char counter = 0; /* Zmienn ą char jako krótka liczba całkowita */ do {... counter = counter + 1; } while( counter < 150 ); Wszystko OK? int counter = 0; /* Teraz zmienna int, niech sizeof(int) == 2 */ do {... counter = counter + 1; } while( counter < 50000 ); Wszystko OK? Copyright Roman Simiński Strona : 9

Typy proste w języku C Typy char i int domyślnie signed czy unsigned? Jak sprawdzić czy domyślenie typ char jest signed czy unsigned? Zajrzeć do dokumentacja albo do systemu pomocy, lub napisać, skompilować i uruchomić program: #include <stdio.h> #include <stdlib.h> int main() { char c = 0xff; printf( "W tej implementacji języka C typ char jest domyślnie " ) if( c < 0 ) printf( "signed" ); else printf( "unsigned" ); } return EXIT_SUCCESS; Domyślnie typ int traktowany jest jako typ całkowity ze znakiem. Domyślne traktowanie typu char zależy od implementacji. Copyright Roman Simiński Strona : 10

Typy proste w języku C Typy pochodne typów całkowitych modyfikatory short i long a typ int Modyfikatory short i long mogą być stosowane do typu int. Modyfikator short sygnalizuje chęć skrócenia danej w stosunku do rozmiaru typu int. Modyfikator long sygnalizuje chęć posłużenia się daną dłuższą w stosunku do rozmiaru typu int short int typ całkowity służący do reprezentowania liczb o potencjalnie krótszej reprezentacji wewnętrznej niż typ int, zatem potencjalnie o mniejszym zakresie wartości. long int to typ całkowity służący do reprezentowania liczb o potencjalnie dłuższej reprezentacji wewnętrznej niż typ int, zatem potencjalnie o większym zakresie wartości. Copyright Roman Simiński Strona : 11

Typy proste w języku C Jak jest naprawdę z tymi długościami różnych typów całkowitych? Standard ANSI zakłada, że int oraz short int są co najmniej 16-to bitowe, long int jest co najmniej 32-bitowy. Dodatkowo mówi się, że: sizeof( char ) <= sizeof( short int ) <= sizeof( int ) <= sizeof( long int ) Modyfikatory short i long wprowadzono po to, by umożliwić posługiwanie się różnymi zakresami liczb całkowitych tam, gdzie programiście może się to przydać Najczęstsze zastosowania modyfikatorów unsigned char traktowany jest jak odpowiednik typu byte, unsigned short int traktowany jest odpowiednik typu word. Copyright Roman Simiński Strona : 12

Typy proste w języku C Programista może definiować własne synonimy typów typedef unsigned char typedef unsigned short int typedef unsigned long int byte; word; counter_t; Specyfikacja typedef przypisuje symboliczną nazwę <identyfikator> do istniejącej wcześniej definicji typu <definicja_typu>. typedef <definicja typu> <identyfikator>; Modyfikatory short i long a typy zmiennopozycyjne Można stosować modyfikatory short i long z typami float i double, jednak tylko kombinacja long double ma sens. Typ double naturalnie rozszerza typ float zatem zapis long float to po prostu przestarzały synonim typu double. Z kolei typu double nie można skrócić, zatem specyfikacja short double nie ma sensu. Nie można również skrócić typu float, zatem specyfikacja short float nie ma sensu. Copyright Roman Simiński Strona : 13

Typy proste w języku C Typy wyliczeniowe Typy wyliczeniowe nie występowały we wczesnych implementacjach języka C. W tych implementacjach brakowało sposobu przedstawienia uporządkowanej listy takich elementów, które można przedstawić jedynie nazwami. Przykładem mogą być np. dni tygodnia, miesiące, kolory. Typ wyliczeniowy to tak na prawdę, lista nazwanych stałych całkowitych. enum RGB_colors { RED, GREEN, BLUE }; enum boolean { FALSE, TRUE }; Copyright Roman Simiński Strona : 14

Typy proste w języku C Typy wyliczeniowe, cd.... Stałe wyliczeniowe, są typu int, mogą wystąpić w każdym miejscu dozwolonym dla danej całkowitej. Identyfikatory stałych wyliczeniowych powinny być unikatowe w ramach danego wyliczenia. Każda stała wyliczeniowa ma swoją wartość całkowitą. Pierwsza stała na liście otrzymuje wartość 0, następna 1 itd. Każda stała występująca w wyliczeniu może posiadać swój inicjalizator, przypisujący mu wartość (również ujemną) wyznaczoną przez programistę. Każdy element wyliczenia nie posiadający inicjalizatora otrzymuje wartość o jeden większą od swojego poprzednika na liście enum months { JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEPT, OCT, NOV, DEC }; Copyright Roman Simiński Strona : 15

Typy proste w języku C Typy wyliczeniowe, przykład zastosowania enum months { JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEPT, OCT, NOV, DEC }; void wypisz_nazwe_miesiaca( int kod ) { switch( kod ) { case JAN : printf( "Stycze ń" ); break; case FEB : printf( "Luty" ); break; case MAR : printf( "Marzec" ); break;...... default : printf( "Błedny kod miesiaca" ); break; } }... wypisz_nazwe_miesiaca( FEB ); Copyright Roman Simiński Strona : 16

Typy proste w języku C Typy wyliczeniowe a stałe symboliczne enum ctrl_key_codes { UP = 0x48, DOWN = 0x50, LEFT = 0x4b, RIGHT = 0x4d, DEL = 0x53, INS = 0x52, HOME = 0x47, END = 0x4f, PGUP = 0x49, PGDN = 0x51 }; enum boolean { FALSE, TRUE };? #define UP 0x48 #define DOWN 0x50 #define LEFT 0x4b #define RIGHT 0x4d #define DEL 0x53 #define INS 0x52 #define HOME 0x47 #define END 0x4f #define PGUP 0x49 #define PGDN 0x51 #define FALSE 0 #define TRUE 1 lub #define TRUE (0==0) #define FALSE (!TRUE) Copyright Roman Simiński Strona : 17

Typy proste w języku C Przegląd typów wybranej implementacji Borland C++ 5.x Typ unsigned char 16-bitowa Architektura 32-bitowa 8 0 do 255 8 0 do 255 char 8-128 do 127 8-128 do 127 enum 16-32,768 do 32,767 32-2,147,483,648 do 2,147,483,647 unsigned int 16 0 do 65,535 32 0 do 4,294,967,295 short int 16 int 16 unsigned long 32 long 32 float 32 double 64 long double 80-32,768 do 16 32,767-32,768 do 32 32,767 0 do 32 4,294,967,295-2,147,483,648 do 32 2,147,483,647 3.4 x 10-38 do 32 3.4 x 10 38 1.7 x 10-308 do 64 1.7 x 10 308 3.4 x 10-4932 do 80 1.1 x 10 4932-32,768 do 32,767-2,147,483,648 do 2,147,483,647 0 do 4,294,967,295-2,147,483,648 do 2,147,483,647 3.4 x 10-38 do 3.4 x 10 38 1.7 x 10-308 do 1.7 x 10 308 Przykładowe zastosowania Małe liczby, pełny zakres znaków IBM PC Bardzo małe liczby zakres kodów ASCII Uporządkowane zbiory wartości Większe liczby całkowite, liczniki Mniejsze liczby całkowite, liczniki Typowe liczby całkowite, liczniki Bardzo duże liczby całkowite Duże liczby całkowite Obliczenia naukowe, pojedyncza precyzja (7 cyfr) Obliczenia naukowe, podwójna precyzja (15 cyfr) 3.4 x 10-4932 Obliczenia wysokiej do 1.1 x 10 4932 precyzji, (18 cyfr) Copyright Roman Simiński Strona : 18

Jednostki leksykalne czyli z czego składa się program nudna lecz konieczna dygresja Komentarze Komentarze to fragmenty tekstu spełniające funkcje dowolnych objaśnień robionych przez programistów dla programistów. Nie mogą występować w napisach i stałych znakowych. Komentarze są usuwane z tekstu źródłowego programu. /* To jest komentarz jednoliniowy */ /* Ten komentarz obejmuje kilka linii kodu */ Standard ANSI C nie dopuszcza komentarzy zagnieżdżonych, choć niektóre kompilatory na to zezwalają. /* Ten komentarz obejmuje niedozwolony w ANSI C /* komentarz zagnieżdżony */ powodujący błąd syntaktyczny */ Copyright Roman Simiński Strona : 19

Jednostki leksykalne czyli z czego składa się program nudna lecz konieczna dygresja Komentarze, cd.... Uwaga komentarze nie znikają z kodu bez śladu. Według ANSI C, każdy komentarz zastępowany jest znakiem spacji. Zatem poniższa kombinacja nie jest poprawna syntaktycznie: int licz/* licznik wystąpie ń */nik; Komentarze w języku C++ W języku C++ można używać komentarzy takich jak w C oraz komentarzy jednoliniowych, rozpoczynających się od pary // i rozciągających się aż do końca linii. int licznik; // Ta zmienna będzie licznikiem wystąpie ń wzorca Komentowanie znaczenia zmiennych Głupie komentarze, które w niczym nie pomagają: int counter; /* Ta zmienna będzie licznikiem */ float paliwo; /* Zmienna rzeczywista o nazwie paliwo */ int i, j; /* Zmienne indeksowe tablicy*/ Te są wyraźnie lepsze: int counter; /* Licznik tych linii pliku, które zawieraj ą wzorzec */ float paliwo; /* Zmienna przechowuje ilość paliwa zużytego przez pojazd */ float delta; /* Delta wyróżnik trójmianu kwadratowego */ Copyright Roman Simiński Strona : 20

Jednostki leksykalne czyli z czego składa się program nudna lecz konieczna dygresja Komentarze opisujące funkcje przykład mocno rozbudowanej wersji: /*------------------------------------------------------------------------- Funkcja: float oblicz_delte( float a, float b, float c ) Przeznaczenie i opis działania: Wykorzystywana w wyznaczaniu miejsc zerowych trójmianu kwadratowego. Funkcja oblicza wyróżnik trójmianu kwadratowego w postaci: y = a * x^2 + b * x + c wg. wzoru: delta = b*b 4*a*c Funkcja wstawia wartość 1 do zmiennej globalnej brak_rozw_rzecz jeżeli wyróżnik ma wartośc ujemna, 0 w przeciwnym wypadku. Paramtery: a, b, c współczynniki trójmianu kwadratowego, jak opisano wyżej Rezultat: Wartość wyróżnika obliczona wg. wzoru jak wyżej Wejście: Paramtery Wyjście: Rezultat i zmienna globalna brak_rozw_rzecz Efekty uboczne: Modyfikacja zmiennej globalnej brak_rozw_rzecz -------------------------------------------------------------------------*/ float oblicz_delte( float a, float b, float c ) { float delta = b*b 4*a*c; if( delta < 0 ) brak_rozw_rzecz = 1; else brak_rozw_rzecz = 0; return delta; } Copyright Roman Simiński Strona : 21

Jednostki leksykalne czyli z czego składa się program nudna lecz konieczna dygresja Syntaktyka z czego zbudowany jest program?` W trakcie procesu kompilacji kod źródłowy dzielony jest na elementy zwane jednostkami leksykalnymi (ang. tokens). Rozróżnia się sześć klas jednostek leksykalnych: identyfikatory (ang. identifiers), słowa kluczowe (ang. keywords), stałe (ang. constants), napisy (ang. string-literals), operatory (ang. operators), separatory (ang. punctuators). Copyright Roman Simiński Strona : 22

Jednostki leksykalne czyli z czego składa się program nudna lecz konieczna dygresja Identyfikatory Identyfikator to ciąg liter, cyfr i znaków podkreślenia rozpoczynający się od litery, przy czym znak podkreślenia traktowany jest jako litera. Duże i małe litery są rozróżniane. Rozróżnia się 31, 32 pierwsze znaki, liczbę znaczących znaków można zwykle w poszczególnych implementacjach redukować. Uwaga polskie znaki nie są traktowane jako litery! Poprawne identyfikatory: J23, J_23, Pi, wartosc_maksymalna, WartoscMaksymalna, Wartosc_Maksymalna, _2Pi Niepoprawne identyfikatory: J 23, 007_James_Bond, 2Pi, wartosc maksymalna, Wartosc-Maksymalna, wartość_maksymalna Uwaga identyfikatory są arbitralnie wybranymi nazwami dla zmiennych, funkcji, definiowanych przez programistę typów danych itp.. Copyright Roman Simiński Strona : 23

Jednostki leksykalne czyli z czego składa się program nudna lecz konieczna dygresja Identyfikatory, cd.... Nie ma normatywnych zaleceń odnośnie konwencji pisania identyfikatorów. Tradycyjnie jednak, w programach pisanych w języku C (w C++ już niekoniecznie) nazwy zmiennych i funkcji pisze się małymi literami, czasem ze znakiem podkreślanie w identyfikatorach będących zlepkami. charcounter, getline, maxline lub char_counter, get_line, max_line Nazwy stałych symbolicznych zwyczajowo pisze się dużymi literami. Słowa kluczowe Słowa kluczowe to identyfikatory zastrzeżone i nie mogą być inaczej stosowane niż określa to standard języka. Słowa kluczowe winny być pisane tak jak je podano, a więc wyłącznie z wykorzystaniem małych liter. Słowa kluczowe wg. normy ANSI C: auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef while union unsigned void volatile Copyright Roman Simiński Strona : 24

Jednostki leksykalne czyli z czego składa się program nudna lecz konieczna dygresja Stałe Stała to jednostka leksykalna reprezentująca określoną wartość numeryczną lub znakową. Dokładniej wyróżnia się stałe: całkowitoliczbowe, znakowe, zmiennopozycyjne, wyliczeniowe. Stałe całkowitoliczbowe Stała całkowita może być zapisywana dziesiętnie, ósemkowo, szesnastkowo. Wszystkie stałe rozpoczynające się od zera traktowane są jako ósemkowe. Wszystkie stałe rozpoczynające się od przedrostka 0x lub 0X są traktowane jako szesnastkowe. int i = 10; /* Stała dziesiętna */ int o = 077; /* Stała ósemkowa */ int h = 0xff; /* Stała szesnastkowa */ Copyright Roman Simiński Strona : 25

Jednostki leksykalne czyli z czego składa się program nudna lecz konieczna dygresja Stałe całkowitoliczbowe, cd.... Dozwolone cyfry ósemkowe to: 0, 1, 2, 3, 4, 5, 6, 7 Dozwolone cyfry szesnastkowe to: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F Stała całkowitoliczbowa może być zakończona przyrostkiem u lub U co oznacza że liczba jest bez znaku (dokładniej najstarszy bit liczby jest częścią wartości). Stała całkowitoliczbowa może być zakończona przyrostkiem l lub L co oznacza że liczba jest długa. Typ stałej znakowej jest dobierany przez kompilator wśród pasujących typów całkowitych występujących w języku C. Wartość stałej całkowitoliczbowej nie może przekraczać zakresu typu liczba całkowita długa bez znaku (unsigned long int). Wartości większe są obcinane. Dla implementacji zakładającej 32-bitową długość liczby długiej bez znaku, wartość maksymalna wynosi odpowiednio: 4 294 967 295 dec 037777777777 oct 0xFFFFFFFF hex Copyright Roman Simiński Strona : 26

Jednostki leksykalne czyli z czego składa się program nudna lecz konieczna dygresja Stałe znakowe Stała znakowa jest ciągiem złożonym z jednego lub więcej znaków, zawartych w apostrofach. Wartością stałej znakowej zawierającej tylko jeden znak jest numeryczna wartość tego znaku w zbiorze znaków maszyny wykonującej program. Wartość stałej wieloznakowej jest zależna od implementacji. W języku C stała znakowa reprezentowana jest jako wartość typu całkowitoliczbowego int. W języku C++ stała znakowa reprezentowana jest przez wartość typu char, stała wieloznakowa natomiast przez wartość typu int. Przykład stałej jednoznakowej 'A' dla maszyn wykorzystujących kod ASCII stała ta reprezentuje wartość całkowitą odpowiadającą kodowi znaku, jest to wartość dziesiętna 65 Inne przykładowe stałe jednoznakowe: 'a' '#" '$' ',' '1' '+' '.' '&' 'C' Copyright Roman Simiński Strona : 27

Jednostki leksykalne czyli z czego składa się program nudna lecz konieczna dygresja Stałe znakowe specjalne Sekwencje specjalne pozwalają na reprezentowanie znaków nie posiadających swoich legalnych symboli graficznych. Dodatkowo sekwencje specjalne są wykorzystywane do zapisu pewnych niewygodnych stałych znakowych. Sekwencja Wartość Znak Znaczenie \a 0x07 BEL Audible bell \b 0x08 BS Backspace \f 0x0C FF Formfeed \n 0x0A LF Newline (linefeed) \r 0x0D CR Carriage return \t 0x09 HT Tab (horizontal) \v 0x0B VT Vertical tab \\ 0x5c \ Backslash \' 0x27 ' Apostrof \" 0x22 " Cudzysłów \? 0x3F? Pytajnik \O any O = łańcuch ósemkowych cyfr \xh any H = łańcuch szesnastkowych cyfr \XH any H = łańcuch szesnastkowych cyfr Copyright Roman Simiński Strona : 28

Jednostki leksykalne czyli z czego składa się program nudna lecz konieczna dygresja Stałe znakowe specjalne, cd.... Wyprowadzenie do strumienia wyjściowego znaku BELL: putchar( '\a' ); lub putchar( '\007' ); lub putchar( '\x07' ); Wyprowadzenie litery A, cofnięcie o jedną pozycję, nadpisanie litery B: putchar( 'A ' ); putchar( '\b' ); putchar( 'B' ); Rozszerzony zbiór znaków Rozszerzone zbiory znaków nie mogą być odwzorowywane przez typ char. Standard ANSI wprowadza typ całkowity wchar_t, jest to typ całkowity zdefiniowany w pliku nagłówkowym stddef.h. Stałe rozszerzonego zbioru znaków zapisuje się z prefixem L, np.: x = L'A'; /* Do x jest przypisana rozszerzona stała znakowa reprezentująca liter ę A */ Copyright Roman Simiński Strona : 29

Jednostki leksykalne czyli z czego składa się program nudna lecz konieczna dygresja Stałe zmienno pozycyjne Stałe zmiennopozycyjne składają się z: części całkowitej (ciąg cyfr), kropki dziesiętnej, części ułamkowej (ciąg cyfr), litery e lub E oraz opcjonalnego wykładnika potęgi ze znakiem, opcjonalnego przyrostka f lub F lub l lub L. Zapis Znaczenie 23.45e6 23.45 10 6.0 0 0. 0 1. 1-1.23-1.23 2e-5 2.0 10-5 3E+10 3.0 10 10.09E34 0.09 10 34 Można pominąć część całkowitą lub część ułamkową (lecz nie obie jednocześnie). Ogólnie mówiąc, notacja stałych zmiennopozycyjnych odpowiada regułom naukowego zapisu liczb w postaci zwykłej i wykładniczej. W przypadku braku przyrostków stałe zmiennopozycyjne są typu double. Dodając przyrostek f lub F można wymusić aby stała była typu float. Podobnie, dodając przyrostek l lub L wymusza się aby stała była typu long double. Copyright Roman Simiński Strona : 30

Jednostki leksykalne czyli z czego składa się program nudna lecz konieczna dygresja Stałe wyliczeniowe Stałe wyliczeniowe zdefiniowane w obrębie danego typu wyliczeniowego są symbolicznymi odpowiednikami pewnych wartości całkowitych typu int. Wartość odpowiadająca danej stałej symbolicznej wynika z deklaracji typu wyliczeniowego. enum months { JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEPT, OCT, NOV, DEC };... int m; /* Iteracja maszerująca po kolejnych miesiącach */ for( m = JAN; m <= DEC; m++ )... Deklarowanie zmiennych wyliczeniowych w języku C spotyka się sporadycznie, można tak: enum months m = MAY; Ale zwyczajowo pisze się tak: int m = MAY; Copyright Roman Simiński Strona : 31

Jednostki leksykalne czyli z czego składa się program nudna lecz konieczna dygresja Napisy Napisy zwane są inaczej literałami łańcuchowymi (ang. string literals) lub stałymi łańcuchowymi (ang. string constans). Napisem jest ciąg znaków ujętych w znaki cudzysłowu. W napisach można stosować znakowe sekwencje specjalne. Napisy są tablicami znakowymi o klasie pamięci static. Na końcu każdego napisu kompilator dopisuje znacznik końca napisu (NUL) oznaczany sekwencją \0. Zatem każdy napis w pamięci operacyjnej zajmuje tak faktycznie o jeden znak więcej. To jest napis a to jego reprezentacja wewnętrzna: T o j e s t n a p i s \0 Fizyczna długość napisu = liczba znaków + 1 Znacznik końca napisu \0 to znak o kodzie 0 Copyright Roman Simiński Strona : 32

Jednostki leksykalne czyli z czego składa się program nudna lecz konieczna dygresja Napisy Sąsiadujące ze sobą napisy są łączone w jeden napis. Zapis: puts( "Ala" " ma " "kota" ); odpowiada zapisowi: puts( "Ala ma kota" ); Napisy mogą zajmować więcej niż jedną linię ale muszą być jawnie łączone znakiem \ (backslash). puts( "Ala ma kota \ i ze dwa psy"); Podobnie jak w przypadku stałych znakowych, napisy złożone ze znaków rozszerzonych są poprzedzane przedrostkiem l lub L, każdy element takiego napisu jest wtedy znakiem typu wchar_t. Łączenie normalnych i rozszerzonych napisów nie jest zdefiniowane. Identyczne napisy występujące wielokrotnie w programie mogą być fizycznie reprezentowane tylko raz. Napis pusty zapisuje się w postaci dwóch, następujących po sobie cudzysłowów "". Copyright Roman Simiński Strona : 33

Jednostki leksykalne czyli z czego składa się program nudna lecz konieczna dygresja Wybrane separatory Nawiasy kwadratowe (ang. brackets) [ ] wykorzystywane są do deklarowania i odwoływania się do jedno i wielowymiarowych tablic. Nawiasy okrągłe (ang. parentheses) ( ) wykorzystywane są do grupowania wyrażeń, izolowania wyrażeń warunkowych, wskazują wywołanie funkcji i jej parametry. Nawiasy klamrowe (ang. braces) { } oznaczają początek i koniec instrukcji złożonej, zwanej również blokiem. Przecinek (ang. comma), rozdziela zwykle elementy na liście parametrów funkcji, występuje również w wyrażeniach przecinkowych. Średnik (ang. semicolon) ; jest znakiem kończącym instrukcję. Każde legalne wyrażenie w języku C (również wyrażenie puste) zakończone znakiem średnika jest interpretowane jako instrukcja wyrażeniowa. a + b; /* Być może nastąpi wartościowanie wyrażenia ale suma zostanie pominięta */ ; /* Instrukcja pusta, powstająca z zakończenia średnikiem wyrażenia pustego*/ Copyright Roman Simiński Strona : 34

Operatory i wyrażenia Operatory arytmetyczne Operatory arytmetyczne to +,, *, / oraz operator reszty z dzielenia modulo %. Operator % nie może być stosowany do liczb rzeczywistych. Uwaga dzielenie na operandach całkowitych daje wynik całkowity, ten kod: int x = 5, y = 2; float f = x/y; printf( Wynik dzielenia %d przez %d wynosi %f, x, y, f ); wyprodukuje: Aby otrzymać wynik rzeczywisty jeden z operandów musi być rzeczywisty, np: int x = 5, y = 2; float f = ( float )x/y; /* Rzutowanie czyni dzieln ą liczb ą rzeczywist ą */ Copyright Roman Simiński Strona : 35

Operatory i wyrażenia Operatory relacji i operatory logiczne Operatory relacji to >, >=, <, <=. Operatory porównania ==,!=. Operatory relacji mają wyższy priorytet niż operatory porównania. Operatory logiczne to && (and) oraz (or). Wyrażenia połączone tymi operatorami oblicza się od lewej do prawej, koniec obliczeń następuje natychmiast po określeniu wartości logicznej wyrażenia. Priorytet operatora && jest wyższy niż a oba są niższe niż operatorów relacji i porównania. dlatego poniższy warunek może być zapisany bez nawiasów: while( c >= A && c <= Z )... Przykład wykorzystania operatorów arytmetycznych, porównania i logicznych: if( ( year % 4 == 0 && year % 100!= 0 ) year % 400 == 0 ) printf( Rok %d jest rokiem przestępnym, ); else printf( Rok %d nie jest rokiem przestępnym, year ); Copyright Roman Simiński Strona : 36

Operatory i wyrażenia Operatory zwiększania ++ i zmniejszania Operatory ++ i zawsze powodują odpowiednio zwiększenie lub zmniejszenie wartości argumentu. Mogą one jednak występować jako przedrostki (ang. prefix) lub przyrostki (ang. postfix). Wersja przedrostkowa zwiększa (zmniejsza) wartość argumentu przed użyciem jego wartości. Wersja przyrostkowa zwiększa (zmniejsza) wartość argumentu po użyciem jego wartości. int a = 5, b; b = ++a; a == 6, b == 6 int a = 5, b; b = a++; a == 6, b == 5 Uwaga na operatory ++ i : i = ++i---i+++i+i--; i = ++i - --i + ++i + i--; Copyright Roman Simiński Strona : 37

Operatory i wyrażenia Operatory bitowe Operatory bitowe mogą być stosowane do argumentów typu całkowitego, są to: Operator Znaczenie & bitowa koniunkcja (and), bitowa alternatywa (or), ^ bitowa różnica symetryczna (xor), << przesunięcie w lewo, >> przesunięcie w prawo, ~ dopełnienie jedynkowe. int x = 5, y = 7, z; z = x & y; 0...0101 0...0111 0...0101 z == 5 z = x y; 0...0101 0...0111 0...0111 z == 7 z = x ^ y; 0...0101 0...0111 0...0010 z == 2 Copyright Roman Simiński Strona : 38

Operatory i wyrażenia Operatory bitowe, przykłady zastosowania Niech będzie zadeklarowana zmienna flag, o rozmiarze 1-go bajta: unsigned char flag = 0; Ustawianie pewnych bitów liczby: flag = flag 1; /* Ustawienie najmłodszego bitu liczby flag */ Zerowanie pewnych bitów liczby: flag = flag & ~1; /* Wyzerowanie najmłodszego bitu flag */ Testowanie czy pewne bity liczby są ustawione: if( flag & 1 ) /* Czy najmłodszy bit jest ustawiony? */... Copyright Roman Simiński Strona : 39

Operatory i wyrażenia Operatory bitowe, przesunięcia bitowe Przesunięcie o jeden bit w lewo: unsigned char flag = 1; /* 00000001 */ flag = flag << 1; /* 00000010 */ flag = flag << 1; /* 00000100 */ Przesunięcie o jeden bit w prawo: unsigned char flag = 128; /* 10000000 */ flag = flag >> 1; /* 01000000 */ flag = flag >> 1; /* 00100000 */ Uwaga na bit znaku: signed char flag = 128; /* 10000000 */ flag = flag >> 1; /* 11000000 */ flag = flag >> 1; /* 11100000 */ Copyright Roman Simiński Strona : 40

Operatory i wyrażenia Operatory bitowe, przesunięcia bitowe przykład wykorzystania Ile bitów ma liczba typu int w danej implementacji? Implementacja z wykorzystaniem iteracji while: int bits_per_int( void ) { int number = 1, counter = 0; } while( number!= 0 ) { number = number << 1; counter ++; } return counter; Implementacja z wykorzystaniem iteracji for: int bits_per_int( void ) { int number = 1, counter = 0; } for( ; number!= 0; counter++ ) number = number << 1; return counter; Copyright Roman Simiński Strona : 41

Operatory i wyrażenia Operatory przypisania Przypisanie wartości jest w języku C wyrażeniem a nie instrukcją. Operator przypisania = jest lewostronnie łączny, co umożliwia łączenie przypisań: int i = 5, j, k, l; j = k = l = i; ale również: j = ( k = ( l = ( i + 5 ) ) + 10 ) * 2; /* j == 40, k == 20, l == 10 */ Dla większości operatorów dwuargumentowych: + - * / % << >> * ^ & można wykorzystywać specjalne operatory przypisania, pozwalające skrócić zapis często wykorzystywanych konstrukcji, takich jak: Wersja z normalna i = i + 2 y = y * 2 x = x << 1 j = j * ( k + 1 ) flag = flag >> k; Wersja skrócona i += 2 y *= 2 x <<= 1 j *= k + 1 flag >>= k; Copyright Roman Simiński Strona : 42

Operatory i wyrażenia Operatory przypisania, cd.... Ogólnie, jeśli expr1 i expr2 to wyrażenia, a op to operator dwuargumentowy, zapis: expr1 = expr1 op expr2 można uprościć do postaci: expr1 op= expr2 Przykład zastosowania: int bits_per_int( void ) { int number = 1, counter = 0; for( ; number!= 0; counter++ ) number = number << 1; return counter; } int bits_per_int( void ) { int number = 1, counter = 0; for( ; number!= 0; counter++ ) number <<= 1; return counter; } int bits_per_int( void ) { int number = 1, counter = 0; for( ; number!= 0; number <<= 1, counter++ ) ; return counter; } Copyright Roman Simiński Strona : 43

Operatory i wyrażenia Optymalizacje... a może niepotrzebne komplikacje? int bits_per_int( void ) { int number = 1, counter = 0; for( ; number!= 0; counter++ ) number <<= 1; return counter; } int bits_per_int( void ) { int number = 1, counter = 0; for( ; number!= 0; number <<= 1, counter++ ) ; return counter; } int bits_per_int( void ) { int number = 1, counter = 0; for( ; ( number <<= 1 )!= 0; counter++ ) ; return counter + 1; } Copyright Roman Simiński Strona : 44

Operatory i wyrażenia Operator warunkowy Bardzo często spotyka się pewne symetryczne instrukcje warunkowe, np.: if( delta < 0 ) brak_rozw_rzecz = 1; else brak_rozw_rzecz = 0; if( a > b ) max = a; else max = b; Można je zapisać krócej, z wykorzystaniem operatora warunkowego: brak_rozw_rzecz = ( delta < 0 )? 1 : 0; max = ( a > b )? a : b; Chociaż: brak_rozw_rzecz = ( delta < 0 )? 1 : 0; brak_rozw_rzecz = ( delta < 0 ); Inny przykład komunikaty w wersji polskiej lub angielskiej: enum WERSJA_JEZYKOWA { POLSKI, ANGIELSKI }; int jezyk = POLSKI;... puts( ( jezyk == POLSKI )? Podaj wartość: : Input value: ); Copyright Roman Simiński Strona : 45