Koło informatyczne

Przyspieszony kurs języka C++

 

Kod U2

Na poprzednich zajęciach poznaliśmy sposób zapisywania liczb w naturalnym systemie dwójkowym NBS (ang. Natural Binary System). System ten nadaje się do zapisu liczb nieujemnych. Do liczb całkowitych dodatnich, ujemnych i zera stosujemy modyfikację tego systemu, która nosi nazwę kodu U2 (U2 = uzupełnienie do podstawy 2). W systemie U2 liczby dwójkowe zawsze posiadają ustaloną z góry liczbę cyfr, czyli bitów. Spowodowane jest to tym, iż najstarszy bit liczby posiada wagę ujemną. Na przykład, 4 bitowa liczba 1011(U2) ma wartość:

 

waga (-23)
-8
22
4
21
2
20
1
 
cyfry 1 0 1 1 = -8 + 2 + 1 = -5
pozycja 3 2 1 0  

 

Zasada obliczania wartości liczby jest identyczna jak w NBS: dodajemy do siebie wagi tych pozycji, na których znajduje się cyfra 1.

Jeśli najstarszy bit liczby ma wartość 0, to waga ujemna nie uczestniczy w tej sumie i liczba jest dodatnia. Jeśli natomiast najstarszy bit ma wartość 1, to liczba zawsze jest ujemna, ponieważ waga ta jest na moduł większa od sumy pozostałych wag. W poniższej tabelce zebraliśmy obok siebie wartości liczb w NBS i U2. Przyjrzyj się im dokładnie:

 

kod
liczby
NBS U2
0000 0 0
0001 1 1
0010 2 2
0011 3 3
0100 4 4
0101 5 5
0110 6 6
0111 7 7
1000 8 -8
1001 9 -7
1010 10 -6
1011 11 -5
1100 12 -4
1101 13 -3
1110 14 -2
1111 15 -1

 

Zwróć uwagę, że wartości liczb U2 i NBS są takie same, gdy najstarszy bit ma wartość 0. Zaczynają się jednak różnić od siebie, gdy bit ten przyjmuje wartość 1. Najstarszy bit liczby U2 nosi nazwę bitu znaku (ang. sign bit).

 

Zakres liczb U2 dla n bitowych liczb określamy następująco:

 

Liczba najmniejsza posiada ustawiony na 1 bit znaku, a wszystkie pozostałe bity wyzerowane (dlaczego?):

 

min(U2) = 1000...000(U2) = (-2n-1)

 

Liczba największa posiada wyzerowany bit znaku i ustawione na 1 wszystkie pozostałe bity (dlaczego?):

 

max(U2) = 0111...111(U2) = 2n-1 - 1

 

Ten ostatni wynik otrzymujemy bardzo prosto. Jeśli pominiemy bit znaku, to dostaniemy n-1 bitową liczbę NBS. Z poprzednich zajęć wiemy, że liczba ta posiada zakres od 0 do 2liczba bitów - 1. Ponieważ u nas liczba bitów wynosi teraz n-1, to maksymalna wartość jest równa 2n-1-1.

 

Ponieważ wartości liczb różnią się od siebie przy tej samej postaci kodu binarnego, komputer musi wiedzieć, jak ten kod interpretować: czy jako liczbę NBS, czy jako liczbę U2. Ten sposób interpretacji nosi nazwę typu. W języku C++ wartości liczbowe posiadają określony typ. Dla liczb całkowitych typy są następujące:

 

NBS U2 Opis
unsigned int int Liczba całkowita 32 bitowa
unsigned short int short int Liczba całkowita 16 bitowa
unsigned long long int long long int Liczba całkowita 64 bitowa

 

Pierwszy typ (unsigned int lub int) jest tzw. typem standardowym. Typy krótki i długi mają zastosowanie w szczególnych sytuacjach. W typach NBS możemy pominąć słówko int.

 

Budowa programu w języku C++

Program w języku C++ posiada określoną budowę. Każdy zawiera tzw. funkcję główną, od której rozpoczyna się wykonanie programu.

Uruchom Code::Blocks i utwórz w katalogu kurscpp nowy projekt konsoli o nazwie 03. Następnie z edytora usuń wszystko i wpisz poniższy kod:

 

Code::Blocks
int main()
{
  return 0;
}

 

Budowa funkcji w języku C++ jest następująca:

 

typ_wyniku nazwa(lista argumentów)
{
   instrukcje
}

 

typ_wyniku  określa rodzaj zwracanych przez funkcję danych. W przypadku funkcji main() jest to int, czyli liczba 32 bitowa ze znakiem w kodzie U2.

nazwa  funkcji pozwala się do niej odwoływać w programie. W języku C++ nazwy składają się z liter małych i dużych, cyfr oraz znaku podkreślenia. Pierwszym znakiem musi być litera. Nazwa nie może być słowem kluczowym języka C++.

lista argumentów  określa dane, które zostaną przekazane do funkcji w momencie jej wywołania. Lista ta może być pusta, jeśli funkcja nie wymaga danych zewnętrznych. Argumentami funkcji zajmiemy się na kolejnych zajęciach.

 

W przypadku naszego programu mamy tylko jedną funkcję main(). Wewnątrz funkcji wykonywana jest instrukcja:

 

return 0;

 

Instrukcja ta kończy działanie funkcji i zwraca podaną wartość jako wynik działania funkcji. W tym przypadku funkcja main() zwróci wartość 0. Wartość ta jest kodem zwrotnym z programu. Kod ten można wykorzystać zewnętrznie, np. aby sprawdzić, czy wykonanie zakończyło się sukcesem. Przyjęto, że kod 0 oznacza sukces, a każda inna wartość jest traktowana jako błąd (lub coś innego niż normalnie).

Jak to sprawdzić? Gdy pracujesz w środowisku Code::Blocks, to wystarczy skompilować i uruchomić program. W okienku terminala otrzymasz informacje o kodzie zwrotnym z programu:

 

Process returned 0 (0x0) execution time : 0.001 s
Press ENTER to continue.

 

Zmień teraz kod programu na poniższy:

 

Code::Blocks
int main()
{
  return 75;
}

 

Skompiluj i uruchom go. Powinieneś otrzymać komunikat:

 

Process returned 75 (0x4B) execution time : 0.005 s
Press ENTER to continue.

 

Uwaga: w zwracanym kodzie brane jest pod uwagę tylko 8 najmłodszych bitów. Zatem wartości kodu zwrotnego mogą być w zakresie tylko od 0 do 255.

Jeśli chcesz uzyskać kod zwrotny z programu, gdy pracujesz w terminalu, to musisz się odwołać do specjalnej zmiennej systemowej $?. Zawiera ona kod zwrotny ostatnio uruchamianego polecenia.

Uruchom terminal (lewy Ctrl + lewy Alt + T). Wpisz polecenia:

 

cd kurscpp/03/bin/Debug
./03
echo $?
 

W wyniku zostanie wyświetlony kod zwracany przez program. Jeśli jednak jeszcze raz wpiszesz polecenie:

 

echo $?
 

to otrzymasz 0. Dlaczego? Ponieważ będzie to kod zwrotny ostatniego polecenia echo, a nie programu 03.

Wróćmy jednak do naszego kodu w języku C++. Program zwykle coś wypisuje w oknie terminala. Niestety, w języku C++ nie ma rozkazów wypisujących coś w oknie terminala. Na pierwszy rzut oka wydaje się to być wadą. Jednak pomyśl – język C++ może być używany do tworzenia programów, które pracują z różnym sprzętem, nawet z takim, który nie posiada terminala. Aby zatem nie zaśmiecać języka zbędnymi elementami, funkcje komunikacyjne realizuje się w C++ za pomocą odpowiednich bibliotek. W bibliotekach tych są zdefiniowane obiekty, które mogą się komunikować z różnymi urządzeniami, w tym i z terminalem.

Aby móc skorzystać z funkcji bibliotecznych, musimy dołączyć do naszego programu tzw. plik nagłówkowy, który zawiera definicję tych funkcji (czyli informuje kompilator, w jaki sposób ma się do nich odwoływać). W tym celu na początku programu umieszczamy tzw. dyrektywę #include:

 

Code::Blocks
#include <iostream>

int main()
{
  return 0;
}

 

Za dyrektywą #include umieszczamy nazwę pliku nagłówkowego, który zostanie dołączony do naszego programu w trakcie kompilacji (działa to w ten sposób, że przed właściwą kompilacją plik jest przekazywany do tzw. preprocesora, który szuka w nim swoich poleceń. Po natrafieniu na dyrektywę #include <plik> preprocesor zastępuje cały ten wiersz zawartością wskazanego pliku. Tak zmieniony plik programu jest zwracany do kompilatora i kompilowany).

Plik iostream zawiera definicję tzw. strumieni wejścia/ wyjścia (ang. iostream = input/output stream). Dzisiaj poznamy strumień wyjścia cout. Dane przesłane do tego strumienia zostaną wyświetlone w oknie konsoli.

 

Code::Blocks
#include <iostream>

int main()
{
  std::cout << 5 << std::endl;
  return 0;
}

 

Dane przesyłamy do strumienia za pomocą operatora <<. Wskazuje on kierunek przesłania danych. Oprócz liczb można również przesyłać teksty w cudzysłowach:

 

Code::Blocks
#include <iostream>

int main()
{
  std::cout << "Witaj, to ja, twój program w języku C++" << std::endl;
  return 0;
}

 

Wszystkie obiekty biblioteczne iostream muszą być poprzedzone identyfikatorem std oraz podwójnym dwukropkiem. Identyfikator ten określa przynależność tych obiektów do przestrzeni nazw std. Ponieważ jest to uciążliwe, możemy sobie uprościć sprawę, dodając na początku programu dyrektywę using namespace:

 

Code::Blocks
#include <iostream>

using namespace std;

int main()
{
  cout << "Witaj, to ja, twój program w języku C++" << endl;
  return 0;
}

 

W programie można umieszczać komentarze. Mamy je zupełnie za darmo. Służą one do objaśniania działania naszego kodu oraz do dokumentacji.

 

Code::Blocks
// Koło Informatyczne
// Przykładowy program C++
// (C)2014 I LO w Tarnowie
//------------------------

#include <iostream>

using namespace std;

// **********************
// *** START PROGRAMU ***
// **********************

int main()
{
  cout << "Witaj, to ja, twój program w języku C++" << endl
       << "---------------------------------------" << endl << endl;

  return 0;
}

 

Komentarze nie są tłumaczone na żaden kod. Ich ilość nie spowoduje, że program będzie działał wolniej. Dlatego stosuj je często. Naprawdę są pożyteczne.

Podsumowując. Typowy program w języku C++ będzie się składał z następujących elementów:

 

// Koło informatyczne
// Przykładowy program C++
// (C)2014 I LO w Tarnowie
//------------------------ 
Komentarz
#include <iostream> 
Pliki nagłówkowe zawierające definicje używanych w programie struktur danych oraz funkcji bibliotecznych.
using namespace std; 
Określa używaną w programie przestrzeń nazw std.
int main()
{
    cout << "Witaj, to ja, twój program w języku C++" << endl
         << "---------------------------------------" << endl << endl;
    return 0;
} 
Każdy program w języku C++ musi posiadać funkcję main(), od której rozpoczyna się wykonywanie programu. Zawartość tej funkcji określa to, co program robi.

 


   I Liceum Ogólnokształcące   
im. Kazimierza Brodzińskiego
w Tarnowie

©2024 mgr Jerzy Wałaszek

Dokument ten rozpowszechniany jest zgodnie z zasadami licencji
GNU Free Documentation License.

Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl

W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe