background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  1 

 

 

 

 

PODSTAWY 

PROGRAMOWANIA

 

 

 

 

 

kurs I - część 1 

https://www.dydaktyka.itta.pwr.wroc.pl/informatyka 

 

 

 

 

 

PROWADZĄCY: dr inŜ. Marcin Głowacki

 

E-Mail: 

Marcin.Glowacki@pwr.wroc.pl

 

Pok.907 C-5  

 

Wrocław 2007 

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  2 

 

LITERATURA PODSTAWOWA 

 
Jerzy Grębosz „

Symfonia C++

” Oficyna Kallimach, Kraków 2002 

Krystyna Koleśnik „

Podstawy programowania strukturalnego w 

Języku C++

”, Oficyna PWR 2006 

Anna Struzińska-Walczak, Krzysztof Walczak, „

Nauka 

programowania dla początkujących C++”

, Wyd. W&W, W-wa 

1999 
 

LITERATURA UZUPEŁNIAJĄCA 

 
Brian W. Kernigham, Dennis M. Ritchie; 

Język ANSI C

, WNT 

2001 
Stroustrup B., 

Język C++

, Warszawa, WNT, 2002 

 
 
 
 
 
 

ZALICZENIE 

 
- test końcowy 
 
Ocena końcowa = 1/3*ćwiczeń + 1/3*laboratorium + 1/3*wykład 

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  3 

1.

PRZEGLĄD TECHNIK PROGRAMOWANIA: 

programowanie liniowe: szereg komend i przeskoki GOTO (np. język Basic), JMP 
(ASEMBLER) 

programowanie proceduralne: funkcje (return), GOSUB (BASIC), CALL FAR i CALL 
NEAR(ASSEMBLER) 

program był traktowany jako seria procedur, działających na danych 

Procedura (funkcja) jest zestawem specyficznych, wykonywanych jedna po drugiej 
instrukcji. 

programowanie strukturalne - z ukrywaniem danych: structure (C), record (PASCAL) 

idea główna to „dziel i rządź.”

 - 

kaŜde zadanie jest rozbijane na zestaw mniejszych 

zadań składowych 

dostęp do danych przez nazwa_strukt.nazwa_zmiennej 

programowanie obiektowe – bazujące na obiektach 

pojawia się pojęcie klasy i obiektów tej klasy 

obiekty zawierają dane w postaci zmiennych i metody operujące na tych danych 

najczęściej obiekty są wyraźnie odrębne i brak zaleŜności pomiędzy nimi, patrz: brak 
dziedziczenia i polimorfizmu 

programowanie zorientowane obiektowo – programowanie obiektowe wzbogacone o 
dziedziczenie i polimorfizm – kod programu sam się orientuje z jakim typem obiektu ma do 
czynienia i dobiera właściwą funkcję realizującą domyślną akcję (podobnie jak 
przeładowanie/przeciąŜenie funkcji i operatorów, które same rozpoznają z jakimi 
argumentami mają do czynienia) 

łatwa rozbudowa i korzystanie z elementów wcześniej zdefiniowanych 

związanie funkcji ze strukturą przetwarzanych danych 

dziedziczenie i ukrywanie danych 

polimorfizm = „wiele form” – jedna nazwa moŜe przybierać wiele form, forma aktualna jest 
związana z daną klasą obiektu 

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  4 

KLASYCZNE PROJEKTOWANIE PROGRAMU: 

Rozpoznanie i analiza problemu 

Projektowanie programu 

Identyfikacja zachowań systemu: kto/co -> akcja -> kogo/czego -> rezultat (gracz-
>rzuca ->kostką -> liczba pomiędzy 1 i 6) 

 Identyfikacja struktur danych 
 Wskazanie bloków funkcjonalnych – algorytm (minimum blokowy) 

Usystematyzowanie i uszczegółowienie 

 Tworzenie nowych typów i struktur danych (jeśli są potrzebne) 
 Ustalenie hierarchii zmiennych i ich zasięgu 
 Określenie wzajemnych zaleŜności – która funkcje wydają rozkazy, a która 

spełniają polecenia, które funkcje wymieniają się usługami – GRAF 
WSPÓŁPRACY 

 Podsystemy – znajdowanie grup obiektów, które realizują odrębne 

funkcjonalnie zadania, np. obsługa menu 

Składanie modelu – określanie stanów, sekwencji działań oraz cykli Ŝyciowych dla 
danych oraz funkcji 

Implementacja 

Testowanie 

Uruchomienie i poprawki 

ANALIZA PROBLEMU 

• 

Od szczegółu do ogółu (wstępujące) 

 niepodzielne części łączy się w większe fragmenty 

• 

Od ogółu do szczegółu (zstępujące) 

 bloki funkcjonalne uściśla się do operacji elementarnych 

• 

W praktyce TECHNIKI MIESZANE 

• 

Struktura danych 

ALGORYTM - SCHEMAT BLOKOWY 

 

• 

START, STOP 

 
 

• 

OPERACJA WYKONAWCZA 

 
 
 
 
 

• 

OPERACJA WARUNKOWA 

 
 
 
 

 

• 

OPERACJA WEJŚCIA/ WYJŚCIA 

 
 
 
 

 

START

 

i=0

 

j=j+1

 

if

 

i<3

 

TAK

 

NIE

 

wyświetl 

podaj k 

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  5 

IMPLEMENTACJA 

Język programowania i narzędzia programistyczne 

stopień złoŜoności języka 

poziom abstrakcji realizowanych funkcji 

projekty z kodem z róŜnych języków 

Podział na odrębne moduły tworzone w zespole programistów 
Właściwe zarządzanie projektem 
 

Język C <-> Assembler 

 
 
 
 
 
 
 
 
 
 
 
 
 
 

Poziomy maszynowe 

 

 

 
L4 – C++ 

int A, B, C; 

 

 

//fragment danych 

… 

A

=

B

+

C; 

 

 

//fragment programu 

 
L3 – Asembler (Intel x86)  

 

L1 – kod maszynowy (Intel x86) 

 

(.data)  

 

 

 

SEGMENT danych 

cc dw (?) ;  

 

 

 

 

(offset cc = 0103h) 

bb dw (?) ;  

 

 

 

 

(offset bb = 0105h) 

aa dw (?) ;  

 

 

 

 

(offset aa = 0107h) 

(.code)  

 

 

 

SEGMENT programu 

 

... 

(*) mov ax, cc   

 

 

 

1010 0001 (A1h) 
0000 0011 0000 0001 (0103h) 

(*+3) add ax, bb  

 

 

 

0000 0011 0000 0110 (0306h) 
0000 0101 0000 0001 (0105h) 

(*+7) mov aa, ax 

 

 

 

1010 0011 (A3h) 
0000 0111 0000 0001 (0107h)

 

 

#include <stdio.h> 
void main() { 
printf("Hello world"); 

 

_TEXT segment byte public 'CODE’ 

;     void main() 

_main proc  near 

;     { 
;     printf("Hello world"); 

 

push  offset DGROUP:s@ 

 

call 

near ptr _printf 

 

pop 

cx 

;     } 

 

ret 

 

_main endp 
 

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  6 

MODEL PRZETWARZANIA  

– wpływ na sposób zakodowania programu 

z podziałem czasu (przełączanie zadań) 

czasu rzeczywistego 

równoległe (wiele procesorów) 

rozproszone (w sieci komputerowej, klastrze) 

 

KOMP

KOMP

KOMP

KOMP

KOMP

KOMP

KOMP

KOMP

Zarządzający

klastrem

Bardzo szybkie łącze np., Gigabit Ethernet

KOMP

Komputer wchodzący w skład klastra

Legenda

SWITCH

SWITCH

Przełącznik sieciowy np., Gigabit Ethernet

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  7 

 

KOMPILACJA i KONSOLIDACJA 

 
Pseudo-kompilatory generują tzw. bajtkod – kod pośredni, który na etapie wykonywania jest 
przekształcany w kod maszynowy – mikrokod wykonywany wewnątrz procesora. Mikrokod jest 
róŜny dla róŜnych typów procesora. 
 

Program

źródłowy

Kompilator

Program

wynikowy

Konsolidator

Program

wykonalny

Program

ładujący

Procesor

Procesor

Procesor

Procesor

Inne

moduły

Tekst programu

(.cpp)

Moduły - objects

(.o lub .obj)

Plik

wykonywalny

Pseudo-

kompilator

Kod

pośredni

Interpreter

Kod

maszynowy

 

 
Inne moduły
 z kodem pośrednim: 
mogą pochodzić z innych kompilatorów dowolnych innych języków programowania: 

Pascal, Asembler, Fortran, Cobol, Modula 2 itd. 

 
 

Program

źródłowy

C

Program

źródłowy

Pascal

Program

źródłowy

Asembler

Program

źródłowy

Fortran

Kompilator

C

Program

wynikowy

Kompilator

Pascal

Program

wynikowy

Kompilator

C++

Program

wynikowy

Kompilator

Asembler

Program

wynikowy

Kompilator

Fortran

Program

wynikowy

Konsolidator

Program

wykonalny

Program

źródłowy

C++

 

 
 

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  8 

PREPROCESOR KOMPILATORA 

• 

Przed uruchomieniem kompilatora 

• 

Dyrektywy rozpoczynające się od: # (hash, krzyŜyk) 

 

#include <nazwa>

 

 

//dla domyślnej lokalizacji plików nagłówkowych 

lub 

#include ”nazwa”

 

 

//dla plików nagłówkowych z bieŜącej kartoteki 

 

• 

Definicja symbolu lub stałej: 

 

#define NMAX 100 
#define cośtam

 

 

• 

Dyrektywa warunkowa: 

Przykład: 

#ifndef p_sumaP

 

 

//jeśli wcześniej nie było zdefiniowane p_sumaP  

#define p_sumaH

 

/*to trzeba zdefiniować p_sumaH i dołączyć 
odpowiedni plik nagłówkowy */ 

#include ”p_suma.h”   

//Umieszczenie treści pliku p_suma.h w tym miejscu 

#endif 

Inny przykład: 

 

#define unix

   

 

//informacja na początku, Ŝe kompilacja w systemie Unix  

 

..... 

 

#ifdef unix 

 

 

#include ”unix.h”

 

//dołącz jakiś własny plik nagłówkowy unix.h 

 

#endif 

 

#ifndef unix

   

 

//dla innego systemu niŜ unix 

 

 

#include system.h

 

//dołącz jakiś własny plik nagłówkowy system.h 

 

#endif 

 

PROGRAM WYKONALNY 

• 

Kompilacja programu źródłowego 

• 

Binarny moduł wynikowy typu „obiekt” 

• 

Łączenie modułów - Link 

• 

Program uruchamialny: .com, .exe 

• 

Uruchamianie krokowe - Debug 

 
 

URUCHOMIENIE i PRZETESTOWANIE  

Faza wdroŜenia i obserwacja zachowania programu w warunkach rzeczywistej eksploatacji 
Odnajdowanie przyczyn błędnego działania programu (ang. TROUBLESHOOTING) 

• 

Błędy kompilacji (składniowe) 

• 

Błędy logiczne 

• 

Błędy funkcjonalne 

• 

Pomyłki fazy projektowania 

 
Obsługa „potencjalnych” błędów uŜytkownika 

• 

Zmiany i rozszerzenia 

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  9 

ZALECENIA OGÓLNE: 

1. Funkcje:  

– 

10 linijek programu,  

– 

wielokrotne powtórzenia. 

– 

wcięcia w tekście programu 

– 

spójny system nazw, np. zgodne z systemem węgierskim 

2. Wyczerpujące komentarze w programach: 

– 

komentarz do końca linii: // 

 

for (i=1;i<5;i++) { 

//pętelka słuŜąca do pokazu zaleceń ogólnych dla studentów

 

       if (iLiczba == 7) 
      . . . 

– 

blok komentarza: /*   blok   */ 

for (i=1;i<5;i++) { 

/*inna pętelka z wykluczoną instrukcją, która nie jest juŜ potrzebna, ale 

moŜe się przydać później w fazie uruchomienia. Po zakończeniu fazy uruchomienia takie 
zbędne instrukcje i bloki komentarzy moŜna usunąć np., Ŝeby nie dawać sobie powodu do 
wstydu i wyśmiewania przez następne pokolenia 
 
      if (iLiczba == 7) */

 

      iLiczba--; 
      . . . 

 

ZŁOTA ZASADA

 

(nieznanego autora - przekazywana z pokolenia na pokolenie) 

 
Cyt. rady starszego kolegi: 
 
 

Program działa tak jak go napisałeś

a nie tak jak Ci się wydawało, Ŝe go napisałeś.

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  10 

2.

 REPREZENTACJA DANYCH

 

 

Dane przechowywane i przetwarzane w komputerach są postaci cyfrowej, zatem w postaci liczb o 
pierwotnej postaci liczb binarnych – zapisanych w 

systemie dwójkowym

 
Dane, które zapisane są w pamięci komputera to tzw. 

zmienne

, ze względu na fakt, Ŝe ich wartości 

mogą być modyfikowane w trakcie działania programu. KaŜda zmienna jest określonego typu i 
posiada unikalną nazwę lub wskazanie w postaci adresu czyli miejsca w pamięci operacyjnej. 
 
WyróŜniono trzy typy zmiennych, w zaleŜności od zasięgu dostępności danych w róŜnych 
miejscach programu: 
 

Globalne

 – deklarowane na początku programu, przed funkcją główną: main() ) dostępne w 

kaŜdym miejscu programu. Rezydują w pamięci przez cały czas funkcjonowania programu w 
miejscu na stałe zarezerwowanym. 
 

Lokalne

 – dostępne w bloku, w którym zostały zadeklarowane i uŜywane tylko w jego obszarze, 

np. w funkcji głównej lub innych zdefiniowanych funkcjach. Przeznaczone są do lokalnego 
przetwarzania i dlatego mają charakter tymczasowy – znikają po zakończeniu funkcji lub nie są 
dostępne po opuszczeniu funkcji, np. w celu realizacji innej funkcji, a po powrocie są nadal 
dostępne. KaŜde jednak nowe wywołanie funkcji tworzy na nowo zestaw zadeklarowanych 
zmiennych z ich wartościami początkowymi. Tworzone są w pamięci podręcznej programu, w 
przestrzeni, która moŜe być wielokrotnie uŜyta do deklarowania róŜnych zmiennych lokalnych. 
 

Statyczne

 – podobnie jak zmienne lokalne dostępne są w bloku, w którym zostały zadeklarowane, z 

tą jednak róŜnicą, Ŝe zachowują swoją wartość podczas ponownego wywołania funkcji. Musza 
posiadać stałą rezerwację w pamięci, podobnie jak zmienne globalne. 

 

Widoczność zmiennych, zmienne statyczne oraz zjawisko przesłaniania zostanie omówione w 
dalszej części kursu. 
 

DEKLARACJE ZMIENNYCH 

 
Deklaracja zmiennej polega na wskazaniu typu zmiennej i nazwy. Nie moŜna zakładać, Ŝe zmienne 
posiadają istotną wartość początkową, która moŜe być przypadkowa. Nie moŜna zakładać, Ŝe 
będzie to zero dla zmiennych przechowujących liczby. MoŜliwe jest zadeklarowanie zmiennych z 
wartościami początkowymi: 
 

Typ nazwa_zmiennej = wartość_zmiennej; 

 

int a,b,c; 
float d,e,f; 
double g,h; 

 
Inicjalizacja wartości początkowych: 
 

int a=0,b=1,c=5; 
float d=0.1,e=0.5,f=7; 
double g=0,h=0; 

 

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  11 

W języku C definicje zmiennych mają ustalone miejsce, zwykle na początku programu lub funkcji. 
W języku C++ dopuszczono większą swobodę co do miejsca umieszczenia deklaracji zmiennych – 
zwykle mogą się pojawiać w dowolnym miejscu programu, np. przed ich pierwszym uŜyciem lub 
nawet w trakcie ich uŜycia: 
 

for (int i=0,i<100,i++){ 
... 

 

int a= (int b=5) + (int c=7);

 

//to tylko przykład - proszę nie stosować takich praktyk. 

 
Poprawiła się wygoda uŜycia zmiennych, ale jednocześnie pojawić się bałagan. NaleŜy stosować 
przede wszystkim rozsądek i utrzymywać w równowadze rozproszenie deklaracji zmiennych oraz 
porządek i czytelność programu. 
 

STRUKTURA PROGRAMU

 

 

 

W przypadku rozbudowanych programów moŜe być bardzo zróŜnicowana. Dla prostych 

przypadków moŜna przyjąć ogólną strukturę składającą się z dyrektyw dołączenia plików 
nagłówkowych #include, następnie zmiennych globalnych 
 
Przykładowa postać ogólna struktury programu: 
 

#include <iostream>  

//biblioteki 

int konto, licznik;

 

//zmienne 

globalne

 

 
int function 

XYZ

(int dana1, int dana2){ 

int wynik, suma, m,n; 

//zmienne 

lokalne

 w funkcji XYZ 

…. 
return suma;  

 

//powrót z funkcji  


 
int 

main()

{

 

int a=0, b, c;

   

//zmienne 

lokalne

 w funkcji głównej 

... 
XYZ(b,10);   

//wywołanie funkcji XYZ 

 
for (

int i=0

; i<10; i++){ 

... 

return 0; 

//powrót z kodem – 0 jeśli poprawne zakończenie 

 

 

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  12 

TYPY DANYCH – WBUDOWANE 

 
Zarówno w języku C, jak i w języku C++ wyróŜniamy pięć podstawowych typów danych: 
 

int 

— typ całkowity. UŜywany jest do zapamiętywania i zapisywania liczb całkowitych. 

 

float 

— typ zmiennopozycyjny (zmiennoprzecinkowy). 

 

double 

— typ zmiennoprzecinkowy podwójnej długości. Zmienne typu 

float 

oraz 

double 

umoŜliwiają zapamiętywanie i zapisywanie liczb posiadających część całkowitą i 
ułamkową. Część ułamkową oddzielamy kropką. 
 

char 

— typ znakowy stosowany do zapamiętywania i zapisywania znaków ASCII oraz 

krótkich liczb reprezentowanych na 8 bitach. 
 

void 

— typ pusty. Za jego pomocą moŜna deklarować funkcje nie zwracające Ŝadnych wartości 

oraz funkcje, które nie pobierają argumentów. Dodatkowo moŜliwe jest tworzenie  
ogólnych wskaźników. 
 

Rozmiar typu <=> zakres liczb 

 

jest uzaleŜniony od architektury procesora (zwykle 16 lub 32 bity) oraz kompilatora. W 
nowoczesnych, 32-bitowych procesorach rodziny Pentium z najnowszymi kompilatorami, 

liczby 

całkowite

 mają 

cztery bajty

.  

Znak

 jest zawsze pojedynczą literą, cyfrą lub symbolem i zajmuje pojedynczy bajt pamięci. 

 
 

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  13 

TYPY ZMIENNYCH 

Nazwa 

Przykład deklaracji 

Zakres 

Bajtów 

Zastosowanie 

Litera,  

char cZnak; 

- 128 ... 127 

Teksty 

Litera bez znaku 

unsigned char ucMala; 

0 ... 255 

Male liczby 

Mała liczba całkowita 

short int siLiczba; 

short siLiczba; 

0 ... 255 

0 ... 65535 

Małe liczby całkowite 

Liczba całkowita 

 

int liczba 

-32768 ... 32767 

–2 147 483 648 do 2 147 

483 647 

Liczby całkowite 

Liczba naturalna 

unsigned int i,j,k; 

unsigned  

0 ... 65535 

0 ... 4 294 967 295 

Liczba naturalna 

DuŜa liczba całkowita 

long int lDuza_liczba; 

long lDuza_liczba; 

–2 147 483 648 do 2 147 

483 647 

-2^31 ... 2^31-1 

DuŜe liczby całkowite 

B. duŜe liczby naturalne  unsigned long int ulBduza; 

unsigned long ulBduza; 

0 ... 2^64-1 

0 ... 2^128-1 

16 

Bardzo duŜe liczby 
naturalne 

Zmiennoprzecinkowa 

float fLiczba; 

±(1,2e-38 ... 3,4e38) 

Z przecinkiem 

 

double float dfUlamek; 

double dfUlamek; 

±(2,2e-308 ... 1,79e308) 

 

 

long double ldXduza 

-3,3e-4932 ... 1,1e4932 

16 

 

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  14 

REPREZENTACJA LICZB STAŁOPOZYCYJNYCH 

Bit znaku dodawany jest na początku liczby blokując jeden bit, pozostała część liczby zapisana jest w naturalnym kodzie binarnym (NKB) lub w 
kombinacjach z modułem lub operacją negowania liczby. 
NKB to zapis liczby w 

naturalnym kodzie binarnym

 sumy kolejnych potęg liczby 2. 

ZM to zapis 

znak-moduł

 (ang. sign-magnitude) utworzono przez dodanie jednego bitu do modułu (wartości bezwzględnej liczby zakodowanej w 

NKB). Występuje podwójna reprezentacja zera. 
U1 – kod uzupełnień do 1 (ang. 1s complement) Najbardziej znaczący bit jest bitem znaku (0-liczba dodatnia, 1-liczba ujemna). Jeśli liczba jest 
dodatnia to wartość liczby zakodowana jest w NKB, a jeśli liczba posiada znak ujemny to negacja pozostałej części liczby stanowi jej wartość poniŜej 
zera. Występuje podwójna reprezentacja zera. 
U2 – kod uzupełnień do 2 (ang. 2s complement) Najbardziej znaczący bit jest bitem znaku (0-liczba dodatnia, 1-liczba ujemna). Jeśli liczba jest 
dodatnia to wartość liczby zakodowana jest w NKB, a jeśli liczba posiada znak ujemny to negacja pozostałej części liczby, po dodaniu 1 stanowi jej 
wartość poniŜej zera. Występuje pojedyncza reprezentacja zera. 
BIAS – kod polaryzowany uŜywany do zapisu cechy liczb zmiennopozycyjnych. Najbardziej znaczący bit jest bitem znaku (1-liczba dodatnia, 0-liczba 
ujemna). Dalej podobnie jak w U2. Jeśli liczba jest dodatnia to wartość liczby zakodowana jest w NKB, a jeśli liczba posiada znak ujemny to negacja 
pozostałej części liczby, po dodaniu 1 stanowi jej wartość poniŜej zera. Występuje pojedyncza reprezentacja zera. 
BCD – kod binarny liczb dziesiętnych reprezentowanych w postaci tetrad (czwórek bitów) reprezentujących kolejne cyfry dziesiętne. KaŜda tetrada 
koduje cyfrę w NKB. Pierwszy bit jest bitem znaku (0-liczba dodatnia, 1-liczba ujemna) 

 

Liczba 

ZM 

U1 

U2 

BIAS 

BCD 

-128 

 

 

10000000 

00000000 

 

-127 

11111111 

10000000 

10000001 

00000001 

1000100100111 

-126 

11111110 

10000001 

10000010 

00000010 

1000100100110 

... 

... 

... 

... 

... 

... 

-1 

10000001 

11111110 

11111111 

01111111 

1000000000001 

10000000 

11111111 

00000000 

10000000 

1000000000000 

00000000 

00000000 

00000000 

10000000 

0000000000000 

00000001 

00000001 

00000001 

10000001 

0000000000001 

00000010 

00000010 

00000010 

10000010 

0000000000010 

00000011 

00000011 

00000011 

10000011 

0000000000011 

00000100 

00000100 

00000100 

10000100 

0000000000100 

... 

... 

... 

... 

... 

... 

126 

01111110 

01111110 

01111110 

11111110 

0000100100110 

127 

01111111 

01111111 

01111111 

11111111 

0000100100111 

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  15 

REPREZENTACJA LICZB ZMIENNOPOZYCYJNYCH 

 

Binarny zapis liczb składa się z trzech części kodowanych o osobnych polach: 

jednobitowe pole 

znaku

 (ang. sign) 

n –  bitowe pole części ułamkowej zwane 

mantysą S 

(ang significant part) 

m – bitowe pole części wykładniczej zwane 

cechą E

 (ang. exponent part) 

 

Liczba A = +/- S * B 

+/- E

 gdzie B jest podstawą wykładnika i zwykle przyjmuje się 2, 10, 16 

 

Część ułamkowa mantysa S jest zawsze z przedziału: [0.5, 1) lub inaczej 0.5 <= S < 1  
A w postaci binarnej:  

0.1

00...0 <= S =< 

0.1

11 ....1  co oznacza 0*2

0

 + 1*2

-1

 + 0* .... =0.5 

MoŜna zauwaŜyć, Ŝe dwie pierwsze pozycje binarne dla całego przedziału są 

takie same

 zatem: 

0.1

 a 

-2 

-3

… a 

-(n+1)

 co oznacza: 1*2

-1

+ a 

-2

 * 2

-2

 + a 

-3

 * 2

-3

 + ... + a 

-(n+1) 

* 2

-(n+1) 

 

Przykładowe długości cechy i mantysy [bity] 

Komputer 

Słowo 

Znak 

Mantysa 

Cecha 

VAX11 

32 

23 

Intel 

80 

64 

15 

Standard 

IEEE754 

64 
32 


48 
23 

15 

 

Standard IEEE 754 dla mantysy 23 bitowej i cechy 8 bitowej umoŜliwia zapis liczb 
od 0.5*2

-128

 do (1-2

-24

) 2

+127

 

 

 
 
-(1-2

-24

) 2

+127

                  - 0.5*2

-128

   +0.5*2

-128

                        +(1-2

-24

) 2

+127

 

                                                        0 

Przykład przeliczenia danej dziesiętnej na binarną postać zmiennoprzecinkową: 

 

Liczba: 0,625625 * 10

   moŜna przedstawić jako 625,625  

Osobno traktując część całkowitą 625 moŜna ją zapisać binarnie jako 

10 0111 0001

 

Część ułamkowa: 0,625 jest sumą 0,5 i 0,125 czyli 1*2

-1

 + 0* 2

-2

 + 1*2 

–3

 zatem 0.

101

 

W rezultacie otrzymujemy liczbę 

10 0111 0001

.101 

PoniewaŜ część całkowita mieści się na 10 bitach normalizujemy liczbę przesuwając o 10 pozycji 
w prawo – robiąc z niej ułamek z częścią wykładnika o wartości 10: 

0.1001110001

101

 * 2

10

 

ale odrzucamy równieŜ przy zapisie mantysy dwa pierwsze bity:       

0.1

001110001101 

 

Bit znaku 

Mantysa 

cecha 

0 (dodatnia) 

0011 1000 1101

 0000 0000 000 

1

 

0001010

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

znak cechy (zapis polaryzowany BIAS) 

Trudność moŜe sprawić przekształcenie części ułamkowej do mantysy. Często trzeba 
normalizować liczbę dziesiętną do odpowiedniego zakresu aby część ułamkowa mieściła się w 
zakresie od 0,5 do 1.

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  16 

Przykład. Sprawdzanie rozmiarów typów zmiennych istniejących w twoim 
komputerze 

 

#include <iostream> 
 
int main(){ 
using std::cout; 
cout << "Rozmiar zmiennej typu int to:\t\t"<< sizeof(int) << " bajty.\n"; 
cout << "Rozmiar zmiennej typu short int to:\t"<< sizeof(short) << " bajty.\n"; 
cout << "Rozmiar zmiennej typu long int to:\t"<< sizeof(long) << " bajty.\n"; 
cout << "Rozmiar zmiennej typu char to:\t\t"<< sizeof(char) << " bajty.\n"; 
cout << "Rozmiar zmiennej typu float to:\t\t"<< sizeof(float) << " bajty.\n"; 
cout << "Rozmiar zmiennej typu double to:\t"<< sizeof(double) << " bajty.\n"; 
cout << "Rozmiar zmiennej typu bool to:\t"<< sizeof(bool) << " bajty.\n"; 
return 0; 

 
 
 
 
 
 
 
 
 
 
 
 
UWAGA:  W twoim komputerze rozmiary zmiennych mog
ą być inne. 
 
 
 

Efekt: 

Rozmiar zmiennej typu 

int

 to: 4 bajty. 

Rozmiar zmiennej typu 

short int

 to: 2 bajty. 

Rozmiar zmiennej typu 

long int

 to: 4 bajty. 

Rozmiar zmiennej typu 

char

 to: 1 bajty. 

Rozmiar zmiennej typu 

float

 to: 4 bajty. 

Rozmiar zmiennej typu 

double

 to: 8 bajty. 

Rozmiar zmiennej typu 

bool

 to: 1 bajty. 

 

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  17 

DEFINICJA TYPÓW przez typedef 

 

Dla przykładu ciągłe wpisywanie 

unsigned short int 

moŜe być Ŝmudne, a co gorsza, moŜe 

spowodować wystąpienie błędu. 
C++ umoŜliwia uŜycie słowa kluczowego 

typedef 

(od 

type definition

, definicja typu), dzięki 

któremu moŜesz stworzyć skróconą formę takiego zapisu. 
Dzięki skróconemu zapisowi tworzysz 

synonim

, lecz zwróć uwagę, Ŝe 

nie jest to nowy typ

Przy zapisywaniu synonimu typu uŜywa się słowa kluczowego 

typedef

, po którym wpisuje się 

istniejący typ, zaś po nim nową nazwę typu.  
Na przykład: 

 

typedef unsigned short int USHORT; 

 

tworzy nową nazwę typu, 

USHORT

, której moŜna uŜyć wszędzie tam, gdzie mógłbyś uŜyć 

zapisu 

unsigned short int

.  

 

Przykład uŜycia 

typedef 

// ***************** 
// Demonstruje u
Ŝycie słowa kluczowego typedef 
#include <iostream> 
typedef unsigned short int USHORT; //definiowane poprzez: typedef 
 
int main() { 
using std::cout;using std::endl; 
USHORT Width = 5; 
USHORT Length; 
Length = 10; 
USHORT Area = Width * Length; 

// UWAGA: * (gwiazdka) oznacza mnoŜenie. 

cout << "Szerokosc:" << Width << "\n"; 
cout << "Dlugosc: " << Length << endl; 
cout << "Obszar: " << Area <<endl; 
return 0; 

 
 
 
 
 

 

Analiza 
W linii 4. definiowany jest synonim 

USHORT 

dla typu 

unsigned short int

.  

Efekt: 

Szerokosc:5 
Dlugosc: 10 
Obszar: 50 
 

 

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  18 

STAŁE 

Do przechowywania danych słuŜą takŜe stałe - wartość stałej nie ulega zmianie. Podczas 
tworzenia stałej trzeba ją zainicjalizować, później nie moŜna juŜ przypisywać jej innej wartości. 
C++ posiada dwa rodzaje stałych: 

literały

 i 

stałe symboliczne

 

LITERAŁY 

Literał jest wartością wpisywaną bezpośrednio w danym miejscu programu. Na przykład: 

int mojWiek = 

19

mojWiek 

jest zmienną typu 

int

 i moŜe być przypisywana dowolna wartość z zakresu 

int

 w 

dowolnym momencie działania programu w miejscu dostępu do zmiennej; 

19

 jest literałem. Programista umawia się sam ze sobą, Ŝe nie będzie zmieniał wartości literału w 

trakcie działania programu. WARTOŚĆ TA MOśE ALE NIE POWINNA BYĆ ZMIENIANA. 
 
 

STAŁE SYMBOLICZNE 

Stała symboliczna jest reprezentowana poprzez swoją nazwę - po zainicjalizowaniu stałej, nie 
moŜna później zmieniać jej wartości. 

• 

Definicja klasyczna z uŜyciem dyrektywy preprocesora 

#define

 przez proste podstawienie 

tekstu: 

#define STUDENCI 89 

gdzie stała 

STUDENCI 

nie ma określonego typu (

int

char

, itd.). Za kaŜdym razem, gdy 

preprocesor natrafia na słowo 

STUDENCI

, zastępuje je napisem 

89

 

• 

Definicja stałych za pomocą 

const

gdzie stała posiada swój typ 

const unsigned short int STUDENCI = 89; 

 
Stała ma typ, którym jest 

unsigned short int

Zalety 

const

kod programu jest łatwiejszy w konserwacji i jest bardziej odporny na błędy, 

kompilator moŜe wymusić uŜycie jej zgodnie z tym typem. 

UWAGA Stałe nie mogą być zmieniane podczas działania programu. Jeśli chcesz na 
przykład 
zmienić wartość stałej 

STUDENCI

, musisz zmodyfikować kod źródłowy, po czym 

skompilować program ponownie. 

 
MoŜliwy jest zapis liczb w formie wykładniczej:8e2 (8*10

2

), 10.4e8 (10.4*10

8

), 5.2e-3 (5.2*10

-3

 

STAŁE WYLICZENIOWE 

Stałe wyliczeniowe umoŜliwiają tworzenie nowych typów, a następnie definiowanie ich 
wartości, które ograniczają się do wartości określonych w definicji typu. 
Na przykład, moŜesz zadeklarować typ 

COLOR 

(kolor) jako wyliczenie, dla którego moŜesz 

zdefiniować pięć wartości: 

RED

BLUE

GREEN

WHITE 

oraz 

BLACK

Składnię definicji wyliczenia stanowią słowo kluczowe 

enum

, nazwa typu, otwierający nawias 

klamrowy, lista wartości oddzielonych przecinkami, zamykający nawias klamrowy oraz średnik. 
 

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  19 

Przykład: 

enum

 

COLOR

 { 

RED, BLUE, GREEN, WHITE, BLACK

 }; 

 
W efekcie nowe wyliczenie otrzymuje nazwę 

COLOR

, tj. tworzony jest nowy typ. 

RED 

(czerwony) jest stałą symboliczną o wartości 

0

BLUE 

(niebieski) jest stałą symboliczną o wartości 

1

GREEN 

(zielony) jest stałą symboliczną o wartości 

2

, itd. 

 
KaŜda wyliczana stała posiada wartość całkowitą. Jeśli tego nie określisz, zakłada się Ŝe pierwsza 
stała ma wartość 

0

, następna 

1

, itd. KaŜda ze stałych moŜe zostać zainicjalizowana dowolną 

wartością. Stałe, które nie zostaną zainicjalizowane, będą miały wartości naliczane począwszy od 
wartości od jeden większej od wartości stałych zainicjalizowanych. Zatem, jeśli napiszesz: 
 

enum

 

COLOR

 { RED=100, BLUE, 

GREEN=500

, WHITE, BLACK=700 }; 

To: 

RED 

będzie mieć wartość 

100

BLUE 

będzie mieć wartość 

101

GREEN 

wartość 

500

WHITE 

(biały) wartość 

501

BLACK 

(czarny) wartość 

700

MoŜesz definiować zmienne typu 

COLOR

, ale mogą one przyjmować tylko którąś z wyliczonych 

wartości (w tym przypadku 

RED

BLUE

GREEN

WHITE 

lub 

BLACK

, albo 

100

101

500

501 

lub 

700

). Zmiennej typu 

COLOR 

moŜesz przypisać dowolną wartość koloru. 

W rzeczywistości moŜesz przypisać jej dowolną wartość całkowitą, nawet jeśli nie odpowiada 
ona dozwolonemu kolorowi - dobry kompilator powinien w takim przypadku wypisać 
ostrzeŜenie. NaleŜy zdawać sobie sprawę, Ŝe stałe wyliczeniowe to w rzeczywistości zmienne 
typu 

unsigned int 

oraz Ŝe te stałe odpowiadają zmiennym całkowitym. MoŜliwość nazywania 

wartości okazuje się bardzo pomocna, na przykład podczas pracy z kolorami, dniami tygodnia 
czy podobnymi zestawami. 
Przykład stałych wyliczeniowych 

#include <iostream> 
int main() { 
enum Days { Sunday, Monday, Tuesday, 
Wednesday, Thursday, Friday, Saturday }; 
 
Days today; 
today = Monday; 

//przypisanie

 

 
if (today == 0 || today == Saturday) 

//sprawdzanie warunku

 

std::cout << "\nUwielbiam weekendy!\n"; 

else 

std::cout << "\nWracaj do pracy.\n"; 

return 0; 

Efekt: 

Wracaj do pracy.

 

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  20 

Analiza 
W linii 3. definiowana jest stała wyliczeniowa 

Days 

(dni), posiadająca siedem, odpowiadających 

dniom tygodnia, wartości. KaŜda z tych wartości jest wartością całkowitą, numerowaną od 

górę (tak więc 

Monday 

— poniedziałek — ma wartość 

1

)1. 

Tworzymy teŜ zmienną typu 

Days 

— tj. zmienną, która będzie przyjmować wartość z listy 

wyliczonych stałych. W linii 7. przypisujemy jej wartość wyliczeniową 

Monday

, którą następnie 

sprawdzamy w linii 9. 
 
Program podobny do poprzedniego, ale wykorzystujący stałe całkowite 

#include <iostream> 
int main() { 
const int Sunday = 0; 
const int Monday = 1; 
const int Tuesday = 2; 
const int Wednesday = 3; 
const int Thursday = 4; 
const int Friday = 5; 
const int Saturday = 6; 
 
int today; 
today = Monday; 
 
if (today == Sunday || today == Saturday) 

std::cout << "\nUwielbiam weekendy!\n"; 

else 

std::cout << "\nWracaj do pracy.\n"; 

 
return 0; 

 
 
 
 

 

Analiza 
ISTOTNY FAKT: Amerykanie liczą dni tygodnia zaczynając od niedzieli.

 

Wynik działania tego programu jest identyczny z wynikiem programu z listingu 3.7. W tym 
programie kaŜda ze stałych (

Sunday

Monday

, itd.) została zdefiniowana jawnie i nie istnieje typ 

wyliczeniowy 

Days

. Stałe wyliczeniowe mają tę zaletę, Ŝe się same dokumentują — 

przeznaczenie typu wyliczeniowego 

Days 

jest oczywiste. 

 

Efekt: 

Wracaj do pracy.

 

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  21 

PRZESTRZEŃ NAZW 

 
Istnieje zdefiniowana (wbudowana) przestrzeń nazw std (od standard). 
 
W języku C++ uŜywamy nazw plików nagłówkowych bez .h na końcu. 
 

#include <iostream> 

a nie tak jak poprzednio 

#include <iostream.h>

 (ang. obsolete) 

 
UŜycie zmiennych i funkcji wymaga wskazania do jakiej przestrzeni nazw naleŜą. 
MoŜna to zrobić na trzy sposoby: 
 

1.  definicja globalna przestrzeni nazw 

 
przed main deklarujemy: 
 

using namespace std; 
 
int main() { 
….. 
cout<<”Co
ś tam”; 

 

2.  definicja lokalna uŜycia przestrzeni nazw 

 
w main oraz w inych funkcjach – wewnątrz klamry 
 

int main () { 
using std::cout; 
…. 
cout<<”Co
ś tam”; 
…. 

3.  bezpośrednie wskazanie przestrzeni nazw, do której naleŜy dana funkcja przy kaŜdym 

wywołaniu funkcji 

 

int main () { 
… 
std::cout<<”Co
ś tam”; 
… 

 
 
 
 
 

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  22 

ZNAKI 

Zmienne znakowe (typu 

char

) zwykle mają rozmiar jednego bajtu, co wystarczy do przechowania 

jednej z 256 wartości (patrz dodatek C). Typ 

char 

moŜe być interpretowany jako mała liczba (od 

0 do 255) lub jako element zestawu kodów ASCII. Skrót ASCII pochodzi od słów American 
Standard Code for Information Interchange. Zestaw znaków ASCII oraz jego odpowiednik ISO 
(International Standards Organization) słuŜą do kodowania wszystkich liter (alfabetu 
łacińskiego), 
cyfr oraz znaków przestankowych. 

UWAGA Komputery nie mają pojęcia o literach, znakach przestankowych i zdaniach. 
Rozpoznają tylko liczby. ZauwaŜają tylko odpowiedni poziom napięcia na określonym złączu 
przewodów. Jeśli występuje napięcie, jest ono symbolicznie oznaczane jako jedynka, zaś gdy 
nie występuje, jest oznaczane jako zero. Poprzez grupowanie zer i jedynek, komputer jest w 
stanie generować wzory, które mogą być interpretowane jako liczby, które z kolei moŜna 
przypisywać literom i znakom przestankowym. 

W kodzie ASCII mała litera „a” ma przypisaną wartość 97. Wszystkie duŜe i małe litery, 
wszystkie cyfry oraz wszystkie znaki przestankowe mają przypisane wartości pomiędzy 0 a 127. 
Dodatkowe 128 znaków i symboli jest zarezerwowanych dla „wykorzystania” przez producenta 
komputera, choć standard kodowania stosowany przez firmę IBM stał się niejako 
„obowiązkowy”. 

UWAGA ASCII wymawia się jako „eski.” 
 

ZNAKI i LICZBY 

Gdy w zmiennej typu 

char 

umieszczasz znak, na przykład „a”, w rzeczywistości jest on liczbą 

pochodzącą z zakresu od 0 do 255. Kompilator wie jednak, w jaki sposób odwzorować znaki 
(umieszczone wewnątrz apostrofów) na jedną z wartości kodu ASCII. 
 
Przykład wypisywania znaków na podstawie ich kodów 

#include <iostream> 
int main(){ 
for (int i = 32; i<128; i++) 
std::cout << (char) i; 
return 0; 

 
 
 
 
 
 
 
 

 

Ten prosty program wypisuje znaki o wartościach od 32 do 127. 
 

Efekt: 

!"#$%&'()*+,-./0123456789:;<=>?@ABCDEF 
GHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijkl 
mnopqrstuvwxyz{|}~_

 

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  23 

ZNAKI SPECJALNE 

Kompilator C++ rozpoznaje pewne specjalne znaki formatujące. 
 

Znak 

Oznacza 

\a

 

Alarm (dzwonek) 

\b

 

Backspace (znak wstecz) 

\f 

Form feed (koniec strony) 

\n 

New line (nowa linia) 

\r 

Carriage return (powrót „karetki”; powrót na 
początek linii) 

\t 

Tab (tabulator) 

\v 

Vertical tab (tabulator pionowy) 

\' 

Single quote (apostrof) 

\" 

Double quote (cudzysłów) 

\? 

Question mark (znak zapytania) 

\\ 

Backslash (lewy ukośnik) 

\0oo 

Zapis ósemkowy 

\xhhh 

Zapis szesnastkowy 

 
 
Przed uŜyciem znaków specjalnych jako zwykłych znaków tj, \ ‘ ” 0 ? powinien pojawić się \ 
zdejmujący znaczenie specjalne, np. ” \” ”, ‘\’ ’, ‘\0’ (znak Zero – Null) 
 
 
 

background image

WYKŁADY cz.1 v.1 (2007)          Podstawy programowania 1           

(dr.inŜ Marcin Głowacki)

  24 

KONWERSJE / RZUTOWANIE TYPÓW 

Jeśli podczas przetwarzania danych w operacji pojawiają się zmienne typów niespodziewanych 
lub niezgodnych z definicją moŜe następować jawna lub niejawna konwersja typów zmiennych. 

 

Konwersje niejawne występują w wyniku próby automatycznego dopasowania przez kompilator 
typów zmiennych dla wykonania zadanej operacji, np.: 

int m,n; 
n=10; 
m=n+1.2345; 

W ostatnim wierszu dokonana została automatyczna konwersja zmiennej n na double, a następnie 
po wykonaniu dodania konwersja sumy do typu int zanim nastąpiło przypisanie do m. 
W wyniku operacji m będzie równe 11 (nastąpi odcięcie części ułamkowej, a nie zaokrąglenie). 

 

Konwersja jawna jest wywoływana świadomie przez programistę. 
Formy zapisu jawnej konwersji: 
dany_typ wynik, wyraŜenie_1; 
inny_typ wyraŜenie_2; 

 

forma funkcji 

 

 

wynik = wyraŜenie_1 + dany_typ(wyraŜenie_2); 

forma rzutowania 

 

wynik = wyraŜenie_1 + (dany_typ)wyraŜenie_2; 

Przykład: 

int m,n; 
n=10; 
m=n+int(1.2345); 

 

Unika zbędnych konwersji niejawnych (n nie będzie konwertowane na double i double na int). 
Rezultat obliczeń będzie taki sam jak w poprzednim przykładzie. 
Przykład: 

#include <iostream> 
int main() { 
using std::cout; using std::endl; 
int wynik_i,m,n,a; 
float wynik_f,b; 
m=4;n=10; a=10;b=4; 
wynik_i=n+int(1.2345); 
cout << "wynik_i: " << wynik_i <<endl; 
wynik_f=n+1.2345; 
cout << "wynik_f: " << wynik_f <<endl; 
wynik_i=n/m; 
cout << "wynik_i: " << wynik_i <<endl; 
wynik_f=a/b; 
cout << "wynik_f: " << wynik_f <<endl; 
return 0; 

 

Efekt: 

Sam się przekonaj !