Sunteți pe pagina 1din 12

LUCRAREA 1

Scopul lucrrii este prezentarea unui scurt istoric a limbajului C i a noiunilor legate de lucrul pe
calculator (limbaj de programare, compilare, baze de numeraie) iar n final iniierea n folosirea
compilatorului Developer C++ prin rularea unor aplicaii tipice de conversie dintr-o baz de numeraie
n alta.

I.

OBSERVAII TEORETICE

1.1.

Scurt istoric C

Limbajul C a fost creat prima dat de ctre Dennis Ritchie i Brian Kernighan la
laboratoarele BELL Labs. din SUA. Versiunea premergtoare lui C a fost B. Odat creat el a fost
folosit - mpreun cu limbajul de asamblare - la scrierea complet a sistemului de operare UNIX.
Aceasta arat c limbajul are o putere i flexibilitate aparte.
1.2.

Limbajul C - caracteristici generale

Limbajul C se bucur de urmtoarele caracteristici:


- este de uz general, adic poate fi folosit att n scrierea de programe tip aplicaie ct
i n situaii dedicate (cum sunt metodele numerice - calcule tiinifice, grafic,
editoare de text .a.);
- de nivel mediu - cu relativ puine instruciuni se pot spune relativ multe lucruri; pe
scara aceasta de clasificare a limbajelor de programare C se afl deasupra limbajului
de asamblare, dar sub limbajele de nivel nalt: Pascal, C++, Java, SmallTalk, Python,
Eiffel, ADA, Fortran etc. (figur cu clasificarea limbajelor de programare din punct
de vedere al nivelului lor - sczut, mediu i nalt);
- compilat - n urma etapelor de compilare i editare a legturilor rezult un fiier
executabil (.exe sau .com); dac se terg de pe hard-disk toate fiierele cu excepia
acestui executabil despre care vorbim - presupunnd c nu se terg i fiierele sistem
- acest program va rula fr probleme majore; C este diferit de limbajele interpretate
(Visual Basic sau Java) n cazul crora n urm procesului de traducere a sursei n
limbaj apropiat de limbajul mainii pe care rulm nu avem un fiier executabil
concret. Ce se ntmpl n acest caz? Odat lansat codul surs, datorit asocierii,
este lansat automat interpretorul acelui limbaj, care preia sursa i o execut,
succesiv, linie cu linie. Efectele instruciunilor se reflect ca i n cazul unui program
executabil. De obicei compilatoarele sunt mai rapide dect interpretoarele, n sensul
c genereaz cod obiect mai rapid. n ultima vreme, deoarece limbajul Java se

ndrumar de laborator

1.3.

impune ca un standard de facto n programarea Internet (s-a i impus, de altfel),


unde este nevoie de rapiditate - suntem foarte aproape de cerinele unui software n
timp real -, nu ar fi deloc de acceptat o ntrziere n ncrcarea paginilor Web, tocmai
datorit timpului de interpretare datorat applet-urilor Java cuprinse de acele
pagini. Programele compilate sunt, n plus, i mai compacte dect cele interpretate;
portabil - adic odat dus de pe o platform hardware pe o alta programul nu are
nevoie de modificri, sau are nevoie de foarte puine modificri pentru a rula corect.
Comportamentul programului aste analog (se poate spune aproape perfect analog)
pe cele dou platforme. La aceasta contribuie i standardizarea limbajului.
flexibil i puternic - C combin flexibilitatea limbajului de asamblare cu puterea
nivelului su mediu.
Baza de numeraie 2 (sistemul BINAR)

Ca n orice baz de numeraie, cifrele folosite n reprezentarea numerelor sunt cuprinse n


intervalul:
[0, baza-1]

Rezult c n baza 2 avem o reprezentare a numerelor folosind doar cifrele 0 i 1.


Fiecare dintre cifrele semnificative ale unei baze de numeraie poart denumirea de digit. n
baza 2 deoarece sunt doar doi digii posibili acetia au preluat denumirea de binary digit (bit). De
aici proveniena cuvntului bit.
n baza 10 aceste cifre sunt 0...9. Alte baze de numeraie folosite n legtur cu sistemul binar
sunt: 4, 8 (octal) i 16 (hexazecimal). Pentru baza 16 cifrele de reprezentare sunt:
0..9 i A..F

deoarece nu s-ar putea spune dac, de exemplu, combinaia 12 este obinut prin alturarea
cifrelor 1 i 2 ca cifre utile de reprezentare, sau este luat ca atare (12). Ar rezulta un mod de
reprezentare echivoc, din moment ce 12 este i valoare separat, dar i o alturare de alte dou
cifre semnificative ale bazei de numeraie 16. S-a convenit atunci folosire primelor litere ale
alfabetului, cu semnificaia:
A ine locul lui 10
B lui 11
...
E lui 14
F lui 15.

n calculatoarele actuale baza de numeraie este 2. Au existat ncercri de creare a unor


calculatoare n baz 10, dar nu s-au putut ridica la performanele calculatoarelor binare. S-a
pstrat astfel sistemul binar ca standard pentru calculatoarele digitale.
S lum un exemplu de numr n baza 2:

0110 1101

Ce nseamn acesta? Cum poate fi interpretat astfel nct s poat fi neles de ctre noi
(adic tradus n baza 10)?

Lucrarea 1

La aceste ntrebri se rspunde plecnd de la regula de reprezentare n orice baz de


numeraie (poziional): fiecrei poziii n numr i corespunde o putere a acelei baze de
numeraie.
Astfel, primei poziii din dreapta i corespunde puterea 0 a lui 2, urmtoarei poziii i
corespunde puterea 1 a lui 2, iar ultimei poziii (prima din stnga) i corespunde puterea 7 a lui
2. Atunci putem genera valoarea acestui numr n baza 10 - plecnd de la dreapta spre stnga astfel:
1*20 + 0*21 + 1*22 + 1*23 + 0*24 + 1*25 + 1*26 + 0*27 = 1 + 4 + 8+ 32 + 64 = 109|10

La fel procedm cu un numr n baza 10 cnd dorim s-i aflm valoarea. Dar, n baza 10
interpretm natural i aproape instantaneu orice numr, care ne sugereaz i o puternic
semnificaie "cantitativ" (adic mrimea acelui numr).
Exemplu:
578

tim imediat c avem de-a face cu 'cinci sute aptezeci i opt' i c acesta se situeaz cam la
jumtatea gamei [0-1000].
Bitul va fi notat de acum nainte cu b. Combinaia de 8 bii succesivi se numete Byte
(octet) i va fi reprezentat prin litera B de acum nainte. Combinaia de 4 bii poart denumirea
de nibble.
Am amintit mai sus i de bazele de numeraie 4, 8 i 16. Vom transforma numrul dat n
baza 2 n aceste baze de numeraie, dar nainte 's numrm' pn la 8 n baza 2.
0000
0001
0010
0011

//
//
//
//

0|10
1|10
2|10
3|10

0100
0101
0110
0111

//
//
//
//

4|10
5|10
6|10
7|10

1000
1001
1100
...
1111

// 8|10
// 9|10
//10|10

10000

//16|10

//15|10

Putem continua n aceeai manier, dar deja se pot trage anumite concluzii.
Observai c s-a fcut o delimitare (o linie liber) ntre valorile 3 i 4, i ntre 7 i 8 (zecimal).
Sunt poziiile n care numrul de bii crete cu o unitate. ntre 3 i 4 trecem de la o reprezentare pe
2 digii (sau bii) la o reprezentare pe 3 bii. Aceasta deoarece pn la valoarea 3 am acoperit

ndrumar de laborator

toate combinaiile posibile de 1 i 0 pe cele dou poziii avute la dispoziie. Cte sunt aceste
combinaii pentru 2 bii? Sunt 4 adic 22. Pn aici avem baza 4 - deoarece cifrele semnificative,
dup cum se vede, sunt 0, 1, 2 i 3.
Continund, trecem aadar la o reprezentare pe trei bii, pentru care combinaiile posibile sunt
8, adic 23. Pn la linia liber ntre 7 i 8 n zecimal avem baza de reprezentare 8, cu cifrele de la
0 la 7.
Urmtoarea trecere se face ntre valorile zecimale 15 i 16, moment n care bitul al cincilea
(din dreapta) intr n joc.
Concluzie:
Fiecare nou bit adugat dubleaz gama de reprezentare, deoarece fiecare nou digit trebuie s ia
valorile de 0 i de 1 posibile pentru acea nou poziie, dar n legtur cu combinaiile de 1 i 0
din dreapta sa. Am marcat cu alb apariia digitului al treilea i valorile de 0 i 1 pe care acesta ele
ia, i cu rou bitul al patrulea nou adugat.
ntr-un numr n baza 2 sunt importante dou poziii:
- Prima din dreapta - care poart denumirea de Least Significant bit (LSb);
o 0 are semnificaia de numr par;
o 1 are semnificaia de numr impar;
- Prima din stnga - care poart denumirea de Most Significant bit (MSb).
Poziia MSb are de obicei rolul de semn al numrului:
o 0 are semnificaia de plus;
o 1 are semnificaia de minus.
Vom vedea la tipurile de date exact ce am vrut s spunem.
Aadar s traducem n bazele 4, 8 i 16 combinaia dat anterior:

0110 1101

Pentru baza 4 am vzut c sunt necesari 2 bii pentru a reprezenta cifrele semnificative ale
acestei baze de numeraie. Atunci, pornind din dreapta, vom grupa doi cte doi biii dai,
rezultnd patru combinaii de cte 2 bii:
01 10 11 01

Traducem apoi n zecimal combinaiile obinute i astfel ajungem la reprezentarea n baza 4.


Obinem, de la stnga la dreapta:
1

Pentru baza 8 sunt necesari 3 bii pentru a reprezenta cifrele semnificative ale acestei baze

de numeraie. Pornind din dreapta, vom grupa de aceast dat trei cte trei biii dai, rezultnd
combinaii de cte 3 bii. Dac nu avem un umr de bii care s se mpart exact la 3, vom
considera c poziiile lips pn la trei poziii - n cazul poziiei din extrema stng - s u n t
c o m p l e t a t e c u 0 - sunt nesemnificative:
001 101 101

Traducem apoi n zecimal combinaiile obinute i astfel ajungem la reprezentarea n baza 8.


Obinem, de la stnga la dreapta:

Lucrarea 1

5
1

Pentru verificare putem scrie:

1*82 + 5*8 + 5 = 64 + 40 + 5 = 109|10

Obinem aceeai valoare cu cea din traducerea direct n baza 2 astfel c am convertit corect
n baz 8 numrul dat.
Pentru baza 16 sunt necesari 4 bii pentru a reprezenta cifrele semnificative ale sistemului
hexazecimal. Ca i pn acum, pornind din dreapta, vom grupa biii patru cte patru, rezultnd
n cazul de fa dou combinaii a 4b.
0110 1101

Rmne s traducem aceste combinaii n zecimal i avem:


6

Verificarea ne d:

6*16 + 13 = 96 + 13 = 109|10

Deci este corect.


1.4.

Structura oricrui program C - scurte detalieri

Aceste scurte detalieri au rolul de a furniza minimul de informaie pentru a putea scrie chiar
de acum un program C.
Aadar:
A.
Comentariu - cu rolul explicrii n cteva cuvinte a rolului i scopului
programului;
n C exist urmtorul stil de comentariu:
sau

/* ... */

pentru comentariu pe o linie

/* ...
...
... */

pentru comentariu pe mai multe linii.

n C++ exist i varianta unic:


//

prin care linia astfel nceput va fi ignorat n totalitate.


B.

Fiierele header - cu extensia .h sau fiierele antet. Rolul lor este de a ncuraja
modularizarea programului. Vom vedea imediat ce conin aceste fiiere.

Fiierele header apar la nceputul unui program. Prezena lor este impus de
anumite funcii ce urmeaz s fie folosite n acel fiier, i al cror prototip
(declaraie de funcie) aparine acelui header.
Aceste fiiere sunt incluse n codul surs al programului cu ajutorul directivei
preprocesor #include
Sintaxa valabil este:
sau

#include<nume.h>

ndrumar de laborator

#include"nume.h"

n prima variant compilatorul caut acel fiier n subdirectorul INCLUDE al directorului


unde a fost instalat compilatorul. Acest director conine toate fiierele antet cu care "vine"
compilatorul (la instalarea acestuia).
n cea de-a doua variant fiierul antet specificat este cutat mai nti n directorul curent
de lucru - adic n directorul unde a fost salvat codul surs al programului la care se lucreaz.
Dac nu este gsit n acel loc, cutarea sa se face n acel subdirector implicit al fiierelor header
(INCLUDE).
C.
Definiii de constante, definiii de tip, declaraii/definiii de variabile globale.
- Definiiile de constante sunt nsoite de directiva preprocesor:
#define

Sintaxa valabil este:

#define NUME_CONSTANTA valoare

prin care se asociaz numelui NUME_CONSTANTA valoarea valoare. Din acest moment,
oriunde avem dreptul de a folosi valoarea numeric asociat, se va nlocui prezena numelui
NUME_CONSTANTA cu valoarea asociat acesteia.
Se recomand folosirea literelor mari pentru a se ti c acea denumire a fost undeva definit
de ctre programator.
-

Definiii de tip

Se fac cu ajutorul operatorului typedef. Un exemplu doar, urmnd s detaliem sintaxa


la momentul potrivit.
typedef int INTREG;

Prin aceast instruciune (se ncheie cu;) se d un alt nume (sau alias) tipului de
baz C integer (specificat prin cuvntul-cheie int). Folosirea noii denumiri se traduce
de fapt prin folosirea tot a lui int, dar n mod indirect. Construcia este util pentru
definirea de tipuri mai complexe (cum sunt tipurile vector, matrice sau structur), ca i
pentru utilizarea unor denumiri mai sugestive n locul celor deja existente n limbaj.
Este recomandat ca denumirea asociat s fie scris cu majuscule, pentru a se face
diferenierea fa de denumirile de variabile care de obicei apar n scriere cu
minuscule.
-

Declaraii/definiii de variabile globale

Sintaxa este neschimbat fa de aceeai declarare/definire de variabile locale. Doar


poziia n care apare declaraia/definiia impune denumire de global. Global are
semnificaia de a fi cunoscut n ntreg fiierul curent. Toate funciile din acest fiier
vor cunoate aceste variabile. O denumire sugestiv pentru ele este de publice. De
obicei se evit folosirea acestora, datorit efectelor secundare pe care le genereaz
atunci cnd sunt folosite (comentariu: dou funcii apelate succesiv).

Lucrarea 1

7
1.5.

Detalii de programare

Pentru nelegerea programelor utilizate n lucrare studiai ANEXA lucrrii.


1.6.

Comenzile compilatorului

nainte de compilare codul surs trebuie salvat (cu combinaia de taste CTRL+S), sau,
echivalent, din meniul File, cu comanda Save as.
Compilarea se va face cu comanda CTRL+F9, iar rularea cu comanda CTRL+F10. Compilarea i
rularea se pot executa, succesiv, printr-o singur tast, anume F9. Aciunile echivalente din
meniu: meniul Execute comanda Compile, respectiv Compile + Run.
Observaii:
1.
Orice nou modificare a codului-surs trebuie urmat obligatoriu de salvarea acestuia
(CTRL+S). Abia dup aceea pot urma celelalte aciuni dorite.
2.
Dac nu se realizeaz aducerea la zi a programului, compilarea i rularea ce urmeaz
se fac tot pe varianta veche, adic ce de dinaintea ultimelor modificri.

II.

DESFURAREA LUCRRII
2.1. S se converteasc din sistemul binar n sistemul zecimal numerele reprezentate
prin combinaiile de bii urmtoare:
a) 0111 1010
b) 110 0111

Conversia se va face:
manual, pe hrtie,
prin rularea programului baza2_10.cpp.
Verificai apoi cele dou rezultate.
2.2.
S se converteasc din sistemul zecimal n sistemul binar numerele reprezentate
prin:
a) 2110
b) 137
c) 256

Conversia se va face:
manual, pe hrtie,
prin rularea programului de conversie asociat.
Verificai apoi cele dou rezultate.

ndrumar de laborator

2.3.
S se converteasc din sistemul zecimal n sistemul hexa-zecimal numerele
reprezentate prin:
a) 127
b) 1024
c) 749

Conversia se va face:
manual, pe hrtie,
prin rularea programului de conversie asociat.
Verificai apoi cele dou rezultate.
2.4. S se converteasc din sistemul hexa-zecimal n sistemul binar numerele
reprezentate prin:
a)
b)
c)
d)

ABC
FFFF
1F0
1FFF

Conversia se va face:
manual, pe hrtie,
prin rularea programului de conversie asociat.
Verificai apoi cele dou rezultate.
2.5. Calculai complementul de 1 i de 2 pentru numerele:
a)
b)
c)
d)
e)
f)

127
-256
-1023
234
0011 1011
1111 0011

Conversia se va face:
manual, pe hrtie,
prin rularea programului dedicat complementului.
Verificai rezultatele.
2.6. Adunai i scdei n sistemul binar i n cel hexazecimal numerele:
a)
b)
c)
d)
e)
f)

123 + 1FF
AAAA FFFF
5210 0A7B
0111 1101
0011 + 1111
1010 - 0101

Conversia se va face:
manual, pe hrtie,
prin rularea programelor de conversie ntre diferitele baze de
numeraie.
Verificai apoi rezultatele.

Lucrarea 1

9
2.7. nmulii i mprii n sistemul binar:

a) 0111 * 1101
b) 0011 / 1111
c) 1010 * 0101 / 0010

Conversia se va face:
manual, pe hrtie,
prin rularea programelor de conversie ntre diferitele baze de
numeraie.
Comparai rezultatele.

III.

NTREBRI
3.1.
3.2.
3.3.
3.4.
3.5.
3.6.
3.7.
3.8.
3.9.
3.10.

IV.

Ce este i ce conine un fiier header?


n ce zon din program pot aprea fiierele header?
typedef este directiv de pre-procesor?
# define este directiv de pre-procesare?
Constantele pot fi definite cu typedef?
Constantele pot fi definite cu # define?
Cum trebuie ncadrate numele fiierelor header?
Pot aprea spaii nainte sau dup numele fiierelor header?
Pentru numerele -128 i +12345 artai rolul LSb i MSb.
Ce semnific baza de numeraie poziional?

ANEXA - sursele complete ale programelor


// 10 in 2 - nerecursiv
#include<stdio.h>
#include<conio.h>
int b10_b2(int, int);
int main(void)
{
int b10 = 1022, b2 = 2;
clrscr();
printf("\n Numarul de impartiri: %i", b10_b2(b10, b2) );
getch();
}

ndrumar de laborator
int b10_b2(int b10, int b2)
{
int pas = 0;
int d, cat, rest;
if(b10 < b2) b10 = b2; // pentru a putea face impartire corecta,
// deimpartitul este mai mare decat impartitorul.
cat = b10; // primul deimpartit.
do
{
d = cat;
cat = d/b2;
// catul impartirii a doi intregi.
rest = d % b2;
// restul impartirii a doi intregi.
printf("\n rest: %i", rest);
pas++;
} while(cat != 0);
return pas; // numarul de executii ale ciclului.
}
// baza 10 n baza 16
#include<stdio.h>
#include<conio.h>
#define SAU ||
typedef enum depasire9 {A=10, B, C, D, E, F} Baza16;
int baza10_16(int);
// prototipul functiei de calcul.
int _baza10_16(int, int*);
// prototipul functiei de calcul.
// parametrul al doilea este pentru resturile calculate,
// adica bitii numarului.
int main(void)
{
int nr10 = 508;
int i, l; // i pentru ciclul for(), iar l pentru lungimea vectorului.
int rest[8]; // retine resturile calculate in pasii de apel recursiv.
clrscr();
// scriu 0 in vector, astfel incat sa am valoare neutra in situatia
// scrierii lui 1. La scrierea unui 0 nu se intampla nimic.
l = sizeof(rest)/sizeof(int);
printf("\n Lungimea vectorului rest: %i", l);
for(i=0; i<l; i++) rest[i] = 0;

10

Lucrarea 1

11
// Apelurile functiilor.
// prima functie
puts("\n Prima functie scrie: ");
baza10_16(nr10);
// odata pornit apelul recursiv, el se va opri din interiorul
// functiei baza10_2().
getch();
// a doua functie
puts("\n\n A doua functie scrie: ");
nr10 = nr10;
// o noua initializare.
_baza10_16(nr10, rest);
// odata pornit apelul recursiv, el se va opri din
// interiorul functiei baza10_2().
for(i=l-1; i>=0; i--)
printf("\n pozitia %i, restul: %i", i, rest[i]);
getch();
}
int baza10_16(int nr10)
{
static int nrApel=0;
// printf("\n Nr apel %i, restul: %i", nrApel, rest[nrApel]);
printf("\n Nr apel %i, restul: %i", nrApel, nr10 % 16);
if(nr10 < 16) return nr10;
// ultimul cat este considerat primul bit util.
// La un nou apel, nr10 are rol de cat.
else {
nrApel++;
baza10_16(nr10/16);
}
}
int _baza10_16(int nr10, int *rest)
{ // al doilea parametru tine resturile
static int nrApel1=0;
Baza16 var16;

// Verific daca resturile depasesc numarul 9, pentru a codifica corect in


// baza 16.
var16 = nr10 % 16;
switch (var16)
{
case A: {
rest[nrApel1] = var16;
break;
}

ndrumar de laborator
case B: {
rest[nrApel1]
break;
}
case C: {
rest[nrApel1]
break;
}
case D: {
rest[nrApel1]
break;
}
case E: {
rest[nrApel1]
break;
}
case F: {
rest[nrApel1]
break;
}
}

12
= var16;

= var16;

= var16;

= var16;

= var16;

rest[nrApel1] = nr10 % 16;


if(nr10 < 16) return nr10;
// ultimul ct este considerat primul bit util.
// La un nou apel, nr10 are rol de ct.
else {
nrApel1++;
_baza10_16(nr10/16, rest);
}
}

S-ar putea să vă placă și