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