to get the file
Transkrypt
to get the file
Metodyka i Technika Programowania Laboratorium 2 Środowisko Code::Blocks Podstawy języka C Preprocesor języka C Opracował: mgr inż. Leszek Ciopiński Wstęp: Środowisko Code::Blocks Jest to zintegrowane środowisko programistyczne (IDE) przeznaczone na większość systemów operacyjnych (Windows, Linux, MacOS X). Służy do kompilowania programów napisanych w języku C/C++ przy użyciu kompilatora gcc. Środowisko to dostępne jest na licencji GNU GPL 3 (bez opłat). Podstawowym celem IDE jest ułatwienie programiście zarządzania plikami i procesem kompilowania programu. Pasek menu i narzędzi Menadżer projektu z listą plików Główne okno programu Okno komunikatów TiMP1 Instrukcja 2 1 Pierwszą czynnością jaką należy wykonać po włączeniu środowiska jest utworzenie nowego projektu. W tym celu należy wydać polecenie File | New | Project… . w nowo otwartym oknie należy wybrać szablon „Console application” i wybrać przycisk „GO”. W nowo otwartym oknie kreatora przechodzimy do następnego kroku przyciskiem „Next”. W odpowiedzi na prośbę wybrania języka wybieramy C i przechodzimy do następnego kroku. W przedstawionym powyżej oknie w pierwszym polu wpisujemy nazwę projektu, bez spacji i polskich znaków diakrytycznych (np. ą, ę). W polu „Folder to ...” wybieramy przycisk oznaczony „...” i wybieramy katalog w którym ma być umieszczony projekt. Proszę pamiętać, że studenci zapisują na komputerach swoje dane na dysku D lub E. Pozostałe dwa pola uzupełniane są automatycznie. Przechodzimy dalej przyciskiem „Next”. W bieżącym kroku wybieramy konfigurację domyślną i kończymy proces tworzenia projektu przyciskiem „Finish”. W menadżerze projektu dodany zostanie nowy projekt. Należy odszukać w nim plik „main.c” i otworzyć go poprzez dwukrotne kliknięcie. Wyświetlony zostanie następujący kod programu: #include <stdio.h> #include <stdlib.h> int main() { printf("Hello world!\n"); return 0; } TiMP1 Instrukcja 2 2 Powyższy program nazywamy zwyczajowo „Hello world” i jest to przykład najprostszego programu w języku C. Aby go skompilować i uruchomić należy wybrać polecenie Build | Build and Run. Do utworzonego projektu można dołączać dodatkowe pliki przy pomocy polecenia File | New | File... i wybierając odpowiednio „C header” (plik nagłówkowy) lub „C source” (plik źródłowy). W przypadku tworzenia danego typu pliku poproszeni zostaniemy o podanie jego nazwy. Dodatkowo dla plików źródłowych (z rozszerzeniem „.c”) zostaniemy zapytani o wybór języka: C lub C++. W przypadku pliku nagłówkowego (z rozszerzeniem „.h”) dodatkowe pole służy do wpisania „słowa - strażnika”. Jest ono jednak uzupełniane w sposób automatyczny. Podstawy języka C W języku C kod programu zgrupowany jest w bloki zwane funkcjami. Bloki takie mogą przyjmować dane wejściowe, jak również mogą zwracać jakąś daną podczas swojego kończenia. Podstawową funkcją, jaka musi wystąpić w programie w języku C jest main(). Stanowi ona punkt startowy programu. Poleceniem zwrócenia wartości z funkcji jest „return”. Funkcja main wygląda następująco: Typ zwracany przez funkcję – int oznacza liczbę, a void brak zwracanej wartości. Typy danych zostaną omówione na drugim wykładzie. int main() { Nazwa funkcji printf("Hello world!\n"); return 0; } Klamra otwierająca blok kodu Przykład wywołania funkcji i przekazania jej parametru wejściowego (tu tekstu do wyświetlenia) Zwrócenie wartości “0”. Wywołanie tego polecenia zawsze powoduje zakończenie wykonywania kodu danej funkcji. Klamra zamykająca blok kodu Należy zwrócić uwagę, że każde polecenie wydane kompilatorowi należy zakończyć znakiem „;” (średnik). Kompilator nie rozróżnia miejsca zakończenia linii (rozpoczęcia nowego wiersza). Pisanie kolejnych poleceń w kolejnych wierszach ma znaczenie estetyczne i pomaga przy późniejszym przeglądaniu kodu. Powyższy program mógłby jednak zostać zapisany w następujący sposób: int main() { printf("Hello world!\n"); return 0; } Istotna jest kolejność tworzenia funkcji. Nie wolno używać funkcji, która nie została jeszcze utworzona lub zadeklarowana. Poniższy fragment jest więc błędny int main(){ fun(); return 0; } void fun() { printf("Hello world!\n"); } Można go jednak łatwo poprawić. W tym celu należy przed całym powyższym fragmentem dopisać TiMP1 Instrukcja 2 3 tzw. prototyp funkcji: extern void tmp(); Prototypy mają jednak dużo szersze zastosowanie. Większe projekty pisane są w wielu plikach, aby podnieść stopień ich przejrzystości. Aby jednak możliwe było ich połączenie, konieczne jest poinformowanie kompilatora, jakie funkcje znajdują się w innym pliku. Służy do tego plik nagłówkowy, zawierający prototypy funkcji. Do wyświetlania danych w języku C używana jest funkcja printf(). Najprostszym sposobem jej użycia jest wyświetlenie zwykłego tekstu, np.: printf("Hello world!"); Spowoduje to wyświetlenie napisu „Hello world!”. Problem pojawia się przy wyświetlaniu dodatkowego tekstu. Konieczne jest wtedy użycie znacznika formatującego „%s”: printf("Moj tekst: %s", "oto on"); W wyniku uzyskamy tekst: „Moj tekst: oto on”. Aby wprowadzić przejście do nowego wiersza konieczne jest zastosowanie symbolu „\n”, np.: printf("Tekst: %s \n %s \n %s", "wiersz1", "wiersz2", "wiersz3"); Wynikiem tej funkcji będzie wyświetlenie napisu: Tekst: wiersz1 wiersz2 wiersz3 Sytuacja komplikuje się jeszcze bardziej przy wyświetlaniu liczb. Dostępne są następujące znaki formatujące: • %d – wyświetla liczbę zapisaną w formacie dziesiętnym • %x lub %X – wyświetla liczbę zapisaną w formacie szesnastkowym • %f lub %F – wyświetla liczbę rzeczywistą (zmiennoprzecinkową) • %e lub %E – wyświetla liczbę w trybie naukowym Przykład: printf("liczba: %d, %x, %f, %e \n", 20, 20, 20.25, 0.500e+10); Wynik: liczba: 20, 14, 20.250000, 5.000000e+009 Liczby w systemie dziesiętnym (DEC) i szesnastkowym (HEX) TiMP1 DEC HEX DEC HEX 1 1 16 10 2 2 17 11 3 3 18 12 4 4 19 13 5 5 20 14 Instrukcja 2 4 Liczby w systemie dziesiętnym (DEC) i szesnastkowym (HEX) DEC HEX DEC HEX 6 6 21 15 7 7 22 16 8 8 23 17 9 9 24 18 10 A 25 19 11 B 26 1A 12 C 27 1B 13 D 28 1C 14 E 29 1D 15 F 30 1E Preprocesor języka C Nieodłącznym elementem języka C jest preprocesor. Z formalnego punktu widzenia jest to parser, tzn. program, który zamienia jeden tekst w inny. Preprocesor służy do dołączania odpowiednich fragmentów kodu w zadane miejsca oraz do wybierania, który fragment kodu ma zostać włączony do kompilacji, a który nie. Użycie preprocesora ma jeszcze tą cechę, że wszelkie operacje przez niego wykonywane mają miejsce jedynie w czasie kompilowania programu, a nie jego normalnego wykonywania. Efektem tego jest podniesienie wydajności programu. Do sterowania parserem używamy dyrektyw. Wszystkie dyrektywy rozpoczynają się znakiem #. Podstawowe dyrektywy to: • #include <stdio.h> – służy do dołączania pliku do aktualnego kodu. W tym przypadku dołączana jest jedna z bibliotek standardowych. Użycie symboli < i > powoduje, że plik szukany będzie w folderze kompilatora. Aby dołączyć własny plik, który jest w folderze roboczym należy użyć znaku cudzysłów zamiast mniejszy/większy • #define – deklaracja stałej. Umożliwia zdefiniowanie stałej wartości, np.: #define PI 3.14 oznacza, że wszędzie, gdzie w kodzie użyty zostanie napis PI, to w trakcie procesu kompilacji zamieniony zostanie na 3.14. Należy zwrócić uwagę, że na końcu dyrektywy nie umieszczamy znaku średnika. • #undef – umożliwia usunięcie poprzednio zadeklarowanej stałej. Pozwala to na zmianę jej wartości, np. zmianę dokładności liczby π: #define PI 3.14 #undef PI #define PI 3.14159 Aby użyć zadeklarowaną stałą w kodzie, wystarczy wpisać jej nazwę. W celu odróżnienia stałych preprocesora od zmiennych kompilatora, przyjęto konwencję pisania nazw stałych DUŻYMI LITERAMI, chociaż nie jest to wymóg kompilatora. • #if – jest pierwszym członem konstrukcji „if … then … else …”, która służy do podjęcia różnych działań w zależności od badanego warunku logicznego. Po opisywanej dyrektywie należy podać warunek. Dozwolone są tylko operacje typu większy „>”, mniejszy „<”, równy „==” (koniecznie podwójny znak równości) i różny „!=”. Jeśli warunek jest spełniony to wykonywany jest kod następujący bezpośrednio po tej dyrektywie. • #else – rozpoczyna fragment kodu, który ma być wykonany, jeśli warunek logiczny przy #if TiMP1 Instrukcja 2 5 • nie jest spełniony. Fragment kodu pomiędzy #if, a #else jest wówczas pomijany #endif – dyrektywa oznaczająca punkt końcowy konstrukcji „if … then … else …”. Przykład: #define LICZBA_A 3 #define LICZBA_B 5 #if LICZBA_A > LICZBA_B #define WYNIK "A jest wieksze od B" #else #define WYNIK "B jest wieksze od A" #endif int main(){ printf(WYNIK); } • #elif – stanowi połączenie dyrektyw „#else” i „#if”. Stosuje się, jeśli potrzebne jest sprawdzenie dodatkowego warunku, jeśli poprzedni warunek logiczny nie był spełniony Przykład: #define WAR 3 #if WAR == 1 #define TEKST "jeden" #elif WAR==2 #define TEKST "dwa" #else #define TEKST "cos innego" #endif • • #ifdef – działa jak #if, przy czym warunek jest spełniony, jeśli podana następnie nazwa stałej jest zadeklarowana. #ifndef – działa jak #if, przy czym warunek nie jest spełniony, jeśli podana następnie nazwa stałej jest zadeklarowana. Oprócz opisanych powyżej dyrektyw istnieje również kilka predefiniowanych stałych (to znaczy takich, które są zdefiniowane w momencie uruchamiania kompilatora i nie trzeba ich samodzielnie definiować): • __LINE__ - numer linii bieżącego wiersza. Wartość zwracana jest liczbą. • __FILE__ - nazwa bieżącego pliku. Wartość zwracana jest tekstem. • __DATE__ - bieżąca data zapisana w formacie mm-dd-rrrr (miesiąc – dzień – pełny_rok). Wartość zwracana jest tekstem. • __TIME__ - aktualny czas zapisany w formacie gg-mm-ss (godzina – minuty – sekundy). Wartość zwracana jest tekstem. TiMP1 Instrukcja 2 6 Komentarze W celu zwiększenia przezroczystości kodu istnieje możliwość zostawiania w nim dodatkowych napisów adresowanych do programisty. Napisy te nazywamy komentarzami i nie są one kompilowane. Istnieją dwa sposoby komentowania: // - służy do wyłączenia tylko jednego wiersza kodu /* */ - służy do wyłączenia wszystkich wierszy umieszczonych pomiędzy znacznikami Przykład: int main(){ // tylko ten wiersz jest komentarzem printf('Hello World!'); /* Ten fragment jest komentarzem i ten też. */ return 0; } TiMP1 Instrukcja 2 7 Zadania: 2A. Napisać i uruchomić program „Hello World” w języku C przy pomocy środowiska Code::Blocks. (1 punkt) 2B. Napisać i uruchomić program, który będzie zawierał dwie funkcje: main() i moja(). Druga funkcja ma znajdować się pod funkcją main() i wyświetlać napis: wiersz1 wiersz2 wiersz3 Funkcja moja() ma być wywołana w funkcji main(). (2 punkty) 2C. Napisać i uruchomić program, który wyświetli następujący tekst: Data: Oct 11 2009 Godzina: 12:00:00 Linia kodu: 5 Wartości podane powyżej mają być uzupełniane automatycznie. (2 punkty) 2D. Napisać i uruchomić program, który zawiera dyrektywy preprocesora realizujące porównanie dwóch wartości podanych jako stałe. Program ma działać następująco: • obie zadeklarowane wartości są równe – wyświetl komunikat: „wartości są równe” • pierwsza wartość jest większa – wyświetl komunikat: „A jest większe od B” • druga wartość jest większa – wyświetl komunikat: „B jest większe od A” (4 punkty) 2E. Napisać i uruchomić program, który zawiera dwa pliki źródłowe. W drugim pliku należy umieścić funkcję wyświetlającą nazwę i adres pliku w sposób automatyczny. Funkcję tę należy wywołać w funkcji main() w pierwszym pliku. UWAGA Tworząc dodatkowy plik w środowisku Code::Blocks należy zaznaczyć oba pola (Debug i Release) na liście „In build targets”(4 punkty) 2F. Napisać i uruchomić program, który posiada następujące cechy: program sprawdza, czy zdefiniowana jest stała o nazwie LICZBA. Jeśli nie to wyświetla komunikat „brak liczby”. W przeciwnym przypadku wyświetlany jest komunikat typu: „Liczba 92 w systemie szesnastkowym posiada zapis: 5C”. Jako liczba musi być podana wartość zdefiniowanej stałej. (4 punkty) TiMP1 Instrukcja 2 8