Sunteți pe pagina 1din 8

12.

Probleme rezolvate n C
12.1. Tiprii pe ecran textul: Primul program C
Program
#include <stdio.h>
void main()
{
printf("Primul program C " ) ;
}
Analiza programului
- prima linie indic includerea bibliotecii stdio.h, care conine funcia printf ;
- funcia main() returneaz void, deci nu conine nici o instruciune return;
- dac uitm s scriem linia #include <stdio.h> atunci la compilare se va returna eroarea: printf:
undeclared identifier.
Efect
Primul program C
12.2. Scriei un program care citete de la tastatur un numar dupa care afiseaza pe ecran acel numar, insotit de un mesaj.
Program
#include <stdio.h>
void main()
{
int n;
printf("Introduceti un numar: ");
scanf("%d", &n);
printf("Ati introdus numarul %d", n);
}
Analiza programului
Prima linie este o directiv de preprocesare, aceasta va include n program headerul stdio.h, care conine
prototipurile (anteturile) funciilor scanf i printf. Apoi urmeaz funcia principal main, care nu returneaz nimic i n
corpul su conine:
- declaraia variabilei n de tip int ;
- afiarea pe ecran a irului "Introduceti un numar: " cu ajutorul functiei printf ;
- citirea numarului de la tastatura si depunerea valorii lui in variabila n cu ajutorul functiei scanf;
- apelul funciei printf, care afieaz pe ecran un mesaj corespunztor (cnd se ntlnete specificatorul de format %d se
va nlocui cu prima variabil de dup virgul i apoi irul obinut se va afia pe ecran).
Efect
Introduceti un numar: 10
Ati introdus numarul 10
12.3. Interschimbai coninutul a doua numere de tip intreg citite de la tastatura.
Program
#include <stdio.h>
'
void main()
{
int a, b, aux;
printf ("Primul numar: ");
scanf ("%d", &a);
printf ("Al doilea numar: ");
scanf ("%d", &b);
aux = a;
a = b;
b = aux;
printf ("Dup interschimbare: a = %d b = %d", a, b);
return 0;
}
Analiza programului
- pe prima linie se include headerul stdio.h pentru a putea utiliza funciile de intrare/ieire printf i scanf ;

- funcia main nu are specificat tipul returnat, deci se va considera c, implicit acest tip este i n t ;
- pe prima linie n corpul funciei principale se declar trei variabile ntregi: a, b i aux ;
- se foloseste de doua ori perechea de functii printf/scanf pentru a afisa un mesaj pe ecran si apoi pentru a citi cele doua
valori intregi de la tastatura, care vor fi depuse in variabilele a, respectiv b; deoarece numerele citite de la tastatura se
introduc in variabile de tip int, in cadrul functiei scanf se foloseste specificatorul de tip %d ;
- urmeaz trei instruciuni de atribuire, care mpreun formeaz metoda celor trei pahare";
- se afieaz rezultatul, folosind un apel de funcie printf; observm c n irul de formatare avem dou secvene
%d, care se vor nlocui cu valorile din variabilele a, respectiv b, apoi se vor afia;
- urmeaz o instruciune return, deoarece cum am specificat mai sus, tipul returnat de funcia principal este int (lipsa
acestei instruciuni va duce la apariia la compilarea avertismentului 'main' : no return value).
Efect
Primul numar: 15
Al doilea numar: 21
Dup interschimbare: a=21 b=15
Analizai i urmtoarea metod de rezolvare (care nu folosete nici o variabil suplimentar) :
#include <stdio.h>
main ()
{
int a, b;
printf("Introducei cele doua valori (a, b): ");
scanf("%d%d", &a, &b);
a = a - b;
b = a + b;
a = b - a;
printf("Dup interschimbare: a=%d, b=%d", a, b);
return 0;
}
Analiza programului
- pe prima linie n corpul funciei principale se declar doua variabile ntregi: a, b ;
- cu ajutorul functiei printf se afiseaza pe ecran mesajul "Introducei cele doua valori (a, b): "
- cele doua valori intregi se citesc cu ajutorul unui singur apel al functiei scanf. In acest sens, se foloseste de doua ori
specificatorul de tip %d, o data pentru variabila a si a doua oara pentru variabila b.
- urmeaza trei instructiuni de atribuire
- se afieaz rezultatul, folosind un apel de funcie printf; observm c n irul de formatare avem dou secvene
%d, care se vor nlocui cu valorile din variabilele a, respectiv b, apoi se vor afia;
Efect
Introduceti cele doua valori (a, b): 15 21
Dup interschimbare: a=21 b=15
12.4. Calculai suma cifrelor unui numr natural dat cu maximum 9 cifre.
Rationament
Pentru a rezolva aceasta problema trebuie sa ne folosim de uneltele de care dispunem pana in acest moment.
Problema care se pune este cum sa obtinem cifrele individuale ale numarului dat. O modalitate simpla si usor de
implementat este de a incepe ruperea numarului in cifre incepand cu cea mai din dreapta (cea mai nesemnificativa), fapt
care se poate realiza calculand restul impartirii la 10 a numarului dat. In acest fel se face primul pas. Trebuiesc insa obtinute
toate cifrele numarului, in vederea insumarii lor. Acest lucru il vom realiza in acelasi mod in care am obtinut prima cifra si
anume: dupa obtinerea primei cifre, vom imparti numarul dat la 10; aceasta operatie va avea ca si efect pierderea ultimei
cifre din numarul initial. In continuare, pentru numarul nou obtinut calculam restul impartirii la 10 si vom obtine ca si mai
sus, ultima cifra a sa, pe care o vom adauga-o la suma. Daca mergem putin inapoi vom observa ca aceasta a doua cifra
obtinuta reprezinta defapt penultima cifra a numarului initial. Vom continua acest rationament de impartire a numerelor si
de adaugare a ultimei cifre la suma pana cand la o impartire la 10 vom obtine catul 0. In acel moment vom sti suma tuturor
cifrelor numarului initial.
Program
#include <stdio.h>
void main(void) {
unsigned long n, m;
short s = 0;
printf("Introduceti numarul: ");

scanf("%ld", &n);
m = n;
while (m!=0)
{
s += m%10; // s=s+m%10
m /= 10;
// m=m/10
}
printf("Suma cifrelor lui %ld este %d.", n, s);
}

,,

Analiza programului
- corpul funciei main conine pe primele linii declaraii de variabile: pe prima linie declarm varibilele m i n de tip ntreg
fr semn pe 4 octei, pe a doua linie variabila s, in care vom calcula suma cifrelor lui n (observam iniializarea acesteia de
la declarare cu 0 !!!);
- citirea numrului n : observm formatul folosit (%ld);
- i se atribuie lui m variabila n, pentru a nu pierde valoarea n; aceasta este o tehnica utilizata intotdeauna cand avem de
modificat valoarea retinuta de o variabila, insa nu dorim sa pierdem valoarea initiala. In acest program, in variabila n avem
initial o valoare citita de la tastatura, si daca nu am folosi atribuirea m=n, am imparti variabila n la 10 pana cand valoarea
acesteia ar deveni 0 si evident nu am mai sti care a fost valoarea initiala. Utilizand insa atribuirea m=n si realizand
impartirile la 10 asupra variabilei m, valoarea lui n ramane nealterata. !!!
- urmeaz o instruciune while care conine dou instruciuni de atribuire compus (n prima se adaug la s ultima cifr a lui
m, iar n a doua se trunchiaz m de ultima cifr); aceste instruciuni se repet pn cnd m va avea valoarea 0 ;
- se afieaz rezultatul folosind o funcie printf; vom afisa astfel un sir de caractere si valorile retinute de variabilele n
si s, utilizand in acest scop specificatorii de tip corespunzatori tipurilor acestor variabile si anume %ld pentru n si %d
pentru s.
Efect
Introduceti numarul: 247
Suma cifrelor lui 247 este 13.
Exemplu de functionare a programului
Sa consideram ca n=247
Urmarind linie cu linie programul de mai sus vom obtine:
s=0
Introduceti numarul: 247
m=247
m=247 != 0
s=s+247%10 s=0+7=7
m=m/10 m=24
m=24 != 0
s=s+24%10 s=7+4=11
m=m/10 m=2
m=2 != 0
s=s+2%10 s=11+2=13
m=m/10 m=0
m=0 => s=13
Suma cifrelor lui 247 este 13.
Observaie
Analizai i urmtoarea form de rezolvare, folosind o instruciune do-while :
#include <stdio.h>
void main(void) {
unsigned long n, m;
short s = 0;
printf("Introduceti numarul: ");
scanf("%ld", &n);
m=n;
do
{

s += m % 10;
m /= 10;
}
while(m!=0);
printf("Suma cifrelor lui %ld este %d.", n, s);
}
12.5. Scriei un program care simuleaz comportarea unui calculator electronic pentru numere ntregi: se introduc dou
numere ntregi i o operaie care poate fi +, -, *, /, reprezentnd adunarea, scderea, nmulirea si catul.
Program
#include <stdio.h>
void main() {
int a, b, re z;
char op;
short ok = 1;
printf ("Primul numar: ");
scanf ("%d", &a);
printf ("Al doilea numar: ");
scanf ("%d", &b);
printf ("Operatia dorita (+,-,*,/) :")
scanf("%c", &op);
switch ( op )
{
case '+': rez = a + b; break; .
case '-': rez = a - b; break;
case '*': rez = a * b; break;
case '/': if (b) rez = a/b;
else {
printf("Impartire la 0 !");
return;
}
break;
default: ok = 0;
}
if (ok) printf("%d %c %d = %d", a, op, b, rez);
else printf("Operator invalid!");
}
Analiza programului
- se declar numerele ntregi a, b i rez de tip i n t, reprezentnd operanzii i rezultatul;
- se declara caracterul op de tip char, reprezentnd operaia care se va executa;
- se declara variabila ok de tip short, care va rmne l dac operaia se termin cu succes, altfel i se va atribui 0 ;
- avand in vedere ca va trebui sa comparam valoarea retinuta de variabila op cu mai multe valori, folosim instructiunea de
selectie switch. Avem 4 ramuri case, una pentru fiecare din valorile +, -, *, / si ramura default pentru cazurile in care op
are orice alta valoare inafara celor 4 enumerate anterior, moment in care ok ia valoarea 0. In cazul in care op are una din
valorile +, -, *, se efectuaza operatia corespunzatoare, iar rezultatul se depune in variabila rez. In cazul in care op are
valoarea /, prima data se va testa cu ajutorul unei instructiuni if, valoarea celui de-al doilea operand, deoarece daca el este 0,
impartirea nu se poate realiza, caz in care se va afisa pe ecran un mesaj corespunzator. Daca valoarea lui b este diferita de 0, se
procedeaza ca si in cazul operatiilor +, -, *.
- in cadrul unei instructiuni if se testeaza valoarea variabilei ok. Dac ok a rmas l, atunci se va afisa operaia efectuat
impreuna cu rezultatul, altfel se va tipari un mesaj ca operatorul introdus de la tastatura nu este unul valid.
Efect
Caz 1:
Primul numar: 15
Al doilea numar: 27
Operatia dorita (+, -, *, /): +
15 + 27 = 42
Caz 2:
Primul numar: 23
Al doilea numar: 0
Operatia dorita (+, -, *, /): /

Impartire la 0 !
Caz 3:
Primul numar: 38
Al doilea numar: 2
Operatia dorita (+, -, *, /): &
Operator invalid!
12.6. Testai dac un numr natural dat este prim. (Prin numr prim nelegem orice numr natural care se mparte doar
la 1 i la el nsui; se considera ca 2 este cel mai mic numar prim).
Program
#include <stdio.h>
#include <math.h>
int prim(unsigned long n) {
unsigned long i;
if (n<=l) return 0;
for (i=2; i*i<=n; i++)
for (i=2; i<=sqrt(n); i++)
if (n % i == 0) return 0;
return l;
}
main () {
unsigned long n;
printf("N = "); scanf("%ld", &n);
if ( prim(n) )
printf("Numrul %ld este prim!", n);
else printf("Numrul %ld nu este prim!", n ) ;
return 0;
}
Analiza programului
- pe primele dou linii ale programului se includ headerele s t di o. h i m t h. h, primul pentru funciile printf i
scanf, al doilea pentru funcia sqrt (radicalul utilizat n funcia prim);
- urmeaz declararea i implementarea funciei prim, care are ca parametru un ntreg fr semn pe 4 octei i returneaz O
dac numrul respectiv nu este prim i l dac numrul este prim. Dac n este mai mic sau egal cu l, se prsete funcia
cu valoarea O ; dac nu, vom parcurge cu ajutorul unei instruciuni for toate numerele naturale cuprinse ntre 2 i >/n ; dac
n se divide cu vreunul dintre ele (restul mpririi lui n la i este 0), atunci se prsete funcia cu valoarea O (n nu este prim).
Dac s-a terminat instruciunea for i nu am prsit funcia nseamn c numrul n este prim, deci se va returna valoarea l;
- urmeaz funcia principal main, n care declarm un numr ntreg N de tip unsigned long, apoi apelm funcia prim prin
intermediul unei instruciuni i f.
Observaie
Este indicat ca n cadrul unei funcii s nu se foloseasc mai multe instruci return ; n acest caz, funcia prim se mai
poate scrie:
int prim(unsigned long n)
{
unsigned long i;
int p - 1; if(n<-l)p * 0; for(i-2; *i<-n; i++)
i* (n % i 0) p - O ; return p;
}
12.7. Dat fiind un tablou unidimensional cu numere ntregi, determinai minimul si maximul din acest tablou.
Program
#include <stdio.h>
int min(int x, int y) {
return x < y ? x : y;
}
int max(int x, int y) {
return x > y ? x : y ;
}
void main() {
int a[100];
int n, i;
int MIN, MAX;

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


printf("Introducei elementele: ");
for(i=0; i<n; i++) scanf("%d",&a[i]);
MIN = MAX = a[0];
for(i-l; i<n; i++)
{
MIN = min(MIN, a[i]);
MAX = max(MAX, a[i]) ;
}
printf("Minimul din tablou este %d!\n", MIN);
printf("Maximul din tablou este %d!", MAX);
}

'

Analiza programului
- funciile min i max calculeaz minimul i maximul dintre dou numere ntregi; dac valoarea expresiei din faa semnului ?"
este nenul, valoarea returnat va fi cea de dup semnul ?", altfel valoarea returnat va fi cea de dup semnul : * ;
- urmeaz declararea unui tablou unidimensional a cu maximum 100 de elemente, a dou variabile ntregi n i i
(dimensiunea tabloului, respectiv o variabil-contor necesar pentru parcurgere) i a dou variabile MIN i MAX
reprezentnd valorile minim, respectiv maxim ale tabloului;
- urmeaz citirea tabloului (mai nti dimensiunea i apoi elementele); observm c elementele tabloului se refer cu
a[i], unde i parcurge irul 0, l, ..., n-i;
- n loc de &a[ i ] se poate folosi i expresia a+i, ntruct aceasta este adresa elementului al i-lea;
- urmeaz o instruciune de atribuire i, ntruct atribuirea acioneaz de la dreapta la stnga, se poate scrie n acest fel
(MIN i MAX se iniializeaz cu valoarea a[ 0 ] ) ;
- apoi, cu ajutorul instruciunii for, se parcurg elementele de la l la n-1 i se reactualizeaz valorile min i max ;
- afiarea numerelor obinute se realizeaz cu ajutorul a dou apeluri ale funciei printf. Observm c n primul apel,
la sfritul irului de formatare, apare secvena \n ; aceast secven este caracterul newline i are ca efect trecerea la o
linie nou.
Efect
Varianta l
Varianta 2
Dimensiunea tabloului: 7
Dimensiunea tabloului:!
Introducei elementele:
Introducei elementele: 23
45 -90 12 67 13 O -3
Minimul din tablou este 23!
Minimul din tablou este -90!
Maximul din tablou este 23!
Maximul din tablou este 67!_____________________________________________________
12.8. De la tastatura se introduce un ir de caractere care poate s conin litere i cifre. S se numere cte cifre, litere
mari i litere mici sunt n ir, s se transforme toate literele mici n litere mari i s se afieze irul astfel obinut. S se
verifice dac acest ir este palindrom.
Program
#include <stdio.h>
#include <ctype.h>
#include <string.h>
void main() {
char s [200];
int ne = O, ni = O, nL - 0;
short palindrom = 1;
int i, n;
printf("irul: ");
scanf("%s",s);
n = strlen (s);
for(i=0; i<n; i++)
{
if( isdigit(s[i]) ) nc++;
if{ islower (s [i] ) ) nl++;
if( isupper(s[i]) ) nL++;
s[i] = toupper(s[i]); } for(i=0; i<n/2; i++)
if(s[i] != s[n-l-i]){palindrom=0; break;}
printf("Numrul de litere mari este %d!\n", nL) ;
printf("Numrul de litere mici este %d!\n", ni);
printf("Numrul de cifre este %d\n", ne);
printf("irul cu litere mari este %s \n",s);

if(palindrom)printf("irul este palindrom!");


else printf("irul nu este palindrom!");
}
Analiza programului
- primele trei linii includ headerele stdio. h pentru funciile de intrare/ieire, ctype. h pentru funciile isdigit, islower,
isupper, toupper i string. h pentru apelul funciei strlen (lungimea irului);
- se declar irul cu maximum 200 de caractere s, variabilele ntregi ne, ni i nL, care se iniializeaz cu o i vor conine numerele
de caractere cifr, liter mic, respectiv liter mare din ir, variabila palindrom, care se iniializeaz cu l (dac vom
constata c dou caractere simetrice n ir difer, i se va atribui 0);
- dup citirea irului urmeaz o instruciune de atribuire n care lui n i se atribuie lungimea lui s;
- cu ajutorul unei instruciuni f or se va parcurge irul (de la O la n-1); vom testa dac elementul curent al irului este liter
mare, mic sau cifr i se va reactualiza variabila corespunztoare prin incrementare, apoi se va transforma caracterul i n
litera mare corespunztoare prin apelul funciei toupper din headerul c type. h;
urmeaz o instruciune for n cadrul creia vom compara elementele simetrice din ir (s[0] cu s[n-l], s[l] cu s[n-2], ..., s [i]
cu s[n-l-i]...), parcurgem caracterele irului pn la jumtate i dac gsim o pereche simetric n care valorile nu sunt egale, i
atribuim variabilei palindrom valoarea 0 i prsim ciclul for ;
- urmeaz instruciunile de afiare.
Efect
Varianta l
Varianta 2
irul: Co2j2oc

irul: ABC12asdc345
Numrul de litere mari este l!
Numrul de litere mari este 3!
Numrul de litere mici este 4!
Numrul de litere mici este 4!
Numrul de cifre este 2
Numrul de cifre este 5
irul cu litere mari este
irul cu litere mari este
CO2J20C
ABC12ASDC345
irul este palindrom!______________________irul nu este palindrom____________________
12.9. Afiarea pe ecran a coninutului unui fiier cu numele dat de la tastatur.
Program
#include <stdio.h>
void main() {
char c, s [ 16 ] ;
FILE *f;
printf("Numele fiierului: ");
scanf("%s", s);
f = fopen(s, "r");
while ( f && !feof(f) )
{
c = fgetc(f) ;
pute(c, stdout);
}
fclose ( f );
}
Analiza programului
- se vor declara variabilele c (caracterul curent citit din fiier i scris pe ecran), s (ir cu maximum 16 caractere
reprezentnd numele fiierului care se introduce de la tastatur), f (variabil de tip stream pentru a citi din fiierul dorit);
- n continuare, se citete numele fiierului i se deschide f pentru citire;
- urmeaz o instruciune repetitiv cu test iniial: ct timp f exist i nu s-a depistat nc sfritul fiierului, se citete un
caracter din fiier i se scrie pe ecran;
- se nchide stream-ul f.
12.10. Scrierea parametrilor din linia de comand.
Program
#include <stdio.h>
int main(int argc, char **argv)
{
int contor;
puts("Argumentele programului sunt:");
for (contor=0; contor<argc; contor++) puts(argv[contor] );
return 0;
}

Analiza programului
- se va declara variabila contor de tip int, cu ajutorul creia vom parcurge elementele vectorului argv[] reprezentnd
parametrii introdui;
- n cadrul unui ciclu for vom parcurge toate elementele vectorului argv[] i le vom afisa pe ecran utiliznd funcia
puts(), ce scrie un ir de caractere la ieirea standard.