Sunteți pe pagina 1din 51

Programare procedurala Laborator 1

Agenda:
1. Familiarizarea cu mediul de dezvoltare MinGW
2. Structura programelor C
3. Operatii de intrare-iesire standard (descriptorii de format pentru intregi).
4. Lista problemelor de rezolvat [Termen 25 octombrie, ora 24.00]

1. Ghid de utilizare
MinGW Developer Studio este un mediu de dezvoltare integrat (Integrated Development
Environment, pe scurt IDE) pentru C/C++. Este de tip light-weight si necesita resurse reduse i ofera
posibilatea de a dezvolta programe intr-un mediu stabil.

Compilatorul si depanatorul MinGW pot fi folosite si independent de MinGW Developer Studio


impreuna cu un alt editor la alegere.

Crearea unui proiect n


Pentru a compila i a lansa spre executare surse C/C++ folosind
mediul MinGW Developer Studio trebuie creat un proiect. Conceptul
de proiect este util in cazul dezvoltarii de aplicatii multifisier.

Pentru a crea un proiect nou putei alege din urmatoarele trei optiuni:
a) Dati click pe prima pictograma din toolbar; b) Selectati File->New;
sau Tastati Ctrl-N.

Crearea unui proiect simplu, care interacioneaz cu consola din


Windows: Alegei locaia n care vrei s se salveze proiectul, alegeti
un nume, selectai "Win32 Console Application" i apoi click pe
butonul "OK".

a r p e n t r u u z ul tau.
s t m at er ia l e ste do a u tor.
Ace ie r d ire c t d e la t a p e v r e u n site
t fis sta
Ai primit aces cestui material nu va fi po

a
Nici o parte a e-mail altei persoane.
in
sau trimisa pr 009
,2
(c)G.Albeanu
Dupa ce a fost creat un proiect n MinGW Developer Studio urmeaza s fie ales si fisierul sursa sau sa
se editeze imediat. Pentru a crea o surs putei da click pe prima icoan din toolbar SAU File->New i
apoi selectai C/C++ Source File i denumii fiierul. Avei grij s fie bifat csua "Add to project",
dac nu este bifat sursa creat nu va fi adaugat la proiect i va trebui adaugat ulterior.

O alt metoda pentru a adauga o surs la un proiect este urmatoarea: right-click pe proiect si se
selecteaza sursa. Se poate introduce orice nume, daca fisierul nu exista atunci cand dati dublu-click
pe nume veti fi intrebati daca doriti ca fisierul sa fie creat. Daca fisierul exista, cand dati dublu-click
pProgramul se compileaz din Build->Build and Execute sau apsnd tasta F8.

Pentru a elimina o anumit surs din proiect se face right-click pe numale sursei in structura
arborescenta a fisierelor proiectului si se selecteaza "Remove p1.c. from project".

a r p e n t r u u z ul tau.
s t m at er ia l e ste do a u tor.
Ace ie r d ire c t d e la t a p e v r e u n site
t fis sta
Ai primit aces cestui material nu va fi po
a
Nici o parte a e-mail altei persoane.
in
sau trimisa pr 009
,2
(c)G.Albeanu
Compilatorul MinGW cere n cazul execuiei corecte a programului codul de retur 0. Aadar nu se
accepta ca main() sa fie declarat void, este obligatoriu ca sa fie declarat ca int.
Tipul de date int este reprezentat pe 4 bytes (adica int desemneaza domeniul de valori -
2147483647 ... 2147483647).
Exist tipul de date long long care este reprezentat pe 8 bytes care ia valori intre -262+1 pana
la 262-1. Pentru a citi/afia numere pe 64 de biti folosind <stdio.h> este necesar specificatorul
de format non-standard "%I64d".
Pointerii ocupa 4 bytes, astfel nct memoria total disponibil este de 4 GB.
MinGW ofer suport pentru Standard Template Library. Dintre structurile implementate fac
parte vectorii, cozile, stivele, arborii echlibrati, cozile de prioritate, etc; iar printre algoritmii
implementai gasim: sortarea, cutarea binar, generarea permutarilor, etc.

Meniuri

a r p e n t r u u z ul tau.
s t m at er ia l e ste do a u tor.
Ace ie r d ire c t d e la t a p e v r e u n site
t fis sta
Ai primit aces cestui material nu va fi po
a
Nici o parte a e-mail altei persoane.
in
sau trimisa pr 009
,2
(c)G.Albeanu
2. Structura programelor C

Un program scris n limbajul C (sau C++) este compus din unul sau mai multe fiiere surs. Un fiier
surs este un fiier text care conine codul surs (n limbajul C/C++) al unui program. Fiecare fiier
surs conine una sau mai multe funcii i eventual, referine ctre unul sau mai multe fiiere
header/antet (.h).
Orice program C/C++ are cel putin funcia principal, numit main. Execuia programului ncepe
cu execuia acestei funcii, care poate apela, la rndul ei, alte funcii. Toate funciile folosite n
program trebuie descrise n fiierele surs (cele scrise de ctre programator), n fiiere header (funciile
predefinite, existente n limbaj), sau n biblioteci de funcii.
Un fiier header/antet este un fiier al mediului de dezvoltare (folderul /include) sau este creat de
ctre programator. Un fisier antet conine declaraii i definiii de funcii i variabile.
Aciunile din fiecare funcie sunt codificate prin instruciuni . Exist mai multe tipuri de
instruciuni. O instruciune este orice expresie valid (de obicei, o asignare sau un apel de funcie),
urmat de simbolul;.

- Comenzi pentru preprocesor;


- Definitii de tipuri de date;
- Prototipuri de functii;
- Variabile;
- Functii;

O functie are forma:

tip nume_functie(parametrii){
variabile locale;
instructiuni;
}

Declararea variabilelor are forma


tip_variabile lista de variabile;

/* Exemplul 1 */
#include <stdio.h>
int main(){

ul tau.
printf(Primul program in C \n'');

a r p e n t r u u z
ste do
return 0;

s t m a
}
t er ia l e a u tor.
Ace ie r d ire c t d e la t a p e v r e u n site
t fis sta
Ai primit aces cestui material nu va fi po
a
Nici o parte a e-mail altei persoane.
in
sau trimisa pr 009
,2
(c)G.Albeanu
3. Testati programul urmator destinat exersarii afisarii numerelor intregi si caracterelor:

#include <stdio.h>
int main(void){
int a=1234;
double b=1234.4321;
char ch='a';
printf("\n\n afis. unui intreg zecimal:");
printf("%d",a);
printf("\n\n afis. unui nr. intreg zecimal pe 7 pozitii, aliniat la
dr.:");
printf("%7d",a);
printf("\n\n afis. unui nr. intreg in baza 16, pe 10 pozitii, aliniat la
dr.:");
printf("%#10x",a);
printf("\n\n un alt mod de afis. a nr. intregi, pe 10 pozitii, aliniate la
dr.:");
printf("%010d",a);
printf("\n\n afis. unui nr. intreg, pe 4 pozitii:");
printf("%4d",a);
printf("\n\n afis. unui nr. real pe 10 pozitii, cu doua zecimale:");
printf("%10.2f",b);
printf("\n\n afis. unui nr. real in functie de o putere a lui 10:");
printf("%e",b);
printf("\n\n afisarea caracterelor");
printf("\n caracterul este %c",ch);
printf("\n codul ASCII este este %d",ch);
return 0;
}

a r p e n t r u u z ul tau.
s t m at er ia l e ste do a u tor.
Ace ie r d ire c t d e la t a p e v r e u n site
t fis sta
Ai primit aces cestui material nu va fi po
a
Nici o parte a e-mail altei persoane.
in
sau trimisa pr 009
,2
(c)G.Albeanu
4. Lista problemelor de rezolvat (Rezolvarea se va transmite prin
e-mail titularului disciplinei, pe adresa
g.albeanu.mi@spiruharet.ro, sub forma de arhiva .zip care
contine sursele C. Pachetul cu rezolvari va avea numele
nume.prenume.grupa.tema1.zip)
1. Modificati programul din Exemplul 1 astfel incat sa afiseze urmatorul mesaj:

***********************************************
* FACULTATEA DE MATEMATICA - INFORMATICA *
* SPECIALIZAREA:____________________________*
* NUMELE______________PRENUMELE_____________*
***********************************************

2. Sa se scrie un program care citind caractere pana la intalnirea sfarsitului de fisier EOF (prin tastarea
CTRL Z) numara spatiile libere, tab-urile si liniile.

Indicatie: caracterele se citesc cu getchar(), se va folosi instructiunea conditionala "if" si se va tine


cont de faptul ca limbajul C recunoaste urmatoarele constante caracter: '\n' -linie noua, '\t' - tab
orizontal.

3. Scrieti un program care dupa fiecare rand scris de la tastatura, il afiseaza astfel incat daca apar mai
multe spatii libere consecutive, acestea sunt inlocuite cu unul singur.

Indicatie: pentru a citi sirul de caractere se foloseste structura repetitiva:


while((c=getchar())!=EOF)
iar pentru a rescrie caracterele se foloseste functia putchar.

4. Scrieti un program care dupa fiecare rand scris de la tastatura, il afiseaza astfel incat fiecare tab este
inlocuit cu "\t", fiecare trecere la o linie noua cu "\n" si fiecare backslash cu "\\".
5. Sa se scrie un program C care preia trei numere intregi a, b si c, si verifica daca ecuatia de gradul
doi cu coeficientii a, b, c are radacini reale pozitive.
6. Sa se scrie un program C care pentru n (n >0) perechi de numere intregi (p, q) afiseaza cel mai mare
divizor comun al numerelor p si q.

a r p e n t r u u z ul tau.
s t m at er ia l e ste do a u tor.
Ace ie r d ire c t d e la t a p e v r e u n site
t fis sta
Ai primit aces cestui material nu va fi po
a
Nici o parte a e-mail altei persoane.
in
sau trimisa pr 009
,2
(c)G.Albeanu
PROGRAMARE PROCEDURALA -L2

PROGRAMARE PROCEDURALA - LABORATOR 2


Programe cu structura liniara si ramificare: SEQ, IF, IF0

OBIECTIVE

directive de precompilare simple: #include, #define


biblioteci standard: < stdio.h >
declararea variabilelor
tipuri fundamentale de date: char, short, int, long, float, double
afisarea si citirea datelor, secvente escape: printf, scanf
operatori aritmetici fundamentali: + - * /
instructiuni
comentarii

CONSTANTE DEFINITE INTR-O DIRECTIVA DE PREPROCESARE


******************************************************
Forma generala: #define nume_constanta(majuscule) valoare_constanta;

TIPURI SIMPLE DE DATE


************************
Sa se scrie un program care afiseaza valoarea minima si valoarea maxima a urmatoarelor
tipuri de date: char, unsigned int, int, long int, float, double.
Indicatie: Se folosesc fisierele header limits.h si float.h unde sunt definite constante
in care sunt memorate valorile cerute.

INSTRUCTIUNI DE RAMIFICARE
*****************************
Instructiunea "if" are forma generala:
if (expresie1) sir_de_instructiuni1
else sir_de_instructiuni2
efect:
-se evalueaza expresie1;
-daca expresie1 este diferita de 0, atunci se executa sir_de_instructiuni1, altfel,
se executa sir_de_instructiuni2.

Instructiunea "switch" are forma generala:


switch(expresie)
{
case c1:sir_de_instructiuni1;
break;
case c2:sir_de_instructiuni1;
break;
.....
case cn:sir_de_instructiuni1;
break;
default: sir_de_instructiuni;
}
unde:
-c1,c2,...,cn sunt constante sau constante simbolice;
efect:
-se evalueaza expresia din paranteza;
-se compara pe rand valoarea expresiei cu valorile c1,c2,...,cn;
-daca valoarea expresiei coincide cu ck se executa sir_de_instructiunik si se trece la
instructiunea care urmeaza instructiunii "switch";
-daca valoarea expresiei nu coincide cu nici una dintre valorile c1,c2,..,cn se executa
sir_de_instructiuni.

file:///C|/...ursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC2%20-consolidare%20pt%20incepataori.htm[10.12.2010 09:29:06]
PROGRAMARE PROCEDURALA -L2

INSTRUCTIUNI REPETITIVE
**************************
Instructiunea "while" are forma generala:
while(expresie) sir_de_instructiuni
efect:
-se evalueaza valoarea expresiei din paranteza;
-daca expresia este adevarata (are valoarea diferita de 0), se executa sir_de_instructiuni
si se reia evaluarea expresiei;
-daca expresia nu este adevarata(=0), se executa instructiunea care urmeaza instructiunii
"while".
Instructiunea "for" are forma generala:
for(exp1;exp2;exp3) sir_de_instructiuni
efect:
-se executa secventa de initializare definita de expresia exp1;
-se evalueaza exp2;
-daca exp2 are valoarea 0, se trece la instructiunea care urmeaza instructiunii "for";
-daca exp2 are o valoare diferita de 0 se executa sir_de_instructiuni;
-se executa secventa de reinitializare definita de exp3 si se evalueaza exp2.
Instructiunea "do-while" are forma generala:
do
sir_de_instructiuni
while(expresie)
efect:
-se executa sir_de_instructiuni;
-se evalueaza expresie;
-daca expresie este diferita de 0, se executa din nou sir_de_instructiuni;
-daca expresie este 0, se executa instructiunea care urmeaza instructiunii "do-while".

OPERATORI
************
Operatori aritmetici: +,-,*,%(restul impartirii), /;
Operatori de incrementare si decrementare: ++, --;
Operatori relationali: <, <=, >, >=;
Operatori de egalitate: ==, !=;
Operatori logici: !(negatie), &&("si" logic), ||("sau" logic).

EXERCITII

1. Executati urmatorul program:


#include <stdio.h>
int main(void){
int nr_intreg;
float nr_real;
long nr_long;
printf("Introduceti trei numere");
printf("un intreg:");
scanf("%d", &nr_intreg);
printf("un real si %s",
"un long:");
scanf("%f%ld", &nr_real, &nr_long );
printf("\nAti introdus: un intreg = %d,\n un real = %f,
\n un long = %ld", nr_intreg, nr_real, nr_long);
return 0;
}

Modificati programul anterior astfel incit sa puteti introduce urmatoarele


tipuri de date in ordinea precizata: un char (caracter ASCII),
un double (numar rational in dubla precizie), unsigned int (numar intreg fara semn).
Pentru descriptorii de format: Folositi help-ul pentru detalii.

2. Realizati un program care sa afiseze succesorul unei numar


memorat intr-o variabila de tip char.

file:///C|/...ursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC2%20-consolidare%20pt%20incepataori.htm[10.12.2010 09:29:06]
PROGRAMARE PROCEDURALA -L2

Testati programul pentru valoarile -1 si 128.

Modificati programul anterior astfel incit variabila sa fie de tip unsigned char.

Testati din nou programul pentru valoarile -1 si 128, precum si pentru 256. Ce observati?

3. Urmatorul program afiseaza caracterul memorat in variabila ch:


#include <stdio.h>
int main(void) {
char ch = 'A';
printf("Caracterul memorat in var. ch este: %c", ch );
return 0;
}

Modificati programul anterior astfel incit sa afiseze codul ASCII al caracterului memorat.

4. Sa se scrie un program care sa converteasca o temperatura in grade Celsius in echivalentul


ei in grade Farenheit.
Formula de conversie este: F = 32 + 9/5 C
Programul trebuie sa tipareasca ambele valori ale temperaturii cu mesajele
corespunzatoare.

Exersati cu alte formule de calcul, pentru alte teme privind conversia (exemplu: cursul
valutar).

5. Se da urmatorul program care determina numarul maxim de ore


dintr-un interval de timp specificat in secunde:
#include <stdio.h>
#define SEC_IN_ORA 3600
int main(void){
int secunde;
printf( "Dati numarul de secunde:" );
scanf( "%d", &secunde );
printf( "Nr. max. de ore: %d\n", secunde / SEC_IN_ORA );
return 0;
}

Modificati programul anterior astfel incit sa afiseze intervalul de timp in format


<ore>H:<minute>M:<secunde>S.
De exemplu, pentru un interval de 7384 secunde avem 2H:3M:4S.

6. [Ramificare: IF] Se da urmatorul program care calculeaza minimum a doua numere reale:
#include <stdio.h>
int main(void){
float a = 5, b = 7;
printf("Minimum este ");
if ( a < b )
printf("%d", a);
else
printf("%d", b);
return 0;
}

Sa se modifice programul anterior astfel incit sa calculeze minimum a 3


numere reale.
Sa se modifice programul anterior astfel incit sa calculeze maximum a 3
numere reale preluate de la tastatura.

file:///C|/...ursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC2%20-consolidare%20pt%20incepataori.htm[10.12.2010 09:29:06]
PROGRAMARE PROCEDURALA -L2

7. Scrieti un program de transformare a numarului n din baza p in baza q (n,p


si q cel putin doi, se citesc de la tastatura).

8. (Conjunctura lui Goldbach)


Orice numar par mai mare decat 2 se poate scrie ca suma a doua numere prime.
Scrieti un program C care verifica aceasta conjunctura pentru numere situate intre m si n,
doua numere citite de la tastatura.
De exemplu, daca m=700 si n=1100, atunci afisati:

700 = 17 + 683
702 = 11 + 691
704 = 3 + 701
...
1098 = 5 + 1093
1100 = 3 + 1097

9.
Folosind o instructiune "for" sa se citeasca caractere pana la aparitia unui "." si sa
se determine numarul acestora.
10. Sa se scrie un program care citeste caractere pana la aparitia unui '.' iar la tastarea
unei litere mici se afiseaza litera mare corespunzatoare si vice-versa. Sa se modifice
programul astfel incat sa foloseasca o instructiune "for".

Indicatie: se foloseste faptul ca pentru transformarea unei litere mari in litera mica
este suficient sa scadem din codul ei codul literei 'A' si sa adaugam codul literei 'a'.
11. Scrieti un program care sa scrie textul de intrare sub forma unui cuvant pe
linie. sa se modifice programul astfel incat sa foloseasca o instructiune "for".

12. Sa se determine cantitatea de vopsea necesara zugravirii unei camere cu pereti


dreptunghiulari ale caror dimensiuni le cititi. Sa se tina cont ca exista o fereastra
rotunda (cititi raza) pe unul dintre pereti si o usa dreptunghiulara pe un altul. Se
stie ca pentru 1 metru patrat de perete se consuma 0.75 litri de vopsea.

13. Sa se citeasca un numar intreg pozitiv care reprezinta secunde. Sa se scrie un program
care afiseaza cate ore, cate minute si cate secunde inseamna numarul citit.

14. Se citesc doua date de la tastatura, una a nasterii si una a zilei curente. Sa se
verifice daca datele sunt valide. Sa se scrie un program care calculeaza cati ani, cate
luni si cate zile are in ziua curenta persoana a carei zi de nastere a fost citita.

15. Sa se corecteze un text in care fiecare propozitie este scrisa pe un rand: sa se


elimine spatiile suplimentare, tab-urile sa se inlocuiasca cu un spatiu, fiecare rand
sa inceapa cu o litera mare, fiecare rand sa se termine cu '.','?' sau '!', ghilimelele
sa se inchida dupa 4 cuvinte iar parantezele rotunde dupa 3 cuvinte. Sa se afiseze cate
erori au fost corectate.

Bibliografie

file:///C|/...ursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC2%20-consolidare%20pt%20incepataori.htm[10.12.2010 09:29:06]
PROGRAMARE PROCEDURALA

PROGRAMARE PROCEDURALA - LABORATOR 3


Intrari/iesiri. Tipuri fundamentale.

OBIECTIVE

tipuri fundamentale de date


declararea variabilelor
caractere, atomi lexicali, comentarii, cuvinte rezervate, identificatori, constante
citirea si afisarea: specificatori de format
instructiuni de control simple

EXERCITII

1. Scrieti un program care citeste un intreg zecimal (in baza 10) de cel mult 5 cifre de la tastatura si il afiseaza
incadrat de 2 caractere %:
in octal (baza 8), pe 6 pozitii, aliniat la dreapta
in hexazecimal (baza 16), pe 6 pozitii, aliniat la stanga.

2. Se cere un program care citeste un caracter de la tastatura folosind functia scanf si afiseaza codul sau ASCII
precum si adresa sa din memorie (in hexazecimal).

3. Sa se scrie un program care sa calculeze nota finala pentru o disciplina. De la tastatura se vor citi urmatoarele:
nota la laborator, ponderea ei in nota finala, nota la lucrarea scrisa, ponderea ei in nota finala, nota la seminar si
ponderea ei in nota finala. Se va afisa nota finala.

4. Se considera programul urmator ce contorizeaza (numara) nr. de aparitii (de cate ori apare) a fiecarui caracter
mic ('a' .. 'z') dintr-un fisier text:
int main(void) {
int i, nr_aparitii[26];
char c;
FILE *finput, *foutput;
finput = fopen("in.txt","rt");
foutput = fopen("out.txt","wt");
for (i=0; i<26; i++)
nr_aparitii[i] = 0;
//citeste cate un caracter si incrementeaza
//nr de aparitii pentru caracterul respectiv:
while ((c = getc(finput)) != EOF)
if ('a' <= c && c <= 'z') nr_aparitii[c-'a']++;
//scrie in fisierul de iesire nr de aparitii
//pentru fiecare caracter din alfabet:
for (i=0; i<26; i++)
fprintf(foutput,"%c - %3d\n",'A'+i, nr_aparitii[i]);
return 0;
}

Sa se modifice programul anterior astfel incat numararea caracterelor sa se faca doar pentru o multime de
caractere specificate de catre utilizator si fara a sa se face distinctie intre caracterele mari si cele mici.
Exemplu:
In fisierul de intrare "in.txt" se gaseste sirul: asDfaAhh
Multimea de caractere precizata de utilizator este: ah
In fisierul de iesire "out.txt" va fi scris:
A-3h-2

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC3.htm[10.12.2010 09:26:58]
PROGRAMARE PROCEDURALA

5. Scrieti un program C care citeste dintr-un fisier text de intrare "in.txt" numarul de linii, respectiv coloane, si
elementele unei matrice, si afiseaza matricea citita din fisier.

6. Se considera urmatorul program care dubleaza toate numerele dintr-un fisier de intrare si le scrie intr-un fisier de
iesire. Numele fisierelor sint precizate in linia de comanda:
int main(int nr_arg, char *arg[]) {
//declararea variabilelor:
int i, n;
float val;
FILE *finput = NULL, *foutput = NULL;
//verifica daca sunt cel putin doua argumente in linia de comanda:
if (nr_arg < 3) {
printf("Linie de comanda gresita.\n%s\n %s %s",
"Trebuie sa introduceti", arg[0],
"fisier_intrare fisier_iesire\n");
return 1;
}
//deschide fisierele de intrare si iesire si
//verifica daca nu au aparut erori:
finput = fopen(arg[1],"rt");
if ( !finput )
return 1; //fisierul de intrare nu a putut fi deschis
foutput = fopen(arg[2],"wt");
if (!foutput) //fisierul de iesire nu a putut fi deschis{
//inchide primul fisier:
fclose(finput);
return 1;
}
//citeste numarul de valori reale ce se gasesc in fisierul de intrare:
fscanf(finput, "%d,",&n);
//pentru fiecare nr citit din fisierul de intrare il dubleaza
//si rezultatul il salveaza in fisierul de iesire:
for (i=0; i<=n;i++){
fscanf(finput,"%f", &val);
val *= 2;
fprintf(foutput,"%f\n", val);
}
//inchide fisierele de intrare si iesire:
fclose(finput);
fclose(foutput);
return 0;
}

Modificati programul anterior astfel incit sa primeasa trei nume de fisiere in linia de comanda.

Daca primul fisier contine numerele N1,...,N10 si al doilea, numerele M1,...,M10, in al treilea sa se scrie
numerele max(N1, M1), max(N2, M2), .... max(N10, M10).

7. Sa se scrie un program care rezolva o multime de ecuatii de gradul I cu coeficienti reali. Coeficientii vor fi
preluati dintr-un fisier text, inregistrati linie cu linie.

8. Sa se scrie un program de rezolvare a unei ecuatii de gradul II cu coeficienti reali. Coeficientii vor fi preluati
dintr-un fisier text.

9. Scrieti un program care, avand la intrare doua siruri de caractere, determina cel mai lung subsir comun si
pozitiile la care acesta incepe in fiecare dintre cele doua siruri.

10. Jocul Scrabble


Fanii jocului Scrabble sunt obisnuiti cu anagramele - grupuri de cuvinte cu aceleasi litere dar in alta ordine( ex:
ACAR, ARAC, CARA). Exista totusi cuvinte care nu au acest atribut, adica indiferent cum sunt aranjate literele
componente, nu se poate forma un alt cuvant( ex: MOS). Asemenea cuvinte sunt numite ananagrame. Bineinteles
ca aceste definitii depind de domeniul in care lucram. Un asemenea domeniu poate fi intreg dictionarul limbii

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC3.htm[10.12.2010 09:26:58]
PROGRAMARE PROCEDURALA

romane, dar asta ar creea unele probleme. Putem restrange domeniul, sa spunem de exemplu: domeniul muzical,
caz in care NOTA devine o ananagrama relativa( pentru ca TONA nu este in acelasi domeniu). Scrieti un
program care sa citeasca un dictionar dintr-un anumit domeniu (memorat intr-un fisier) si sa determine toate
ananagramele relative. Cuvintele formate dintr-o singura litera sunt ananagrame deoarece ele nu pot fi
"rearanjate". Un dictionar nu contine mai mult de 1000 de cuvinte si un cuvant are cel mult 20 de litere, mici sau
mari. Liniile fisierului nu au mai mult de 80 de caractere, cuvintele sunt separate prin spatii si orice cuvant se
gaseste in intregime pe o linie. Ananagramele gasite vor fi scrise intr-un fisier de iesire, fiecare pe cate o linie, in
ordine lexicografica. Observatie: tieD si EdiT sunt anagrame!
Exemplu :
Intrare :
ladder came tape soon leader acme RIDE lone Dreis peat
ScAlE orb eye Rides dealer NotE derail LaCeS drIed
noel dire Disk mace Rob dries
Iesire :
Disk
NotE
derail
drIed
eye
ladder
soon

11. Afisare LC
Un prieten, obisnuit cu afisarea ecranelor de la mini-computerele de buzunar, va roaga sa scrieti un program
care sa afiseze numerele in stilul cu care este el obisnuit.
Fisierul de intrare "inLC.txt" va contine citeva linii, fiecare linie continind o pereche de doua numere s,n, unde n
este numarul ce va fi afisat iar s este dimensiunea folosita la afisare.
In fisierul de iesire "outLC.txt" se vor afisa numerele in stilul LC: se foloseste semnul - pentru segmentele
orizontale si | pentru segmentele verticale. Fiecare cifra ocupa exact s+2 coloane si 2s+3 linii. Exista exact o
singura coloana de spatii intre doua cifre vecine si o singura linie goala intre numere.
Exemplu:
Intrare:
2 12345
3 67890
Iesire:
-- -- --
| | | | | |
| | | | | |
-- -- -- --
| | | | |
| | | | |
-- -- --
--- --- --- --- ---
| | | | | | | |
| | | | | | | |
| | | | | | | |
--- --- ---
| | | | | | | |
| | | | | | | |
| | | | | | | |
--- --- --- ---

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC3.htm[10.12.2010 09:26:58]
.
PROGRAMARE PROCEDURALA

PROGRAMARE PROCEDURALA - LABORATOR 4


Instructiuni de control

OBIECTIVE

operatori si expresii relationale;


operatori si expresii de egalitate;
instructiuni de ramificare: if, if-else, switch (break)
instructiuni repetitive: while, for, do-while

EXERCITII

1. Din moment ce + si ++ sunt operatori, rezulta ca expresia a+++b poate fi interpretata fie ca (a++ + b), fie (a +
++b) depinzand de modul de "grupare" a semnului +.
Scrieti un program scurt pentru a stabili interpretarea compilatorului C folosit.
2. Scrieti un program C pentru a calcula n!, unde n este citit de la tastatura. Testati programul pentru valori n = 7,
8, 9, 10. Ce observati? Explicati.
3. Scrieti un program care citeste un numar natural n si determina, aplicand criteriile de divizibilitate, daca este
divizibil cu 2,3,4,5,9,25.Se recomanda folosirea instructiunii switch.

4. Folosind o bucla while, scrieti un program C care calculeaza al n-lea termen din sirul din Fibonnacci. Reamintim
ca sirul lui Fibonnacci este dat de recurenta liniara de ordin 2:

a_1=a_2=1;
a_{n+2}=a_{n+1}+a_n, n>=1

5. Scrieti un program C care sa calculeze cel mai mare divizor comun dintre a si b, unde a, b sunt numere intregi,
folosind algoritmul lui Euclid.

6. Fie functia lui Collatz:


{ n/2 daca n este par
f(n) =
{ 3*n+1 daca n este impar

Sa se scrie un program C care, pentru un n dat, determina k natural minim astfel incat
(f o f o ... o f)(n)=1.
de k ori

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC4.htm[10.12.2010 09:27:32]
PROGRAMARE PROCEDURALA

7. Se da un numar intreg n > 0.


Gasiti toate perechile de numere intregi (x,y) pentru care x^2+n=y^2.
Gasiti perechea (a,b) pentru care n=(2^a)*(2*b+1).

8. (Serii Farey)
Seria Farey de ordinul n = sirul crescator al fractiilor reduse, cuprinse intre 0 si 1, cu numitorul <=n. De
exemplu, seria Farey de ordinul 7:
0/1,1/7,1/6,1/5,1/4,2/7,1/3,2/5,3/7,1/2,4/7,3/5,2/3,5/7,3/4,4/5,5/6,6/7,1/1.
Notam seria Farey de ordinul n prin (x_1,y_1),(x_2,y_2), ...
Aratati ca x_(k+1) * y_k - x_k * y_(k+1) = 1.
Aratati ca :
x_0 = 0, x_1 = y_0 =1, y_1 = n
x_(k+2) = [(y_k+n) / y_(k+1)] * x_(k+1) - x_k
y_(k+2) = [(y_k+n) / y_(k+1)] * y_(k+1) - y_k
Scrieti un program care genereaza seria Farey de ordinul n, pentru n dat.

9. Sa se genereze numarul natural n, pornind de la cifra 4 si efectuand la fiecare pas una din urmatoarele operatii:
impartire la 2
adaugarea(concatenarea) la dreapta a cifrei 0
adaugarea(concatenarea) la dreapta a cifrei 4
Poate fi generat astfel orice numar natural n?

10. Scrieti un program care citeste o pictura desenata cu caractere ascii dintr-un fisier de intrare "desen.txt" si umple
o regiune aleasa de utilizator cu un caracter specificat de acesta. Fisierul contine exact 20 linii si 40 coloane.
Fiecare linie contine numai spatii si caracterele din imagine. Fiecare linie din imagine se termina cu caracterul
"sfirsit de linie". Marginea picturii va fi marcata de *.
Programul va citi imaginea din fisierul de intrare, va afisa imaginea citita si va cere utilizatorului o pozitie din
regiunea ce se doreste a fi umpluta (eng. fill), precum si caracterul folosit la umplere (diferit de spatiu).
Liniile sint numerotate de la 0 la 19 de sus in jos, iar coloanele sint numerotate de la 0 la 39 de la stinga la
dreapta.
Doua pozitii sint in aceeasi regiune daca initial sunt umplute cu "spatiu" si sunt adiacente (orizontal sau vertical)
sau sint conectate de o secventa de pozitii adiacente.
Imaginea modificata va fi afisata si apoi salvata in fisierul de iesire "out.txt".

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC4.htm[10.12.2010 09:27:32]
PROGRAMARE PROCEDURALA

PROGRAMARE PROCEDURALA - LABORATOR 5


Instructiuni de control

(continuarea temei 4)

OBIECTIVE

operatori si expresii relationale;


operatori si expresii logici;
instructiuni de decizie: if, if-else, switch, break, continue
instructiuni repetitive: while, for, do-while

EXERCITII

1. Folosind structura for, scrieti un program care evalueaza urmatoarele formule logice (sub forma unei tabele de
adevar): x1 || x3 || x5 si x1 && x2 || x4 && x5

2. Operatia matematica min(x,y) se poate reprezenta ca o expresie conditionala:


(x < y) ? x : y

Intr-un mod similar, descrieti operatiile aritmetice


min(x, y, z) si max(x, y, z, t)

Folosind functia "rand()" sa se genereze n numere naturale si sa se afiseze minimul si maximul dintre acestea,
folosind un algoritm de complexitate 3*n/2 + O(1).

3. Operatia matematica min(x,y) poate fi definita printr-un macro:


#define MIN(x,y) ((x<y)?(x):(y))

Modificati problema anterioara astfel incit sa definiti macrourile MIN si MAX.

4. (Jocul hartie, pumn, foarfece) Presupunem ca avem doi jucatori care folosesc mana dreapta pentru
reprezentarea a trei obiecte:
hartie = palma intinsa
pumn = mana stransa sub forma de pumn
foarfece = doua degete departate (semnul Victoriei)

Ei isi arata simultan mana dreapta in una din aceste configuratii (de mai multe ori). Daca ei arata acelasi lucru,
este remiza (nu castiga nimeni). Daca nu, atunci se aplica una din urmatoarele trei reguli:
a) Hartia acopera pumnul (deci, palma intinsa castiga fata de pumn);
b) Pumnul sparge foarfecele;

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC5.htm[10.12.2010 09:27:45]
PROGRAMARE PROCEDURALA

c) Foarfecele taie hartia.

Sa se simuleze acest joc, facand un numar arbitrar de evenimente precizand scorul final. Se cere sa se joace
varianta I: persoana-calculator, si varianta a II-a: calculator-calculator.

5. Zilele secolului 20 pot fi notate folosind intregi in forma "zi/luna/an". De exemplu, 1/7/93 inseamna 1 iulie 1993.
Scrieti o functie care memoreaza ziua, luna si anul compact, astfel:
a) pentru zile (maxim 31) sunt suficienti 5 biti;
b) pentru luna (12) sunt suficienti 4 biti;
c) pentru ani (100) sunt suficienti 7 biti;

Functia trebuie sa aiba la intrare ziua, luna si anul ca intregi si trebuie sa returneze data "impachetata" pe un
"intreg" pe 16 biti. Scrieti inca o functie care face "despachetarea". Ce relevanta are aceasta prioblema pentru
evenimentul Y2K (Milenium)

6. Folosind operatorii pe biti, scrieti programe C care:


a) testeaza daca un numar de tip "int" sau "long" este divizibil cu 8.
Generalizare (divizibilitate cu 2^n);
b) testeaza daca un numar este pozitiv sau negativ;
c) calculeaza pentru un n dat, multiplii de 2, 4, ... Generalizare;
d) calculeaza pentru un n dat, [n/2], [n/4], ... Generalizare;

7. (Puncte sa) Fie a un tablou bidimensional (mXn).


Un punct sa al acestui tablou este un element a[i0,j0] cu proprietatea:
a[i0,j0] = min{a[i0,j] : 0<=j<=n-1} = max{a[i,j0] : 0<=i<=m-1}
Scrieti un program care determina punctele sa (daca exista) ale unui tablou bidimensional.

8. Fiind dat un numar intreg n > 0, sa se afiseze toate numerele naturale formate cu cifrele sale.

9. Se da o matrice patratica. Sa se ordoneze crescator fiecare linie a matricei, apoi sa se rearanjeze liniile astfel
incat suma elementelor de pe diagonala sa fie minima.

10. (Codificarea si decodificarea permutarilor) Consideram tabloul x de dimensiune n, continand o permutare a


elementelor 1..n.
Se defineste un alt tablou xcod, tot de dimensiune n, astfel:
xcod[i] = |{j : j<i si x[j]<x[i]}| .

Scrieti un program care construieste tabloul xcod corespunzator unui tablou dat x.
Scrieti un program care decide, pentru un tablou dat xcod cu valori intregi, daca exista o permutare a carei
codificare este xcod si, in caz afirmativ, o construieste.
Atentie! Programul poate utiliza alte variabile simple, dar nu si alte tablouri.

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC5.htm[10.12.2010 09:27:45]
PROGRAMARE PROCEDURALA

PROGRAMARE PROCEDURALA - LABORATOR 6


Instructiuni, pointeri, tablouri

OBIECTIVE

operatori si expresii relationale;


operatori si expresii logici;
instructiuni de ramificare: if, if-else, switch, break, continue
instructiuni repetitive: while, for, do-while
pointeri, tablouri

EXERCITII

1. Realizati un program care sa afiseze un tabel (cu trei coloane) care sa contina: n, reprezentarea binara a lui 2^n,
reprezentarea binara a lui (2^n)-1, pentru n = 0, 1, 2, ..., 32. Apoi, afisati un tabel (tot cu trei coloane) care sa
contina: n, 10^n si (10^n)-1 pentru n = 0, 1, 2, ..., 7 (in baza zece). Ce asemanare observati ?

2. Scrieti un program C care arata pe cati octeti sunt memorati pointerii catre tipurile fundamentale de date. Ce
observati ?

3. Scrieti o functie care calculeaza suma divizorilor naturali ai unui numar natural n. Un numar este perfect daca
este egal cu suma divizorilor proprii pozitivi (ex: 28 = 1 + 2 + 4 + 7 + 14). Realizati un program care sa
genereze primele k numere perfecte (k < 5 !).

4. Scrieti o functie care insumeaza elementele de rang (index) impar, respectiv par, ale unui vector cu elemente de
tip "double".
Sugestie: Functia poate incepe astfel:
void suma(double a[],
/* vector cu elemente de tip double */
int n,
/* lungimea vectorului a */
double *impar,
/* va contine suma numerelor de pe pozitii impare */
double *par);
/* va contine suma numerelor de pe pozitii pare */

5. Implementati o functie care sa calculeze valoarea unui determinant asociat unei matrice patratice. In cazul in
care determinantul este nenul, sa se calculeze si inversa matricei.

6. Sa se rearanjeze elementele unui vector de numere intregi, astfel incat cele pare sa apara inaintea celor impare. In

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC6.htm[10.12.2010 09:28:03]
PROGRAMARE PROCEDURALA

cadrul subsecventei de numere pare, respectiv impare, elementele trebuie sa apara in ordinea in care erau in
vectorul initial.

7. Calculati inversa unei permutari cu un numar constant de variabile suplimentare

8. (Jocul vietii- LIFE) Se considera o populatie de virusi care se afla in anumite noduri ale unei retele n X n. Un
virus traieste daca are 2 sau 3 vecini, altfel moare (sufocat sau de singuratate). Intr-un nod liber cu 2 sau 3
vecini, se naste un virus. Scrieti un program care vizualizeaza evolutia populatiei de virusi.

9. Un patrat magic (de latura n) are proprietatea ca include in locatiile sale toate numerele intregi din intervalul 1,
..., n^2 si sumele numerelor de pe fiecare linie, fiecare coloana sau fiecare diagonala sunt egale. De exemplu:
6 1 8
7 5 3
2 9 4

este un patrat magic de dimensiune 3. Sa se scrie un program C care testeaza daca un patrat este magic sau nu.
De asemenea, incercati sa generati toate patratele magice de ordin n.

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC6.htm[10.12.2010 09:28:03]
Aveti atasate cele 5 sectiuni ale temelor de discutat in cadrul laboratorului.

Cerinta consta in studiu individual si rezolvarea a 5 exercitii, cite unul din fiecare sectiune.

*********************************************************
* LABORATOR - PROGRAMARE PROCEDURALA - LIMBAJ C - 7-8 decembrie 2010 *
*********************************************************

I. main(...) - main cu argumente - exercitii pe baza cursului

I. main(...) cu argumente

Sa se studieze programul:

Argumentele functiei main reprezinta sirurile de carcatere din linia de comanda prin care s-a lansat in executie
programul. Functia main are doua argumente care sunt numite in mod traditional astfel
void main(int argc, char *argv[])
{
}
unde argc reprezinta numarul de siruri din linia de comanda, iar argv[] contine adresele acestor siruri. In argv[0] se
gaseste adresa sirului care reprezinta numele programului.

Exemplul 1
#include <stdio.h>
void main(int argc, char *argv[])
{
int i;
printf("\nArgumentele functiei main (initiala intre paranteze):");
for(i=0;i<argc;i++)
printf("\n%d: (%c)%s",i,argv[i][0],argv[i]+1);
}
Daca programul este lansat prin linia de comanda
d:>argmain1 abcd xyz uvw
atunci iesirea produsa este urmatoarea

Argumentele functiei main (initiala intre paranteze):


0: (D):\PSG_SERV\PCLP_II\ARGMAIN1.EXE
1: (a)bcd
2: (x)yz
3: (u)vw

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC7.txt[10.12.2010 09:28:51]
Exemplul 2
#include <stdio.h>
#include <stdlib.h>
void main(int argc, char **argv)
{
long suma=0;
printf("\n");
for( ;argc>1;argc--) {
printf("%s %c ", argv[argc-1], argc==2 ? '=':'+');
suma += atol (argv[argc-1]);
}
printf("%ld",suma);
}
Functia long atol(char *s); cu prototipul in <stdlib.h> converteste numarul reprezentat de sirul s intr-o valoare de tip
long. Mai exista:
double atof(const char *s);
long double _atold(const char *(s));
int atoi(const char *s);
Efectul acestor functii poate fi obtinut si cu sscanf();
Daca programul este lansat prin linia de comanda
D:>aduna 1 2 3 4
iesirea produsa este urmatoarea: 4 + 3 + 2 + 1 = 10

IIa. POINTERI (recapitulare);


IIb. POINTERI SI FUNCTII;
IIc. POINTERI SI VECTORI;
IId. EXERCITII.

IIa. POINTERI
***********

Un pointer este o variabila care contine adresa unei variabile. Orice


pointer poate contine adresa variabilelor de un singur tip.
Declaratia pointer-ului p, la numere intregi este:

int *p

Ea ne spune ca expresia "*p" este un int (adica in p se pot


memora adrese de intregi). Operatorul "*" aplicat unui pointer
p, acceseaza obiectul la care p este pointer.

Operatorul unar "&" da adresa unui obiect. Rezulta ca declaratia:

p=&c

atribuie adresa lui c variabilei p. Se spune ca p este pointer la c.

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC7.txt[10.12.2010 09:28:51]
Exemplul 1:

Urmatoarele linii pot face parte dintr-un program care lucreaza


cu un pointer p la intregi:

int x=1,y=2;
int *p; /* p este un pointer la intergi */

p=&x;
y=*p;
*p=0;

Daca p este pointer la un intreg, atunci *p poate sa apara in


orice context in care apare x, variabila intreaga. De exemplu:

*p=*p+1;

il creste pe *p cu 1.

Daca q este un alt pointer, este posibila atribuirea:

q=p

IIb. POINTERI SI FUNCTII


***********************

Scrieti un program in care sa cititi doua numere intregi si sa


aplicati pentru aceste numere urmatoarea functie de interschimbare
a valorilor

void inversare(int x,int y)


{
int aux;

aux=x;
x=y;
y=aux;
}

Ce observati?

inversare(a,b) de fapt inverseaza copii ale lui a si b (parametrii functiei


sunt transmisi prin valoare).

Schimbati functia de mai sus cu functia care urmeaza si care se va apela


in program astfel: inversare(&a,&b).

void inversare(int *px,int *py)


{
int aux;

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC7.txt[10.12.2010 09:28:51]
aux=*px;
*px=*py;
*py=aux;
}

Ce observati?

De aceasta data parametrii functiei sunt niste pointeri la intregi.


Ei nu se modifica, dar se modifica valorile memorate in locatiile
de memorie la care sunt pointeri.

IIc. POINTERI SI VECTORI


************************

Declaratia:

int a[10];

defineste un vector cu 10 elemente, adica, 10 elemente (a[0], a[1],


..., a[9]) memorate in locatii de memorie consecutive.

Daca p este un pointer la un intreg, declarat astfel:

int *p;

atunci atribuirea

p=&a[0];

il determina pe p sa fie pointer la elementul 0 a lui a, adica p va


contine adresa lui a[0].

Daca p este pointer la un anumit element din tablou, atunci, prin


definitie p+1 este pointer la urmatorul element, p+i este pointer
la al i-lea element dupa elementul la care este pointer p, iar
p-i este pointer la al i-lea element inainte de p. Prin urmare,
daca p este pointer la a[0], atunci

*(p+1)

se refera la valoarea memorata in a[1], p+i este adresa lui


a[i] si *(p+i) este valoarea memorata in a[i].

Prin definitie, valoarea unei variabile sau a unei expresii de


tip "array" este adresa elementului 0 al acelui "array". Deci,
dupa atribuirea

p=&a[0];

p si a au valori identice. Aceasta atribuire se mai poate scrie:

p=a

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC7.txt[10.12.2010 09:28:51]
Prin urmare:

a[i] si *(a+i) sunt echivalente


&a[i] si a+i sunt echivalente.

Observatie: un nume de array este un pointer constant si nu poate fi


modificat (nu poate fi pointer la alta adresa).

Exemplul 2:

Urmatoarea functie determina lungimea unui sir de caractere privit ca


un pointer:

int lungime_string(char *s)


{
int n;

for(n=0;*s!='\0';s++) n++;

/* s++ este echivalent cu s=s+1, adica s va deveni pointer la adresa urmatoare. Dupa apelarea functiei lungime_string,
s nu este modificat, chiar daca in interiorul functiei au avut loc atribuirile s++, pentru ca apelul parametrilor
se face prin valoare*/

return n;
}

Daca p si q sunt pointeri la doua elemente ale unui array, putem sa ii


comparam. De exemplu:

p<q

este advarat daca p este pointer la un element de indice mai mic fata de q.

Exemplul 3:
Urmatoarea functie copiaza sirul de caractere t in sirul de caractere s.
Ea este scrisa in doua variante: vectoriala si cu pointeri.

void copiaza_sir(char s[],char t[])


{
int i;

i=0;
while((s[i]=t[i])!='\0')
i++;
}

void copiaza_sir(char *s,char *t)


{
int i;

i=0;
while ((*s=*t)!='\0')

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC7.txt[10.12.2010 09:28:51]
{
s++;
t++;
}
}

Pentru ca argumentele functiei sunt apelate prin valoare, in interiorul functiei


pointerii s si t pot fi modificati, fara ca acest lucru sa aiba efect dupa apelul functiei.

Exemplul 4:
Aveti aici doua variante ale functiei copiaza_sir, care folosesc avantajele programarii
in C.

void copiaza_sir(char *s,char *t)


{
int i;

i=0;
while ((*s++=*t++)!='\0');
/* aici, datorita prioritatii operatiilor, intai sunt comparati *s si
*t si apoi sunt incrementati s si t*/
}

void copiaza_sir(char *s,char *t)


{
int i;

i=0;
while (*s++=*t++);
}

Exemplul 5:
Aveti aici o functie (scrisa in doua variante) care compara sirurile de caractere s si
t si, in functie de ordinea lexicografica, intoarce o valoare negativa
daca s este mai mic decat t, 0 daca s si t sunt egale, sau o valoare pozitiva
daca s este mai mare decat t.

int compara(char s[], char t[])


{
int i;

for (i=0;s[i]==t[i];i++)
if (s[i]=='\0') return 0;
return s[i]-t[i];
}

int compara(char *s, char *t)


{
int i;

for (;*s==*t;s++,t++)

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC7.txt[10.12.2010 09:28:51]
if (*s=='\0') return 0;
return *s-*t;
}

IId. EXERCITII
*************

1. Fie urmatorul program, care numara liniile de o lungime data dintr-un text
citit de la tastatura:

#include <stdio.h>
#define MAX 1000 /*lungimea maxima a unei linii*/

int o_linie(char linie[], int l_max);

/*"o_linie" este o functie care are ca parametrii sirul de caractere "linie"


si intregul "l_max" care reprezinta valoarea maxima
pe care o poate lua lungimea unei linii. Functia "o_linie" intoarce un numar
intreg care reprezinta lungimea liniei*/

int main()
{
char linie[MAX];
int l,ll,nr=0;

printf("dati lungimea liniilor cautate:",l);


scanf("%d",&l);
getchar();
while((ll=o_linie(linie,MAX))>0)
if(ll==l)
nr++;
printf("\nsunt %d linii de lungime %d",nr,l);
return 0;

int o_linie(char linie[], int l_max)


{
int i=-1;
char c;

while(--l_max>0&&(c=getchar())!=EOF&&c!='\n')
linie[++i]=c;

linie[++i]='\0';
return i;
}

Rescrieti programul de mai sus, astfel incat functia "o_linie" sa lucreze cu pointeri.

2. Scrieti o functie care lucreaza cu vectori, si apoi o functie care lucreaza cu


pointeri, ambele copiind sirul de caractere t la sfarsitul sirului de caractere s.

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC7.txt[10.12.2010 09:28:51]
3. Scrieti o functie care lucreaza cu pointeri si care intoarce 1 daca sirul de caractere
t apare in sirul de caractere s si intoarce 0 in caz contrar. Modificati functia
astfel incat sa afiseze in loc de 1, prima pozitie a sirului t in sirul s.

4. Scrieti o functie care lucreaza cu pointeri si care inverseaza un sir de caractere.

5. Scrieti o functie copiaza_n(char *s,char *t,n) care copiaza primele n elemente ale
sirului de caractere t la sfrasitul sirului de caractere s.

6. Scrieti o functie care foloseste pointeri si transforma un sir de caractere intr-un


numar intreg.

Indicatie: Se pot folosi functiile "isspace" si "isdigit" din "ctype.h" care verifica
daca un caracter este spatiu, respectiv cifra.

7. Scrieti o functie care foloseste pointeri si transforma un sir de caractere


intr-un numar real.

IIIa. STRUCTURI;
IIIb. POINTERI LA STRUCTURI;
IIIc. VECTORI DE STRUCTURI
IIId. EXERCITII.

IIIa. STRUCTURI
************

O structura este o colectie de una sau mai multe variabile care pot fi de tipuri
diferite, grupate sub un singur nume. Structurile sunt utile la organizarea unor date
complicate, pentru ca permit unui grup de variabile sa fie tratat ca o unitate.

Declararea unei structuri este de forma:

struct nume_structura {
declaratii ale membrilor structurii;
}

De exemplu un punct in plan poate fi declarat in felul urmator:

struct punct {
int x;
int y;
};

unde x si y sunt coordonatele punctului.

O declarare de structura defineste un tip de date si de aceea acolada inchisa care


marcheaza sfarsitul declararii structurii, poate fi urmat de o lista de variabile
care vor fi structuri de acel tip. Un alt mod de declarare a unor variabile care sunt

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC7.txt[10.12.2010 09:28:51]
structuri este de a folosi mai tarziu in program declaratia:

struct nume_structura lista de variabile;

De exemplu o variabila "pct" care este un punct in plan se poate declara:

struct punct pct;

Pentru a accesa un membru al unei structuri se foloseste operatorul ".":

nume_structura.membru;

De exemplu pentru a tipari coordonatele unui punct dat de variabila "pct" putem
scrie:

printf("%d,%d", pct.x, pct.y);

Un membru al unei structuri poate fi la randul lui o structura.

IIIb. POINTERI LA STRUCTURI


************************

Cand o structura de dimensiuni mari este parametru al unei functii, este in general
mai eficient ca parametrul sa fie o adresa (pointer) de structura. Pointerii
la structuri se definesc in acelasi mod ca pointerii la alte variabile. De exemplu:

struct punct origine, *p;

este o declaratie prin care se specifica faptul ca "origine" este o structura


"punct" iar p este un pointer la o structura punct. De aceea se poate scrie:

p=&origine;
printf("originea este (%d,%d)\n", (*p).x, (*p).y);

Prin "(*p).x" si prin "(*p).y" se acceseaza membrii "x" si "y" ai unui punct
a carui adresa este memorata in pointerul p.

Daca p este un pointer la o structura, un mod mai rapid de a accesa membrii


acelei structuri este:

p->membru

Prin urmare, putem sa scriem:

printf("originea este (%d,%d)\n", p->x, p->y")

IIIc. VECTORI DE STRUCTURI


*************************

Atunci cand este nevoie de perlucrarea mai multor elemente care sunt structuri de
acelasi tip, se pot defini si vectori de structuri astfel:

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC7.txt[10.12.2010 09:28:51]
struct nume_structura{
declaratiile membrilor structurii;
} v[nr_maxim_de_elemente]

IIId. EXERCITII
*************

1. Folosind structura punct de mai sus, sa se defineasca o noua structura


dreptunghi ai carei membri sa fie dati de doua structuri de tip punct. Aceste doua
puncte reprezinta pentru un dreptunghi coltul din stanga jos si coltul din dreapta sus.
Presupunand ca dreptunghiurile au laturile
paralele cu axele de coordonate, sa se scrie (utilizand si pointeri la
structuri) functii pentru:
- a determina coordonatele punctului aflat la intersectia diagonalelor.
- a determina distanta dintre coltul din stanga jos si coltul din
dreapta sus;
- a verifica daca un punct este sau nu in interiorul unui dreptunghi;
- a verifica daca intersectia a doua dreptunghiuri este vida sau nu.
- a verifica daca un dreptunghi este inclus in alt dreptunghi.

2. Sa se scrie un program care defineste o structura asociata unui numar complex.


Sa se scrie functii pentru: adunarea, inmultirea numerelor complexe, determinarea
modulului unui numar complex. Sa se scrie o functie care evalueaza urmatoarea
functie complexa:

exp(z)=1+z/1!+z^2/2!+...+z^n/n!

3. Rezultatele unor studenti care au dat patru examene sunt memorate sub forma
unor inregistrari cu 3 campuri:
- un numar unic asociat fiecarui student;
- numele studentului;
- un vector de 4 elemnte, reprezentand cele 4 note.
Sa se scrie un program care citeste o lista de astfel de studenti sub forma
unui vector de inregistari. Apoi, folosind un meniu, se va cauta un student dupa nume,
numar sau media obtinuta la examene. Daca un astfel de student este gasit, sunt afisate
numarul, numele, notele si media.

IVa. FUNCTII DE ALOCARE SI ELIBERARE A MEMORIEI PENTRU POINTERI;


IVb. TIPURI DE LISTE: COZI SI STIVE;
IVc. LISTE CREATE DINAMIC;
IVd. EXERCITII.

IVa.FUNCTII DE ALOCARE SI ELIBERARE A MEMORIEI PENTRU POINTERI


************************************************************

Functia "malloc": aloca un grup de locatii de memorie si intoarce un pointer


la acel grup. Argumentul functiei "malloc" este reprezentat de numarul de locatii
de memorie necesare pentru memorarea tipului de date spre care "pointeaza" rezultatul

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC7.txt[10.12.2010 09:28:51]
functiei "malloc". Acest numar de locatii de memorie este obtinut folosind functia
"sizeof". De exemplu:
p=malloc(sizeof(int))
aloca spatiu de memorie pentru un numar intreg a carui adresa este memorata in p.

Functia "free" elibereaza spatiul de memorie alocat pentru date spre care "pointeaza"
argumentul functiei. De exemplu
free(p)
elibereaza spatiu de memorie rezervat pentru tipul de date a caror adresa este
memorata in p.

Prototipurile functiilor "malloc" si "free" se afla in fisierul "alloc.h".

IVb. TIPURI DE LISTE: COZI SI STIVE


**********************************

Stiva = o lista in care elementele sunt pozitionate in ordinea inversa citirii


lor. Adica primul element din lista va fi ultimul element citit si ultimul element
din lista va fi primul element citit.

Coada = o lista in care elementele sunt pozitionate in ordinea citirii lor. Adica
primul element din lista va fi primul element citit si ultimul element din lista va
fi ultimul element citit.

IVc LISTE CREATE DINAMIC


************************

In C listele pot fi create secvential (cu ajutorul vectorilor), sau dinamic,


construind (cu ajutorul pointerilor) elmentele listei atunci cand este nevoie de ele.

Cateva din avantajele abordarii dinamice sunt:


- evitarea rezervarii inutile a unor locatii de memorie;
- inserarea sau eliminarea unor elemente oriunde in sau din lista se realizeaza
mai usor.

In mod dinamic se pot crea liste simplu inlantuite (in care fiecare element este
"legat" de urmatorul element din lista), sau liste dublu inlantuite (in care fiecare
element este "legat" atat de elementul care il precede, cat si de elementul care il
urmeaza in lista.

In abordarea dinamica, un element al unei liste simplu inlantuite poate fi definit


cu ajutorul unei structuri cu doua campuri. In primul camp este memorata partea
de informatie iar in al doilea camp este memorata adresa urmatorului element din lista.
De exemplu, pentru o lista simplu inlantuita structura care defineste tipul nod
poate fi scrisa astfel:

typedef struct
{ int inf;
struct nod *leg;
} nod;

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC7.txt[10.12.2010 09:28:51]
O lista este identificata prin primul sau element, numit cateodata si capul listei.
Acest lucru se intampla deoarece, pornind de la primul nod, se pot identifica
toate elementele listei.

Pentru a marca sfarsitul unei liste care nu este circulara, ultimul element al
listei se va lega la pointerul nul (NULL).

Adaugarea unui element intr-o stiva se poate scrie cu ajutorul functiei:

nod *a_stiva(nod *v,int n)


{
nod *q;
q=malloc(sizeof(nod));
q->inf=n;
q->leg=v;
v=q;
return v;
}

Adaugarea unui elemnt intr-o coada se poate scrie cu ajutorul functiei:

nod *a_coada(nod *v, int n)


{
nod *r,*s;
s=malloc(sizeof(nod));
s->inf=n;
s->leg=NULL;
if (!v) v=s;
else
{
r=v;
while(r->leg) r=r->leg;
r->leg=s;
}
return v;
}

Observam ca atat la adaugarea intr-o stiva, cat si la adaugarea intr-o coada


rezultatul functiilor "a_stiva" si "a_coada" este un pointer la o variabila
de tip nod. Acest pointer reprezinta de fapt adresa primului element din lista
(adica a capului listei).

In functia "main", inainte de apelarea celor doua functii, pointerul "v" trebuie
initializat cu pointerul "NULL".

Afisarea informatiilor memorate intr-o lista se poate realiza cu ajutorul functiei:

void listare(nod *v)


{
while(v)
{
printf("%d ",v->inf);

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC7.txt[10.12.2010 09:28:51]
v=v->leg;
}
printf("\n");
}

IVd EXERCITII
************

1. Sa se scrie un program in care sunt create o coada de caractere si o stiva de


cuvinte (siruri de caractere). Sa se afiseze cele doua liste.

2. Sa se scrie o functie care determina numarul de aparitii ale unui element


intr-o lista.

3. Sa se scrie un program in care este creata o stiva cu divizorii pozitivi ai unui


numar intreg pozitiv.
a. Sa se scrie o functie care intoarce media aritmetica a elementelor din stiva.
b. Sa se scrie o functie care determina daca elementele listei sunt ordonate si
determina ordinea in care sunt scrise.

4. Sa se scrie un program in care sunt create doua cozi de numere intregi.


a. Sa se scrie o functie care verifica daca cele doua liste sunt identice.
b. Sa se scrie o functie care verifica daca a doua lista este inclusa
in prima lista.
c. Sa se scrie o functie care pune la sfarsitul primei liste elementele
celei de-a doua liste.

5. Sa se scrie un program in care este creata o stiva de caractere.


a. Folosind functia "free", sa se scrie o functie care elimina elementele
listei care au in partea de informatie caracterul "t".
b. Sa se elimine din lista toate elementele care au in partea de
informatie vocale.

6. Sa se scrie un program in care este creata o coada de numere intergi pozitive.


a. Sa se scrie o functie in care se construieste o lista cu numerele pare
de pe pozitiile impare ale listei initiale.
b. Sa se scrie o functie care inverseaza o lista.

7. Presupunand ca doua multimi de numere intregi sunt memorate sub forma de


liste, sa se scrie un program care realizeaza reuniunea, intersectia, diferenta
si diferenta simetrica (reuniunea diferentelor) pentru cele doua multimi.

Va. ARBORI BINARI;


Vb. EXERCITII;
Vc. FISIERE;

Va. ARBORI BINARI


****************

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC7.txt[10.12.2010 09:28:51]
Constructia dinamica a arborilor binari este asemanatoare cu cea a
listelor, cu mentiunea ca in cazul arborilor structura care defineste tipul nod
va avea trei inregistrari cu doua parti de adresa (pentru subarborele stang si subarborele
drept al nodului) si o parte de informatie.

Un fragment de program in care este creat un arbore binar de sortare se


poate scrie astfel:

#include <stdio.h>
#include <alloc.h>

typedef struct
{ int inf;
struct nod *stg,*dr;
} nod;

nod *un_nod(int x)
{
nod *a;

a=malloc(sizeof(nod));
a->stg=NULL;
a->inf=x;
a->dr=NULL;
return a;
}

nod *inserare(nod *a,int x)


{
if (a)
if (x<=a->inf) a->stg=inserare(a->stg,x);
else a->dr=inserare(a->dr,x);
else
{
a=un_nod(x);
}
return a;
}

nod *creare(nod* a)
{int n;

printf("dati numerele\n");
scanf("%d",&n);
while (n)
{
a=inserare(a,n);
scanf("%d",&n);
}
return a;
}

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC7.txt[10.12.2010 09:28:51]
int main()
{
nod *a=NULL;

a=creare(a);
return 0;
}

Vb. EXRCITII
************

1. Sa se scrie un program in care este creat un arbore binar de sortare care este
parcurs in preordine, inordine si postordine. Sa se scrie o functie care determina
daca exista un nod in care campul inf este un numar citit de la tastatura. Daca
exista un astfel de nod rezultatul functiei va fi subarborele cu radacina in acel
nod.

Vc. FISIERE
************

Fisierele pot fi de doua tipuri: fisiere text si fisiere binare. Fisierele text
sunt formate din caractere ASCII si pot fi scrise cu ajutorul unui editor de texte.
Fisierele binare constau dintr-o succesiune de inregistrari care sunt create cu
ajutorul unui program si nu pot fi create folosind un editor de texte.

Intr-un program in C fisierele sunt declarate prin intermediul unui


pointer la tipul FILE. Astfel un fisier identificat in program prin
numele f1 este declarat astfel:

FILE *f1;

Inainte de prelucrare un fisier trebuie deschis, iar dupa prelucrare fisierul


trebuie inchis. Aceste operatii se fac cu ajutorul functiilor fopen si fclose.

Functii folosite pentru fisiere text:

fputc
fputs
fprintf
fgetc
fgets
fscanf
ferror

Functii folosite pentru fisiere binare:

fread
fwrite

Pe langa citirea si scrierea secventiala in/dintr-un fisier este posibil si accesul


direct la datele inregistrate intr-un anumit loc din fisier. Acest lucru se face
cu ajutorul functiei

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC7.txt[10.12.2010 09:28:51]
int fseek(FILE *nume_fisier, long nr_octeti, int origine)

unde nr_octeti reprezinta numarul de octeti cu care se face deplasarea in


interiorul fisierului, incepand cu originea. Variabila "origine" poate sa ia
urmatoarele valori:

SEEK_SET = inceputul fisierului;


SEEK_CUR = pozitia curenta din fisier;
SEEK_END = sfarsitul fisierului.

Cautati in HELP definitia functiilor mentionate mai sus.

Exemplul 1:

In programul urmator sunt citite date dintr-un fisier text cu numele "grupe.txt" si
care se afla in directorul radacina al discului logic d. Fisierul "grupe.txt" este
scris in prealabil intr-un editor de texte si are urmatorul continut:

23 grupa1
25 grupa2
27 grupa3
21 grupa4

#include <stdio.h>

#define nume_fisier "d:\\grupe.txt"


#define read "r"

int main()
{
FILE *f1;
int nr;
char nume_grupa[20];

f1=fopen(nume_fisier,read);
if (f1==NULL)
{
printf("%s nu poate fi deschis\n",nume_fisier);
exit(1);
}

while (!feof(f1))
{
fscanf(f1,"%d",&nr);
fgets(nume_grupa, 20, f1);
printf("%10d %s", nr, nume_grupa);
}
fclose(f1);
return 0;
}

Exemplul 2:

In programul urmator este creat un fisier in care este memorat un vector de

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC7.txt[10.12.2010 09:28:51]
inregistrari, fiecare inregistrare continand urmatoarele date ale unui student:
nume, varsta, note.

#include <stdio.h>
#include <stdlib.h>

#define fisier_studenti "d:\\studenti.bin"


#define max 100
#define scrie_bin "wb"

typedef struct{
char nume[20];
int varsta;
int note[3];
}inreg;

FILE *deschide_fisier(char nume_fisier[], char scop[])


{
FILE *fisier;

fisier=fopen(nume_fisier,scop);
if (fisier==NULL)
{
printf("%s nu poate fi deschis\n", nume_fisier);
exit(1);
}
else
return fisier;
}

inreg citeste_inreg(void)
{
inreg student;
int i;

printf("nume: ");gets(student.nume);
printf("varsta: ");scanf("%d",&student.varsta);
for(i=0;i<3;i++)
{
printf("nota %d: ",i+1); scanf("%d",&student.note[i]);
}
getchar();
return student;
}

void citeste_lista(inreg lista[],int *lungime)


{
int i=0;
char raspuns;

do
{
lista[i]=citeste_inreg();
i++;

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC7.txt[10.12.2010 09:28:51]
printf("continuati? (d/n)");
raspuns=getchar();
getchar();
}
while(raspuns=='d');
*lungime=i;
}

void afiseaza_lista(inreg lista[],int lungime)


{
int i;

for(i=0;i<lungime;i++)
printf("%-10s\t %d %2d%2d%2d\n",
lista[i].nume,lista[i].varsta,lista[i].note[0],lista[i].note[1],lista[i].note[2]);
}

int main()
{
FILE *studenti;
inreg lista[max];
int lungime;

studenti=deschide_fisier(fisier_studenti,scrie_bin);
citeste_lista(lista, &lungime);
fwrite(lista, sizeof(inreg), lungime, studenti);
afiseaza_lista(lista, lungime);
fclose(studenti);
return 0;
}

file:///C|/Dropbox/_FMI/Cursuri/Programare%20procedurala/Programare%20procedurala/2%20Laboratoare/LabC7.txt[10.12.2010 09:28:51]
Teme de programare procedurala in C
1. Preliminarii

In cele ce urmeaza se considera ca tipurile de date intregi BYTE, WYDE, QUAD si


OCTA au dimensiunile 1, 2, 4, respectiv 8 octeti.

#include <stdio.h>
#define OCTA long long
#define QUAD long int
#define WYDE short int
#define BYTE char
int main(void){
printf("\nsizeof BYTE = %d", sizeof(BYTE));
printf("\nsizeof WYDE = %d", sizeof(WYDE));
printf("\nsizeof QUAD = %d", sizeof(QUAD));
printf("\nsizeof OCTA = %d", sizeof(OCTA));
return 0;
}

Observati structura unui program C foarte simplu si modul de specificare a functiei main
fara argumente.

2. Exercitii si subiecte cu caracter teoretic

2.1. Functia abs. Prototip. Utilizare. Situatii speciale. Studiu asupra programului:
#include <stdio.h>
#include <stdlib.h>
int main(void){
int x= abs(-2147483648);
printf("\nRezultat: %d", x);
return abs(-2147483647);
}

Ce afiseaza? Explicati rezultatul obtinut.

2.2. Sa se studieze functiile din math.h (folderul include al mediului de programare


MinGW 2.05) si sa se utilizeze pentru a scrie corect, in C, urmatoarele expresii :
a) 5x2+7xy+3y2;
b) x2+y2+z2+3xyz;
x 2 + 3x + 2
c)
x2 +1
x +1
d)
2x + 3y + z 2
2

e) |x2-2x-3|
f) |5x2-3xz-y2|
g) ln (x2+4x+4)
h) log x 2 +1 ( x 2 + 6 x + 9)
i) sin (x3+5x-7)
j) x2 + y2 + z2 + 2
7 x 2 + 3 y 2 + 12
k)
x2 + y2 +1
l) ex-y+z
m) e 3 x + 2 y z
2 2

n) lg(3x2+z2+7)
x 2 + 5 + ln(2 x + 1)
o)
| 7x + 6 |

2.3. Identificatori formati corect, respectiv incorect. Sa se analizeze secventele urmatoare


si sa se marcheze identificatorii formati corect:
a) alfa1
b) _a_l_f
c) ___
d) 1_2_3
e) 1a2b
f) *ab*
g) x^3

2.4. Care este valoarea de adevar a propozitiilor?


a) Identificatorii aBBa si ABBA se refera la acelasi obiect
b) Identificatorii NaN1 si nan1 se refera la obiecte diferite
c) bool este cuvant cheie al limbajului C
d) IF este cuvint cheie al limbajului C
e) auto este cuvint cheie al limbajului C

2.5. Constantele zecimale: Specificare, descriptori de citire si afisare standard.


2.6. Constantele octale: Specificare, descriptori de citire si afisare standard.
2.7. Constantele hexazecimale: Specificare, descriptori de citire si afisare standard.
2.8. Constantele reale: Specificare, descriptori de citire si afisare standard.
2.9. Constantele caracter: Specificare, descriptori de citire si afisare standard.
2.10. Constantele sir de caractere: Specificare, descriptori de citire si afisare standard.
2.11. Constantele MANIFEST definite in biblioteca standard: M_E, M_LOG10E, M_PI,
M_LOG2E, M_LN2, M_PI2, M_LN10, M_PI4 (din math.h), CHAR_MAX,
LONG_MAX, CHAR_MIN, LONG_MIN, INT_MAX, INT_MIN, SHRT_MAX,
SHRT_MIN (limits.h)
2.12. Definirea variabilelor (cu acces in citire si modificare). Cuvintele cheie: short, int,
short, long, signed, unsigned, float, double.
2.13. Definirea constantelor (variabile cu acces numai in citire). Cuvintul cheie const.
Analizati textul:
#include <stdio.h>
int main(void){
const int a = 4;
int *p;
p=&a;
printf("\n Adresa lui a este: %p", p);
printf("\na = %d", *p);
return 0;
}
2.14. Prioritatea operatorilor
2.15. Precedenta operatorilor
2.16. Structuri algebrice realizate cu datele de tip intreg.
2.17. Structuri algebrice realizate cu datele de tip IEEE 754.
2.18. Operatorul de atribuire
2.19. Operatori aritmetici (unari si binari)
2.20. Relatii binare. Operatori relationali
2.21. Operatori logici
2.22. Operatori la nivel de bit (complement, +, ., <<, >>);
2.23. Clase speciale de operatori: conversia explicita, sizeof, adresare, ?:, virgula.
2.24. Afisarea si citirea datelor (constante sau variabile). Descriptorii de format.
2.25. Inserarea comentariilor in programe C
2.26. Instructiunea vida
2.27. Instructiunea expresie. Expresii aritmetice. Expresii logice. Expresii speciale.
2.28. Instructiunea compusa
2.29. Instructiunea if (IF si IFR)
2.30. Instructiunea switch
2.31. Instructiunea for
2.32. Instructiunea while
2.33. Instructiunea dowhile
2.34. Instructiunea break
2.35. Instructiunea continue
2.36. Instructiunea goto
2.37. Functii C predefinite (math.h, stdlib.h)
2.38. Functii C definite de programator. Instructiunea return.
2.39. Clase de alocare. Clasele auto, register, static
2.40. Domeniul de vizibilitate. Specificatorii static si extern
2.41. Definirea constantelor folosind enum
2.42. Sinonime pentru tipuri de date, typedef
2.43. Inregistrari. Cuvintul cheie struct
2.44. Cimpuri de biti. Aplicatii.
2.45. Uniuni. Cuvintul cheie union. Aplicatii.
2.46. Tablouri. Definire, declarare, initializare.
2.47. Pointeri
2.48. Tablouri si pointeri. Legaturi intre tablouri si pointeri. Tablouri de pointeri. Pointeri
catre tablou.
2.49. Transferul parametrilor. Parametrii Read Only (transfer prin valoare), parametrii
Read-Write (transfer prin pointeri).
2.50. Transferul parametrilor de tip tablou multidimensional, structura, uniune.
2.51. Siruri de caractere. Functiile predefinite: string.h (strlen, strcpy, strncpy, strcat,
strncat, strcmp, strncmp, strchr, strrchr, strstr, strrstr, functii de conversie (atof, atoi, atoll,
itoa, ltoa, toupper, tolower etc.), verificare (isalnum, isalpha, isdigit, iscntrl, isascii,
isprint, isgraph, islower, isupper, ispunct, isspace, isxdigit). Analiza sirurilor: strtok
2.52. Functia main cu argumente
2.53. Probleme simple: sume, produse, numarare, medii aritmetice, cautari, verificare de
proprietati, maxime, minime, constructii de tablouri, explorarea tablourilor (pe linii, pe
coloane, in spirala, diagonal, etc.), siruri recurente, algoritmi de conversie (din zecimal in
orice baza de numeratie si invers), polinoame.
2.54. Aplicatii ale pointerilor (liste, arbori, grafuri si digrafuri)
2.55. Fisiere (text, binare). Sortare externa. Probleme cu fisiere.
2.56. Crearea secventelor de test. Testarea programelor C scrise pentru rezolvarea
problemelor simple si dificile.
2.57. Biblioteci statici
2.58. Biblioteci dinamice
2.59. Monitorizarea complexitatii programelor (evaluarea timpului de executare).
2.60. Studiul corectitudinii programelor prin utilizarea de asertiuni (assert.h)

3. Exemple de probleme dificile

3.1. Problema 1 [Permanentul unei matrice]

Permanentul unei matrice patrate este definit printr-o formula similara cu cea a
determinantului, cu diferenta ca fiecarui termen al permanentului ii este atribuit semnul
plus, in timp ce pentru un determinant semnele plus si minus alterneaza. Astfel
permanentul matricei

|| a b c ||
|| d e f ||
|| g h i ||
este: aei + bfg + cdh + gec + hfa + idb.

Elaborati un algoritm si scrieti programul C, corect - cu asertiuni pentru verificarea


corectitudinii, care calculeaza permanentul matricei cu elementele intregi a[i,j] =
(i+1)*(j+1), pentru i = 0, 1, ..., n-1; j = 0, 1, 2, ..., n-1.

Programul trebuie sa lucreze corect pentru valori n = 1, 2, ..., 20.

3.2. Problema 2 [Combinari]


Elaborati algoritmul si scrieti programul C care determina, corect - cu asertiuni pentru
verificarea corectitudinii logice, numarul submultimilor cu 13 elemente ale unei multimi
cu 52 de elemente.

3.3. Problema 3 [Determinant]

Scrieti un program C pentru a calcula, corect - cu asertiuni pentru verificarea


corectitudinii logice, determinantul unei matrice patratice cu n linii si n coloane. Aplicati
(executati) programul pentru a calcula determinantul matricilor tridiagonale (1, 1, -1),
pentru n intre 20 si 100. Ce observati?

Nota:
Matricea tridiagonala este de forma:
||1 -1 0 0 0 ... 0 ||
||1 1 -1 0 0 ... 0 ||
||0 1 1 -1 0 ... 0 ||
||0 0 1 1 -1 ... 0 ||
|| ..........0 1 1-1 0..||
||0 0 ..........01 1 -1||
||0 0 ...........0 1 1||

3.4. Problema 4 [Sir Fibonacci]

Fie S[1] = "a", S[2] = "b" si S[n+2] = S[n+1]S[n], n>0; cu alte cuvinte S[n+2] se
formeaza prin plasarea lui S[n] in dreapta lui S[n+1]. Avem S[3]="ba", S[4] = "bab", S[5]
= "babba". Scrieti un program C, corect - cu asertiuni pentru verifcarea corectitudinii
logice, care citeste un sir de caractere, de lungime ce putin 256, verifica daca este sir
Fibonacci (in sensul constructiei din enunt), iar in caz afirmativ determina: pozitia
literelor duble, frecventa (numarul aparitiilor!) literelor a si frecventa literelor b din sir.

3.5. Problema 5 [Patratul magic de ordinul n]

Patratul magic de ordinul n este o dispunere intr-un patrata numerelor de la 1 la nxn in


asa fel incat suma fiecarei linii si suma fiecarei coloane sa fie egale cu n(nxn+1)/2, la fel
ca si suma celor doua diagonale. Regula de generare a acestor patrate este datorata lui
Manuel Moschopoulos, care a trait la Constantinopol in jurul anului 1300: se porneste cu
1 imediat sub celula din mijloc, dupa care deplasarea se face pediagonala catre dreapta si
in jos (la depasirea unei margini continuarea are loc ca si cum intregul plan ar fi acoperit
de patrate dispuse unul langa altul) pana se ajunge la o celula ocupata; urmatoarea celula
se va alege la doua linii mai jos de ultima completata, pe aceeasi coloana. Metoda aceasta
functioneaza pentru orice numar impar. Studiul pentru numere pare va ramane ca
optional.
Se cere un program C, corect - cu asertiuni pentru verificarea corectitudinii logice, care sa
genereze patratul magic de ordinul 23.

3.6. Problema 6 [Inversa unei permutari - in acelasi loc]


Sa se scrie un program C, corect - cu asertiuni pentru verificarea corectitudinii, care
citeste un sir cu n numere intregi, din multimea 1, 2, ..., n si verifica daca sirul reprezinta
o permutare a multimii 1, 2, ..., n. In caz afirmativ va furniza, in acelasi spatiu, fara a
folosi un tablou intermediar, inversa permutarii date la intrare.

3.7. Problema 7 [Transpusa unei matrice dreptunghiulare]

Sa se scrie un program C, corect - cu asertiuni pentru verificarea corectitudinii logice,


care citeste o matrice a[i, j] cu m linii si n coloane (m diferit de n) si obtine transpusa
matricei initiale, in acelasi spatiu de memorie, folosind cat mai putine resurse. NU se va
folosi un tablou temporar cu n randuri si m coloane.

3.8. Problema 8 [Explorarea digrafurilor pe latime - BF]

Sa se scrie un program C, corect - cu asertiuni pentru verificarea corectitudinii logice,


care citeste un digraf cu n varfuri si un varf v[0], iar apoi afiseaza lista varfurilor
digrafului care sunt atinse prin explorarea pe latime a digrafului pornind din varful v[0].

3.9. Problema 9 [Explorarea digrafurilor in adancime - DF]

Sa se scrie un program C, corect - cu asertiuni pentru verificarea corectitudinii logice,


care citeste un digraf cu n varfuri si un varf v[0], iar apoi afiseaza lista varfurilor
digrafului care sunt atinse prin explorarea in adancime a digrafului pornind din varful
v[0].

3.10. Problema 10 [Jocul Scrabble]

Fanii jocului Scrabble sunt obisnuiti cu anagramele - grupuri de cuvinte cu aceleasi litere
dar in alta ordine( ex: ACAR, ARAC, CARA). Exista totusi cuvinte care nu au acest
atribut, adica indiferent cum sunt aranjate literele componente, nu se poate forma un alt
cuvant( ex: MOS). Asemenea cuvinte sunt numite ananagrame. Bineinteles ca aceste
definitii depind de domeniul in care lucram. Un asemenea domeniu poate fi intreg
dictionarul limbii romane, dar asta ar creea unele probleme. Putem restrange domeniul, sa
spunem de exemplu: domeniul muzical, caz in care NOTA devine o ananagrama relativa(
pentru ca TONA nu este in acelasi domeniu). Scrieti un program C - corec logic - cu
asertiuni pentru verificarea corectitudinii logice - care sa citeasca un dictionar dintr-un
anumit domeniu (memorat intr-un fisier) si sa determine toate ananagramele relative.
Cuvintele formate dintr-o singura litera sunt ananagrame deoarece ele nu pot fi
"rearanjate". Un dictionar nu contine mai mult de 1000 de cuvinte si un cuvant are cel
mult 20 de litere, mici sau mari. Liniile fisierului nu au mai mult de 80 de caractere,
cuvintele sunt separate prin spatii si orice cuvant se gaseste in intregime pe o linie.
Ananagramele gasite vor fi scrise intr-un fisier de iesire, fiecare pe cate o linie, in ordine
lexicografica. Observatie: tieD si EdiT sunt anagrame!
Exemplu :
Intrare :
ladder came tape soon leader acme RIDE lone Dreis peat
ScAlE orb eye Rides dealer NotE derail LaCeS drIed
noel dire Disk mace Rob dries

Iesire :
Disk
NotE
derail
drIed
eye
ladder
soon

3.11. Problema 11 [Afisare LC]

Un prieten, obisnuit cu afisarea ecranelor de la mini-computerele de buzunar, va roaga sa


scrieti un program C - corect logic - cu asertiuni pentru verificrea corectitudinii logice -
care sa afiseze numerele in stilul cu care este el obisnuit.
Fisierul de intrare "inLC.txt" va contine citeva linii, fiecare linie continind o pereche de
doua numere s,n, unde n este numarul ce va fi afisat iar s este dimensiunea folosita la
afisare.
In fisierul de iesire "outLC.txt" se vor afisa numerele in stilul LC: se foloseste semnul -
pentru segmentele orizontale si | pentru segmentele verticale. Fiecare cifra ocupa exact
s+2 coloane si 2s+3 linii. Exista exact o singura coloana de spatii intre doua cifre vecine
si o singura linie goala intre numere.
Exemplu:

Intrare:

2 12345
3 67890

Iesire:
-- -- --
| | | | | |
| | | | | |
-- -- -- --
| | | | |
| | | | |
-- -- --

--- --- --- --- ---


| | | | | | | |
| | | | | | | |
| | | | | | | |
--- --- ---
| | | | | | | |
| | | | | | | |
| | | | | | | |
--- --- --- ---

3.12. Problema 12 [4 este inceputul?]

Sa se scrie un program c, corect logic - cu asertiuni pentru verificarea corectitudinii


logice - care sa genereze numarul natural n, pornind de la cifra 4 si efectuand la fiecare
pas una din urmatoarele operatii:

* impartire la 2
* adaugarea(concatenarea) la dreapta a cifrei 0
* adaugarea(concatenarea) la dreapta a cifrei 4

Poate fi generat astfel orice numar natural n?

3.13. Problema 13 [Imagine]

Sa se scrie un program c, corect logic - cu asertiuni pentru verificarea corectitudinii


logice - care citeste o pictura desenata cu caractere ascii dintr-un fisier de intrare
"desen.txt" si umple o regiune aleasa de utilizator cu un caracter specificat de acesta.
Fisierul contine exact 20 linii si 40 coloane. Fiecare linie contine numai spatii si
caracterele din imagine. Fiecare linie din imagine se termina cu caracterul "sfirsit de
linie". Marginea picturii va fi marcata de *.
Programul va citi imaginea din fisierul de intrare, va afisa imaginea citita si va cere
utilizatorului o pozitie din regiunea ce se doreste a fi umpluta (eng. fill), precum si
caracterul folosit la umplere (diferit de spatiu).
Liniile sint numerotate de la 0 la 19 de sus in jos, iar coloanele sint numerotate de la 0 la
39 de la stinga la dreapta.
Doua pozitii sint in aceeasi regiune daca initial sunt umplute cu "spatiu" si sunt adiacente
(orizontal sau vertical) sau sint conectate de o secventa de pozitii adiacente.
Imaginea modificata va fi afisata si apoi salvata in fisierul de iesire "out.txt".

3.14. Problema 14 [Codificare si decodificare de permutari]

Consideram tabloul x de dimensiune n, continand o permutare a elementelor 1..n.


Se defineste un alt tablou xcod, tot de dimensiune n, astfel:

xcod[i] = |{j : j<i si x[j]<x[i]}| .

Sa se scrie un program C, corect logic - cu asertiuni pentru verificarea corectitudinii


logice - care construieste tabloul xcod corespunzator unui tablou dat x.
De asemena scrieti programul C corect logic care decide, pentru un tablou dat xcod cu
valori intregi, daca exista o permutare a carei codificare este xcod si, in caz afirmativ, o
construieste.

Atentie! Programul poate utiliza alte variabile simple, dar nu si alte tablouri.
3.15. Problema 15 [TRIUNGHI]

Se considera un triunghi de cifre zecimale (ca in exemplul de mai jos) in care pe prima
linie apare o cifra, ..., pe linia i apar i cifre (1 <= i <= n). Se doreste determinarea
maximului sumelor cifrelor cre apar pe drumurile care pleaca din varful triunghiului si
care ajung la baza, astfel incat succesorul unei cifre de pe linia i si coloana j ( 1 <= j <= i
<= n-1) este cifra care se gaseste pe linia i+1 si coloana j sau coloana j+1.

Exemplu:
7
38
810
2744
pentru n = 4 - maximul cautat este 25.

Sa se scrie un program C, corect logic - cu asertiuni pentru verificarea corectitudinii


logice - care rezolva problema enuntata.

3.16. Problema 16 [CELULE]

Intr-un lant cu N celule unite in cerc, fiecare celula se poate gasi in doua stari: "linistita"
si "excitata". Daca la un anumit moment o celula a fost excitata, atunci ea emite un
semnal care dupa un timp scurt (sa zicem o milisecunda) ajunge la fiecare dintre cele
doua celule vecine cu ea. Fiecare celula este excitata atunci si numai atunci cand la ea
ajunge un semnal de la una dintre celulele vecine; daca semnalele ajung deodata din
amandoua prtile, atunci ele se anuleaza si celula nu se excita. Pentru o configuratie
initiala indicati ce se intampla la microsecundele 1, 2, ..., 15 Se va mentine excitatia
oricat de mult sau se va linisti?

Sa se scrie un program C, corect logic - cu asertiuni pentru verificarea corectitudinii


logice - care rezolva problema enuntata.

3.17. Problema 17 [Lantul slabiciunilor]

Se considera N persoane (N > 2) si un tablou cu N linii si N coloane in care la intersectia


liniei i cu coloana j se afla valoarea 1 daca persoana i cunoaste persoana j si, valoarea 0 in
caz contrar.

Fiind date doua persoane x si y care nu se cunosc intre ele sa se afle numarul minim de
persoane (si care sunt acestea) prin intermediul carora y poate face cunostinta cu x;

Se cer toate grupurile maximale in care fiecare persoana sa cunoasca pe toate celelalte din
grup.
Sa se scrie un program C, corect logic - cu asertiuni pentru verificarea corectitudinii
logice - care rezolva cerintele din problema enuntata.

3.18. Problema 18 [Virusi]

Intr-o colonie formata din N bacterii intra un virus. In primul minut el omoara o bacterie,
apoi se divizeaza in doi noi virusi si concomitent fiecare dintre bacteriile ramase se
divizeaza de asemenea in alte doua. In minutul urmator cei doi virusi omoara doua
bacterii, apoi cei doi virusi si toate bacteriile ramase din nou se divizeaza, samd.
Colonia va trai nelimitat sau va fi omorata dupa un timp?

Sa se scrie un program C, corect logic - cu asertiuni pentru verificarea corectitudinii


logice - care rezolva problema enuntata.

3.19. Problema 19 [Grup abelian]

Pe o multime X cu N elemente se defineste o lege de compozitie interna *.

Sa se scrie un program C, corect logic - cu asertiuni pentru verificarea corectitudinii


logice - care verifica daca (X, *) este grup abelian.

3.20. Problema 20 [GLOSAR DE TERMENI]

Se doreste realizarea unui dictionar de termeni. Putem scrie cuvantul[1] inainte de


cuvantul[2] daca definitia cuvantul[2] depinde direct sau indirect de definitia cuvant[1].
Trebuie sa nu existe definitii "circulare". Se cere un mod de aranjare a cuvintelor in
glosar astfel incat nici un termen sa nu fie folosit inainte de a fi definit.

Sa se scrie un program C, corect logic - cu asertiuni pentru verificarea corectitudinii


logice - care preia perechi de cuvinte si furnizeaza lista cuvintelor conform cerintei
enuntate.

3.21. Problema 21 [Relatie de ordine partiala]

Se stie ca dandu-se oordonare partiala oarecare a unei multimi S cu n elenemte: x[1],


x[2], ..., x[n], se poate construi o matrice de incidenta a[i,j], unde a[i,j]=1 daca x[i]<= [j]
si a[i,j]=0 in caz contrar si ca se pot permuta liniile si coloanele matricei astfel incat toate
elementele de sub diagonala sa fie egale cu zero.

Sa se scrie un program C, corect logic - cu asertiuni pentru verificarea corectitudinii


logice - care obtine matricea de incidenta cu zero sub diagonala.

3.22. Problema 22 [Expozitie de pictura]

Planul unei expozitii de pictura se poate reprezeta sub forma unui graf neorientat, in care
muchiile reprezinta corodoarele pe peretii carora sunt expuse tablouri, iar punctele de
intersectie ale coridoarelor marcheaza nodurile grafului. Dandu-se punctul de intrare in
expozitie si stiind ca punctul de iesire coincide cu cel de intrare, sa se gaseasca trei trasee
distincte de parcurgere a expozitiei astfel incat sa fie vizionate toate tablourile.

Observatie. Tablourile sunt expuse pe ambele parti ale coridoarelor, traversarea unui
coridor fiind echivalenta cu vizionarea tablourilor pe o singura parte.

Sa se scrie un program C, corect logic - cu asertiuni pentru verificarea corectitudinii


logice - care rezolva problema pusa.

3.23. Problema 23 [Subsiruri de lungime maxima]

Se considera un fisier text cu numele dat de la tastatura, care contine elementele unui sir
x[1], x[2], ..., x[n], n>=1, x[i] numar intreg. Se cere:
1) sa se memoreze sirul intr-o lista simplu inlantuita astfel incat prin parcurgere
elementele sa fie listate in ordine crescatoare.
2) Pornind de la sirul din fisier, sa se determine un subsir de lungime maxima, cu
elementele numere prime si ordonat crescator (ordinea aparitiilor in sirul initial se
pastreaza si in subsir).

Sa se scrie un program C, corect logic - cu asertiuni pentru verificarea corectitudinii


logice - care rezolva problema pusa.

3.24. Problema 24 [Reprezentare condensata]

Un numar in baza 10 cu foarte multe cifre se reprezinta condensat in felul urmator:


fiecare cifra zecimala se scrie pe patru biti iar semnul se reprezinta prin numarul 15 pe
patru biti daca numarul este pozitiv, respectiv 14 pe patru biti daca numarul este negativ;
bitii de semn sunt plasati la sfarsit. Cifrele impreuna cu semnul trebuie sa ocupe un
numar par de octeti. Daca este cazul, numarul se completeaza cu maximum trei zerouri
nesemnificative (reprezentate pe cate patru biti). Se citesc de la intrare, pana la intalnirea
marcii de sfarsit de fisier, linii care contin cate un sir de cifre zecimale.
Sa se reprezinte in memorie numarul obtinut prin concatenarea sirurilor de cifre citite. La
fiecare concatenare a unui nou sir se va afisa reprezentarea rezultatului partial.

Exemplu:
-573<CR> se reprezinta 573E
21<CR> 0057321E
123<CR> 00057321123E

Sa se scrie un program C, corect logic - cu asertiuni pentru verificarea corectitudinii


logice - care rezolva problema pusa.

3.25. Problema 25 [Permutare ca produs de cicluri disjuncte]


Pentru un numr n >= 2 si o permutare sigma a multimii {1, 2, ..., n} se doreste listarea
tuturor ciclurilor disjuncte ale caror produs (compunere de permutari) este siigma. De
asemenea se doreste aflarea numarului de inversiuni ale permutarii sigma.

Sa se scrie un program C, corect logic - cu asertiuni pentru verificarea corectitudinii


logice - care rezolva problema pusa.

3.26. Problema 26 [Expresii in forma poloneza]

Fie E un sir de caractere ce reprezinta o expresie aritmetica corecta.

Sa se scrie un program C, corect logic - cu asertiuni pentru verificarea corectitudinii


logice - care citeste sirul E, construieste arborele binar asociat expresiei si afiseaza
expresia aritmetica in notatia poloneza prefixata si postfixata, stiind ca:

- expresia aritmetica contine operatori aritmetici binari (+, -, *, /), litere (a .. z), cifre
(0..9), paranteze rotunde (, ), drepte [, ] si acolade {, }. Operatorul - nu poate fi unar (in
loc de -5 trebuie scris 0-5);

- un operand este format dintr-o singura litera sau cifra;

- parantezele rotunde nu pot contine in interior decat perechi de paranteze rotunde;


parantezele patrate nu pot contine in interior decat perechi de paranteze rotunde sau
patrate; parantezele acolade pot contine in interior perechi de paranteze de orice tip.

Datele de intrare se afla intr-un fisier text al carui nume va fi introdus de la tastatura,
fiecare linie din fisier fiind o expresie aritmetica corecta.

3.27. Problema 27 [Grai local]

Se considera un text intr-un grai local.

Sa se scrie un program C, corect logic - cu asertiuni pentru verificarea corectitudinii


logice - care cerceteaza daca in acest text exista o anumita secventa si - in caz afirmativ -
sa determine de cate ori apare aceasta secventa in text si intre ce pozitii.

Datele de intrare:

Textul se va introduce dintr-un fisier text al carui nume va fi introdus de la tastatura;

Secventa cautata se introduce de la tastatura.

Date de iesire:

- numarul de aparitii;
- pozitie inceput-sfarsit
Exemplu:
Nume de fisier: test.txt
Continut: uite muica ce facui
Secventa: ui
Raspuns:
3
1-2
7-8
18 - 19

3.28. Problema 28 [Ferestre]

Se doreste reprezentarea pe ecran a unor ferestre suprapuse. Pentru fiecare fereastra se


citeste o linie continand 6 numere: coordonatele (coloana, linie) ale coltului din stanga-
sus si ale coltului dreapta-jos, adancimea ferestrei (fereastra de adancime minima va fi
deasupra celorlalte, deci total vizibila) si codul ASCII al caracterului cu care se va umple
fereastra. Se citesc de la dispozitivul de intrare mai multe linii pana ce se da o linie cu 6
valori nule. In reprezentarea marginilor, respectiv colturilor ferestrelor se vor folosi
caracterele '|', '-' si respectiv '+'.

Sa se scrie un program C, corect logic - cu asertiuni pentru verificarea corectitudinii


logice - care rezolva problema pusa.

3.29. Problema 29 [TEXT]

Se da un text de cel putin 1000 de caractere (litere mici si spatii). Se cere determinarea
celei mai lungi secvente in care literele sunt ordonate alfabetic; precum si cea mai lunga
secventa simetrica (care este aceeasi citita de la stanga la dreapta si invers).

Sa se scrie un program C, corect logic - cu asertiuni pentru verificarea corectitudinii


logice - care rezolva problema pusa.

3.30. Problema 30 [Transmiterea informatiei]

In vederea asigurarii unei transmiteri cat mai exacte de informatii de la un calculator la


altul, transferul se efectueaza pe grupe de cate 8 biti astfel: ultimii 7 biti reprezinta
informatia, iar primul bit se numeste bit de paritate si are aloarea 0 daca suma celor 7
cifre binare de informatie este un numar par sau 1 in caz contrar.

Sa se scrie un program C, corect logic - cu asertiuni pentru verificarea corectitudinii


logice - care pentru un text ASCII format din caractere imprimabile - cu coduri intre 32 si
127 - scrie succesiunile de 8 biti corespunzatoare caracterelor, fiecare succesiune pe 8 biti
fiind urmata de un blanc (spatiu).

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