Indrumar Lab-Oct 2008

75
 Dragoş Burileanu Dragoş Burileanu Dragoş Burileanu Dragoş Burileanu Claudius Dan Claudius Dan Claudius Dan Claudius Dan Marius Pădure Marius Pădure Marius Pădure Marius Pădure  

Transcript of Indrumar Lab-Oct 2008

Page 1: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 1/75

 

Dragoş Burileanu Dragoş Burileanu Dragoş Burileanu Dragoş Burileanu Claudius Dan Claudius Dan Claudius Dan Claudius Dan 

Marius Pădure Marius Pădure Marius Pădure Marius Pădure  

Page 2: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 2/75

 

1

1.  Descrierea mediului de lucruDev-C++

Dev-C++ este un mediu integrat de dezvoltare pentru limbajul de programare C/C++ şi este oferit gratuit decătre firma   Bloodshed Software (Website: http://www.bloodshed.net). El foloseşte compilatorul GCC(GNU C –  Free Software Foundation) şi poate crea fişiere executabile Win32, fie în mod consolă, fie prin intermediulunei interfeŃe grafice (GUI), şi de asemenea biblioteci statice sau dinamice (DLL-uri).

CerinŃele de sistem recomandate de către autori sunt următoarele: sistem de operare MS -Windows 2000, XP; 32MB memorie RAM; unitate centrală (compatibilă Intel ) la 400 MHz; spaŃiu pe disc disponibil 200 MB.

În afara distribuŃiei sale gratuite, Dev-C++ are un număr de caracteristici care îl fac extrem de atractiv pentruutilizare. Fără a intra în detalii, vom remarca în mod special faptul că interfaŃa grafică este foarte flexibilă, dar şiintuitivă şi uşor de folosit şi include toate facilităŃile necesare unui mediu de programare evoluat (editare completă,listare de funcŃii, compilare şi rulare, depanare, creare de proiecte, adăugare de biblioteci etc.).

În această lucrare se utilizează mediul Dev-C++ pentru programarea în limbajul C, iar compilarea surselor vaavea ca rezultat obŃinerea de fişiere executabile Win32.

1.1.  Editarea unui program

 Editarea (adică scrierea   fişierului sursă al programului) se poate face în mediul Dev-C++ în două moduri. Omodalitate eficientă, recomandată în special atunci când avem mai multe fişiere sursă, este de a crea mai întâi un

 Proiect  (meniul File, opŃiunile New şi apoi Project...); în acest mod se permite adăugarea sau eliminareaimediată a unor fişiere şi editarea legăturilor  după compilarea tuturor fişierelor sursă, ca şi un control al diferiŃilor  parametri disponibili în mediul de programare. O a doua modalitate, mai simplă, este de a se crea direct un (singur)fişier sursă; această metodă va fi descrisă succint şi ilustrată în cele ce urmează.

Presupunând ca suntem deja în interfaŃa grafică, se selectează meniul File, iar din New se alege Source 

File (sau se foloseşte combinaŃia de taste CTRL+N), aşa cum este prezentat în Figura 1.1.

Se va deschide astfel o nouă fereastră (numita iniŃial Untitled1) în care se va scrie efectiv programul sursă.După încheierea editării, fişierul sursă trebuie salvat pe disc. Salvarea se face prin comanda Save As... (sau

Save) din meniul File, aşa cum este ilustrat în Figura 1.2; fişierele se vor salva ca fişiere C (C source), şi vor avea pe disc extensia „.c”.

Figura 1.1. Deschiderea unui fişier sursă nou

1.2.  Compilarea programului

Următoarea etapă ce trebuie parcursă este compilarea programului sursă rezultat după terminarea editării, adică„traducerea” sa în limbajul calculatorului şi obŃinerea unui program obiect , reprezentat în cod maşină sau într-un limbajapropiat de acesta. În cazul limbajului C, procesul de compilare şi editare de legături se împarte de fapt între mai multe programe:  preprocesorul , compilatorul propriu- zis, asamblorul  şi editorul de legături, rezultând în final un  fişier executabil .

Page 3: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 3/75

 

 

2

Figura 1.2. Salvarea fişierului editat

În mediul Dev-C++ etapele sugerate anterior (practic compilarea şi editarea legăturilor) sunt parcurse automat şitransparent pentru utilizator prin apelarea opŃiunii Compile din meniul Execute, sau folosind combinaŃia de taste

Ctrl+F9 (Figura 1.3).

Figura 1.3. OpŃiunea de compilare a fişierului sursă

În cazul în care nu există erori, este creat un fişier executabil (având extensia „.exe”) care poate fi rulat, parteade jos a ferestrei interfeŃei grafice arătând, de exemplu, ca în Figura 1.4.

În cazul în care se constată erori la compilare (tipic erori sintactice), lansarea în execuŃie nu este posibilă, iar erorile sunt semnalate în fereastra Compiler (aflată în colŃul din stânga jos al interfeŃei grafice). Figura 1.5 prezintă oastfel de situaŃie; este vorba de acelaşi exemplu (problema 2.2 din Capitolul 2), în care s-au omis intenŃionat ghilimelelece încadrează specificatorul de format   %d din linia 10.

După ce erorile au fost înlăturate este necesar să se facă o nouă compilare (de remarcat faptul că după fiecaremodificare adusă codului sursă, acesta trebuie recompilat). Când compilarea a decurs bine, este permisă rularea programului.

1.3.  Rularea programului

Rularea programului se face prin comanda Run (sau Ctrl+F10) din meniul Execute (a se vedea şi Figura1.4). Această comandă lansează în execuŃie programul, tipărind eventual mesaje şi rezultate pe ecranul calculatorului.

Page 4: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 4/75

 

 

3

Figura 1.4. Compilarea cu succes a fişierului sursă

Figura 1.5. O situaŃie ce conduce la erori de compilare a programului

În această etapă sunt puse în evidenŃă erorile la execuŃie, cum ar fi împărŃirea cu zero, sau sunt puse în evidenŃăerorile de logică dacă rezultatele sunt eronate. Dacă se descoperă astfel de erori, programatorul trebuie să se reîntoarcăla editarea programului sursă, să-l recompileze şi să-l ruleze din nou.

Pentru ca programul să fie lansat în execuŃie automat după compilare se poate folosi comanda Compile &

Run (sau F9) din meniul Execute.

Page 5: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 5/75

 

 

4

2.  Programe simple; variabile şi constante,operaŃii de intrare/ieşire formatate

2.1.  Probleme rezolvate

P2.1 ScrieŃi un program care afişează pe ecran un text dat.

#include <stdio.h>

#include <stdlib.h>

int main() {printf("Acesta este un program C");printf("\n");printf("creat\n");printf("de mine.");printf("\n");system("PAUSE");return 0;

}

Programul va afişa pe ecran, după compilare şi execuŃie:

Acesta este un program Ccreat

de mine.

  DiscuŃie: 

  – Comanda#include realizează includerea în fişierul sursă a unui alt fişier (situat într-un director cunoscut decătre compilator), în acest caz a unor fişiere speciale care descriu conŃinutul unor biblioteci şi care poartă denumirea de  fişiere header , având extensia „.h”. În exemplul anterior, stdio.h este fişierul care defineşte funcŃiile standard deI/O din biblioteca C (printre acestea numărându-se şi funcŃiile printf() şi scanf()), iar stdlib.h este un fişier ce defineşte un număr de funcŃii utilitare din biblioteca standard (cum este şi system()).

 – Programul propriu-zis este descris de funcŃia main(). Acoladele ‚{‘ şi ‚}’ din interiorul funcŃiei marchează practic începutul şi sfârşitul programului. InstrucŃiunile se execută secvenŃial; în cazul anterior, succesiunea operaŃiilor corespunde cu cea de scriere a comenzilor, deoarece nu se precizează explicit un salt la o altă instrucŃiune.

  – FuncŃiaprintf() afişează şirul de caractere inclus între ghilimele. SecvenŃa de caractere ‚\n’ determinătrecerea afişării la un rând nou („newline”). Există şi alte secvenŃe de caractere care determină deplasarea poziŃieiurmătoare de afişare.

  – InstrucŃiuneasystem("PAUSE") are următorul efect: după afişarea rezultatelor, fereastra de rulare  DOS  rămâne deschisă până când se introduce un caracter oarecare de la tastatură, permiŃând astfel vizualizarea şiinterpretarea rezultatelor programului (în lipsa unei astfel de comenzi, fereastra se închide automat după rulare).

  – InstrucŃiunea return utilizată în main() determină întoarcerea unui cod de terminare către sistemul deoperare (valoarea întoarsă trebuie să fie un întreg). Uzual, valoarea ‚0’ indică faptul că programul s-a terminat normal;orice altă valoare indică faptul că există o eroare. Precizăm că toate programele din această lucrare întorc valori din main(), deşi din punct de vedere tehnic acest lucru este opŃional (strict formal, deoarece instrucŃiunea return este plasată pe ultima linie din main(), execuŃia programului oricum se încheie).

=============================

P2.2 ScrieŃi un program care citeşte două numere întregi a şi b şi calculează suma lor.

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

int main() {int a, b, s;printf("Introduceti primul numar, a: ");scanf("%d", &a);printf("Introduceti al doilea numar, b: ");scanf("%d", &b);s = a + b;printf("Suma celor doua numere este %d", s);printf("\n");system("PAUSE");return 0;

}

Page 6: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 6/75

 

 

5

Dacă se introduc de la tastatură, de exemplu, numerele –7 şi 7, programul va afişa pe ecran, după compilareşi execuŃie:

Introduceti primul numar, a: -7

Introduceti al doilea numar, b: 7

Suma celor doua numere este 0

  DiscuŃie: 

  – InstrucŃiunea int a, b, s; declară variabilele de tip întreg a, b şi s. Variabila s va fi folosită pentru a stoca valoarea sumei dintre a şi b.

  – FuncŃiascanf() citeşte un caracter introdus de la tastatură; conform specificatorului „%d”, valoarea citită vafi de tip întreg şi va fi stocată la adresa variabilei ce urmează simbolului ‚&’.  – Linia s = a + b; atribuie variabilei s valoarea a + b.  – Linia printf("Suma celor doua numere este %d", s);  va afişa pe ecran textul Suma

celor doua numere este urmat de valoarea calculată a lui s.

=============================

P2.3 ScrieŃi un program care calculează diferenŃa a două numere întregi introduse de la tastatură.

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

int main() {int a, b;

printf("Introduceti doua numere intregi: ");scanf("%d %d", &a, &b);printf("%d - %d = %d", a, b, a - b);printf("\n");system("PAUSE");return 0;

}

  Dacă se introduc de la tastatură, de exemplu, numerele 7 şi 9, programul va afişa pe ecran, după compilareşi execuŃie:

Introduceti doua numere intregi: 7 9

7 - 9 = -2 

  DiscuŃie: 

  – InstrucŃiunea scanf("%d %d", &a, &b); permite citirea de la tastatură a două numere întregi: prima

valoare citită va fi stocată la adresa variabilei a, cea de a doua la adresa variabilei b. De notat că spaŃiul dintre celedouă grupe de caractere „%d” din  "%d %d"  spune funcŃiei  scanf()  că cele două numere introduse de latastatură pot fi separate de spaŃii.

  – Este absolut corectă utilizarea unor expresii (cum este  „a - b”) în lista de parametri a funcŃiei printf(); ele vor fi evaluate înainte de apelul funcŃiei. Această variantă este chiar mai eficientă decât utilizarea uneivariabile suplimentare, sa spunem c, căreia să i se atribuie valoarea  „a - b”  (această metodă a fost folosită în problema 2.2), deoarece reduce spaŃiul de memorie necesar programului.

=============================

P2.4 ScrieŃi un program care calculează aria unui cerc de rază dată; valoarea razei se va citi de la tastatură şi va fiun număr întreg.

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

int main() {/* Declaratii */int raza;float aria, pi = 3.14;

/* Comenzi */printf("Introduceti raza: ");scanf("%d", &raza);aria = pi * raza * raza; /* calculul ariei */printf("Aria cercului de raza %d este %f", raza, aria);printf("\n");system("PAUSE");return 0;

}

Page 7: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 7/75

 

 

6

Dacă se introduce de la tastatură, de exemplu, valoarea 3, programul va afişa:

Introduceti raza: 3

Aria cercului de raza 3 este 28.260000 

  DiscuŃie: 

  – Se declară variabila raza de tip întreg. Deoarece suprafaŃa unui cerc nu este neapărat un număr întreg,variabila aria în care este calculată va fi declarată de tip real (deci se va utiliza tipul float).

 – Variabila reală pi se iniŃializează cu valoarea 3.14. Deoarece această variabilă nu este de fapt asociată decâtvalorii constante 3.14, acelaşi efect putea fi obŃinut utilizând modificatorul  const. Acesta poate fi folosit pentru acrea constante de un anumit tip; astfel, compilatorul va fi informat că variabila care urmează nu poate fi modificată de program. Prin urmare, instrucŃiunea float aria, pi=3.14; din programul anterior se putea înlocui cu:

float aria;const float pi = 3.14;

 – Comentariile se pot introduce oriunde în program.

=============================

P2.5 ScrieŃi un program care transformă temperatura exprimată în grade Fahrenheit în grade Celsius. Se va utilizaformula: C = ( F  –32)*5/9 , unde C – grade Celsius (număr real), F – grade Fahrenheit (număr întreg).

#include <stdio.h>#include <stdlib.h>int main() {

int gradf;float gradc;

printf("Introduceti temperatura in grade Fahrenheit: ");scanf("%d", &gradf);gradc = (gradf - 32) * 5.0 / 9.0;printf("Temperatura in grade Celsius este %f", gradc);printf("\n");system("PAUSE");return 0;

}

Dacă se introduce de la tastatură, de exemplu, valoarea 100, programul va afişa:

Introduceti temperatura in grade Fahrenheit: 100

Temperatura in grade Celsius este 37.777779 

  DiscuŃie: 

 – După cum s-a cerut în enunŃul problemei, se declară variabilele gradf de tip întreg şi gradc de tip real.Cele două constante utilizate (5 şi 9) se vor introduce în program sub forma „5.0” şi respectiv „9.0”; deşi asupraacestui lucru vom reveni în capitolul următor, vom spune deocamdată doar faptul că rezultatul împărŃirii a doi întregieste un întreg, deci evaluarea expresiei  „(gradf - 32)*5/9”  ar fi dus la un rezultat incorect (chiar dacăvariabila gradc a fost declarată de tip float).

=============================

P2.6 ScrieŃi un program care transformă măsura unui unghi din grade (număr întreg) în radiani (număr real).Se va utiliza relaŃia de transformare cunoscută: rad = grad * π / 180.

#include <stdio.h>

#include <stdlib.h>

int main() {int grad;float rad;const float pi = 3.141593;printf("Introduceti unghiul in grade: ");scanf("%i", &grad);rad = grad * pi / 180;printf("Masura unghiului este de %4.2f radiani", rad);printf("\n");system("PAUSE");return 0;

}

Page 8: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 8/75

 

 

7

Dacă se introduce de la tastatură, de exemplu, valoarea 360, programul va afişa:

Introduceti unghiul in grade: 360

Masura unghiului este de 6.28 radiani

  DiscuŃie: 

  – După cum s-a arătat la partea teoretică, ca specificator de format pentru numere întregi zecimale poate fiutilizat atât „%d” cât şi „%i”; s-a folosit aici a doua variantă.

  – Fiecare caracter ce indică formatul variabilei poate fi precedat în cadrul unui specificator de format de un

modificator ce va determina felul în care se va tipări valoarea. Astfel, în exemplul anterior, „%4.2f” utilizat la adoua funcŃie printf() are următoare semnificaŃie: se va tipări un număr real în format zecimal utilizând în total 4caractere (incluzând punctul zecimal), cu 2 cifre la partea fracŃionară.

=============================

2.2.  Probleme propuse

1. ScrieŃi un program care să vă afişeze numele pe ecran, ca şi seria şi grupa, pe două rânduri succesive.

2. Se citeşte un întreg . ScrieŃi un program care să afişeze: „AŃi introdus numărul .. .”.

3. ScrieŃi un program care citeşte doi întregi şi calculează produsul lor.

4. ScrieŃi un program care calculează lungimea unui cerc de rază dată; valoarea razei se va citi de la tastatură şi va fi

un număr întreg.

5. ScrieŃi un program care transformă temperatura exprimată în grade Celsius în grade Fahrenheit.

6. ScrieŃi un program care transformă măsura unui unghi din radiani în grade.

7. ScrieŃi programe care calculează arii pentru pătrat, dreptunghi, triunghi.

8. ScrieŃi programe care calculează volume pentru cub, paralelipiped, piramidă.

Page 9: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 9/75

 

 

8

3.  Tipuri fundamentale de date, operatori şi expresii

3.1.  Probleme rezolvate

P3.1 Următorul program ilustrează utilizarea tipurilor fundamentale de date în C.

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

int main() {long int i = 66000;unsigned short int u;

double x, y;char b_mic, b_mare, ch;

u = 66000;printf("%ld\t%hu\n\n", i, u);

x = 12.3468, y = 11.2e-2;printf("x = %f sau %6.3f sau %e\n", x, x, x);printf("y = %f sau %8.4f sau %E\n\n", y, y, y);

b_mic = 'b', b_mare = 'B', ch = 'm';

printf("Codurile ASCII pentru 'b' si 'B' sunt: %d, %d\n", b_mic, b_mare);printf("Dupa '%c' urmeaza '%c'\n", b_mic, b_mic + 1);

printf("Majuscula corespunzatoare lui '%c' este '%c'", ch, ch - 'a' + 'A');printf("\n");system("PAUSE");

return 0;

}

Programul va afişa pe ecran, după compilare şi execuŃie:

66000 464

x = 12.346800 sau 12.347 sau 1.234680e+001y = 0.112000 sau 0.1120 sau 1.120000E-001

Codurile ASCII pentru 'b' si 'B' sunt: 98, 66Dupa 'b' urmeaza 'c'

Majuscula corespunzatoate lui 'm' este 'M'

  DiscuŃie: 

 – Programul are, aşa cum se observă, trei părŃi complet distincte. În prima parte se dau două exemple de folosirea numerelor întregi. Programul va afişa corect numărul 66000 declarat long int (de fapt, s-ar fi afişat corect şidacă ar fi fost declarat int, deoarece pe majoritatea calculatoarelor curente reprezentarea internă a lui int este pe32 de biŃi), însă nu afişează corect acelaşi număr declarat unsigned short int. Numerele de tipul unsignedshort int sunt întotdeauna reprezentate pe 16 biŃi, gama lor fiind între 0 şi 216 –1=65535; de altfel, compilatorulsemnalizează acest lucru printr-un mesaj de atenŃionare (fereastra Compiler). Specificatorii de format „%ld” şi„%hu”  permit afişarea numerelor întregi zecimale de tipurile long int şi respectiv unsigned short int.

 – Partea a doua ilustrează câteva modalităŃi de afişare a numerelor reale. Variabilele x şi y se declară detipul double şi se iniŃializează cu două valori concrete. În principiu, specificatorul de format „%f”  poate fi folosit cuoricare din tipurile  float sau  double şi afişarea se face uzual cu 6 cifre la partea fracŃionară. Utilizarea

specificatorului „%e” sau „%E” conduce la afişarea numărului real în formatul ştiinŃific; formatul „%6.3f” va duce laafişarea lui x cu 6 caractere în total (5 cifre plus punctul zecimal) şi 3 cifre precizie pentru partea fracŃionară (caatare, numărul 12.3468 se va rotunji la 12.347); în sfârşit, formatul „%8.4f” va duce la afişarea lui y subforma „ 0.1120” (deoarece lăŃimea câmpului de afişare specificată prin format este 8, cu două unităŃi mai maredecât este necesar, afişarea se completează cu două spaŃii libere la stânga numărului).

 – În partea a treia a programului se exemplifică utilizarea şi afişarea caracterelor. Cele trei variabile folosite suntdeclarate de tipul char; constantele caracter se scriu între simbolurile apostrof. Compilatorul plasează, de exemplu,codul ASCII al lui ‚b’, 98, la adresa variabilei b_mic; similar pentru celelalte două variabile. Aceste valori pot fiutilizate, de exemplu, pentru a face diferite calcule aritmetice (după cum se arată şi în program), şi se afişează canumere întregi dacă se foloseşte specificatorul de format ‚%d’, sau sunt reconvertite în caracterele corespunzătoare dacăeste folosit specificatorul ‚%c’. Această idee este reluată şi în problema următoare.

=============================

Page 10: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 10/75

 

 

9

P3.2 ScrieŃi un program care afişează codul ASCII al unui caracter citit de la tastatură.

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

int main() {char ch;

printf ("Introduceti un caracter: ");ch = getch();printf("\nCaracterul %c are codul ASCII %3d", ch, ch);

printf("\n");system("PAUSE");return 0;

}

Dacă se introduce de la tastatură, de exemplu, caracterul ‚c’, programul va afişa:

Introduceti un caracter: (c)

Caracterul c are codul ASCII 99 

  DiscuŃie: 

 – Se declară variabila ch de tip caracter. FuncŃia getch() citeşte un caracter de la tastatură, adică aşteaptă până când este apăsată o tastă şi apoi întoarce codul său ASCII. Este o variantă a funcŃiei de I/O getche(), dar spredeosebire de aceasta din urmă, nu afişează automat pe ecran caracterul introdus de la tastatură (se mai spune că „nu areecou pe ecran”). Precizăm că funcŃiile getch() şi getche() nu sunt funcŃii ANSI. Bibliotecile standard ANSI

  pun la dispoziŃia utilizatorului doar funcŃiile getc() şi getchar() care însă citesc primul caracter introdus şiaşteaptă validarea scrierii de către utilizator prin tasta <Enter>. Caracterele necitite, inclusiv <Enter>, rămân în buffer şi vor fi citite de următoarele apeluri la getc() sau getchar(). Recomandăm folosirea funcŃiilor getch() şi getche() care sunt mai flexibile.

 – Specificatorul de format „%3d” defineşte dimensiunea minimă a câmpului în care se va afişa numărul întreg(3 în cazul de faŃă); deoarece codul ASCII al lui ‚c’ este 99 (pentru exemplul considerat anterior), deci necesită douăcifre, se va tipări un spaŃiu suplimentar la stânga sa. De notat că dacă se indică o lăŃime de câmp mai mică decât estenecesar, compilatorul va aloca totuşi lăŃimea necesară (doar numărul de zecimale precizat prin format va fi respectatîntocmai).

=============================

P3.3 ScrieŃi un program care adună şi înmulŃeşte două numere complexe exprimate sub forma z 1 = a + bi ,  z 2 = c + d  i (se citesc efectiv a, b, c, d – numere reale). IndicaŃie: (a + bi) + (c + d  i) = (a + c) + (b + d )i

(a + bi)(c + d  

i) = (ac – bd ) + (ad + bc)i#include <stdio.h>#include <stdlib.h>

int main() {float a, b, c, d;

printf("Introduceti z1: ");scanf("%f %f", &a, &b);printf("Ati introdus z1 = %f + %fi", a, b);printf("\nIntroduceti z2: ");scanf("%f %f", &c, &d);printf("Ati introdus z2 = %f + %fi", c, d);printf("\nz1 + z2 = %f + %fi", a + c, b + d);printf("\nz1 * z2 = %f + %fi ", a * c – b * d, a * d + b * c);printf("\n");system("PAUSE");return 0;

}

Dacă se introduc de la tastatură, de exemplu, numerele 1.2 şi 2.1, respectiv 3.4 şi 4.3, programul va afişa:

Introduceti z1: 1.2 2.1 

Ati introdus z1 = 1.200000 + 2.100000iIntroduceti z2: 3.4 4.3 

Ati introdus z2 = 3.400000 + 4.300000iz1 + z2 = 4.600000 + 6.400000iz1 * z2 = -4.950000 + 12.300000i

=============================

Page 11: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 11/75

 

 

10

P3.4 Următorul program ilustrează utilizarea operatorilor de împărŃire (/) şi modulo (%).

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

int main() {int i = 7, j = 4, k, l;float f = 7.0, g = 4.0, h;

k = i / j;h = i / j;printf("7 / 4 = %d sau %f", k, h); /* rezultate incorecte */h = f / g;printf("\n7.0 / 4.0 = %f\n", h); /* rezultat corect */l = i % j;printf("Restul impartirii lui 7 la 4 este %d", l);printf("\n");system("PAUSE");return 0;

}

Programul va afişa pe ecran, după compilare şi execuŃie:

7 / 4 = 1 sau 1.0000007.0 / 4.0 = 1.750000Restul impartirii lui 7 la 4 este 3

=============================

P3.5 Următorul program ilustrează utilizarea operatorilor de incrementare şi decrementare.

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

int main() {int x, y = 10, z;

x = ++y; /* secventa echivalenta cu: y++; x = y; */printf("x = %d, y = %d\n", x, y);

y = 10;z = --y + 5; /* secventa echivalenta cu: y--; z = y+5; */printf("z = %d, y = %d\n", z, y);

y = 10;x = y++; /* secventa echivalenta cu: x = y; y++; */printf("x = %d, y = %d\n", x, y);

y = 10;z = 3 * y--; /* secventa echivalenta cu: z = 3 * y; y--; */printf("z = %d, y = %d", z, y);printf("\n");system("PAUSE");return 0;

}

Programul va afişa pe ecran, după compilare şi execuŃie:

x = 11, y = 11z = 14, y = 9x = 10, y = 11z = 30, y = 9

=============================

P3.6 Următorul program ilustrează utilizarea operatorilor relaŃionali şi logici.#include <stdio.h>#include <stdlib.h>

int main() {int i = 10, j, k, l = 18, m, n;int a, b, c, d, e;

/* Sectiunea 1 */j = i > 5;

Page 12: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 12/75

 

 

11

k = i >= 50;printf("j = %d, k = %d\n", j, k);

/* Sectiunea 2 */m = ((i > 11) && (l < 19)) || (l > 10);printf("m = %d\n", m);

/* Sectiunea 3 */n = 10 > 5 && !(10 < 9) || 3 >= 4;printf("n = %d\n\n", n);

a = 0, b, c = 7, d = 5, e;

/* Sectiunea 4 */b = d += 2;printf("b = %d\n", b);

/* Sectiunea 5 */b = c++ > 7;printf("b = %d, c = %d\n", b, c);

/* Sectiunea 6 */b = a == 0 && c;printf("b = %d\n", b);

/* Sectiunea 7 */e = !a > c >= 2;printf("e = %d", e);

printf("\n");

system("PAUSE");return 0;

}

Programul va afişa pe ecran, după compilare şi execuŃie:

j = 1, k = 0m = 1n = 1

b = 7b = 0, c = 8b = 1e = 0

  DiscuŃie: 

 – SecŃiunea 1: expresia i > 5 este evaluată „adevărat” (10 > 5), deci va primi valoarea ‚1’, apoi j = 1;expresia i >= 50 este evaluată „fals”, deci va primi valoarea ‚0’, apoi k = 0. – SecŃiunea 2: se execută mai întâi parantezele; 0 && 1 = 0, apoi 0 || 1 = 1; în final m = 1. – SecŃiunea 3: ordinea de evaluare este următoarea:

1.  (10 < 9) = 0 2.  !(0) = 13.  10 > 5 = 1 , 3 >= 4 = 0

4.  1 && 1 || 0  ≡  (1 && 1) || 0 = 1 || 0 = 1 5.  n = 1 

  – SecŃiunea 4: operatorii ‚=’ şi „+=” au aceeaşi prioritate şi asociativitate de la dreapta spre stânga; prinurmare, ordinea de evaluare este următoarea:

1.  d += 2  ≡  d = d + 2 = 7 2.  b = 7 

 – SecŃiunea 5: ordinea de evaluare este următoarea:

1.  c > 7 = 0 2.  b = 0 3.  c++ = 8

 – SecŃiunea 6: „==” are prioritate mai mare decât „&&”; ordinea de evaluare este următoarea:1.  a == 0 = 1 2.  1 && c = 1 3.  b = 1

 – SecŃiunea 7: ordinea de evaluare este următoarea:1.  !a = 1 2.  1 > c = 0  ,  0 >= 2 = 0 3.  e = 0 

=============================

Page 13: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 13/75

 

 

12

P3.7 Următorul program ilustrează conversiile implicite de tip în expresii şi atribuiri, ca şi utilizarea operatoruluicast .

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

int main() {/* Sectiunea 1 */int a = 10, b = 3;float c = 10.0, d;int u, x, y;unsigned char ch_1, ch_2;double v;int i, j;float k, l, m, n, p;

d = c / (a / b);printf("d = %f\n\n", d);

/* Sectiunea 2 */u, x = 230, y = 260;v = 10.333;u = v;ch_1 = x;ch_2 = y;printf("u = %d ch_1 = %d ch_2 = %d\n\n", u, ch_1, ch_2);

/* Sectiunea 3 */i = 5, j = 4;k = i / j;l = (float)(i / j);printf("k = %f\tl = %f\n", k, l);m = (float)i / j;n = i / (float)j;p = (float)i / (float)j;printf("m = %f\tn = %f\tp = %f\n", m, n, p);printf("(float)(4 * 6) / 5 = %f", (float)(4 * 6) / 5);

printf("\n");system("PAUSE");return 0;

}

Programul va afişa pe ecran, după compilare şi execuŃie:

d = 3.333333

u = 10 ch_1 = 230 ch_2 = 4

k = 1.000000 l = 1.000000m = 1.250000 n = 1.250000 p = 1.250000(float)(4 * 6) / 5 = 4.800000

  DiscuŃie: 

 – SecŃiunea 1: se evaluează mai întâi paranteza; împărŃirea lui a la b  produce un rezultat întreg (3), ambiioperanzi fiind întregi; această valoare este apoi convertită la o valoare reală, deoarece tipul lui c este float (chiar dacă rezultatul final al unei expresii va fi de tipul cel mai larg, regulile de conversie implicită sunt aplicate operaŃie după

operaŃie).  – SecŃiunea 2: u  primeşte valoarea întreagă a lui v; ch_1 este afişat corect, deoarece numărul întreg 230intră în gama de reprezentare a tipului unsigned char, adică [0, 255], în schimb ch_2 nu este afişat corect, producându-se o pierdere de informaŃie (numai cei 8 biŃi inferiori ai lui y sunt copiaŃi în ch_2).

ObservaŃie: putem deduce simplu valoarea ce va fi afişată pe ecran în acest ultim caz; numărul întreg 260exprimat în binar este 100000100, iar ultimii 8 biŃi codifică practic numărul întreg 4 (numărul 4 reprezentat în binar este100).

 – SecŃiunea 3: alături de lucrurile discutate deja până în acest moment, mai facem doar o precizare: teoretic, estesuficient sa forŃăm tipul unuia dintre cei doi operanzi ce realizează o operaŃie, deoarece cel de-al doilea operand va fiadus automat la tipul celui dintâi.

=============================

Page 14: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 14/75

 

 

13

3.2.  Probleme propuse

1. ScrieŃi un program care calculează şi afişează pe ecran media aritmetică a două numere întregi citite de la tastatură.PropuneŃi mai multe variante de a rezolva corect problema, Ńinând cont de faptul că media trebuie să fie un număr real.

2. ScrieŃi un program care citeşte pe n întreg şi afişează valoarea expresiei n/(n+1) cu patru zecimale.

3. DeduceŃi ce afişează următorul program:

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

int main() {

int i=3, j=5, k=10, x, z, u;

float y;

x = i * k / j + k – j + 3 * i;

printf("x = %d\n", x);

y = (2 * k) / (float)(i * j) + 7;

printf("y = %f\n", y);

i = 3, j = 5, k = 10;

z = --i * j++;

printf("z = %d\n", z);

i = 3, j = 5, k = 10;

u = i < j == j > k;

printf("u = %d", u);

printf("\n");

system("PAUSE");

return 0;

}

4. Ce este incorect la următorul program?

#include <stdio.h>

#include <stdlib.h>

int main() {

int x;

(float)x = 10.22;

printf("x = %f\n");

system("PAUSE");

return 0;

}

Page 15: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 15/75

 

 

14

4.  InstrucŃiuni condiŃionale

4.1.  Probleme rezolvate

P4.1 Următorul program simplu determină dacă un număr întreg introdus de la tastatură este pozitiv (strict pozitivsau zero), sau strict negativ.

#include <stdio.h>

#include <stdlib.h>

int main() {

int numar;

printf("Introduceti un numar intreg: ");

scanf("%d", &numar);

if(numar < 0)

printf("Ati introdus un numar negativ!");

else

printf("Ati introdus un numar pozitiv!");

printf("\n");

system("PAUSE");

return 0;

}

=============================

P4.2 Următorul program simplu citeşte un caracter introdus de la tastatură şi verifică dacă acesta a fost caracterul‚t’.

#include <stdio.h>

#include <stdlib.h>

int main() {

char ch;

printf("Tastati un caracter: ");

scanf("%c", &ch);

if(ch == 't')printf("Ati tastat 't'!");

else

printf("Ati tastat %c ...", ch);

printf("\n");

system("PAUSE");

return 0;

}

=============================

P4.3 Următorul program ilustrează valorile logice „adevărat” şi „fals” în C, folosind două decizii simple.

#include <stdio.h>

#include <stdlib.h>

int main() {if(32)

printf("Acest text va fi intotdeauna afisat.");/* orice valoare diferită de 0 este considerată "adevarat"! */

if(0)printf("Acest text nu va fi afisat niciodata.");

printf("\n");system("PAUSE");return 0;

}

=============================

Page 16: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 16/75

 

 

15

P4.4 ScrieŃi un program care calculează şi afişează rădăcinile ecuaŃiei de gradul doi cu coeficienŃi reali2 0ax bx c+ + = (coeficienŃii fiind citiŃi de la tastatură); se va presupune, pentru simplificare, că 0a ≠ .

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

int main() {

float a, b, c, delta, x1, x2;

printf("Introduceti a (diferit de 0): ");scanf("%f", &a);

printf("Introduceti b: ");

scanf("%f", &b);

printf("Introduceti c: ");

scanf("%f", &c);

delta = b * b – 4 * a * c;

if(delta >= 0) {

x1 = (-b + sqrt(delta)) / (2 * a); /* functia sqrt()

este definita in fisierul header 'math.h' */

x2 = (-b - sqrt(delta)) / (2 * a);

printf("\nSe obtin radacini reale:\n");

printf("x1 = %1.3f\tx2 = %1.3f", x1, x2);

} else {

printf("\nSe obtin radacini complexe:\n");

printf("x1 = %1.3f + %1.3fi", -b / (2 * a),

sqrt(-delta) / (2 * a));

printf("\nx2 = %1.3f - %1.3fi", -b / (2 * a),

sqrt(-delta) / (2 * a));

}

printf("\n");

system("PAUSE");

return 0;

}

=============================

P4.5 Următorul program simplu ilustrează funcŃionarea instrucŃiunilor  if multiple.

#include <stdio.h>

#include <stdlib.h>

int main() {

int i = 100, j = -20;

if(i > 0)

if(i > 1000)

printf("i este foarte mare!");

else

printf("i este mare");

/* se va afisa "i este mare"; else-ul este asociat

celui mai apropiat if */

if(j > 0) {if(j > 1000)

printf("\nj este foarte mare!");

} else

printf("\nj este negativ");

/* se va afisa "j este negativ"; datorita folosirii

acoladelor, else-ul este asociat primului if */

printf("\n");

system("PAUSE");

return 0;

}

=============================

Page 17: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 17/75

 

 

16

P4.6 ScrieŃi un program care să determine dacă trei numere întregi introduse de la tastatură pot constitui o datăcalendaristică (nu se iau în consideraŃie anii bisecŃi sau dacă luna are 30/31 zile).

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

int main() {int zi, luna, an;

printf("Introduceti ziua: ");scanf("%d", &zi);

printf("Introduceti luna: ");scanf("%d", &luna);printf("Introduceti anul: ");scanf("%d", &an);

if((zi > 0) && (zi <= 31))if((luna > 0) && (luna <= 12))

if((an > 0) && (an < 10000))printf ("Poate fi data calendaristica.");

elseprintf("Nu poate fi data din cauza anului!");

elseprintf("Nu poate fi data din cauza lunii!");

elseprintf ("Nu poate fi data din cauza zilei!");

printf("\n");

system("PAUSE");return 0;

}

=============================

P4.7 ScrieŃi un program care să calculeze şi să afişeze minimul dintre două numere reale citite de la tastatură, şirespectiv maximul dintre valorile absolute a două numere întregi, folosind operatorul condiŃional.

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

int main() {/* Sectiunea 1 */

float a, b, min;int c, d, e, f;

printf("Introduceti a: ");scanf("%f", &a);printf("Introduceti b: ");scanf("%f", &b);min=(a < b) ? a : b;

/* secventa echivalenta cu:if(a < b)

min = a;else

min = b; */printf("Minimul dintre a si b este %f\n\n", min);

/* Sectiunea 2 */

printf("Introduceti c: ");scanf("%d", &c);printf("Introduceti d: ");scanf("%d", &d);e = (c < 0) ? –c : c; /* se calculeaza modulul lui c */f = (d < 0) ? –d : d; /* se calculeaza modulul lui d */printf("Maximul dintre |c| si |d| este %d", (e > f) ? e : f);/* daca e>f se va afisa e, altfel se va afisa f */

printf("\n");system("PAUSE");return 0;

}

=============================

Page 18: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 18/75

 

 

17

P4.8 Următorul program ilustrează funcŃionarea structurii de selecŃie. Se citesc două numere întregi a şi b şi ooperaŃie între ele (+, –, *, sau /) şi se va afişa rezultatul operaŃiei.

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

int main() {int a, b;float rez;char op;

printf("Introduceti a: ");

scanf("%d", &a);printf("Introduceti b: ");scanf("%d", &b);printf("Introduceti operatia: ");op = getche();

switch(op) {case '+':

printf("\nSuma este %d", a + b);break;

case '-':printf("\nDiferenta este %d", a - b);break;

case '*':printf("\nProdusul este %d", a * b);break;

case '/':

if(b == 0)printf ("\nImpartirea nu se poate efectua!");else

printf("\nCatul este %f", (float)a / (float)b);break;

default:printf ("\nAti introdus un cod incorect!");

}

printf("\n");system("PAUSE");return 0;

}

=============================

P4.9 ScrieŃi un program care să calculeze şi să afişeze aria sau lungimea unui cerc de rază dată (număr întreg, cititde la tastatură), în funcŃie de opŃiunea utilizatorului.

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

int main() {int r;float pi = 3.14;char c;

printf("Introduceti raza: ");scanf("%d", &r);printf("Introduceti optiunea, astfel:\n");printf("pentru arie: A sau a \n");printf("pentru lungime: L sau l \n");printf("pentru iesire din program: Q sau q \n\n");c=getch();

switch(c) {

default:printf("Optiune necunoscuta!");break;

case 'q':case 'Q':

printf("Iesire!");break;

case 'a':case 'A':

printf("Aria este: %.2f", pi * r * r);break;

case 'l':case 'L':

printf("Lungimea este: %.2f", 2 * pi * r);break;

}

Page 19: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 19/75

 

 

18

printf("\n");system("PAUSE");return 0;

}

  DiscuŃie: 

  – SecŃiunile structurii de selecŃie pot fi plasate în orice ordine; de exemplu, aşezarea lui  default  laînceputul structurii, ca în exemplul anterior, nu afectează în nici un fel funcŃionarea programului.

 – Aşa cum se cunoaşte, instrucŃiunile asociate unui case  pot lipsi complet; aceasta permite, de exemplu, cadouă sau mai multe case să execute aceleaşi instrucŃiuni fără să fie nevoie de repetarea lor 

 – SecvenŃa din program realizată cu switch se putea scrie şi folosind instrucŃiuni de decizie multiple de tipul if-else-if, dar era evident mai complicat:

if(c == 'a' || c == 'A')printf("Aria este: %.2f", pi * r * r);

else if(c == 'l' || c == 'L')printf("Lungimea este: %.2f",2 * pi * r);

else if(c == 'q' || c == 'Q')printf("Iesire!");

elseprintf("Optiune necunoscuta!");

=============================

4.2.  Probleme propuse

1. Ce este incorect la următorul program? Ce va afişa programul dacă după compilare şi execuŃie se introduce de latastatură numărul –10?

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

int main() {int i;

printf("Introduceti un numar intreg: ");scanf("%d", &i);

if(i > 0);printf("Ati introdus un numar pozitiv!");

printf("\n");system("PAUSE");return 0;

}

2. ScrieŃi un program care calculează şi afişează rădăcina ecuaŃiei de gradul întâi cu coeficienŃi reali 0ax b+ =  (coeficienŃii fiind citiŃi de la tastatură); discuŃie. IndicaŃie: ecuaŃia are soluŃie dacă 0a ≠ ; dacă 0a = : dacă 0b = ecuaŃia este nedeterminată, iar dacă 0b ≠  ecuaŃia nu are soluŃie.

3. Folosind instrucŃiuni de decizie, scrieŃi un program care citeşte de la tastatură un număr întreg  x şi afişează ovaloare y calculată astfel:

3 , pentru 0

3 , pentru x [0, 4]

3 9 , pentru 4

 x x

 y

 x x

− + <

= ∈ − >

 

4. ScrieŃi un program care citeşte două numere întregi de la tastatură, împarte cele două numere şi afişează rezultatul.

Cum numitorul trebuie să fie diferit de zero, discutaŃi această situaŃie în două moduri: folosind o decizie if ...else şi respectiv operatorul condiŃional.

5. ScrieŃi un program care să calculeze şi să afişeze maximul şi minimul dintre trei numere întregi citite de latastatură, utilizând operatorul condiŃional.

6. ScrieŃi un program care citeşte de la tastatură un număr întreg între 1 şi 7 şi afişează denumirea zilei din săptămânăcorespunzătoare cifrei respective: 1 – luni, 2 – marŃi etc. Programul va semnaliza printr-un mesaj de eroare dacănumărul introdus nu a fost în intervalul solicitat. IndicaŃie: se va folosi o instrucŃiune switch.

Page 20: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 20/75

 

 

19

5.  Cicluri

5.1.  Probleme rezolvate

P5.1 Următorul program simplu ilustrează utilizarea ciclului cu test iniŃial: se introduc continuu caractere de latastatură, până când este tastată litera ‚q’.

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

int main() {

char ch;

printf("Introduceti un caracter ('q' pentru terminare): ");ch = getch();while(ch != 'q') {

printf("\nAti introdus %c ", ch);ch = getch();

}

printf("\n\nAti introdus q!");printf("\n");system("PAUSE");return 0;

}

  DiscuŃie: 

 – Accentuăm faptul că în C, ciclurile acceptă pentru testarea condiŃiei orice fel de expresii. Mai mult, se potrealiza operaŃii complexe în expresia ce semnifică testul de condiŃie; astfel, partea de program următoare:

ch = getch();while(ch != 'q') {

printf("\nAti introdus %c ", ch);ch = getch();

}

se poate scrie mai simplu astfel:

while((ch = getch()) != 'q') {printf("\nAti introdus %c ", ch);

}

=============================

P5.2 Următorul program simplu ilustrează utilizarea ciclului cu test final: se afişează pătratele numerelor întregicuprinse între a şi 2a, unde a este un întreg pozitiv care se citeşte de la tastatură.

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

int main() {int a, b;

printf("Introduceti un numar intreg pozitiv (<100): ");scanf("%d", &a);b = 2 * a;printf("start\n");

do {printf("%d * %d = %d\n", a, a, a * a);a++;

} while(a <= b);

printf("stop\n");system("PAUSE");return 0;

}

Dacă se introduce de la tastatură, de exemplu, numărul 4, programul va afişa:

Introduceti un numar intreg pozitiv (<100): 4start4 * 4 = 165 * 5 = 256 * 6 = 367 * 7 = 498 * 8 = 64stop 

Page 21: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 21/75

 

 

20

  DiscuŃie: 

 – Cu aceeaşi observaŃie ca cea făcută la problema 5.1, ciclul cu test final din problemă se mai poate scrie, deexemplu, astfel (reamintim că un operator de incrementare sau decrementare utilizat ca prefix determină ca valoareanouă să fie calculată înaintea evaluării expresiei):

do {printf("%d*%d = %d\n", a, a, a * a);

} while(++a <= b);

=============================

P5.3 Următorul program simplu ilustrează forma de bază a ciclului cu contor: se citeşte un număr natural 2n ≥  şi se afişează suma n+++ ...21 .

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

int main() {int n, s, i;

printf("Introduceti un numar natural (>=2): ");scanf("%d", &n);s = 0;for(i = 1; i <= n; i++) {

s = s + i;}printf("Suma numerelor de la 1 la %d este %d", n, s);

printf("\n");system("PAUSE");return 0;

}

  DiscuŃie: 

 – O variantă a programului anterior, utilizând un ciclu cu test iniŃial, este următoarea:

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

int main() {int n, i = 0, s = 0;

printf("Introduceti un numar natural (>=2): ");

scanf("%d", &n);while(i < n) {

i++;s += i;

}printf("Suma numerelor de la 1 la %d este %d", n, s);printf("\n");system("PAUSE");return 0;

}

=============================

P5.4 Să se explice ce afişează următorul program după compilare şi execuŃie, ca şi particularităŃile ciclului for utilizat. Ce se întâmplă dacă se introduce de la tastatură un număr întreg negativ? Dar dacă se introduce unnumăr natural impar?

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

int main() {int i, j;

printf("Introduceti un numar natural par: "); scanf("%d", &i);for( ; i; i -= 2) {

j = i * i * i;printf("%d %d\n", i, j);

}system("PAUSE");return 0;

}

Page 22: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 22/75

 

 

21

Dacă se introduce de la tastatură, de exemplu, numărul 8, programul va afişa:

Introduceti un numar natural par: 8

8 5126 2164 642 8 

  DiscuŃie: 

 – Programul numără descrescător, din doi în doi, de la valoarea introdusă de utilizator şi până la 2, apoi afişează

aceste numere, împreună cu cuburile acestora, pe rânduri succesive. – Sunt ilustrate o serie de variaŃii în modul de utilizare ale ciclului cu contor în C:

• secŃiunea iniŃializare a ciclului lipseşte, deoarece contorul i este iniŃializat practic de către utilizator înafara ciclului (atenŃie însă că semnul ‚;’ trebuie să fie prezent!);

• testul de condiŃie are următoarea semnificaŃie: ciclul se reia atât timp cât i este „adevărat”, adică diferitde zero; de asemenea, se observă că modificarea contorului se poate face cu orice valoare, şi nu numai cu 1 (ca în Pascal , de exemplu);

• contorul este utilizat şi în corpul ciclului, în cazul problemei de faŃă pentru calculul lui j (acest lucru este posibil, aşa cum s-a specificat şi la partea teoretică, deoarece valoarea contorului nu este modificată de operaŃiile dincadrul ciclului).

  – Dacă numărul introdus de la tastatură este negativ, sau pozitiv impar, ciclul se repetă la infinit ( justificaŃi această afirmaŃie!).

=============================

P5.5 ScrieŃi un program care citeşte de la tastatură două numere naturale a şi b, cu a b< , afişează numerele

naturale din intervalul [ , ]a b în ordine crescătoare şi apoi descrescătoare, şi de asemenea calculează şi

afişează media aritmetică a numerelor a şi b.

#include <stdio.h>

#include <stdlib.h>

int main() {int a, b, i, s = 0;

printf("Introduceti a (natural): ");

scanf("%d", &a);printf("Introduceti b (natural, b>a): ");

scanf("%d", &b);

printf("\nNumerele dintre a si b in ordine crescatoare:\n");i = a;while(i <= b) {

printf ("%d ", i);

i++;}

printf("\n");

printf(

"Numerele dintre a si b in ordine descrescatoare:\n");i--; /* dupa ultima iteratie a ciclului

anterior, i = b + 1! */

do {printf("%d ", i);i--;

} while (i >= a);

printf("\n");printf("Media aritmetica a numerelor dintre a si b: ");

for (i = a; i <= b; i++) s = s + i;printf("%.3f",(float)s / (b – a + 1));printf("\n");

system("PAUSE");

return 0;}

=============================

Page 23: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 23/75

 

 

22

P5.6 ScrieŃi un program care citeşte de la tastatură un număr întreg n din intervalul [0, 100] , calculează şiafişează pe n!

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

int main() {int n, i;double fact;/* variabila fact = n! este declarata 'double' deoarece

poate avea valori care sa nu poata fi reprezentate nici

cu 4 octeti! */

printf("Introduceti un numar intreg intre 0 si 100: ");scanf("%d", &n);while(n < 0 || n > 100) {

printf("Numarul introdus nu apartine intervalului!");printf("\nIntroduceti din nou numarul: ");scanf("%d", &n);

}if(n > 0) {

for(fact = 1.0, i = 2; i <= n; i++) {fact = fact * i;/* sectiunea initializare cuprinde doua expresii

separate de operatorul ','! */}

}

else {fact = 1;/* pentru cazul n = 0 se foloseste definitia

standard 0! = 1 */}printf("Pentru n = %d, n! = %g\n", n, fact);/* specificatorul de format '%g' asigura tiparirea in

formatul e sau f, care dintre ele este mai compact */system("PAUSE");return 0;

}

=============================

P5.7 ScrieŃi un program care afişează toŃi divizorii unui număr natural n citit de la tastatură; dacă numărul este prim, se va afişa acest lucru printr-un mesaj.

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

int main() {int n, i, k;

printf("Introduceti un numar natural: ");scanf("%d", &n);k = 0;for(i = 2; i <= n / 2; i++) {

if(n % i == 0) {printf("%d ", i);k = 1;

}}

if(k == 1) printf("sunt divizorii lui %d", n);else printf("Numarul %d este prim!", n);printf("\n");system("PAUSE");return 0;

}

Dacă se introduce de la tastatură, de exemplu, numărul 36, programul va afişa:

Introduceti un numar natural: 36

2 3 4 6 9 12 18 sunt divizorii lui 36

Page 24: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 24/75

 

 

23

  DiscuŃie: 

  – Programul foloseşte un ciclu cu contor pentru a căuta divizorii; se parcurge intervalul [2, / 2]n ,

incrementând unitar contorul i şi se caută numerele la care n se împarte exact (n%i==0). Variabila auxiliară k,iniŃializată cu 0, devine 1 dacă s-a găsit cel puŃin un divizor.

 –  JustificaŃi condiŃia de terminare a ciclului i<=n/2; este testul de condiŃie formulat corect indiferent dacă neste par sau impar?

=============================

P5.8 ScrieŃi un program care citeşte de la tastatură două numere naturale a şi b ( a b< ) şi afişează toatenumerele prime din intervalul [ , ]a b .

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

int main() {int a, b, i, j, k, m;

printf("Introduceti a (natural): ");scanf("%d", &a);printf("Introduceti b (natural, b>a): ");scanf("%d", &b);m = 0;for(i = a; i <= b; i++) {

k = 0;for(j = 2; j <= i / 2; j++) {if(i % j == 0) k=1;

}if(k == 0) {

printf("%d ", i);m = 1;

}}if(m == 1)

printf("sunt numerele prime dintre %d si %d", a, b);else

printf("Intre %d si %d nu exista numere prime!", a, b);

printf("\n");system("PAUSE");

return 0;}

Dacă se introduc de la tastatură, de exemplu, perechile de numere 3, 18 şi respectiv 24, 28, programul vaafişa în cele două situaŃii:

Introduceti a (natural): 3

Introduceti b (natural, b>a): 18 3 5 7 11 13 17 sunt numerele prime dintre 3 si 18

Introduceti a (natural): 24

Introduceti b (natural, b>a): 28 Intre 24 si 28 nu exista numere prime!

  DiscuŃie: 

 – Problema este ceva mai complicată decât cea anterioară, în special dacă se doreşte tratarea tuturor cazurilor  posibile. Primul ciclu for foloseşte contorul i  pentru a parcurge întreg intervalul [ , ]a b ; se presupune mai întâi

că fiecare număr  i din interval este prim şi se iniŃializează cu 0 variabila k. Se parcurge apoi cu al doilea ciclu for (contor  j) intervalul [2, / 2]i pentru a se cerceta dacă fiecare i are sau nu divizori, similar algoritmului utilizat în

 problema 5.7; dacă se găseşte un divizor, k va lua valoarea 1. Dacă după parcurgerea întregului ciclu interior  k rămâne 0, înseamnă că i este prim, se afişează, şi ciclul exterior continuă cu următoarea valoare a lui i.

Variabila auxiliară m foloseşte în acest program pentru a se putea trata şi cazul special în care în intervalul[ , ]a b nu există numere prime; m se iniŃializează cu 0 înainte de primul ciclu, şi devine 1 dacă a fost găsit cel puŃinun număr prim (care s-a afişat).

=============================

Page 25: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 25/75

 

 

24

P5.9 Următorul program ilustrează folosirea instrucŃiunilor   break  şi  continue: se afişează numereleimpare dintre 1 şi un număr natural ales de utilizator; trebuie să se permită reluarea exerciŃiului (fără ieşireadin program), dacă utilizatorul doreşte acest lucru, iar dacă valoarea introdusă este 0≤ , programul va tipăriun mesaj de eroare şi va fi abandonat.

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

int main() {int n, i, k;char ch;

k = 1;do {

printf("Introduceti un numar natural (>0): ");scanf("%d", &n);if(n <= 0) {

printf("Valoare ilegala!\n");break;/* se abandoneaza ciclul 'do...while' */

}for(i = 1; i <= n; i++) {

if(i % 2 == 0)continue;/* se trece la inceputul ciclului 'for':

se incrementeaza contorul, se reevalueazaconditia, apoi ciclul continua; programul nuva afisa numerele pare */

printf("%d ", i);

}printf("sunt numerele impare intre 1 si %d", n);printf("\nDoriti sa reluati? (D/N): ");ch = getche();if(ch == 'N')

k=0;printf("\n\n");

} while(k);system("PAUSE");return 0;

}

=============================

5.2.  Probleme propuse

1. ScrieŃi un program care citeşte pe n natural şi afişează valoarea expresiei:

1 1 11 1 1 2 1

 sn

= + + ++ + +

K.

2. ScrieŃi un program care citeşte pe n natural şi afişează valoarea expresiei:0! 1! 2! ! s n= + + + +K  

3. ScrieŃi un program care afişează numerele dintr-un interval [ , ]a b ce se divid cu un număr natural k citit.

4. ScrieŃi un program care afişează numerele prime mai mici decât un număr natural k citit.

5. ScrieŃi un program care să descompună în factori primi un număr natural n citit.

6. ReluaŃi problema 5.9, cu următoarea modificare: se vor afişa numerele divizibile cu 3 dintre 1 şi un număr naturaln citit.

7. Este corect următorul fragment de program? Ce funcŃie realizează? Ce face, în principiu, ciclul cu contor scris subforma

 for(;;)?

...for( ; ;) {

ch = getche();if(ch == 'A') break;

}...

Page 26: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 26/75

 

 

25

6.  Tablouri şi şiruri de caractere

6.1.  Probleme rezolvate

P6.1 ScrieŃi un program care citeşte de la tastatură un vector de maxim 10 elemente întregi împreună cudimensiunea sa efectivă şi apoi afişează elementele sale. Precizare: Întrucât la rularea programului nu este cunoscut de la început numărul de elemente (el este maimic decât 10) se va opta pentru citirea, la început, a numărului de elemente.

#include <stdio.h>

#include <stdlib.h>

int main() {int v[10], n, i;

printf("Introduceti nr. de elemente: ");scanf("%d", &n);

for(i = 0; i < n; i++) {printf("v[%d] = ", i);scanf("%d", &v[i]);

}

printf("Valorile citite sunt:\n");for(i = 0; i < n; i++)

printf("v[%d] = %d\n", i, v[i]);

system("PAUSE");return 0;

}

Programul va afişa pe ecran după compilare şi execuŃie:

Introduceti nr. de elemente: 3 v[0] = -1 v[1] = 0 v[2] = 1 Valorile citite sunt:v[0] = -1v[1] = 0v[2] = 1

  DiscuŃie:  – Primul ciclufor citeşte elementele vectorului. – Cel de al doilea ciclu for afişează valorile citite şi memorate.

=============================

P6.2 ScrieŃi un program citeşte un vector de elemente întregi, împreună cu dimensiunea sa efectivă, afişează înordine inversă elementele vectorului şi calculează media aritmetică a elementelor sale.

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

int main() {int v[10], n, i, s;float m;

printf("Introduceti n: ");scanf("%d", &n);

for(i = 0; i < n; i++) {printf("v[%d] = ", i);scanf("%d", &v[i]);

}

for(i = n - 1; i >= 0; i--)printf("%d ", v[i]);

s = 0;for(i = 0; i < n; i++)

s += v[i];

Page 27: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 27/75

 

 

26

m = (float)s / n;printf("\tma = %.2f\n", m);

system("PAUSE");return 0;

}

Programul va afişa pe ecran după compilare şi execuŃie:

Introduceti n: 4 v[0] = 1 v[1] = 2 

v[2] = 3 v[3] = 4 

4 3 2 1 ma = 2.50

  DiscuŃie: 

 – După citire numărului de elemente, n, primul ciclu for citeşte elementele vectorului. – Al doilea ciclufor parcurge vectorul de la ultimul (i ia valoarea n - 1) până la primul său element (i >= 0)

 prin decrementarea (i--) contorului.  – Variabila s (ce va conŃine suma tuturor elementelor vectorului) se iniŃializează cu valoarea 0. Al treilea ciclu

for parcurge vectorul şi la fiecare pas al ciclului se adună la vechea valoare a variabilei s, valoarea lui v[i].

 – La final, media aritmetică, ma, este calculată şi afişată. De remarcat conversia de tip (float)s / n.=============================

P 6.3 ScrieŃi un program care citeşte un vector de elemente întregi, împreună cu dimensiunea sa efectivă, şidetermină maximul şi minimul dintre elementele acestui vector.

#include <stdio.h>

#include <stdlib.h>

int main() {int v[20], n, i, max, min;

printf("Introduceti numarul de elemente din vector: ");scanf("%d", &n);

for(i = 0; i < n; i++) {

printf("v[%d] = ", i);

scanf("%d", &v[i]);}

min = max = v[0];

for(i = 1; i < n; i++) {if(v[i] >= max)

max = v[i];

if(v[i] <= min)

min = v[i];

}

printf("max = %d\tmin = %d\n", max, min);

system("PAUSE");

return 0;}

Programul va afişa pe ecran după compilare şi execuŃie:

Introduceti numarul de elemente din vector: 4 v[0] = -1 

v[1] = 5 

v[2] = -3 v[3] = 4 

max = 5 min = -3

Page 28: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 28/75

 

 

27

  DiscuŃie: 

 – După citire numărului de elemente, n, primul ciclu for citeşte elementele vectorului.  – Variabilelemin şi max sunt iniŃializate cu valoarea primului element din vector, v[0]. Algoritmul parcurge

vectorul şi testează la fiecare pas al ciclului for  pentru fiecare element v[i], relaŃia sa de inegalitate în raport cumin respectiv max. În primul caz, dacă v[i] este mai mare decât max, atunci elementul v[i] reprezintă unmaxim local şi deci valoarea lui v[i] i se atribuie variabilei max. În al doilea caz, dacă v[i] este mai mic decâtmin atunci elementul v[i] reprezintă un minim local şi deci valoarea lui v[i] i se atribuie variabilei min. Lasfârşitul ciclului for, variabilele min şi max conŃin valorile minimă respectiv maximă din vectorul v.

=============================

P6.4 ScrieŃi un program care citeşte un vector de elemente întregi, împreună cu dimensiunea sa efectivă,ordonează crescător elementele vectorului şi apoi afişează vectorul ordonat. Se va utiliza metoda de ordonare(se utilizează şi termenul sortare) denumită, în limba engleză, „bubble-sort ”.

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

int main() {int v[20], n, i, ind, tmp;

printf("Introduceti numarul de elemente din vector: ");scanf("%d", &n);

for(i = 0; i < n; i++) {printf("v[%d] = ", i);

scanf("%d", &v[i]);}

do {ind = 0;for(i = 0; i < n - 1; i++) {

if(v[i] > v[i+1]) {tmp = v[i];v[i] = v[i+1];v[i+1] = tmp;ind = 1;

}}

} while(ind);

for(i = 0; i < n; i++)printf("v[%d] = %d\n", i, v[i]);

system("PAUSE");return 0;}

Programul va afişa pe ecran după compilare şi execuŃie:

Introduceti numarul de elemente din vector: 4 v[0] = -1 v[1] = 4 v[2] = 2 v[3] = 0 v[0] = -1v[1] = 0v[2] = 2v[3] = 4

  DiscuŃie: 

  – Primul ciclu for citeşte elementele vectorului. Anterior acesteia a fost citit numărul de elemente alevectorului, n.

  – Programul utilizează o variabila ind, cu rol de indicator. Aceasta variabila se iniŃializează cu valoarea 0înaintea unui ciclu care compară perechile succesive de elemente ale vectorului, elementul curent şi următorul. Pentru parcurgerea vectorului se foloseşte un ciclu for care evoluează de la 0 până la penultimul element (ultima comparaŃiese face între penultimul şi ultimul element). Dacă o pereche de elemente succesive este în ordinea dorită se trece lacompararea următoarei perechi. Dacă o pereche de elemente nu se află în ordinea dorită se schimbă între ele şivariabilei ind i se atribuie valoarea 1. Parcurgerea ciclului se reia până când toate elementele sunt în ordinea dorită,respectiv până când  ind îşi păstrează valoarea 0 după parcurgerea întregului vector. Aceasta este metoda deordonare / sortare „bubble-sort ”.

 – Pentru interschimbarea elementelor care nu se află în ordinea dorită se utilizează variabila temporară tmp.

=============================

Page 29: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 29/75

 

 

28

P6.5 ScrieŃi un program care citeşte o matrice de maxim 10 × 10 elemente întregi, împreună cu dimensiunile saleefective (linii respectiv coloane) şi afişează atât matricea iniŃială cât şi matricea având coloanele pareinterschimbate cu coloanele impare (interschimbarea afectează coloanele alăturate, 0-1, 2-3 etc.).

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

int main() {int A[10][10], m, n, i, j, tmp;

printf("Introduceti nr. de linii: ");scanf("%d", &m);printf("Introduceti nr. de coloane: ");scanf("%d", &n);

for(i = 0; i < m; i++)for(j = 0; j < n; j++) {

printf("A[%d][%d] = ", i, j);scanf("%d", &A[i][j]);

}

printf("\nMatricea citita este:\n");for(i = 0; i < m; i++) {

for(j = 0; j < n; j++)printf("%d\t", A[i][j]);

printf("\n");

}

for(j = 0; j < (n / 2) * 2; j += 2)for(i = 0; i < m; i++) {

tmp = A[i][j];A[i][j] = A[i][j+1];A[i][j+1] = tmp;

}

printf("\nMatricea avand coloanele interschimbate este:\n");for(i = 0; i < m; i++) {

for(j = 0; j < n; j++)printf("%d\t",A[i][j]);

printf("\n");}

system("PAUSE");return 0;}

Programul va afişa pe ecran după compilare şi execuŃie:

Introduceti nr. de linii: 2 Introduceti nr. de coloane: 2 A[0][0] = 1 A[0][1] = 2 A[1][0] = 3 A[1][1] = 4 

Matricea citita este:1 23 4

Matricea avand coloanele interschimbate este:2 14 3

Dacă se introduce o altă matrice rezultatul va fi:

Introduceti nr. de linii: 3 Introduceti nr. de coloane: 5 A[0][0] = 1 A[0][1] = 2 A[0][2] = 3 A[0][3] = 4 A[0][4] = 5 

Page 30: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 30/75

 

 

29

A[1][0] = 6 A[1][1] = 7 A[1][2] = 8 A[1][3] = 9 A[1][4] = 10 A[2][0] = 11 A[2][1] = 12 A[2][2] = 13 A[2][3] = 14 A[2][4] = 15 

Matricea citita este:

1 2 3 4 56 7 8 9 1011 12 13 14 15

Matricea avand coloanele interschimbate este:2 1 4 3 57 6 9 8 1012 11 14 13 15

  DiscuŃie: 

 –  AtenŃie: dacă textul problemei nu specifică în mod explicit că avem de a face cu o matrice pătrată, matricea prelucrată poate avea numărul de linii diferit de cel de coloane!

 – Citirea elementelor matricei A se face cu ajutorul a două cicluri for imbricate: prima din ele, care utilizeazăcontorul i, parcurge liniile matricei; a doua, ce utilizează contorul j, parcurge coloanele matricei  A. Reprezentareasugestiva a parcurgerii matricei în acest caz este prezentată în Figura 6.a. Parcurgerea unei matrice se poate face, îngeneral, utilizând şi parcurgerea pe coloane şi apoi pe linii ca în Figura 6.b.

 – Interschimbarea coloanelor pare cu cele impare se face utilizând a doua modalitate de parcurgere a matricei.Cu excepŃia cazului când n este impar, toate coloanele j se interschimbă cu coloanele j+1 utilizând o variabilă

temporară tmp pentru fiecare element A[i][j].=============================

P6.6 ScrieŃi un program care citeşte de la tastatură o matrice pătrată de dimensiune maximă 10 × 10 elementereale împreună cu dimensiunea sa efectivă şi determină şi afişează suma elementelor de pe diagonala principală şi de pe diagonala secundară.

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

int main() {float mat[10][10];int dim, i ,j;float sum1 = 0.0, sum2 = 0.0;

printf("Introduceti dimensiunea matricei patrate: ");scanf("%d", &dim);

/* Citirea matricei */for(i = 0; i < dim; i++)

for(j = 0; j < dim; j++) {printf("Introduceti mat[%d][%d]: ", i, j);scanf("%f", &mat[i][j]);

}/* Afisarea matricei citite */printf("\nMatricea introdusa este:\n\n");for(i = 0; i < dim; i++) {

for(j = 0; j < dim; j++) {printf("%1.3f\t",mat[i][j]);

}printf("\n");

}

A[0][0] A[0][1]

A[1][0] A[1][1]

A[0][0] A[0][1]

A[1][0] A[1][1](6.a) (6.b)

Page 31: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 31/75

 

 

30

/* Suma elementelor de pe diagonala principala */for(i = 0; i < dim; i++)

sum1 += mat[i][i];printf("\nSuma elementelor de pe diagonala principala");printf(" este %1.3f\n", sum1);

/* Suma elementelor de pe diagonala secundara */for(i = 0; i < dim; i++)

sum2 += mat[i][dim-i-1];printf("\nSuma elementelor de pe diagonala secundara");printf(" este %1.3f\n", sum2);

system("PAUSE");return 0;

}

  Programul va afişa pe ecran, după compilare şi execuŃie:

Introduceti dimensiunea matricei patrate: 4 Introduceti mat[0][0]: 1 Introduceti mat[0][1]: 2 Introduceti mat[0][2]: 3 Introduceti mat[0][3]: 4 Introduceti mat[1][0]: 5 Introduceti mat[1][1]: 6 Introduceti mat[1][2]: 7 Introduceti mat[1][3]: 8 Introduceti mat[2][0]: 9 Introduceti mat[2][1]: 10 Introduceti mat[2][2]: 11 Introduceti mat[2][3]: 12 Introduceti mat[3][0]: 13 Introduceti mat[3][1]: 14 Introduceti mat[3][2]: 15 Introduceti mat[3][3]: 16 

Matricea introdusa este:

1.000 2.000 3.000 4.0005.000 6.000 7.000 8.0009.000 10.000 11.000 12.00013.000 14.000 15.000 16.000

Suma elementelor de pe diagonala principala este 34.000

Suma elementelor de pe diagonala secundara este 34.000

  DiscuŃie: 

 – Mai întâi se citeşte dimensiunea efectivă a matricei şi apoi elementele sale. Programul nu verifică faptul cădimensiunea nu depăşeşte dimensiunea maximă. Recomandăm ca citirea dimensiunii să se facă astfel:

do {printf("Introduceti dimensiunea matricei patrate: ");scanf("%d", &dim);

} while(dim < 1 || dim > 10);

 – Apoi se afişează matricea citită pentru a verifica datele introduse. – Se calculează şi se afişează suma elementelor de pe diagonala principală. Aceste elemente au acelaşi indice

 pentru linii şi coloane. – Se calculează şi se afişează suma elementelor de pe diagonala secundară. Aceste elemente au indicele coloaneiegal cu „dimensiunea – indicele rândului – 1”. În expresia anterioară trebuie să scădem 1 pentru că în C numărătoareaîncepe de la 0!

=============================P6.7 ScrieŃi un program care citeşte două şiruri de maximum 100 de caractere de la tastatură, concatenează al

doilea şir de caractere la primul şi afişează rezultatul.

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

int main() {char s1[201], s2[101];int i, j;

Page 32: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 32/75

 

 

31

i = j = 0;printf("Introduceti sirul 1: ");scanf("%s", s1);printf("Introduceti sirul 2: ");scanf("%s", s2);

while(s1[i] != NULL)i++;

/* atribuie de la capatul sirului 1caracterele din s2 cat timp mai sunt caractere in s2 */

while(s2[j] != NULL) {s1[i] = s2[j];i++;j++;

}s1[i] = NULL;printf("%s\n", s1);

system("PAUSE");return 0;

}

Dacă se introduc de la tastatură şirurile "aaa" respectiv "bbb" programul va rula astfel:

Introduceti sirul 1: aaa Introduceti sirul 2: bbb aaabbb

  DiscuŃie: 

 – Cele două şiruri de caractere, s1 şi s2, sunt citite cu ajutorul funcŃiei scanf().  – Primul ciclu while parcurge sir1  până la capăt prin detectarea condiŃiei s1[i] == NULL. Din acel

moment caracterele din al doilea şir se adaugă în continuare în primul şir cu al doilea ciclu while. Al doilea cicluwhile se putea scrie condensat astfel: while((s1[i++] = s2[j++]) != NULL); 

 – Se remarcă utilizarea operatorului de post-incrementare. Cât timp rezultatul atribuirii s1[i] = s2[j] nueste NULL, adică sir2 nu s-a terminat, se incrementează i, apoi se incrementează j. Corpul instrucŃiunii while conŃine o instrucŃiune vidă întrucât atribuirile sunt realizate direct în condiŃia instrucŃiunii.

 – La ieşirea din al doilea ciclu while, pentru a marca sfârşitul şirului concatenat, se atribuie s1[i] = NULL. – Problema se poate rezolva şi apelând funcŃia standard strcat() astfel:

#include <stdio.h>

#include <stdlib.h>#include <string.h>

int main() {char s1[201], s2[101];

printf("Introduceti sirul 1: ");scanf("%s", s1);printf("Introduceti sirul 2: ");scanf("%s", s2);strcat(s1, s2);

printf("%s\n", s1);

system("PAUSE");return 0;

}

=============================

P6.8 ScrieŃi un program care citeşte un şir de maximum 100 de caractere de la tastatură şi apoi citeşte încă uncaracter separat, care se va elimina din şirul de caractere dacă el există în şir. Programul va afişa rezultatul.

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

int main() {char sir[101], c;int i, j;

printf("Introduceti sirul de caractere\n");printf("apoi caracterul ce se doreste eliminat ");

Page 33: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 33/75

 

 

32

printf("separat prin spatiu\n");

scanf("%s %c", sir, &c);

for(i = j = 0; sir[i] != NULL; i++)

if(sir[i] != c)

sir[j++] = sir[i];

sir[j] = NULL;

printf("%s\n", sir);

system("PAUSE");return 0;

}

Dacă se introduc de la tastatură şirul "orar" respectiv caracterul 'o', programul va rula astfel:

Introduceti sirul de caractere

apoi caracterul ce se doreste eliminat separat prin spatiu

orar o

rar

  DiscuŃie: 

  – Ciclulfor parcurge şirul de caractere, sir. Cât timp nu s-a atins sfârşitul şirului, adică sir[i] != NULL,se testează dacă elementul curent este diferit de caracterul ce se doreşte eliminat, sir[i] != c, şi dacă da atunci

elementul curent din şir se păstrează pe poziŃia curentă prin atribuirea sir[j++] = sir[i], echivalentă cusecvenŃa: sir[j] = sir[i]; j++; (j se incrementează pentru a pregăti următoarea iteraŃie). Dacă elementulcurent este identic cu caracterul ce se doreşte eliminat, atunci atribuirea anterioară nu are loc, astfel că în următoareleiteraŃii, sir[j], care este următorul element din sir, va fi suprascris cu primul caracter diferit de c întâlnit însir.

 – De remarcat atribuirea sir[j] = NULL care marchează sfârşitul de şir.

=============================

P6.9 ScrieŃi un program care citeşte un şir de maximum 100 de caractere de la tastatură şi afişează acest şir în

ordine inversă.

#include <stdio.h>

#include <stdlib.h>

int main() {

char sir[101];

int i = 0;

scanf("%s", sir);

while(sir[i] != NULL)

i++;

while(i >= 0) {

i--;

printf("%c", sir[i]);

}

system("PAUSE");

return 0;

}

Dacă de la tastatură se introduce şirul "abcd", programul va rula astfel:

abcd 

dcba

=============================

Page 34: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 34/75

 

 

33

6.2.  Probleme propuse

1. ScrieŃi un program care citeşte de la tastatură un vector de maximum 50 de numere întregi şi determină numărulelementelor impare ale vectorului.

2. ScrieŃi un program care citeşte de la tastatură doi vectori de maximum 100 de elemente întregi (numărulelementelor poate fi diferit) apoi determină şi afişează intersecŃia celor doi vectori (adică elementele comune celor doi vectori).

3. ScrieŃi un program care citeşte de la tastatură un vector de maximum 20 de elemente întregi şi interschimbă

elementele de pe poziŃii pare cu cele de pe poziŃiile impare.

4. ScrieŃi un program care citeşte de la tastatură un vector de maximum 30 de elemente întregi şi sortează în ordinecrescătoare doar elementele de pe poziŃiile impare.

5. ScrieŃi un program care citeşte de la tastatură un vector de maximum 15 elemente întregi şi inserează un element pe o poziŃie k . Precizare: se vor citi de la tastatură vectorul împreună cu dimensiunea sa efectivă, elementul ce sedoreşte inserat precum şi poziŃia unde se doreşte inserat elementul.

6. ScrieŃi un program care citeşte de la tastatură o matrice pătrată de dimensiuni maxime 10 × 10 elemente reale,afişează matricea transpusă şi apoi calculează suma elementelor matricei.

7. ScrieŃi un program care citeşte de la tastatură o matrice de dimensiuni maxime 10 × 10 elemente întregi apoidetermină şi afişează elementele maxime de pe fiecare linie.

8. ScrieŃi un program care citeşte de la tastatură o matrice pătrată de dimensiuni maxime 100 × 100 elemente realeapoi calculează suma elementelor de sub şi de deasupra diagonalei principale.

9. ScrieŃi un program care citeşte de la tastatură două matrice A şi B (de dimensiuni maxime 10 × 10 elemente reale)apoi calculează produsul lor. Precizare: programul va semnala cazul în care cele doua matrice nu se pot înmulŃi.

10. ScrieŃi un program care citeşte de la tastatură două şiruri de caractere (de maximum 51 de caractere fiecare) şielimină toate caracterele conŃinute în al doilea şir din primul şir. Exemplu: sir1 = "abcdabcd", sir2 = "ad" şi trebuie să rezulte "bcbc". 

11. ScrieŃi un program care citeşte de la tastatură două şiruri de caractere (de maximum 11 caractere fiecare) şiafişează pe ecran numărul de apariŃii ale caracterelor din primul şir în cel de al doilea şir.

 Exemplu: sir1 = "abc", sir2 = "aacde"şi trebuie să rezulte "a = 2, b = 0, c = 1" 

12. ScrieŃi un program care citeşte de la tastatură două şiruri de caractere (de maximum 41 de caractere fiecare) şidetermină de câte ori apare secvenŃa de caractere din al doilea şir în primul. Exemplu: sir1 = "abcdabcc", sir2 = "ab"

şi programul trebuie să afişeze "Sirul ab apare de 2 ori".

13. ScrieŃi un program care citeşte de la tastatură două şiruri de caractere (de maximum 31 de caractere fiecare) şitransformă caracterele majuscule în minuscule şi caracterele minuscule în majuscule. Exemplu: sir = "abcdABC" şi programul trebuie să afişeze "ABCDabc".

Page 35: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 35/75

 

 

34

7.  Alte tipuri de date:structuri, uniuni, tipul enumerat

7.1.  Probleme rezolvate

P7.1 ScrieŃi un program care citeşte datele pentru un grup de cel mult 10 persoane şi afişează datele citite. Precizări: Pentru fiecare persoana se vor memora numele,  prenumele şi data naşterii. Datele fiecărei

 persoane va fi memorat sub forma unei structuri. Data naşterii va fi tot o structură care va avea câmpurile zi,lună şi an.

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

int main() {struct data {

int zi;char luna[12];int an;

};

struct persoana {char nume[20];char prenume[20];

struct data datan;};

struct persoana grup[10];int i, n;

do {printf("Introduceti numarul de persoane: ");scanf("%d", &n);

} while ((n <= 0) || (n > 10));

for(i = 0; i < n; i++) {do {

printf("Nume Prenume An Luna Zi\n");scanf("%s\t%s\t%d\t%s\t%d",

&grup[i].nume, &grup[i].prenume,

&grup[i].datan.an, &grup[i].datan.luna,&grup[i].datan.zi);

} while((grup[i].datan.an < 0) ||((grup[i].datan.zi <= 0) &&(grup[i].datan.zi >= 31)));

}

printf("Nume Prenume An Luna Zi\n");for(i = 0; i < n; i++)

printf("|%s\t|%s\t|%d\t|%s\t|%d\t|\n",grup[i].nume, grup[i].prenume, grup[i].datan.an,grup[i].datan.luna, grup[i].datan.zi);

printf("\n");

system("PAUSE");

return 0;}

Programul va afişa:

Introduceti numarul de persoane: 2 Nume Prenume An Luna ZiPOPA Marius 1980 Mai 22

Nume Prenume An Luna ZiDUTA Ioana 1981 Iunie 2

Nume Prenume An Luna Zi|POPA |Marius |1980 |Mai |22 ||DUTA |Ioana |1981 |Iunie |2 |

Page 36: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 36/75

 

 

35

  DiscuŃie: 

 – În programul anterior se definesc două structuri: data şi persoana. Structura persoana utilizează uncâmp datan care este de tipul struct data.

  – Variabila grup este un tablou de 10 elemente de tipul persoana.  – Primul ciclu do – while citeşte numărul de persoane, n, care trebuie să fie un număr  pozitiv şi mai mic 

decât 10. Deci corpul ciclului va fi executat până când n va fi în intervalul [1, 10].  – Al doilea ciclu for citeşte element cu element persoanele din variabila grup. De notat că elementul

grup[i] are 3 câmpuri: primele două (nume, prenume) sunt de tipul şir de caractere în timp ce al treilea este detipul struct datan. Al treilea câmp are la rândul sau trei alte câmpuri: zi, luna şi an. Deci pentru accesareaacestor subcâmpuri avem nevoie de operatorul ,,.” aplicat de două ori asupra unei variabile de tipul grup[i].

  – Al treilea ciclu for afişează rezultatele citite de la tastatură ca un tabel sub forma:| Nume | Prenume | An | Luna | Zi |.

=============================

P7.2 ScrieŃi un program care citeşte două numere complexe de la tastatură, calculează şi afişează suma celor douănumere complexe. Precizare: Un număr complex se va memora sub forma unei structuri cu câmpurile real şi imag .

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

int main(void) {typedef struct {

float real;float imag;

} complex;

complex a, b, sum;

printf("Introduceti partea reala a primului nr.: ");scanf("%f", &a.real);printf("Introduceti partea imaginara a primului nr.: ");scanf("%f", &a.imag);printf("Introduceti partea reala celui de al doilea nr.: ");scanf("%f", &b.real);printf("Introduceti partea imaginara celui de al ");printf("doilea nr.: ");scanf("%f", &b.imag);

sum.real = a.real + b.real;sum.imag = a.imag + b.imag;

printf("Suma celor doua numere complexe este: ") ;printf(" %.2f + (%.2f) * i\n", sum.real, sum.imag);

system("PAUSE");return 0;

Programul va afişa:

Introduceti partea reala a primului nr.: 1.2 Introduceti partea imaginara a primului nr.: 1.0 Introduceti partea reala a celui de al doilea nr.: -0.2 Introduceti partea imaginara a celui de al doilea nr.: 0 

Suma celor doua numere complexe este: 1.00 + (1.00) * i

  DiscuŃie: 

DeclaraŃia  typedef  introduce un tip utilizator cu numele complex. Structura are doua câmpuri: real şiimag de tipul float. a, b şi sum sunt cele trei variabile utilizate în cadrul programului. a şi b se citesc de latastatură iar rezultatul sumei complexe se atribuie variabilei sum. Această atribuire se poate face numai utilizândoperatorul ,,.” pentru a selecta individual câmpurile real şi imag. De notat că atribuirea sum = a + b  nu esteposibilă în C.

=============================

P7.3 ScrieŃi un program care citeşte şi stochează două momente succesive de timp, ce reprezintă, de exemplu,momentul la care a plecat un atlet şi respectiv a sosit un atlet într-o competiŃie. Programul va afişa timpulscurs între cele două momente.

Page 37: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 37/75

 

 

36

#include <stdio.h>#include <stdlib.h>int main() {

struct timp {int ora; /* ora */int min; /* minutul */int sec; /* secunda */

};

struct timp start, stop;

int start_int, stop_int;

printf("Introduceti start: ");scanf("%d:%d:%d", &start.ora, &start.min, &start.sec);printf("Introduceti stop: ");scanf("%d:%d:%d", &stop.ora, &stop.min, &stop.sec);

start_int = start.ora * 3600 + start.min * 60 + start.sec;stop_int = stop.ora * 3600 + stop.min * 60 + stop.sec;

printf("timp: %d s\n", stop_int - start_int);

system("PAUSE");return 0;

Programul va afişa:Introduceti start: 10:11:10 Introduceti stop: 10:12:11 timp: 61 s

  DiscuŃie: 

− start şi stop reprezintă două variabile care stochează ora, minutul şi secunda în care a plecat respectiv aterminat proba atletul. start_int şi stop_int reprezintă echivalentul în secunde al celor două momente detimp. RelaŃia de calcul are în vedere faptul că o oră are 3600 de secunde iar un minut are 60 de secunde. DiferenŃa dintrecele două variabile, stop_int - start_int, reprezintă echivalentul în secunde al timpului efectuat.

=============================

P7.4 ScrieŃi un program care determină spaŃiul de memorie ocupat de o structură.

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

struct exemplu {int i;int *p;double d;char str[80];

} s;

int main() {printf("Structura exemplu are dimensiunea: %d octeti.", sizeof(struct exemplu));printf("\n");

system("PAUSE");

return 0;}

Programul va afişa:

Structura exemplu are dimensiunea: 96 octeti.

=============================

P7.5 ScrieŃi un program care codează şi decodează un întreg folosind uniuni prin inversarea ordinii octeŃilor carecompun numărul întreg. Pentru valorile variabilelor din program, se va afişa:

10 codat este: 167772160167772160 decodat este: 10

Page 38: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 38/75

 

 

37

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

int encode(int i);

int main() {int i;int in;union coddecod {

int num;char c[4];

} crypt;unsigned char ch;

printf("Intoduceti un numar intreg: ");scanf("%d", &in);

/* codarea intregului */crypt.num = in;ch = crypt.c[0];crypt.c[0] = crypt.c[3];crypt.c[3] = ch;ch = crypt.c[1];crypt.c[1] = crypt.c[2];crypt.c[2] = ch;i = crypt.num;

printf("%d codat este: %d\n", in, i);

/* decodarea intregului */crypt.num = i;ch = crypt.c[0];crypt.c[0] = crypt.c[3];crypt.c[3] = ch;ch = crypt.c[1];crypt.c[1] = crypt.c[2];crypt.c[2] = ch;in = crypt.num;

printf("%d decodat este: %d", i, in);

printf("\n");

system("PAUSE");

return 0;}

  Programul va afişa pe ecran, după compilare şi execuŃie:

Intoduceti un numar intreg: 10 10 codat este: 167772160167772160 decodat este: 10

  DiscuŃie: 

 – Prin intermediul unei uniuni se pot accesa octeŃii care compun un număr întreg.

P7.6 ScrieŃi un program care memorează pe rând, în acelaşi spaŃiu de memorie, un caracter, un număr întreg şi unnumăr real.

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

int main() {union {

char c;int i;float f;

} u;

u.c = 'A';printf("Un caracter: %c\n", u.c);

u.i = 65;printf("Codul ASCII: %d\n", u.i);

Page 39: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 39/75

 

 

38

printf("Caracterul urmator: %c\n", u.c + 1);

u.f = u.i + 0.14;printf("Un float: %.2f\n", u.f);

u.f = 3.14;u.i = 2;printf("Aria cercului de raza %d: %.2f\n", u.i, u.f * u.i * u.i);

system("PAUSE");return 0;

}

Programul va afişa:Un caracter: ACodul ASCII: 65Caracterul urmator: BUn float: 65.14Aria cercului de raza 2: 0.00

  DiscuŃie: 

 – În cadrul programului se defineşte o variabilă u având tipul „union”. Variabila poate stoca la un momentdat un caracter, un întreg sau un număr real.

 – Primele două linii după declararea variabilei atribuie variabilei u, în câmpul c (adică u.c) valoarea 'A'.Variabila este apoi tipărită cu ajutorul specificatorului de format %c pentru caractere.

 – Următoarele trei linii ilustrează atribuirea valorii 65, de data aceasta, câmpului i. În acest punct al execuŃiei programului, valoarea câmpului c este distrusă. Tipărirea se va face utilizând specificatorul de format %d. A treialinie ilustrează tipărirea caracterului asociat codului ASCII imediat următor. Întrucât codul ASCII are valoarea 65 (el

având asociat caracterul 'A'), programul va afişa caracterul 'B'. – Următoarele 2 linii atribuie câmpului f o valoare egală cu vechea valoare a câmpului i (adică 65) la carese adună 0.14. De remarcat faptul că vechea valoare, 65, se pierde numai după ce a avut loc atribuirea, adică ordineaoperaŃiilor se desfăşoară astfel încât se adună întâi 65 cu 0.14 şi apoi se atribuie lui u.f valoarea 65.14. În acestmoment, u.i îşi pierde valoarea 65.

 – Ultimele trei linii ilustrează calculul ariei unui cerc într-un mod greşit. În primele două linii atribuirile u.f = 3.14 (adică numărul PI) şi u.i = 2 (adică raza cercului) au ca efect modificarea valoarea lui PI astfel încâtrezultatul final este în mod greşit altul decât cel aşteptat. Întrucât o variabilă de tipul enumerat poate lua valori de maimulte tipuri în timpul execuŃiei programului, în lucrul cu uniuni trebuie avut grijă ca la orice moment de timp să fie ştiuttipul datei ce se află stocat în variabila uniune.

=============================

P7.7 ReluaŃi problema anterioară dar construiŃi şi o metodă care vă permite să aflaŃi în orice moment tipulinformaŃiei stocate.

#include <stdio.h>

#include <stdlib.h>int main() {

struct {int tip;union {

char c;int i;float f;

} u;} z;z.u.c = 'A';z.tip = 0;z.u.f = 3.1415;z.tip = 2;

switch (z.tip) {case 0: printf("Un caracter: %c\n", z.u.c);

break;case 1: printf("Un intreg: %d\n", z.u.i);

break;case 2: printf("Un float: %f\n", z.u.f);

break;default: printf("Format necunoscut\n");

break;}

system("PAUSE");return 0;

}

Programul va afişa:

Un float: 3.141500

Page 40: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 40/75

 

 

39

  DiscuŃie: 

 – Acest program ilustrează utilizarea unei uniuni, u, în cadrul unei structuri, z. Structura are un câmp, tip, detipul întreg. Valorile pe care le ia câmpul tip (de exemplu: 0 pentru caractere, 1 pentru întregi şi 2 pentru real), pot fimodificate la momentul atribuirii unui subcâmp al uniunii, u. Astfel, în orice moment de timp se cunoaşte tipul stocatîn câmpul u după valorile câmpului tip.

  – InstrucŃiunea switch decide, funcŃie de valoarea din câmpul tip (0, 1, 2), cum trebuie afişatăvariabila z. 

=============================

P7.8 ScrieŃi un program care calculează media notelor obŃinute la probele de verificare (laborator ,  parŃial  şiexamen) ale unei materii ( fizică , biologie şi chimie) utilizând tipul enumerat.

#include <stdio.h>

#include <stdlib.h>

int main() {typedef enum {laborator, partial, examen} didactic;

didactic activitate;

typedef enum {fizica, biologie, chimie} materii;

materii materie;

float nota, suma;

for(materie = fizica; materie <= chimie; materie++) {

suma = 0.0;for(activitate = laborator; activitate <= examen;

activitate++) {

scanf("%f", &nota);suma += nota;

}

printf("Media = %.2f\n", suma/3);

}

system("PAUSE");

return 0;

}

În urma introducerii notelor la laborator, parŃial şi lucrarea finală, pentru fiecare din cele materii, programulva afişa:

9

10

10

Media = 9.678

8

7.5

Media = 7.83

  DiscuŃie: 

 – Programul anterior citeşte de la tastatură notele obŃinute de un student la diferite materii, fiecare materie avândexaminări, de exemplu, la laborator, pe parcursul semestrului, respectiv la examenul final. La finalul fiecărei materii, programul afişează media la materia respectivă.

  – Programul defineşte două enumerări, didactic şi materii, având ca membri tipul de examinare(laborator, parŃial sau examen) respectiv numele materiilor la care s-a efectuat examinarea (fizica,biologie, chimie). Variabilele activitate şi materie sunt de tipul didactic respectiv materii.

  – Variabilele nota şi suma sunt de tipul float. Cu ajutorul a două cicluri for se parcurg toate materiile posibile, respectiv toate probele. Variabila suma se iniŃializează cu valoarea 0 la începutul celui de al doilea ciclufor. În interiorul acestuia se citeşte succesiv variabila nota, aceasta urmând să se adune la totalul din variabilasuma.

 – La finalul ultimului ciclu for, se afişează valoarea mediei.

=============================

Page 41: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 41/75

 

 

40

7.2.  Probleme propuse

1. ScrieŃi un program care citeşte de la tastatură un vector de elemente complexe, calculează şi afişează sumacomplexă a tuturor elementelor sale.

2. ScrieŃi un program care citeşte de la tastatură un vector de elemente complexe, calculează şi afişează produsulcomplex al tuturor elementelor sale.

3. Să se modifice programul P7.3 astfel încât să nu mai afişeze numai numărul total de secunde, ci şi timpul efectuatsub forma: ore : minute : secunde.

 Exemplu: 3700 secunde reprezintă 1 ora, 1 minut şi 40 de secundeadică „1:1:40”.

4. ScrieŃi un program care citeşte de la tastatură un vector de coordonate ale unei structuri împreună cu masele plasate la coordonatele respective şi calculează centrul de greutate al structurii. Precizări:− fiecare coordonată împreună cu masa asociată se va memora într-o structură definită astfel:

typedef struct {float x, y, masa;

} punct;

− punctele se vor memora într-o matrice definită astfel:

punct mase[MAX];

−structura va putea fi alcătuită din cel mult 100 de puncte.

5. ModificaŃi programul P7.8 astfel încât să memoreze numele materiilor şi notele obŃinute în structuri.

6. ScrieŃi un program care memorează scorurile obŃinute de cel mult 10 jucători împreună cu numele jucătorilor.InformaŃiile se vor memora într-o matrice constituită din structuri definite astfel:

typedef struct {char nume[20];int scor;

} jucator;

7. ScrieŃi un program care implementează o agendă telefonică sub forma unei structuri cu următoarea definiŃie:

typedef struct {char nume[20];char prenume[20];

char adresa[20];unsigned int cod_postal; unsigned int numar;unsigned int prefix; unsigned int mobil;

} intrare;

8. ScrieŃi un program care scrie octeŃii care formează o valoare de tip double sub formă zecimală în ordineaoctet 7 , octet 6 , octet 5, octet 4, octet 3, octet 2, octet 1, şi octet 0, unde octet 7  este octetul cel mai semnificativ iar octet 0 este octetul cel mai puŃin semnificativ. Precizări:− ordinea în memorie a octeŃilor depinde de platforma de calcul: există calculatoare de tip „BIG_ENDIAN”, lacare primul octet din memorie este cel mai puŃin semnificativ şi de tip „LITTLE_ENDIAN” la care primul octeteste cel mai semnificativ. Va trebui ca mai întâi să stabiliŃi ce tip de calculator folosiŃi şi apoi să parcurgeŃi octeŃiiîn ordinea corespunzătoare;− pentru a accesa octeŃii care formează un număr de tip double utilizaŃi uniunea:

typedef union {char octet[8];double numar;

} valoare; 

Page 42: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 42/75

 

 

41

8.  FuncŃii simple; recursivitate

8.1.  Probleme rezolvate

P8.1 ScrieŃi un program care calculează integrala unei funcŃii oarecare, într-un interval [a, b] ale cărui limite sevor citi de la tastatura. Utilizatorul va specifica şi numărul de subintervale de discretizare. Metoda deintegrare este metoda dreptunghiurilor.

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

float f(float x) {return (x * x - x + 1);

}

int main() {float a, b, intg, eps;int n; /* numarul de subintervale */int i;

printf("Introduceti limita de inceput a intervalului: ");scanf("%f", &a);

printf("Introduceti limita de sfarsit a intervalului: ");scanf("%f", &b);

printf("Introduceti numarul de subintervale ");printf("de discretizare: ");scanf("%d", &n);

eps = (b - a) / n; /* pasul integrarii */intg = f(a) * eps; /* primul dreptunghi */for(i = 1; i <= n; i++)

intg += f(a + i*eps) * eps;

printf("Valoarea integralei este %.3f\n", intg);

system("PAUSE");return 0;

}

  Programul va afişa pe ecran, după compilare şi execuŃie:

Introduceti limita de inceput a intervalului: 0 Introduceti limita de sfarsit a intervalului: 2 Introduceti numarul de subintervale de discretizare: 1000 Valoarea integralei este 2.671

  DiscuŃie: 

 – Programul reprezintă implementarea directă a metodei dreptunghiurilor folosită la integrarea numerică a uneifuncŃii pe un interval dat. Calculul valorii funcŃiei într-un punct se face cu ajutorul funcŃiei f();

=============================

P8.2 ScrieŃi un program care afişează numerele pare dintr-un interval [a, b] cu ajutorul unei funcŃii. Limiteleintervalului vor fi specificate de utilizator.

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

int par(int k) {if(k % 2 == 0)

return 1;else

return 0;}

int main() {int a, b, i;

printf("a = "); scanf("%d", &a);printf("b = "); scanf("%d", &b);

Page 43: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 43/75

 

 

42

for(i = a; i <= b; i++)if(par(i) == 1)

printf("%d ",i);printf("\n");

system("PAUSE");return 0;

}

  Programul va afişa pe ecran, după compilare şi execuŃie:

a = 1 

b = 20 2 4 6 8 10 12 14 16 18 20

  DiscuŃie: 

 – Parcurgerea intervalului se face în programul principal. Pentru fiecare element din interval funcŃia par() verifică dacă acesta este par. Daca este par funcŃia returnează 1, daca nu este par returnează 0.

=============================

P8.3 ScrieŃi un program care citeşte un număr natural n şi calculează şi afişează factorialul numărului n definitastfel:

( )

>−⋅

==

1 pentru,!1

1 pentru,1!

nnn

nn  

Calculul factorialului se va realiza cu ajutorul unei funcŃii recursive.

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

int factorial(int n) {if(n == 1)

return 1;else

return (n * factorial(n - 1));}int main() {

int i, j, k, n;

do {printf("Introduceti n: ");scanf("%d", &n);

} while(n < 1);

k = factorial(n);

printf("%d! = %d\n", n, k);system("PAUSE");return 0;

}

  Programul va afişa pe ecran, după compilare şi execuŃie:

Introduceti n: 12 12! = 479001600

  DiscuŃie: 

 – Programul verifică valoarea introdusă deoarece o valoare eronată poate conduce la executarea la nesfârşit afuncŃiei factorial(). FuncŃia factorial() se auto-apelează până când se ajunge la factorial de 1.

=============================

P8.4 ScrieŃi un program care citeşte două numere naturale a şi b şi calculează şi afişează cel mai mare divizor comun, c.m.m.d.c., al celor două numere. Cel mai mare divizor comun se va calcula recursiv astfel:

Page 44: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 44/75

 

 

43

<−

>−

=

=

abbba

ababa

baa

ba

dacă),(c.m.m.d.c.

dacă),(c.m.m.d.c.

dacă

),(c.m.m.d.c.  

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

int cmmdc(int a, int b) {if(a == b)

return a;if(a > b)

a = cmmdc(a - b, b);if(a < b)

a = cmmdc(a, b - a);return a;

}

int main() {int i, j, k, a, b;

scanf("%d", &a);scanf("%d", &b);k = cmmdc(a, b);printf("%d", k);printf("\n");

system("PAUSE");return 0;

}

  DiscuŃie: 

  – Se remarcă faptul că funcŃia cmmdc() implementează exact definiŃia matematică formulată în enunŃ.Programul principal nu face decât să citească cele două numere, să apeleze funcŃia cmmdc() şi să afişeze rezultatul.

=============================

P8.5 ScrieŃi un program care citeşte un număr şi stabileşte şi afişează dacă numărul este prim sau nu. Se va scrieşi utiliza o funcŃie care verifică dacă un număr este prim.

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

int divizibil(int n , int i) {if(n % i == 0)

return 0;else

return 1;}

int main() {int n, i;

printf("Introduceti un numar natural: ");scanf("%d", &n);i = 2;

while(i < n) {if(divizibil(n, i) == 1)

i++;else {

i = n+1;printf("Nu este prim\n");}

}if(i == n)

printf("Este prim\n");

system("PAUSE");return 0;

}

Page 45: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 45/75

 

 

44

  Programul va afişa pe ecran, după compilare şi execuŃie:

Introduceti un numar natural: 397 Este prim

  DiscuŃie: 

 – Pentru a verifica dacă un număr, n, este prim se parcurge intervalul (1, n) şi pentru fiecare număr din intervalse verifică dacă acesta este divizor al lui n. Atunci când am găsit un divizor înseamnă că numărul nu este prim şi ieşimdin ciclul while (i devine n + 1). FuncŃia divizibil verifică dacă contorul i care parcurge intervalul divide pe n.Daca îl divide returnează 0 iar dacă nu îl divide returnează 1.

=============================

P8.6 ScrieŃi un program care citeşte două numere naturale n şi  p şi calculează cu ajutorul unei funcŃii recursivevaloarea expresiei n

 p. Valoarea expresie va fi afişată. FuncŃia n p se va defini astfel:

>⋅

==

− 1dacă

1dacă1  pnn

 pnn

 p

 p  

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

int putere(int n, int p) {if(p == 1)

return n;else {

n = n * putere(n, p - 1);return n;

}}

int main() {int i, j, k, n, p;

printf("Introduceti 2 numere naturale: ");scanf("%d", &n);scanf("%d", &p);k = putere(n, p);printf("%d\n", k);

system("PAUSE");

return 0;}

  Programul va afişa pe ecran, după compilare şi execuŃie:

Introduceti 2 numere naturale: 2 16 65536

  DiscuŃie: 

  – FuncŃiaputere implementează direct definiŃia propusă. Ea se poate scrie mai compact astfel:

int putere(int n, int p) {if(p != 1)

n = n * putere(n, p - 1);return n;

}

=============================

P8.7 ScrieŃi un program care calculează media aritmetică a elementelor unui vector cu ajutorul unei funcŃii.

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

float medie(int x, float s , int z, int n) {s = s + z;if(x == n)

s = s / n;return s;

}

Page 46: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 46/75

 

 

45

int main() {int i, n, v[10];float s, k;

printf("n = ");scanf("%d", &n);for(i = 1; i <= n; i++) {

printf("v[%d] = ", i);scanf("%d", &v[i]);

}s = 0;for(i = 1; i <= n; i++) {

k = medie(i, s, v[i], n);s = k;

}printf("Media este %f\n", s);

system("PAUSE");return 0;

}

  Programul va afişa pe ecran, după compilare şi execuŃie:

n = 4 v[1] = 1 v[2] = 2 v[3] = 3 v[4] = 4 Media este 2.500000

  DiscuŃie: 

 – La parcurgerea vectorului, funcŃiei  medie()  i se transmit poziŃia curentă (i), suma elementelor anterioare(s), elementul curent (v[i]) şi lungimea vectorului (n). FuncŃia medie() însumează elementele vectorului(s = s + z) până în momentul în care a însumat şi ultimul element. Atunci va împarŃi această sumă la numărul deelemente.

=============================

P8.8 ScrieŃi un program care verifică transferul unei structuri, ca parametru, către o funcŃie.

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

struct strp2 {

int i;double d;} var1;

void f(struct strp2 temp);

int main() {

var1.i = 99;var1.d = 98.6;f(var1);

system("PAUSE");return 0;

}

void f(struct strp2 temp) {

printf("Diferenta dintre cele 2 elemente ");printf("ale structurii este: %lf\n", temp.d - temp.i);

}

  Programul va afişa pe ecran, după compilare şi execuŃie:

Diferenta dintre cele 2 elemente ale structurii este: -0.400000

  DiscuŃie: 

 – Pentru a face verificarea cerută s-a definit o structură cu marca strp2 care are două câmpuri: i de tipîntreg şi d de tip fracŃionar cu precizie dublă. În programul principal se atribuie valori celor două câmpuri ale structuriişi apoi se apelează funcŃia f. Această funcŃie calculează şi afişează diferenŃa dintre cele două câmpuri.

=============================

Page 47: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 47/75

 

 

46

P8.9 ScrieŃi un program care determină şi afişează lungimea unui şir de maxim 200 de caractere cu ajutorul uneifuncŃii.

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

int lungime(char sir[]) {int i;

for(i = 0; sir[i] != '\0'; i++);return i;

}

int main() {char sir[201];

printf("Introduceti sirul dorit:\n");gets(sir);printf("Lungimea sirului este de %d caractere\n",

lungime(sir));

system("PAUSE");return 0;

}

  Programul va afişa pe ecran, după compilare şi execuŃie:

Introduceti sirul dorit: Acesta este sirul a carui lungime o dorim.Lungimea sirului este de 42 caractere

  DiscuŃie: 

 – Citirea şirului de caractere se realizează apelând funcŃia gets(). Aşa cum am mai precizat în Capitolul 6,folosirea acestei funcŃii este nerecomandabilă. Pentru citirea şirului de caractere recomandăm utilizarea instrucŃiunilor:

fgets(sir, 201, stdin);if(sir[strlen(sir)-1] == '\n') sir[strlen(sir)-1] = '\0';

Cea de a doua instrucŃiune elimină caracterul „newline” din şirul citit.  – FuncŃia lungime() primeşte ca parametru un vector de caractere. Lungimea şirului de caractere este

determinat prin oprirea ciclului for la întâlnirea caracterului '\0'. Se remarcă utilizarea instrucŃiunii vide pentruciclul for. FuncŃia lungime() funcŃionează similar cu funcŃia standard strlen().

=============================

P8.10 ScrieŃi un program care citeşte de la tastatură o matrice pătrată de dimensiune maximă 10 × 10 elemente

reale împreună cu dimensiunea sa efectivă şi determină şi afişează suma elementelor de pe diagonala  principală şi de pe diagonala secundară. Se vor scrie şi utiliza funcŃii separate pentru: citirea matricei,scrierea matricei, calculul sumei de pe diagonala principală şi calculul sumei de pe diagonala secundară. Precizare: este vorba de reluarea problemei P6.6 dar cu utilizarea unor funcŃii.

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

void citeste(float mat[][10], int dim) {int i, j;

for(i = 0; i < dim; i++)for(j = 0; j < dim; j++) {

printf("Introduceti mat[%d][%d]: ", i, j);scanf("%f", &mat[i][j]);

}}

float suma1(float mat[][10], int dim) {int i, j;float sum = 0;

for(i = 0; i < dim; i++)sum += mat[i][i];

return sum;}

float suma2(float mat[][10], int dim) {int i, j;float sum = 0;for(i = 0; i < dim; i++)

sum += mat[i][dim-i-1];return sum;

}

Page 48: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 48/75

 

 

47

void tip_mat(float mat[][10], int dim) {int i, j;

printf("\nMatricea introdusa este:\n\n");for(i = 0; i < dim; i++) {

for(j = 0; j < dim; j++) {printf("%1.3f\t",mat[i][j]);

}printf("\n");

}}

int main() {float matrice[10][10];int dim;

do {printf("Introduceti dimensiunea matricei patrate: ");scanf("%d", &dim);

} while(dim < 1 || dim > 10);citeste(matrice, dim);print(matrice, dim);printf("\nSuma elementelor de pe diagonala principala");printf(" este %1.3f\n", suma1(matrice, dim));printf("\nSuma elementelor de pe diagonala secundara");printf(" este %1.3f\n", suma2(matrice, dim));

system("PAUSE");return 0;

}

  Programul va afişa pe ecran, după compilare şi execuŃie:

Introduceti dimensiunea matricei patrate: 4 Introduceti mat[0][0]: 1 Introduceti mat[0][1]: 2 Introduceti mat[0][2]: 3 Introduceti mat[0][3]: 4 Introduceti mat[1][0]: 5 Introduceti mat[1][1]: 6 Introduceti mat[1][2]: 7 

Introduceti mat[1][3]: 8 

Introduceti mat[2][0]: 9 Introduceti mat[2][1]: 10 Introduceti mat[2][2]: 11 Introduceti mat[2][3]: 12 Introduceti mat[3][0]: 13 Introduceti mat[3][1]: 14 Introduceti mat[3][2]: 15 Introduceti mat[3][3]: 16 

Matricea introdusa este:

1.000 2.000 3.000 4.000

5.000 6.000 7.000 8.0009.000 10.000 11.000 12.00013.000 14.000 15.000 16.000

Suma elementelor de pe diagonala principala este 34.000

Suma elementelor de pe diagonala secundara este 34.000

  DiscuŃie: 

  – FuncŃia citeste() realizează citirea efectivă a elementele matricei folosind proprietatea particulară atablourilor de a putea fi modificate într-o funcŃie astfel încât modificările să fie permanente. FuncŃia tip_mat() afişează matricea citită. FuncŃiile suma1() şi suma2() calculează suma elementelor de pe diagonala principală şi,respectiv, de pe diagonala secundară. Programul principal citeşte dimensiunea efectivă a matricei şi apelează funcŃiiledefinite anterior.

=============================

Page 49: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 49/75

 

 

48

8.2.  Probleme propuse

1. ScrieŃi un program C care citeşte de la tastatură un vector de maximum 10 numere întregi împreună cudimensiunea sa efectivă şi separă acest vector în doi vectori: primul vector va fi format din numerele pare dinvectorul iniŃial iar cel de al doilea va fi format din numerele impare din vectorul iniŃial. Citirea vectorului se vaface cu ajutorul unei funcŃii cu prototipul:

void cit_vect(int v[10], int dim);

2. ReluaŃi programul anterior, dar pentru formarea vectorilor scrieŃi şi utilizaŃi două funcŃii având prototipurile:

int pare(int v[10], int par_v[10]);int impare(int v[10], int impar_v[10]);

FuncŃiile vor returna numărul valorilor pare şi respectiv, numărul valorilor impare.

3. ScrieŃi un program C care calculează suma complexă a elementelor dintr-un tablou unidimensional de numerecomplexe. Precizări:

a. Tabloul de numere complexe va fi declarat utilizând următoarele definiŃii:

typedef struct {

float re;

float im;

} complex;complex vector[10];

 b. Elementele tabloului se citesc de la tastatură, element cu element, iar pentru fiecare element, partea reală şi partea imaginară.

c. ScrieŃi câte o funcŃie care calculează partea reală şi, respectiv, partea imaginară a sumei a două numerecomplexe. Prototipurile acestor funcŃii sunt:

float suma_re(complex a, complex b);

float suma_im(complex a, complex b);

Suma globală cerută se va calcula folosind funcŃiile definite anterior.

4. ReluaŃi programul anterior dar pentru calculul sumei a două numere complexe scrieŃi şi utilizaŃi o funcŃie având prototipul:

complex suma(complex a, complex b);

5. ScrieŃi un program C care citeşte de la tastatură o matrice de numere reale de dimensiuni maxime 100 × 100împreună cu dimensiunile sale efective şi afişează elementele maxime de pe fiecare linie şi apoi de pe fiecarecoloană. Precizări:

a. Pentru determinarea maximului de pe linii / coloane se va scrie şi utiliza o funcŃie cu prototipul:

float max_vec(int dim, float vec[100]);

 b. Se vor forma, pe rând, vectori din fiecare linie şi apoi din fiecare coloană.

6. ScrieŃi un program care citeşte un număr natural şi calculează şi afişează secvenŃa Halberstam a acestui număr. Precizări:

a. SecvenŃa Halberstam a unui număr se calculează astfel: dacă numărul este par el se împarte la 2; dacă număruleste impar se adună 3 şi se adună 1; se reiau operaŃiile până când valoarea ajunge egală cu 1.

 b. Calculul numărului următor al secvenŃei Halberstam se va face cu ajutorul unei funcŃii.

7. ScrieŃi o funcŃie care afişează o întrebare şi citeşte răspunsul utilizatorului care poate fi doar ‚d’, pentru „da”, sau‚n’, pentru „nu”; citirea se repetă până când răspunsul este ‚d’ sau ‚n’. ScrieŃi apoi un program care verificăfuncŃionarea corectă a funcŃiei. Precizare: Prototipul funcŃiei este: 

int ok(char s[]);

8. ScrieŃi o funcŃie care calculează suma de plată pentru o activitate primind numărul de ore lucrate şi salariul orar.Dacă numărul de ore lucrate este mai mic decât sau egal cu 40 se plăteşte salariul orar. Pentru orele cuprinse între40 şi 60 salariul orar creşte cu 50 %. Pentru orele care depăşesc 60 se plăteşte dublu. ScrieŃi şi programul principalcare verifică funcŃionarea funcŃiei.

Page 50: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 50/75

 

 

49

9. ScrieŃi o funcŃie care caută toate spaŃiile dintr-un şir de caractere şi le înlocuieşte cu semnul ‚-’ returnând numărulde spaŃii înlocuit. Prototipul funcŃiei este:

int inlocuieste(char sir[]);

ScrieŃi şi programul principal care verifică funcŃionarea funcŃiei.

10. ScrieŃi o funcŃie care determină şi returnează momentul sosirii primului tren într-o staŃie de cale ferată. FuncŃia primeşte ca argumente momentul plecării din staŃie şi o structură care conŃine orele de plecare şi de sosire. Precizări:a. Structura pentru memorarea programului de circulaŃie a unui tren va fi definită astfel:

typedef struct moment {int ora;int minut;

} Moment;typedef struct program {

Moment plecare;Moment sosire;

} Program_tren;

  b. Programul de circulaŃie între două staŃii este alcătuit dintr-un tablou format din structuri de tipProgram_tren.

c. FuncŃia va căuta primul tren care pleacă după ora indicată şi va afişa orele de plecare şi sosire.

ScrieŃi şi programul principal care verifică funcŃionarea funcŃiei.

11. ScrieŃi o funcŃie care afişează şirul de caractere primit ca parametru şi apoi îl subliniază scriind numărulcorespunzător de caractere ‚_’ pe rândul următor. Pentru determinarea lungimii şirului de caractere se va folosifuncŃia standard strlen(), „ string length”, care are următorul prototip:

int strlen(char s[]);

ScrieŃi şi programul principal care verifică funcŃionarea funcŃiei.

Page 51: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 51/75

 

 

50

9.  Pointeri

9.1.  Probleme rezolvate

P9.1 ScrieŃi un program care determină suma elementelor de pe diagonala unei matrice pătrate de dimensiunemaximă 10 × 10 formată din numere reale. Pentru citirea matricei se va scrie şi utiliza o funcŃie care citeştematricea împreună cu dimensiunile sale efective.

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

#define DIMMAX 10

void citmat(float mat[][DIMMAX], int *dim);

int main(void) {int dimef, i;float mat[DIMMAX][DIMMAX], sumdiag;

citmat(mat, &dimef);sumdiag = 0.0;for(i = 0; i < dimef; i++)

sumdiag += mat[i][i];printf("Suma elementelor de pe diagonala este: %f\n",

sumdiag);system("PAUSE");

return 0;}

void citmat(float mat[][DIMMAX], int *dim) {int i, j;do {

printf("Introduceti dimensiunea efectiva (<=10): ");scanf("%i", dim);

} while (*dim > 10 || *dim < 0);

for(i = 0; i < *dim; i++)for(j = 0; j < *dim; j++) {

printf("mat[%d][%d] = ", i, j);scanf("%f", &mat[i][j]);

}}

  Programul va afişa pe ecran, după compilare şi execuŃie:

Introduceti dimensiunea efectiva (<=10) :20 Introduceti dimensiunea efectiva (<=10) :2 mat[0][0] = 1 mat[0][1] = 2 mat[1][0] = 3 mat[1][1] = 4 Suma elementelor de pe diagonala este: 5.000000

  DiscuŃie: 

  – Acest program pune în evidenŃă utilizarea pointerilor la transferul unei valori dintr-o funcŃie. Al doilea parametru al funcŃiei citmat() este un pointer prin intermediul căruia se transferă dimensiunea efectivă a metricei.

=============================

P9.2 ScrieŃi un program care determină suma elementelor de pe diagonala unei matrice pătrate formată dinnumere reale. Pentru citirea matricei se va scrie şi utiliza o funcŃie care citeşte matricea împreună cudimensiunile sale efective.  Precizare: deşi problema pare identică cu problema 9.1 nu este aşa; de aceastădată programul trebuie să poată prelucra matrice oricât de mari.

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

float **citmat(int *dim);

int main(void) {int dimef, i;float **mat, sumdiag;

Page 52: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 52/75

 

 

51

if(!(mat = citmat(&dimef))) {

printf("Matricea nu se poate citi!\n");

system("PAUSE");

return 1;

}

sumdiag = 0.0;

for(i = 0; i < dimef; i++)

sumdiag += mat[i][i];

printf("Suma elementelor de pe diagonala este: %f\n",

sumdiag);system("PAUSE");

return 0;

}

float **citmat(int *dim) {

int i, j;

float **mat;

printf("Introduceti dimensiunea efectiva: ");

scanf("%i", dim);

/* Se aloca memorie pentru tabloul de pointeri care

constituie matricea */

if(!(mat = (float **)malloc(*dim * sizeof(float *)))) {

printf("Matricea este prea mare!\n");return NULL;

}

/* Se aloca memorie pentru fiecare linie a matricei */

for(i = 0; i < *dim; i++)

if(!(mat[i] = (float *)malloc(*dim * sizeof(float)))) {

printf("Matricea este prea mare!\n");

return NULL;

}

/* Se citesc elementele matricei */

for(i = 0; i < *dim; i++)

for(j = 0; j < *dim; j++) {

printf("mat[%d][%d] = ", i, j);

scanf("%f", &mat[i][j]);}

return mat;

}

  Programul va afişa pe ecran, după compilare şi execuŃie:

Introduceti dimensiunea efectiva: 2 

mat[0][0] = 1 

mat[0][1] = 2 

mat[1][0] = 3 

mat[1][1] = 4 

Suma elementelor de pe diagonala este: 5.000000

sauIntroduceti dimensiunea efectiva: 123456 

Matricea este prea mare!

Matricea nu se poate citi!

  DiscuŃie: 

 – Acest program pune în evidenŃă utilizarea pointerilor pentru alocarea dinamică a unei matrice. Se observă cămatricea este declarată ca fiind de tip loat ** adică de tip „pointer la pointer”. În funcŃia citmat() se alocă maiîntâi un vector de pointeri care reprezintă matricea propriu-zisă şi apoi se alocă câte un pointer către fiecare rând dinmatrice. Se observă că procedând astfel elementele matricei se pot adresa exact ca atunci când matricea a fost alocatăstatic.

=============================

Page 53: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 53/75

 

 

52

P9.3 ScrieŃi un program care afişează pe ecran conŃinutul şi adresele a două variabile de tip întreg, apoi atribuieadresa uneia dintre ele unui pointer şi reia afişarea utilizând pointerul.

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

int main() {int j, k;/* declarare variabila de tip pointer */int *ptr;j = 1;k = 2;

/* ptr contine adresa la care este stocata variabila k */ptr = &k;

printf("\nj are valoarea %d si este stocat la adresa %p ", j, &j);printf("\nk are valoarea %d si este stocat la adresa %p", k, &k);printf("\nptr are valoarea %p si este stocat la adresa %p”, ptr, &ptr);printf("\nValoarea int catre care arata pointerul este: %d", *ptr);printf("\n");system("PAUSE");return 0;

}

Programul va afişa pe ecran, după compilare şi execuŃie:

j are valoarea 1 si este stocat la adresa 0022FF6Ck are valoarea 2 si este stocat la adresa 0022FF68ptr are valoarea 0022FF68 si este stocat la adresa 0022FF64Valoarea int catre care arata pointerul este: 2

  DiscuŃie: 

  – Programul pune în evidenŃă modul de utilizare a pointerilor. Se observă faptul că înainte de a fi utilizat, pointerului trebuie să i se atribuie o adresă validă. Dacă se omite instrucŃiunea:

ptr = &k;

afişarea va arăta astfel:

j are valoarea 1 si este stocat la adresa 0022FF6C

k are valoarea 2 si este stocat la adresa 0022FF68ptr are valoarea 004010C0 si este stocat la adresa 0022FF64Valoarea int catre care arata pointerul este: 807409035

 – Precizăm că adresele afişate pot diferi de cele de mai sus în funcŃie de spaŃiul de memorie alocat programuluide către sistemul de operare precum şi faptul că în varianta eronată este posibil ca programul să nu funcŃioneze de loc.

=============================

P9.4 ScrieŃi un program care construieşte un vector şi îl afişează atât în mod obişnuit, cât şi utilizând pointeri.Programul va afişa apoi adresele elementelor din vector şi valorile lor. Se va încerca şi depăşireadimensiunilor tabloului.

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

int main() {int tablou[] = {1, 23, 17, 4, -5, 100};int *ptr;int i;ptr = &tablou[0]; /* sau ptr = tablou; */printf("\n");

/* Afisarea vectorului */for(i = 0; i < 6; i++) {

printf("tablou[%d] = %d", i, tablou[i]);printf("\tptr + %d = %d\n", i, *(ptr+i));

}

printf("\n");

Page 54: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 54/75

 

 

53

/* Afisarea adreselor la care sunt stocate elementelevectorului */

for(i = 0; i < 6; i++)printf("adresa pentru tablou[%d]: %d\n", i, ptr+i);

printf("\n");

/* Afişare cu depasirea spatiului vectorului */for(i = 0; i <= 6; i++) {

printf("ptr + %d = %d\n", i, *(ptr++));}

printf("\n");system("PAUSE");return 0;

}

Programul va afişa pe ecran, după compilare şi execuŃie:

tablou[0] = 1 ptr + 0 = 1tablou[1] = 23 ptr + 1 = 23tablou[2] = 17 ptr + 2 = 17tablou[3] = 4 ptr + 3 = 4tablou[4] = -5 ptr + 4 = -5tablou[5] = 100 ptr + 5 = 100

adresa pentru tablou[0]: 2293576

adresa pentru tablou[1]: 2293580adresa pentru tablou[2]: 2293584adresa pentru tablou[3]: 2293588adresa pentru tablou[4]: 2293592adresa pentru tablou[5]: 2293596

ptr + 0 = 1ptr + 1 = 23ptr + 2 = 17ptr + 3 = 4ptr + 4 = -5ptr + 5 = 100ptr + 6 = 2293664

  DiscuŃie: 

 – Prima instrucŃiune atribuie pointerului ptr adresa primului element din vectorul tablou. Aşa cum se aratăşi în comentariu, această instrucŃiune se poate scrie şi:

ptr = tablou;

ObservaŃie: Precizăm că un tablou nu este un vector. Din acest motiv atribuirea:

tablou = ptr;

nu este corectă. – Primul ciclu for afişează valorile memorate în vector utilizând atât direct vectorul cât şi pointerul. – Cel de al doilea ciclu afişează adresele de memorie la care sunt stocate elementele vectorului. Se observă că

elementele vectorului sunt memorate în locaŃii succesive de memorie. – În cel de al treilea ciclu se repetă afişarea, dar se depăşeşte dimensiunea vectorului. Aşa cum se observă din

rezultatul rulării programului, limbajul C nu verifică depăşirea dimensiunii vectorului. În acest mod programul rulează

mult mai repede dar programatorul trebuie să fie foarte atent pentru a nu comite astfel de greşeli.=============================

P9.5 ScrieŃi un program care concatenează două şiruri de caractere (stringuri) strA şi strB, rezultatul fiinddepozitat în stringul strA. Programul caută apoi prima literă 'c' din strA şi o înlocuieşte cu secvenŃa"CCC". În final, se va alipi şi porŃiunea rămasă din strA la stringul final. Prima concatenare se va realizacu ajutorul pointerilor. Pentru copierile şi concatenările ulterioare se vor utiliza funcŃiile standardstrcpy() şi strcat().

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

Page 55: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 55/75

 

 

54

int main() {char strA[80] = "Sir de caractere demonstrativ";char strB[80] = "SIR2";char strC[80] = "CCC";char aux[80];/* Declara pointeri catre tipul caracter */char *pA, *pB, *paux;int i;

/* Afiseaza stringul strA */printf("strA = '%s'\n", strA);

/* Pointerul pA va contine adresa stringului strA */pA = strA;printf("Adresa stringului strA: %p\n", &pA);

/* Pointerul pB va contine adresa stringului strB */pB = strB;printf("strB = '%s'\n", pB);

/* Avanseza pana la sfarsitul lui strB */while(*pB != '\0')

*pB++;

/* Concateneaza strB cu strA */while (*pA != '\0')

*pB++ = *pA++;/* Adauga caracterul NULL care marcheza sfarsitul

stringului */pB = '\0';

/* Afiseaza rezultatul concatenarii */printf("Concatenare stringuri: '%s'\n\n", strB);

/* Inlocuire 'c' cu 'CCC' */printf("Inlocuire 'c' cu 'CCC'\n");printf("======================\n");

/* pB arata din nou catre inceputul stringului strB */pB = strB;/* Cauta primul caracter 'c' */while((*pB != '\0') && (*pB != 'c'))

pB++;

/* Copiaza caracterele de dupa litera 'c' intr-un stringauxiliar. Mai intai verifica faptul ca s-a gasitlitera 'c' */

if(*pB == 'c') {pB++; /* Avanseaza la caracterul de dupa 'c' */paux = aux;(void)strcpy(paux, pB);pB--; /* Aduce inapoi la adresa lui 'c' */

}

/* Copiaza strC in locul unde era litera 'c' */(void)strcpy(pB, strC);printf("Noul strB: '%s'\n", strB);/* Adauga sirul de caractere salvat */(void)strcat(pB, paux);printf("String final: '%s'\n", strB);system("PAUSE");

return 0;}

Programul va afişa pe ecran, după compilare şi execuŃie:

strA = 'Sir de caractere demonstrativ'Adresa stringului strA: 0022FE24strB = 'SIR2'Concatenare stringuri: 'SIR2Sir de caractere demonstrativ'

Inlocuire 'c' cu 'CCC'======================Noul strB: 'SIR2Sir de CCC'String final: 'SIR2Sir de CCCaractere demonstrativ'

Page 56: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 56/75

 

 

55

  DiscuŃie: 

  – Modul în care se realizează concatenarea este similar codului din funcŃia standard strcat(). AceastăsecŃiune se poate rescrie într-un mod mai compact astfel:

/* Avanseza pana la sfarsitul lui strB */while(*pB++ != '\0');/* Aduce inapoi la caracterul NULL */pB--;/* Copiaza strA in strB inclusiv caracterul NULL */while((*pB++ = *pA++) != '\0');

 – Pentru înlocuirea caracterului 'c' mai întâi acesta este localizat. Apoi se salvează restul şirului de caracterecare urmează după acesta şi se compune noul şir de caractere prin două operaŃii succesive de concatenare.

=============================

P9.6 ScrieŃi un program care, prin două funcŃii distincte, verifică egalitatea alfabetică sau numerică aargumentelor, folosind pointeri. Afişarea se va face utilizând funcŃia standard puts() şi citirea se va facecu fgets().

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

void verifica(char *a, char *b,int (*cmp)(const char *, const char *));

int comparanum(const char *a, const char *b);

int main() {char s1[80], s2[80];

puts("Introduceti primul argument:");fgets(s1, 80, stdin);if(s1[strlen(s1)-1] == '\n') s1[strlen(s1)-1] = '\0';puts("Introduceti al doilea argument:");fgets(s2, 80, stdin);if(s2[strlen(s2)-1] == '\n') s2[strlen(s2)-1] = '\0';

/* Parametrii functiei apelate sunt 2 pointeri de tipcaracter */

if(isalpha(*s1)) {puts("Argumente de tip caracter\n");/* Utilizeaza functia standard strcmp */verifica(s1, s2, strcmp);

} else {

puts("Argumente de tip numeric\n");/* Utilizeaza functia comparanum */verifica(s1, s2, comparanum);

}

puts("\n");

system("PAUSE");return 0;

}

void verifica(char *a, char *b,int (*cmp)(const char *, const char *)) {

/* Utilizeaza printf pentru a lasa cursorulpe aceeasi linie */

printf("Verificarea egalitatii: ");

/* (*cmp)(a,b)apeleaza functia de comparare a carei adresase afla in cmp cu argumentele a si b */

if(!(*cmp)(a,b))puts("Argumentele sunt egale");

elseputs("Argumentele nu sunt egale");

}

int comparanum(const char *a, const char *b) {/* atoi(x) converteste stringul catre care arata pointerul x

intr-un numar intreg (atoi = ASCII to int) */if(atoi(a) == atoi(b))

return 0;else

return 1;}

Page 57: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 57/75

 

 

56

  Programul va afişa pe ecran, după compilare şi execuŃie:

Introduceti primul argument:str1

Introduceti al doilea argument:str2

Argumente de tip caracter

Verificarea egalitatii: Argumentele nu sunt egale

  DiscuŃie: 

  – Pentru verificarea tipului de valori citite se foloseşte funcŃia standard isalpha() care returnează„adevărat” dacă şirul de caractere este de tip alfanumeric (cuprinde şi litere) sau „fals” dacă este format doar din cifre.

 – Cel de al treilea argument al funcŃiei verifica() este un pointer către o funcŃie. FuncŃia verifica() apelează funcŃia de verificare a egalităŃii prin intermediul pointerului la funcŃie.

=============================

P9.7 ScrieŃi un program care încarcă valori într-o structură folosind un pointer către aceasta.

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

struct strpoint {int i;char str[80];

} s, *p;/* s este variabila de tip structura si

p un pointer catre o astfel de structura */int main() {

p = &s; /* pointerul arata catreadresa de inceput a structurii */

s.i = 10; /* incarcare obisnuita */p->i = 10; /* incarcare folosind pointerul */strcpy(p->str, "tablou unidimensional de caractere");printf("%d %d %s", s.i, p->i, p->str);printf("\n");

system("PAUSE");return 0;

}

Programul va afişa pe ecran, după compilare şi execuŃie:

10 10 tablou unidimensional de caractere

  DiscuŃie: 

 – Programul pune în evidenŃă utilizarea operatorului ->.

=============================

P9.8 ScrieŃi un program care schimbă între ele două linii ale unei matrice de dimensiuni 3 × 3 elemente reale şi

apoi le schimbă la loc. Se vor defini şi utiliza funcŃii diferite pentru citirea unei matrice, afişarea unei matrice precum şi pentru schimbarea între ele a liniilor.

#include <stdio.h>

#include <stdlib.h>

void citeste(float mat[][3]) {

int i, j;

for(i = 0; i < 3; i++) {

for(j = 0; j < 3; j++) {

printf("Introduceti elem. mat[%d][%d]: ", i, j);

scanf("%f", &mat[i][j]);

}

}

}

Page 58: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 58/75

 

 

57

void afiseaza(float mat[][3]) {

int i, j;

for(i = 0; i < 3; i++) {

for( j = 0; j < 3; j++) {

printf("%f\t", mat[i][j]);

}

printf("\n");

}

}

void schimba1(float mat[][3], int i, int j) {

int k;

float temp;

for(k = 0; k < 3; k++) {

temp = *(mat[i] + k);

*(mat[i] + k) = *(mat[j] + k);

*(mat[j] + k) = temp;

}

}

void schimba2(float mat[][3], int i, int j) {int k;float temp;

for(k = 0; k < 3; k++) {temp = *(*(mat + i) + k);*(*(mat + i) + k) = *(*(mat + j) + k);*(*(mat + j) + k) = temp;

}}

int main(void) {int i, j;float m[3][3];

citeste(m);printf("***********************************************\n");printf("Inainte de inversarea liniilor\n");afiseaza(m);printf("***********************************************\n");

printf("Introduceti indicele primei linii (<3): ");scanf("%d", &i);while(i < 0 || i >= 3) {

printf("Date incorecte\n");printf("Introduceti indicele primei linii (<3): ");scanf("%d", &i);

}

printf("Introduceti indicele celei de a doua linii (<3): ");scanf("%d", &j);while(j < 0 || j >= 3) {

printf("Date incorecte\n");printf("Introduceti indicele celei de a doua linii (<3): ");

scanf("%d", &j);

}

printf("***********************************************\n");printf("Liniile inversate\n");schimba1(m, i, j);afiseaza(m);printf("***********************************************\n");printf("Liniile inversate din nou\n");schimba2(m, i, j);afiseaza(m);

system("PAUSE");return 0;

}

Page 59: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 59/75

 

 

58

Programul va afişa pe ecran, după compilare şi execuŃie:

Introduceti elem. mat[0][0]: 1 Introduceti elem. mat[0][1]: 2 Introduceti elem. mat[0][2]: 3 Introduceti elem. mat[1][0]: 4 Introduceti elem. mat[1][1]: 5 Introduceti elem. mat[1][2]: 6 Introduceti elem. mat[2][0]: 7 Introduceti elem. mat[2][1]: 8 Introduceti elem. mat[2][2]: 9 ***********************************************

Inainte de inversarea liniilor1.000000 2.000000 3.0000004.000000 5.000000 6.0000007.000000 8.000000 9.000000***********************************************Introduceti indicele primei linii (<3): 0 Introduceti indicele celei de a doua linii (<3): 1 ***********************************************Liniile inversate4.000000 5.000000 6.0000001.000000 2.000000 3.0000007.000000 8.000000 9.000000***********************************************Liniile inversate din nou1.000000 2.000000 3.0000004.000000 5.000000 6.0000007.000000 8.000000 9.000000

  DiscuŃie: 

 – Schimbarea între ele a liniilor matricei se face utilizând două funcŃii diferite. FuncŃia schimba1() pune înevidenŃă faptul că în limbajul C o matrice bidimensională este o matrice unidimensională formată din matriceunidimensionale. FuncŃia schimba2() utilizează pointerii pentru accesul la valorile din matrice.

=============================

P9.9 ScrieŃi un program care caută un subşir într-un şir de caractere. Programul va afişa poziŃia subşirului în şir sau un mesaj de eroare dacă subşirul nu a fost găsit.

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

int cauta(char *sir1, char *sir2) {char *p, *q, *temp;for(p = sir1; *p != '\0'; p++) {

for(q = sir2, temp = p;*q != '\0' && *temp != '\0' && *temp == *q;q++, temp++);

if(*q == '\0')return p - sir1;

}return -1;

}int main(void) {

char sir1[200], sir2[200];int poz;

printf("Introduceti primul sir\n");fgets(sir1, 200, stdin);if(sir1[strlen(sir1)-1] == '\n')

sir1[strlen(sir1)-1] = '\0';

printf("Introduceti sirul al doilea\n");fgets(sir2, 200, stdin);if(sir2[strlen(sir2)-1] == '\n')

sir2[strlen(sir2)-1] = '\0';

poz = cauta(sir1, sir2);if(poz != -1)

printf("Sirul '%s' se gaseste in '%s' la pozitia %d\n",sir2, sir1, poz);

elseprintf("Sirul '%s' nu se gaseste in '%s'\n",

sir2, sir1);

system("PAUSE");return 0;

}

Page 60: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 60/75

 

 

59

  Programul va afişa pe ecran, după compilare şi execuŃie:

Introduceti primul sirUnu doi trei

Introduceti sirul al doileadoi

Sirul 'doi' se gaseste in 'Unu doi trei' la pozitia 4

sau

Introduceti primul sir

Unu doi treiIntroduceti sirul al doilea

 patru

Sirul 'patru' nu se gaseste in 'Unu doi trei'

  DiscuŃie: 

  – Se remarcă modul în care se face căutarea cu ajutorul a două cicluri cu contor. Ciclul cu contor exterior avansează poziŃia de căutare în şirul în care se caută. Cel de al doilea ciclu realizează căutarea propriu-zisă. Mai întâi, lainiŃializarea ciclului, se aduc cei doi pointeri, la începutul celor două şiruri de caractere. Căutarea continuă cât timp maiexistă caractere în cele două şiruri şi caracterele din cele două şiruri sunt identice. Dacă la ieşirea din ciclul intern s-auepuizat caracterele din şirul căutat înseamnă că şirul a fost găsit. PoziŃia se determină prin diferenŃa dintre pointerul careindică începutul şirului în care se caută şi pointerul care indică începutul subşirului găsit.

=============================

P9.10 ScrieŃi un program care citeşte dimensiunea exactă a unui vector de numere întregi, construieşte, citeşte şiafişează acest vector.

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

int main(void) {int dim, i;int *vector;

do {printf("Introduceti dimensiunea vectorului: ");scanf("%d", &dim);

} while(dim <= 0);

if(!(vector = (int *)malloc(dim * sizeof(int)))) {printf("Dimensiunea %d este prea mare!\n", dim);

printf("Vectorul nu are loc in memorie!\n");system("PAUSE");return 1;

}

printf("Citire\n");for(i = 0; i < dim; i++) {

printf("vector[%d] = ", i);scanf("%d", vector + i);

}

printf("Scriere\n");for(i = 0; i < dim; i++)

printf("vector[%d] = %d\n", i, *(vector + i));

free(vector);

system("PAUSE");return 0;

}

  Programul va afişa pe ecran, după compilare şi execuŃie:

Introduceti dimensiunea vectorului: 3 Citirevector[0] = 1 vector[1] = 2 vector[2] = 3 Scrierevector[0] = 1vector[1] = 2vector[2] = 3

Page 61: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 61/75

 

 

60

sau

Introduceti dimensiunea vectorului: 1567311664 

Dimensiunea 1567311664 este prea mare!

Vectorul nu are loc in memorie!

  DiscuŃie: 

  – Programul alocă spaŃiul de memorie necesar stocării vectorului. Se verifică faptul că spaŃiul de memorie a  putut fi alocat. Dacă alocarea eşuează, execuŃia programului se întrerupe. După citire şi scriere spaŃiul de memorie

alocat este eliberat.=============================

P9.11 ScrieŃi un program care citeşte, sortează şi afişează un vector de şiruri de caractere implementând o

 procedură de tip bubble-sort şi comparând pointerii alăturaŃi.

#include <stdio.h>

#include <stdlib.h>

void sort(char *p[], int nr) {

char *temp;

int i, j, k;

for(k = 0; k < nr - 1; k++) {

for(i = 0; i < nr - 1; i++) {

j = i + 1;

if(strcmp(p[i], p[j]) > 0) {

temp = p[i];

p[i] = p[j];

p[j] = temp;

}

}

}

}

int main() {char *p[] = {"Gabi", "Bebe", "Alina", "Claudia", "Catalin",

"Andrei"};int j;

printf("Sirurile nesortate sunt:\n");for(j = 0; j < 6; j++)

printf("%s\n", p[j]);

sort(p, 6);

printf("\nSirurile sortate sunt:\n");for(j = 0; j < 6; j++)

printf("%s\n", p[j]);

system("PAUSE");return 0;

}

  Programul va afişa pe ecran, după compilare şi execuŃie:

Sirurile nesortate sunt:Gabi

BebeAlinaClaudiaCatalinAndreiAna

Sirurile sortate sunt:AlinaAnaAndreiBebeCatalinClaudiaGabi

Page 62: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 62/75

 

 

61

  DiscuŃie: 

 – Prin utilizarea pointerilor către şirurile de caractere sunt modificate adresele către care indică pointerii şi nusunt mutate şirurile de caractere propriu-zise. Efectul rămâne cel dorit, dar este obŃinut cu un efort de calcul mult maimic.

=============================

9.2.  Probleme propuse

1.ScrieŃi un program care determină de câte ori un subşir de caractere se regăseşte într-un alt şir de caractere. IndicaŃie: se va generaliza soluŃia de la problema 9.9.

2. ScrieŃi un program care citeşte trei variabile a, b şi c şi apoi le roteşte între ele astfel: a -> b, b -> c şic -> a.

3. ScrieŃi un program care citeşte şi sortează în ordinea ascendentă dată de cuvant_cheie un vector format dinînregistrări definite astfel:

typedef struct {char cuvant_cheie[10];int alte_date;

} Inregistrare;

Pentru ordonare / sortare se va utiliza funcŃia qsort() disponibilă în bibliotecile standard C şi declarată în

stdlib.h. IndicaŃie: funcŃia qsort() este declarată astfel:

void qsort(void *base, int nmemb, int size,

int(*compar)(const void *elem1, const void *elem2));

unde:- base este adresa de început a vectorului;- nmemb reprezintă numărul de elemente din vector;- size este dimensiunea în octeŃi a unui element din vector şi- compar este un pointer către o funcŃie definită de utilizator care realizează comparaŃia între douăelemente ale vectorului, elem1 şi elem2, returnând o valoare întreagă mai mică decât, egală cu, sau maimare decât zero după cum elem1 este mai mic, egal cu, sau mai mare decât elem2.

4. O metodă de sortare presupune adăugarea valorilor dintr-un vector una câte una într-un vector nou. Prima valoareeste adăugată la începutul vectorului. Valorile următoare sunt adăugate în poziŃia corespunzătoare ordinii sale prindeplasarea datelor adăugate deja pentru a face loc valorii care se adaugă. Această metodă poartă numele de„sortare prin inserare” („insertion sort ”). ScrieŃi o funcŃie denumită insort() care realizează astfel sortarea şise comportă în acelaşi mod precum funcŃia qsort() descrisă în problema anterioară. FuncŃia insort() vaavea prototipul:

void insort(void *base, int nmemb, int size,int(*compar)(const void *elem1, const void *elem2));

Prototipul este similar cu al funcŃiei qsort() realizând sortarea unui vector cu adresa de început indicată debase, format din nmemb elemente de tip arbitrar şi de dimensiune size şi care sunt comparate de funcŃiacompar(). ScrieŃi şi programul principal care testează funcŃia.

5. ScrieŃi o funcŃie care primeşte ca argument un şir de caractere şi returnează un pointer către primul caracter care nueste spaŃiu din acest şir de caractere.Precizări:a.  Se vor considera spaŃii caracterele ' ' („ space”) şi '\t' („tab”). b.  Prototipul funcŃiei este:

char *primul_caracter(char *sir);

c.  ScrieŃi şi programul principal care testează funcŃia.

6. ScrieŃi un program care citeşte un text, îl desparte în cuvinte şi afişează cuvintele textului ordonate alfabetic.

7. ScrieŃi un program care citeşte un text şi afişează doar ultimele 5 linii ale textului.

Page 63: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 63/75

 

 

62

8. ScrieŃi un program care parcurge lista definită mai jos cu ajutorul pointerului p_lista şi afişează numărul şinumele.

define MAX 4

struct lista {int numar;char nume[10];

} data[MAX] = {1, "Ion",2, "Vasile",3, "Gheorghe",4, "Maria"

};

struct lista *p_lista;

9. ScrieŃi un program care citeşte o expresie matematică simplă formată din doi operanzi numerici şi un operator (+,-, *, /) şi determină şi afişează valoarea expresiei. Un exemplu de rulare a programului va arăta astfel:

Introduceti expresia:

1.25 * 4

= 5

10. ScrieŃi un program care citeşte de la tastatură o matrice de numere reale de dimensiuni maxime 10 x 10, împreunăcu dimensiunile sale efective şi determină câtul împărŃirii modulului sumei numerelor negative din matrice lasuma numerelor pozitive din matrice. Programul va semnala cazul special al împărŃirii prin zero. Pentru calcululsumelor se va folosi o funcŃie cu următorul prototip:

void suma(float A[][10], int n, int m, float *pos, float *neg);

unde:A[][10] este matricea de lucru;n, m sunt dimensiunile efective ale matricei;pos suma numerelor pozitive;neg suma numerelor negative.

11. ReluaŃi problema anterioară şi scrieŃi un program care citeşte de la tastatură o matrice de numere reale de oricedimensiuni, împreună cu dimensiunile sale efective şi determină câtul împărŃirii modulului sumei numerelor negative din matrice la suma numerelor pozitive din matrice. Programul va semnala cazul special al împărŃirii prinzero. Pentru calculul sumelor se va folosi o funcŃie cu următorul prototip:void suma(float **A, int n, int m, float *pos, float *neg);

unde:A  este matricea de lucru;n, m sunt dimensiunile efective ale matricei;pos suma numerelor pozitive;neg suma numerelor negative.

12. ScrieŃi un program care citeşte de la tastatură o matrice de numere reale de dimensiuni maxime 10 x 10, împreunăcu dimensiunile sale efective şi determină câtul împărŃirii modulului produsului elementelor de pe diagonala principală a matricei la produsul elementelor de pe diagonala secundară a matricei. Programul va semnala cazulspecial al împărŃirii prin zero. Pentru calculul sumelor se va folosi o funcŃie cu următorul prototip:

void prod_diag(float A[][10], int n, float *dprin, float *dsec);

unde:

A[][10] este matricea de lucru;n este dimensiunea efectivă a matricei;dprin produsul elementelor de pe diagonala principală;dsec   produsul elementelor de pe diagonala secundară.

13. ScrieŃi o funcŃie care primeşte ca parametru un număr întreg şi returnează un pointer către numele luniicalendaristice corespunzătoare. Dacă numărul nu reprezintă o lună, este mai mic decât 1 sau mai mare decât 12,funcŃia va returna un pointer către şirul de caractere „nici o luna”. Precizări:a. Denumirile lunilor vor fi memorate într-o variabilă locală statică a funcŃiei definită astfel:

static char *luna[] = {"nici o luna","ianuarie",

Page 64: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 64/75

 

 

63

"februarie","martie","aprilie","mai","iunie","iulie","august","septembrie","octombrie","noiembrie","decembrie"

};

 b. Prototipul funcŃiei este:

char *denumire_luna(int numar);

ScrieŃi şi programul principal care verifică funcŃionarea funcŃiei.

14. Folosind funcŃia din exerciŃiul anterior scrieŃi o altă funcŃie care primind un şir de caractere de forma"zzllaaaa" returnează data scrisă sub forma "zi luna an". De exemplu: funcŃia primeşte "15042004" şi returnează "15 aprilie 2004". FuncŃia va verifica şi corectitudinea datei rejectând date cum ar fi"2902001" (anul 2001 nu a fost bisect) sau "31042005" (aprilie nu are 31 de zile). ScrieŃi şi programul principal care verifică funcŃionarea funcŃiei.

15. ScrieŃi o funcŃie care citeşte cel mult n numere reale de tip float şi le plasează în memorie începând de laadresa indicată de pfloat. FuncŃia va returna numărul valorilor citite. Prototipul funcŃiei este:

int citeste_n_nr(int n, float *pfloat);

ScrieŃi şi programul principal care verifică funcŃionarea funcŃiei.

Page 65: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 65/75

 

 

64

10.  Probleme recapitulative

10.1.  Probleme rezolvate

P10.1 ScrieŃi un program care să calculeze şi să afişeze, în funcŃie de opŃiunea utilizatorului, următoarele mărimi pentru un cilindru cu raza bazei şi înălŃimea date (numere reale): aria bazei, circumferinŃa cercului de bazăşi volumul cilindrului; programul va fi reluat până când utilizatorul doreşte terminarea sa şi se va cererepetarea opŃiunii, dacă aceasta nu s-a făcut corect.

#include <stdio.h>

#include <stdlib.h>

#define PI 3.14159265358979323846

int main() {float raza, inaltimea;char ch;double raspuns;int semnal=1;

while(semnal) {printf("Alegeti una din optiunile:\n");printf(

"Aria (A), Circumferinta (C), Volumul (V), Iesire (Q): ");ch = getche();printf("\n");ch = toupper(ch);

if(ch == 'A' || ch == 'C' || ch == 'V')do {

printf("Introduceti raza: ");} while(scanf("%f", &raza) != 1);

if(ch == 'V')do {

printf("Introduceti inaltimea: ");} while(scanf("%f", &inaltimea) != 1);

switch(ch) {case 'A':

raspuns = PI * raza * raza;printf("Aria bazei este: %g\n\n", raspuns);break;

case 'C':raspuns = 2 * PI * raza;printf(

"Circumferinta bazei este: %g\n\n", raspuns);

break;case 'V':

raspuns = PI * raza * raza * inaltimea;printf(

"Volumul cilindrului este: %g\n\n", raspuns);break;

case 'Q':semnal=0;break;

default:printf(

"Optiunea necunoscuta '%c' este ignorata!\n\n", ch);break;

}}

printf("\n");system("PAUSE");return 0;

}

  Programul va afişa pe ecran, după compilare şi execuŃie:

Alegeti una din optiunile:Aria (A), Circumferinta (C), Volumul (V), Iesire (Q): v  Introduceti raza: 10 Introduceti inaltimea: 1 Volumul cilindrului este: 314.159

Alegeti una din optiunile:Aria (A), Circumferinta (C), Volumul (V), Iesire (Q): q  

=============================

Page 66: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 66/75

 

 

65

P10.2 ScrieŃi un program care să deseneze pe ecran un ‚X’ cu dimensiunea specificată de utilizator (număr natural≤ 20, înălŃimea egală cu lăŃimea), folosind simbolul ‚  * ’.De exemplu, dacă se introduce numărul 5, desenul va trebui să arate astfel:

* ** *

** *

* *

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

int main() {int d; /* dimensiunea */int r; /* numarul liniei */int c; /* numarul coloanei */printf("Introduceti dimensiunea: ");scanf("%d", &d);

/* pentru "diagonala principala", '*' va apare cand r = c; pentru "diagonalasecundara", '*' va apare cand c=d–r+1 */

printf("Desenul cerut arata astfel:\n\n");for(r = 1; r <= d; r++) {

for(c = 1; c <= d; c++) {if(r == c || c == d – r + 1)

printf("*");

elseprintf(" ");

}printf("\n");

}printf("\n");system("PAUSE");return 0;

}

  Programul va afişa pe ecran, după compilare şi execuŃie:

Introduceti dimensiunea: 8 Desenul cerut arata astfel:

* ** *

* *****

* ** ** *

=============================

P10.3 Programul următor citeşte de la tastatură o matrice de maxim 10 × 10 numere întregi apoi determinăelementele minime pe linii şi maxime pe coloane.

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

int main() {int A[10][10], n, m, i, j, min, max;

printf("Introduceti nr. de linii: ");scanf("%d", &n);printf("Introduceti nr. de coloane: ");scanf("%d", &m);

for(i = 0; i < n; i++)for(j = 0; j < m; j++) {

printf("A[%d][%d] = ", i, j);scanf("%d", &A[i][j]);

}

printf("Elementele minime pe linii: \n");

for(i = 0; i < n; i++) {

min = A[i][0];

for(j = 0; j < m; j++) {

Page 67: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 67/75

 

 

66

if (A[i][j] < min)

min = A[i][j];

}

printf("Linia %d are minimul: %d\n", i, min);

}

printf("Elementele maxime pe coloane: \n");

for(j = 0; j < m; j++) {

max = A[0][j];

for(i = 0; i < n; i++) {

if (A[i][j] > max)

max = A[i][j];

}

printf("Coloana %d are maximul: %d\n", j, max);

}

system("PAUSE");

return 0;

}

  Programul va afişa pe ecran, după compilare şi execuŃie:

Introduceti nr. de linii: 3 Introduceti nr. de coloane: 3 A[0][0] = 1 A[0][1] = 2 

A[0][2] = 3 A[1][0] = 4 A[1][1] = 5 A[1][2] = 6 A[2][0] = 7 A[2][1] = 8 A[2][2] = 9 Elementele minime pe linii:Linia 0 are minimul: 1Linia 1 are minimul: 4Linia 2 are minimul: 7Elementele maxime pe coloane:Coloana 0 are maximul: 7Coloana 1 are maximul: 8Coloana 2 are maximul: 9

=============================

P10.4 Programul următor citeşte de la tastatură o matrice de maximum 10 × 10 numere întregi şi sorteazăcrescător liniile matricei. Precizare: prin convenŃie, o linie este mai mare decât alta dacă primul element de pe o linie este mai mare decât primul element de pe a doua. Dacă primele elemente sunt egale regula seaplică pentru următoarele perechi de elemente de pe liniile respective.

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

/* functie care interschimba linia l1 cu l2 in matricea A */void int_linii(int A[][10], int n, int m, int l1, int l2) {

int j, tmp;for(j = 0; j < m; j++) {

tmp = A[l1][j];A[l1][j] = A[l2][j];A[l2][j] = tmp;

}}

int main() {int A[10][10], n, m, i, j, ind;

printf("Introduceti nr. de linii: ");scanf("%d", &n);printf("Introduceti nr. de coloane: ");scanf("%d", &m);

/* citirea matricii */for(i = 0; i < n; i++)

for(j = 0; j < m; j++) {

Page 68: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 68/75

 

 

67

printf("A[%d][%d] = ", i, j);scanf("%d", &A[i][j]);

}

ind = 1; /* setare indicator */while(ind) {

ind = 0;/* parcurgere matrice pe linii */for(i = 0; i < n; i++)

for(j = 0; j < m; j++)if(A[i][j] <= A[i+1][j])

/* s-a gasit un element mai mic pe liniaurmatoare deci parcurgerea liniei i se incheie */break;

else {/* se interschimba linia curenta cu

urmatoarea */int_linii(A, n, m, i, i+1);ind = 1; /* setam indicatorul */break; /* terminam parcurgerea liniei i */

}}

/* afisare matrice */for(i = 0; i < n; i++)

for(j = 0; j < m; j++)printf("A[%d][%d] = %d\n", i, j, A[i][j]);

system("PAUSE");return 0;

}

  Programul va afişa pe ecran, după compilare şi execuŃie:

Introduceti nr. de linii: 3 Introduceti nr. de coloane: 3 A[0][0] = 9 A[0][1] = 8 A[0][2] = 7 A[1][0] = 6 A[1][1] = 5 A[1][2] = 4 A[2][0] = 3 A[2][1] = 2 

A[2][2] = 1 A[0][0] = 3A[0][1] = 2A[0][2] = 1A[1][0] = 6A[1][1] = 5A[1][2] = 4A[2][0] = 9A[2][1] = 8A[2][2] = 7

=============================

P10.5 Programul următor citeşte de la tastatură o matrice de maximum 10 × 10 numere întregi apoi elimină o liniea matricei. Precizare: indexul liniei ce se doreşte eliminată va fi citit tot de la tastatură.

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

int main() {int A[10][10], n, m, i, j, ie;

printf("Introduceti nr. de linii: ");scanf("%d", &n);printf("Introduceti nr. de coloane: ");scanf("%d", &m);

/* citirea matricii */for(i = 0; i < n; i++)

for(j = 0; j < m; j++) {

Page 69: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 69/75

 

 

68

printf("A[%d][%d] = ", i, j);scanf("%d", &A[i][j]);

}

/* citirea corecta a indicelui ie al liniei ce se doresteeliminata */

while(1) {printf(

"Introduceti indicele liniei ce se doreste eliminata: ");scanf("%d", &ie);if ((ie >= 0) && (ie <= n))

break;else

printf("Indice incorect\n");}

/* cu i de la ie la n se aduc liniile i+1 pe liniile i */for(i = ie; i < n; i++)

for(j = 0; j < m; j++)A[i][j] = A[i+1][j];

/* decrementam numarul total de linii */n--;/* afisam matricea */for(i = 0; i < n; i++)

for(j = 0; j < m; j++)printf("A[%d][%d] = %d\n", i, j, A[i][j]);

system("PAUSE");return 0;

}

  Programul va afişa pe ecran, după compilare şi execuŃie:

Introduceti nr. de linii: 3 Introduceti nr. de coloane: 3 A[0][0] = 1 A[0][1] = 2 A[0][2] = 3 A[1][0] = 4 A[1][1] = 5 A[1][2] = 6 A[2][0] = 7 

A[2][1] = 8 A[2][2] = 9 Introduceti indicele liniei ce se doreste eliminata: 1 A[0][0] = 1A[0][1] = 2A[0][2] = 3A[1][0] = 7A[1][1] = 8A[1][2] = 9

=============================

P10.6 Programul următor citeşte de la tastatură o matrice de dimensiuni n × m de numere întregi (maximum10 × 10) şi înlocuieşte coloana k cu un vector de n elemente ce se va citi tot de la tastatură. Precizare: poziŃia coloanei, k , se va citi tot de la tastatură.

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

int main() {int A[10][10], n, m, k, i, j, v[10];printf("Introduceti nr. de linii: ");scanf("%d", &n);printf("Introduceti nr. de coloane: ");scanf("%d", &m);

for(i = 0; i < n; i++)for(j = 0; j < m; j++) {

printf("A[%d][%d] = ", i, j);scanf("%d", &A[i][j]);

}

Page 70: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 70/75

 

 

69

while(1) {printf("Introduceti indicele coloanei ce se ");printf("doreste inlocuita: ");scanf("%d", &k);if ((k >= 0) && (k <= m))

break;else

printf("Indice incorect\n");}

/* citim in vectorul v noua coloana a matricii A */

printf("Acum introduceti noile elemente ale coloanei:\n");for(i = 0; i < n; i++) {printf("A[%d][%d] = ", i, k);scanf("%d", &v[i]);

}

/* parcurgem coloana k si inlocuim elementele sale */for(i = 0; i < n; i++)

A[i][k] = v[i];

/* tiparim noua matrice */printf("Noua matrice are elementele:\n");for(i = 0; i < n; i++)

for(j = 0; j < m; j++)printf("A[%d][%d] = %d\n", i, j, A[i][j]);

system("PAUSE");return 0;

}

  Programul va afişa pe ecran, după compilare şi execuŃie:

Introduceti nr. de linii: 3 Introduceti nr. de coloane: 3 A[0][0] = 1 A[0][1] = 2 A[0][2] = 3 A[1][0] = 4 A[1][1] = 5 A[1][2] = 6 A[2][0] = 7 A[2][1] = 8 A[2][2] = 9 Introduceti indicele coloanei ce se doreste inlocuita: 1 Acum introduceti noile elemente ale coloanei:A[0][1] = 1 

A[1][1] = 2 A[2][1] = 3 Noua matrice are elementele:A[0][0] = 1A[0][1] = 1A[0][2] = 3A[1][0] = 4A[1][1] = 2A[1][2] = 6A[2][0] = 7A[2][1] = 3A[2][2] = 9

=============================

P10.7 Programul următor afişează graficul unei funcŃii (de exemplu sin( x) pe o perioadă) în format ASCII.Programul scalează funcŃia în intervalul ce se doreşte afişat şi tipăreşte un singur caracter '*' pe poziŃiacorespunzătoare valorii funcŃiei. Terminalul alfanumeric se va considera de 80 coloane şi 25 linii.

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

#define NC 40 /* numarul de coloane */#define NL 25 /* numarul de linii */

main() {float v[NL-1], x, M, m, q;int i, j;for(i = 0; i < NL - 1; i++) {

x = (float)(i-12);/* functia ce se afiseaza */v[i] = sin(2 * 3.1415926535 * x / NL);

}

Page 71: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 71/75

 

 

70

/* Se gasesc maximumul, M, si minimul, m, functiei */M = m = v[0];for(i = 0; i < NL - 1; i++)

if(v[i] > M)M = v[i];

for(i = 0; i < NL - 1; i++)if(v[i]<m)

m=v[i];

/* gaseste pasul minim */

q = (NC - 1) / (M - m);/* parcurge terminalul alfanumeric linie cu linie */for(i = 0; i < NL - 1; i++)

for(j = 0; j < NC; j++) {if(j == ceil((v[i] - m) * q)) {

printf("*\n"); /* tipareste '*' si trece pe linia urmatoare */break; /* iese de ciclul for ce parcurge

liniile daca s-a tiparit ’*’*/} else

printf(" "); /* tipareste spatiu */}

system("PAUSE");return 0;

}

  Programul va afişa pe ecran, după compilare şi execuŃie:

**

**

****

**

**

**

*

* ***

**

**

*

=============================

P10.8 ScrieŃi un program care să implementeze un calculator de buzunar foarte simplu (doar cele 4 operaŃiielementare).

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

int main(int argc, char *argv[]) {float nr1, nr2, rez;char op;

printf("Introduceti expresia (nr op nr, op = +-x/)\n");scanf("%f %c %f", &nr1, &op, &nr2);switch(op) {

case '+':rez = nr1 + nr2;break;

case '-':rez = nr1 - nr2;

Page 72: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 72/75

 

 

71

break;case 'x':

rez = nr1 * nr2;break;

case '/':if(nr2 == 0) {

printf("Impartire la 0!\n");system("PAUSE");exit(4);

} elserez = nr1 / nr2;

break;default:

printf("Eroare: operator necunoscut\n");system("PAUSE");exit(5);

}

printf("%g %c %g = %g\n", nr1, op, nr2, rez);

system("PAUSE");return 0;

}

  Programul va afişa pe ecran, după compilare şi execuŃie:

Introduceti expresia (nr op nr, op = +-x/)25.75 x 3.14

25.75 x 3.14 = 80.855

=============================

10.2.  Probleme propuse – Teme de casă

1. ScrieŃi un program care citeşte un număr întreg reprezentat în baza 10 şi îl converteşte şi afişează reprezentat în baza 16.

2. ScrieŃi un program care citeşte de la tastatură un număr natural n cu cel mult 9 cifre şi determină numărul naturalk < n care are numărul maxim de divizori primi.

3. ScrieŃi un program care citeşte perechi de numere reale care reprezintă coordonatele carteziene ale unui poligonconvex şi apoi calculează şi afişează aria poligonului.

4. ScrieŃi un program care citeşte un număr întreg pozitiv n < 50 000 reprezentând numărul de zile care au trecut dela 1 ianuarie 1900 şi determină şi afişează data calendaristică corespunzătoare. Se vor lua în consideraŃie şi anii bisecŃi (1900 a fost an bisect iar 2000 nu a fost an bisect).

5. ScrieŃi un program care citeşte din fişierul „nr.in” un număr natural cu minim 2 cifre şi maxim 5000 de cifrezecimale şi apoi calculează şi scrie în fişierul „nr.out” pătratul acestui număr.

6. ScrieŃi un program care determină câte perechi de numere naturale care nu depăşesc un număr dat, n, au cel maimic divizor comun un alt număr dat, d . Programul va afişa perechile de numere obŃinute.

7. ScrieŃi un program care determină toate numerele naturale i < n care au proprietatea că sunt egale cu sumafactorialelor cifrelor care le conŃin. Exemplu: 145 = 1! + 4! + 5!

 Numărul n va fi citit de la tastatură.

8. ScrieŃi un program care determină care este numărul natural maxim care se poate construi din cifrele distincte aleunui număr natural în baza 10 cu maxim 80 de cifre care se citeşte de la tastatură.

9. ScrieŃi un program care citeşte un număr natural n cu maxim 50 de cifre zecimale şi determină şi afişează secvenŃamaximă de cifre consecutive care se repetă de cel puŃin 2 ori în scrierea numărului n.

10. ScrieŃi un program care citeşte ecuaŃiile a n drepte din plan şi determină şi afişează dreptele care aparŃin aceleiaşiclase de paralelism. EcuaŃia unei drepte este dată de formula: a ⋅ x + b ⋅ y + c = 0; două drepte aparŃin aceleaşiclase de paralelism dacă au aceeaşi pantă.

11. ScrieŃi un program care citeşte într-un şir de caractere care reprezintă o expresie care conŃine mai multe numerecomplexe şi operaŃii între acestea apoi calculează şi afişează rezultatul expresiei.

Page 73: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 73/75

 

 

72

 Precizări:OperaŃii: + , - , * , ^ Exemplu: (2 + 3 * i) ^ 3 + (7 + 9 * i) * (10 – 4 * i)

12. ScrieŃi un program care citeşte coordonatele a trei figuri geometrice formate doar din linii drepte şi determină şiafişează doar segmentele care se înscriu în suprafaŃa unui dreptunghi ale cărui coordonate vor fi şi ele citite de latastatură.  Precizare: această operaŃie, denumită în limba engleză „clipping ”, este foarte importantă în afişareagrafică a informaŃiei.

13. ScrieŃi un program care citeşte coordonatele unui graf orientat şi îi ordonează vârfurile astfel încât toate arcele să

aibă aceeaşi orientare. Programul va semnala dacă acest lucru nu este posibil.  Exemplu: Dacă avem (1, 2) (2, 3)(3, 1) nu este posibilă ca toate arcele să aibă aceeaşi orientare.

14. ScrieŃi un program care citeşte un fişier reprezentând un program C şi scrie la ieşire acelaşi program în careacoladele corespunzătoare - ‚{‘ respectiv ‚}’ - au fost aşezate una sub alta. În cazul mai multor acolade imbricate,cele din interior se vor deplasa faŃă de cele din exterior. Restul textului se va alinia pe aceeaşi coordonată cu celedouă acolade corespunzătoare.

15. ScrieŃi un program care citeşte un arbore n-ar (n este un număr natural) şi îi scrie reprezentarea fiu – frate. Precizare: în reprezentarea fiu - frate un arbore n-ar este reprezentat ca un arbore binar astfel încât pentru un vârf  x legătura stânga reprezintă primul fiu iar legătura dreapta reprezintă fratele.

16. ScrieŃi un program care citeşte un număr natural n (cu maxim 10 cifre) şi determină toate numerele ce pot fiobŃinute mutând pe rând prima cifră a numărului n şi a celor obŃinute pe parcurs pe ultima poziŃie. Exemplu: 4273

273473423427

Problema va fi rezolvată în trei moduri:− folosind unul sau mai multe tablouri cu elemente de tip numeric;− folosind tipul şir de caractere;− folosind metode aritmetice.

17. ScrieŃi un subprogram care să calculeze valoarea 2 la puterea 3000. TransformaŃi apoi subprogramul pentrucalculul oricărei puteri adică: n la puterea m (n < 10, m < 3001, m > 0, n şi m întregi).

18. ScrieŃi un program care citeşte polinoame rare şi le memorează sub forma unei liste simplu înlănŃuite, unde pentrufiecare monom, se memorează gradul şi coeficientul. ScrieŃi o funcŃie pentru suma a două polinoame rare,

specificate ca parametru.

19. ScrieŃi un program care citeşte n puncte din plan (n ≤ 100) date prin coordonatele lor carteziene şi determină încare dintre aceste puncte putem alege centrul cercului de rază minimă ce conŃine în interior toate cele n punctedate, precum şi raza cercului. Precizări: datele vor fi citite din fişierul text „PUNCTE.TXT” , ce are pe prima linievaloarea lui n, iar pe următoarele n linii coordonatele carteziene ale punctelor, câte două pe linie ( x respectiv y),valori reale.

20. ScrieŃi un program care citeşte fişierul text „TEST.IN” care conŃine un text scris pe mai multe linii şi afişeazătoate caracterele folosite, codul ASCII corespunzător precum şi frecvenŃa lor de apariŃie.

21. ScrieŃi un program care estimează cu 6 zecimale numărul π (3.1415926535...) în modul următor:a) Se vor genera perechi de numere pseudo-aleatoare de tipul ( x, y) cu 0 < x, y < 1; b) Se vor număra câte perechi de astfel de numere pseudo-aleatoare cad în interiorul sfertului de cerc situat în

cadranul 1 al planul ( x, y);c) se va evalua pi ca 4 × <numărul_de_puncte_din_interiorul_sfertului_de_cerc> / <numărul_total_de_puncte>.

22. ScrieŃi un program care să citească elementele a două matrice, fiecare dintr-un fişier, să calculeze matricea produsşi să o tipărească într-un al treilea fişier. Matricele vor fi structurate în fişiere pe linii şi coloane. Se va afişa unmesaj de eroare dacă înmulŃirea matricelor nu este posibilă.

23. ScrieŃi un program care citeşte elementele unei matrice pătrate, dintr-un fişier ASCII, calculează matriceatranspusă şi o tipăreşte într-un alt fişier. Precizări: Matricea va fi structurată în primul fişier pe linii şi coloane astfel:1.0 -1.33 3.44-3.14 5.67 00 4.67 10.01 

Page 74: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 74/75

 

 

73

24. ScrieŃi un program care citeşte din fişierul „INPUT.TXT” două propoziŃii scrise fiecare pe câte o linie.PropoziŃiile conŃin cuvinte formate din literele alfabetului englez. Orice alt caracter este considerat separator.Programul:− va afişa numărul de cuvinte din fiecare propoziŃie;− va verifica dacă ultimul cuvânt din prima propoziŃie este o anagramă (are aceleaşi litere) a ultimului cuvânt dincealaltă propoziŃie. Pentru verificarea cuvintelor scrieŃi şi folosiŃi o funcŃie recursivă. Precizări:Rezultatele se vor scrie în fişierul „OUTPUT.TXT” astfel:− pe primele două linii programul va scrie numărul de cuvinte din fiecare propoziŃie;

− pe ultima linie va scrie mesajul „DA” sau „NU” pentru cazurile în care ultimele cuvinte sunt sau nu anagrame.

25. ScrieŃi un program care citeşte fişierul „AMENZI.TXT” care conŃine evidenŃa amenzilor de circulaŃie pe o perioadă dată. Fiecărui conducător auto i se alocă 4 linii: prima linie va conŃine numele, cea de a doua numărul deînmatriculare al maşinii, ce de a treia suma de bani corespunzătoare amenzii şi cea de a patra dacă amenda a fostsau nu plătită (0 – neplătită, 1 - plătită). Programul va citi mai întâi numărul de înregistrări, n. Apoi programul:− va afişa suma de bani rezultată din amenzi, precum şi numele şoferilor şi numărul maşinii care a plătit amenzilecele mai mari;− numele şoferilor care nu au plătit amenda/amenzile ordonate alfabetic;− procentul de amenzi neîncasate.

26. ScrieŃi un program care citeşte lista abonaŃilor telefonici dintr-un oraş dintr-un fişier care conŃine numărul detelefon şi numele abonatului pe câte o linie. Programul va crea o listă de premiere care să cuprindă abonaŃii alcăror numere de telefon cuprind doar cifre pare iar prima şi ultima cifră sunt proporŃionale.

27. ScrieŃi un program care citeşte două fişiere ASCII structurate astfel:a. primul fişier va conŃine, structurat pe linii, numele şi prenumele candidaŃilor la un concurs de admitere, separate prin unul sau mai multe spaŃii, în formatul <nume> <prenume>; b. al doilea fişier va conŃine, structurat pe linii, media la examenul de admitere.Programul va asocia numele şi prenumele persoanei de la linia i din primul fişier cu nota de la linia i din al doileafişier. Programul va concatena cele trei câmpuri (numele, prenumele şi nota), le va sorta în ordinea crescătoare amediei şi va scrie rezultatul într-un al treilea fişier ASCII. Exemple de fişiere:fişier1.txt 

CONSTANTIN IoanaPOPESCU GeorgeVASILESCU Costin

fişier2.txt 

8.669.527.89

fişier3.txt 

POPESCU George 9.52CONSTANTIN Ioana 8.66VASILESCU Costin 7.89 

28. ScrieŃi un program care citeşte două fişiere ASCII structurate astfel:a. primul fişier va conŃine, structurat pe linii, numele şi prenumele angajaŃilor unei firme, separate prin unul saumai multe spaŃii, în formatul <nume> <prenume>; b. al doilea fişier va conŃine, structurat pe linii, data naşterii, în formatul<zi> <luna> <an>.Programul va asocia numele şi prenumele persoanei de la linia i din primul fişier cu data naşterii de la aceeaşi liniedin al doilea fişier. Programul va concatena cele cinci câmpuri (numele, prenumele, zi, luna, an), le va sorta înordinea descrescătoare a vârstei şi va scrie rezultatul într-un al treilea fişier ASCII.

 Exemplu:fişier1.txt 

CONSTANTIN IoanaPOPESCU GeorgeVASILESCU Costin

fişier2.txt 

8 Ianuarie 197827 August 198016 Octombrie 1978

fişier3.txt 

CONSTANTIN Ioana 8 Ianuarie 1978VASILESCU Costin 16 Octombrie 1978POPESCU George 27 August 1980

Page 75: Indrumar Lab-Oct 2008

5/11/2018 Indrumar Lab-Oct 2008 - slidepdf.com

http://slidepdf.com/reader/full/indrumar-lab-oct-2008 75/75

 

 

74

29. ScrieŃi un program care să recunoască într-un fişier sursă C directiva de preprocesare „#define” şi care săgenereze un alt fişier preprocesat. Exemplu:fişier1.c #include <stdio.h>#include <stdlib.h>#define PI 3.1415int main() {

printf("pi = %f", PI);return 0;

}

fişier2.c #include <stdio.h>#include <stdlib.h>int main() {

printf("pi = %f", 3.1415);return 0;

}

30. ScrieŃi un program care citeşte fişierul „TEXT.TXT” care conŃine un text ce se încheie cu o linie goală. Să seafişeze toate cuvintele textului în ordine alfabetică. Precizări:− lungimea unui cuvânt este de maxim 25 caractere;− numărul de cuvinte din text este cel mult 100;− cuvintele sunt despărŃite printr-un spaŃiu;− se va folosi sortarea prin inserŃie.RescrieŃi programul pentru a putea prelucra un text oricât de mare şi în care cuvintele sunt despărŃite prin orice tipde spaŃiu sau semn de punctuaŃie.

31. ScrieŃi un program care construiască un fişier cu înregistrări de tip bibliotecă cu următoarele câmpuri: Numele autoruluiTitlul cărŃii

 Editura Anul apariŃiei Lista cuvintelor cheie

Programul va permite următoarele operaŃii:a. introducerea unei înregistrări noi în bibliotecă; b. ştergerea unei înregistrări din bibliotecă;c. extragerea într-un fişier nou a înregistrărilor în funcŃie de valoarea unui anumit câmp:

 Numele autoruluiTitlul cărŃii Editura Anul apariŃiei ExistenŃa unui anumit cuvânt în lista cuvintelor cheie

d. sortarea fişierului în ordinea crescătoare a numelor autorilor (ordine lexicografică), iar pentru acelaşi autor,înregistrările se ordonează în funcŃie de anul apariŃiei;e. interclasarea a două fişiere ordonate conform punctului anterior. Numele fişierelor se citesc de la tastatură.Programul va construi un fişier ordonat care conŃine reuniunea celor două fişiere iniŃiale şi va elimina duplicateledin fişier.

32. ScrieŃi un program care citeşte fişierul text „INTRARE.IN” care conŃine un text scris pe mai multe linii şi rescrietextul pe pagini formate din două coloane cu linii de lungime egală. Lungimea unei linii „ ln” şi dimensiunea unei pagini „lp” se citesc de la tastatură.RescrieŃi programul extinzându-l pentru a putea împărŃirea textul în k coloane.