Sunteți pe pagina 1din 17

PCLP. Laborator 3: Date și instrucțiuni. Intrare cu format – scanf.

Aplicații cu tablouri
și numere

I. INSTRUCŢIUNEA while
Aplicație rezolvată 1. Fie programul următor care utilizează formula C˚=(5/9)(F˚-32) pentru a afișa tabelul
temperaturilor pe scara Fahrenheit împreună cu temperaturile echivalente pe scara Celsius:

#include <stdio.h>
/* print Fahrenheit-Celsius table
for fahr = 0, 20, ..., 300; floating-point version */
main()
{
float fahr, celsius;
float lower, upper, step;
lower = 0; /* lower limit of temperature scale */
upper = 300; /* upper limit */
step = 20; /* step size */
fahr = lower;
while (fahr <= upper) {
celsius = (5.0/9.0) * (fahr-32.0);
printf("%3.0f %6.1f\n", fahr, celsius);
fahr = fahr + step;
}
}

Ciclul while lucrează astfel: Se testează condiţia dintre paranteze: (fahr <=
upper). Dacă este adevărată (valoare lui fahr este mai mică sau egală cu valoarea lui
upper), se execută corpul ciclului (cele trei instrucţiuni incluse între parantezele
acoladă). Apoi condiţia este re-testată şi dacă este adevărată, corpul ciclului este
executat din nou. Când condiţia de test devine falsă (valoarea lui fahr depăşeşte
valoarea lui upper) ciclul se termină, iar execuţia programului continuă cu
instrucţiunea care urmează ciclului, sau se termină, dacă nu mai există nicio
instrucţiune în program. Corpul ciclului while poate conţine una sau mai multe
instrucţiuni incluse între paranteze acoladă, sau o singură instrucţiune fără acolade.

Aplicaţie propusă 1. Modificați programul anterior astfel încât ieșirea lui să afișeze
un antet Fahrenheit Celsius la cele două coloane ca în imaginea din dreapta.

Aplicaţie propusă 2. Scrieţi un program care să afişeze tabelul corespondenţelor temperaturilor de la scara
Celsius la scara Fahrenheit folosind formula: F˚ = C˚ * (9/5) + 32

II. INTRĂRI: scanf()

Prototipul funcţiei scanf()se găsește în fişierul stdio.h. Ea se folosește la citirile programelor și are sintaxa:
int scanf(const char *lista_de_formate [,adresa,..]);

Adresele se specifică prefixând fiecare variabilă care se citește cu operatorul adresă &. Funcţia scanf() citeşte
de la tastatura o secvenţă de câmpuri de intrare, caracter cu caracter, până la terminarea introducerii câmpurilor
şi apăsarea tastei <Enter>. Ordinea din lista_de_formate a formatelor variabilelor trebuie să coincidă cu
ordinea listei adreselor variabilelor în care se face citirea. Fiecare variabilă care se dorește a fi citită trebuie
corelată cu un specificator de format specific din lista_de_formate.
Specificatorii de format sunt alcătuiţi din caracterul %, un caracter opţional * (asterisc) pentru suprimarea
atribuirii, un număr opţional pentru specificarea dimensiunii maxime a câmpului, un caracter opţional h, H sau L
pentru a indica dimensiunea spaţiului de destinaţie şi un caracter de conversie.

1
Caracter de
Date citite; Tip argument
conversie
d întreg zecimal; int *
i întreg; int *. Întregul poate fi în octal (cu 0 în faţă) sau în hexazecimal (fiind precedat de 0x sau de 0X)
o întreg octal (cu sau fără un zero în faţă); int *
u întreg zecimal fără semn; unsigned int *
x întreg hexazecimal (cu sau fără 0x sau 0X în faţă); int *
caractere; char *. Următoarele caractere de la intrare (în mod implicit 1) sunt stocate în spațiul indicat. Regula
c
obișnuită de salt peste spațiile albe este eliminată; pentru a citi următorul caracter diferit de spațiu alb, folosiți %1s.
şir de caractere (care nu se află în ghilimele); char *, indicând spre un tablou de caractere suficient de mare pentru
s
a stoca șirul și un caracter terminator '\0' care va fi adăugat.
e, f, g număr în reprezentare virgulă mobilă cu semn opţional, punct zecimal opţional şi exponent opţional; float *.
% caracterul % ; nu se efectuează nici o atribuire.

Aplicație rezolvată 2. Programul următor exemplifică citirea unor variabile de tip întreg, caracter, real și real
dublă precizie.
#include <stdio.h>
main()
{
int i;
char c;
float r;
double rd;
printf("Introduceti un caracter = "); scanf("%c", &c);
printf("Introduceti un nr intreg = "); scanf("%d", &i);
printf("Introduceti un nr real = "); scanf("%f", &r);
printf("Introduceti un nr real dublu = "); scanf("%le", &rd);
printf("\nVariabilele introduse sunt :\n");
printf("Caracterul = %c\n", c);
printf("Nr intreg = %d\n", i);
printf("Nr real = %f\n", r);
printf("Nr real dublu = %e\n", rd);
}

Aplicație rezolvată 3. Programul următor citește un șir de caractere conținând două numere întregi separate
printr-un caracter oarecare și apoi afișează separat cele două numere întregi. %*c suprimă citirea caracterului
dintre cele două numere întregi.
#include <stdio.h>
main()
{
int a, b;
printf("introduceti doua numere intregi separate printr-un caracter = ");
scanf("%d%*c%d",&a,&b);
printf("primul numar = %d\n", a);
printf("al doilea numar = %d\n", b);
}
Aplicație rezolvată 4. Programul următor citește o dată calendaristică (zi, lună, an) în care cele trei numere
întregi corespunzătoare zilei, lunii și anului sunt scrise fără separație între ele. scanf permite citirea unor valori
de dimensiune fixă ( în cazul nostru 2 cifre, 2 cifre, 4 cifre: %2d%2d%4d ), oprind citirea datelor chiar dacă
următorul caracter corespunde formatului datei curente.
#include <stdio.h>
main()
{
int zi, luna, an;
printf("data calendaristica = ");
scanf("%2d%2d%4d", &zi, &luna, &an);
printf("ziua = %d\n", zi);
printf("luna = %d\n", luna);
printf("anul = %d\n", an);
}
2
Aplicație rezolvată 5. Programul următor implementează un calculator rudimentar care adună la suma
anterioară valoarea reală curent citită. La întâlnirea sfârșitului de fișier (^Z), se returnează EOF acesta este
diferit de un număr real dublu, deci citirea nu se mai efectuează și scanf returnează 0 care este diferit de 1, deci
condiția lui while() devine falsă și ciclul se termină.
#include <stdio.h>
main()
{
double suma, v;
suma = 0;
while (scanf("%lf", &v) == 1){
suma = suma + v;
printf("\t%.2f\n", suma);
}
}

Aplicație propusă 3. Scrieți un program complet pentru secvența de cod de mai jos care să citească și să
afișeze o dată calendaristică în forma: 25 dec 2016. Observație: Nu se folosește operatorul & cu luna, deoarece
numele unui tablou este o adresă (pointer).

int zi, an;


char luna[20];
scanf("%d %s %d", &zi, luna, &an);

Aplicație propusă 4. Scrieți un program complet pentru secvența de cod de mai jos care să citească și să
afișeze o dată calendaristică în forma: zz/ll/aa. Observație: Pot apărea diferite caractere (chiar litere) în șirul
de caractere ce conține formatul din cadrul funcției scanf; acestea trebuie să corespundă acelorași caractere din
datele de intrare.

int zi, luna, an;


scanf("%d/%d/%d“, &zi, &luna, &an);

Aplicație rezolvată 6. Ideea cu separatorul / între zi, luna, an poate fi folosită pentru separarea părții întregi
de partea fracționară într-un număr real considerând punctul ca separator. Programul următor citește un număr
real și extrage partea întreagă și cea fracționară în două variabile întregi, pe care le afișează.
#include <stdio.h>
main()
{
int pi, pf;
printf("Introduceti un numar real cu parte intreaga si parte fractionara = ");
scanf("%d.%d",&pi,&pf);
printf("partea intreaga = %d\t partea fractionara = %d\n", pi, pf);
}

III. INSTRUCŢIUNEA for

Aplicație rezolvată 7. Programul următor, echivalent cu programul prezentat la început, afișează tabelul
temperaturilor pe scara Fahrenheit împreună cu temperaturile echivalente pe scara Celsius.
#include <stdio.h>
main()/* print Fahrenheit-Celsius table */
{
int fahr;
for (fahr = 0; fahr <= 300; fahr = fahr + 20)
printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
}

Instrucţiunea for implementează tot un ciclu, reprezentând o generalizare a instrucţiunii while.


În interiorul parantezelor sunt trei părţi separate prin punct şi virgulă. Prima parte, iniţializarea,
fahr = 0

este procesată o singură dată, înainte de intrarea în ciclu. Partea a doua este testul sau condiţia
care controlează ciclul:
3
fahr <= 300
Această condiție este evaluată; dacă ea este adevărată este executat corpul ciclului. Apoi se execută
partea a treia, pasul de incrementare:
fahr = fahr + 20

și condiția (partea a doua) este reevaluată. Ciclul se termină dacă condiția a devenit falsă. Ca și la while,
corpul ciclului poate fi o singură instrucțiune sau un grup de instrucțiuni incluse între acolade.

Aplicație propusă 5. Modificați corespunzător programul anterior pentru a afișa tabela conversiei
temperaturilor din scara Fahrenheit în scara Celsius în ordine inversată, de la 300˚F la 0˚F.

Aplicație rezolvată 8. Programul următor, echivalent cu programul prezentat la Aplicația rezolvată 7, folosește
constante simbolice și directiva #define.
#include <stdio.h>
#define LOWER 0 /* lower limit of table */
#define UPPER 300 /* upper limit */
#define STEP 20 /* step size */
main() /* print Fahrenheit-Celsius table */
{
int fahr;

for (fahr = LOWER; fahr <= UPPER; fahr = fahr + STEP)


printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
}

Observație. Cantitățile LOWER, UPPER şi STEP sunt constante simbolice, nu sunt variabile, nu apar în declarații.
Convenție: Numele constantelor simbolice se scriu cu MAJUSCULE, iar numele variabilelor se scriu cu
minuscule. Nu există punct și virgulă la finalul unei linii #define.

IV. CITIREA ŞI SCRIEREA CARACTERELOR


Biblioteca standard furnizează câteva funcții pentru citirea sau scrierea unui caracter odată. Dintre
acestea cele mai simple sunt: getchar şi putchar. De fiecare dată când este apelată getchar citește următorul
caracter de intrare dintr-un flux de text şi îl returnează ca valoarea sa. Adică după
c = getchar();

variabila c conține următorul caracter al intrării. Uzual caracterele provin de la tastatură.


Funcția putchar afișează (scrie) un caracter de fiecare dată când este apelată:
putchar(c);

scrie variabila întreagă c ca un caracter, de obicei pe ecran.

IV. 1. Copierea fișierelor


Dintre funcțiile furnizate de biblioteca standard cele mai simple sunt: getchar şi putchar.
De fiecare dată când este apelată getchar citește următorul caracter de intrare dintr-un flux de text şi îl
returnează ca valoarea sa. Adică după
c = getchar();

variabila c conține următorul caracter al intrării. Uzual caracterele provin de la tastatură.


Funcția putchar afișează (scrie) un caracter de fiecare dată când este apelată:
putchar(c);

scrie variabila întreagă c ca un caracter, de obicei pe ecran.

Aplicație rezolvată 9. Scrieți două variante ale unui program care copiază intrarea sa la ieșirea sa, caracter cu
caracter conform modelului:

4
Citește un caracter citire cu getchar()
afisare cu putchar()
Cât timp (caracterul nu este indicatorul de sfârșit de fișier ) citire cu getchar()
Scrie caracterul tocmai citit afisare cu putchar()
Citeşte un caracter

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

/* copy input to output; 1st version */ /* copy input to output ; 2nd version */
main() main()
{ {
int c; int c;

c = getchar(); while ((c = getchar()) != EOF)


while (c != EOF) { putchar(c);
putchar(c); }
c = getchar();
}
}

Explicați de ce sunt echivalente cele două programe de mai sus.

Aplicație propusă 6. Pe baza celor două exemple de mai sus scrieți un program în care verificați că expresia
getchar() != EOF este 0 sau 1.

Aplicație propusă 7. Scrieţi un program pentru a afișa valoarea lui EOF.

IV.2. Numărarea caracterelor


Aplicație rezolvată 10. Următoarele două programe scrise în C numără caracterele introduse de la tastatură
până la introducerea lui ^Z. Explicați de ce sunt echivalente.

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

/* count characters in input; 1st version */ /* count characters in input; 2nd version */
main() main()
{ {
long nc; double nc;

nc = 0; for (nc = 0; getchar() != EOF; ++nc)


while (getchar() != EOF) ;
++nc; printf("%.0f\n", nc);
printf("%ld\n", nc); }
}

IV.3. Numărarea liniilor


Aplicație rezolvată 11. Următorul program numără liniile citite. Numărarea liniilor se reduce la numărarea
caracterelor newline: ’\n’.
#include <stdio.h>
/* count lines in input */
main()
{
int c, nl;
nl = 0;

while ((c = getchar()) != EOF)


if (c == '\n')
++nl;
printf("%d\n", nl);
}
5
if (expresie) Observație. Instrucțiunea if. Una şi numai una dintre cele două instrucţiuni asociate cu un
instrucţiune if-else este efectuată. Dacă expresie este adevărată atunci este if (condiţie )
1 1
executată instrucţiune1; dacă nu - și există else - este executată instrucţiune1
else
instrucţiune instrucţiune2. else if (condiţie )
2 2
Instrucțiunile if pot fi imbricate pentru implementarea unei decizii cu mai instrucţiune2
multe variante. condiţiile sunt evaluate în ordine de sus până o anumită condiţie este ...
satisfăcută; în acel moment partea de instrucţiune corespunzătoare este executată şi ...
întreaga construcție este terminată. Dacă nicio condiţie nu este satisfăcută, este executată else
instrucţiunea de după ultimul else, în caz că există. instrucţiune
n

Aplicație propusă 8*. Scrieți un program care să numere blank-urile (’ ’), tab-urile (’\t’) şi newline-urile
(’\n’).

Aplicație propusă 9*. Scrieți un program care să copieze intrarea sa pe ieșirea sa, înlocuind fiecare șir de
caractere de unul sau mai multe blank-uri cu un singur blank.

Aplicație propusă 10*. Scrieți un program care să copieze intrarea sa pe ieșirea sa, înlocuind fiecare tab prin
\t, fiecare blank prin \b şi fiecare backslash prin \\. Acest program va determina vizualizarea tab-urilor şi
blank-urilor într-un mod clar.

IV.4. Numărarea cuvintelor

Aplicație rezolvată 12. Programul următor numără liniile, cuvintele și caracterele introduse. Prin cuvânt
înțelegem o secvență de caractere care nu conține blank-uri, tab-uri sau caractere newline.
#include <stdio.h>

#define IN 1 /* inside a word */


#define OUT 0 /* outside a word */

/* count lines, words, and characters in input */


main()
{
int c, nl, nw, nc, state;
state = OUT;
nl = nw = nc = 0;
while ((c = getchar()) != EOF) {
++nc;
if (c == '\n')
++nl;
if (c == ' ' || c == '\n' || c == '\t')
state = OUT;
else if (state == OUT) {
state = IN;
++nw;
}
}
printf("%d %d %d\n", nl, nw, nc);
}

Aplicație propusă 11*. Cum ați testa corectitudinea programului de mai sus? Ce tipuri de intrări sunt cele mai
susceptibile de a descoperi bug-uri dacă există ?

Aplicație propusă 12*. Scrieți un program care afișează intrările sale sub forma unui cuvânt pe câte o linie.

6
V. APLICAȚII cu tablouri unidimensionale: vectori

Un tablou (array) memorează, sub un nume unic, un șir de valori, fiecare valoare fiind accesată pe baza unui
indice al poziției sale.

Aplicație rezolvată 13. Programul următor afișează un tablou unidimensional (vector) de numere reale.
#include <stdio.h> v[0] v[1] v[2] v[3] v[4] v[5] v[6]
main() 4.2 0 -2.2 0.50 12.0 0.33 3.40
{
float v[7] = {4.2, 0, -2.2, 0.50, 12.0, 0.33, 3.40};
int i, n = 7;
for (i = 0; i < n; i++)
printf("v[%d] = %g\n", i, v[i]);
}

Aplicație rezolvată 14. Programul următor numără aparițiile fiecărei cifre (0, 1, 2, … , 9) a caracterelor spații
albe (blank, tab, LF) și a tuturor celorlalte caractere. Sunt 12 categorii de intrări: utilizăm un vector care să
memoreze numărul de apariții ale fiecărei cifre (ndigit[10]) și două variabile simple (nwhite, nother) care să
memoreze numărul de apariții a caracterelor albe, respectiv numărul de apariții a celorlalte caractere.

#include <stdio.h> /* count digits, white space, others */


main()
{ 
int c, i, nwhite, nother;
int ndigit[10];
nwhite = nother = 0;
for (i = 0; i < 10; ++i)
ndigit[i] = 0;
while ((c = getchar()) != EOF)
if (c >= '0' && c <= '9')
++ndigit[c-'0'];
else if (c == ' ' || c == '\t' || c == '\n')
++nwhite;
else
++nother;

printf(" digits =");


for (i = 0; i < 10; ++i)
printf(" %d", ndigit[i]);
printf("\n white space = %d \n
other = %d\n",nwhite, nother);
}

Aplicație rezolvată 15*. Scrieți un


program care să afișeze o histogramă a
lungimii cuvintelor citite pe intrare.
#include <stdio.h>
#define MAX_LENGTH 15
#define IN_WORD 1
#define OUT_WORD 0
int main(void)
{
int c, word_in_out;
int word_length[MAX_LENGTH +
1];
int l;
int i, j;
unsigned int max_count;

for (i = 0; i <= MAX_LENGTH; ++i)


word_length[i] = 0;

7
word_in_out = OUT_WORD;
printf("Introduceti cateva cuvinte, la final Ctrl+Z.\n");
while (1) {
c = getchar();
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
if (word_in_out == OUT_WORD) {
l = 0;
word_in_out = IN_WORD;
}
++l;
} else {
if (word_in_out == IN_WORD) {
if (l <= MAX_LENGTH)
++word_length[l - 1];
else
++word_length[MAX_LENGTH];
word_in_out = OUT_WORD;
}
if (c == EOF)
break;
}
}
printf("\nHistograma orizontala:\n\n");
printf(" lungime| numar\n");
printf(" cuvant | aparitii\n");
for (i = 0; i <= MAX_LENGTH; ++i) {
if (i != MAX_LENGTH)
printf(" %2d | ", i + 1);
else
printf(" >%2d | ", MAX_LENGTH);
for (j = 0; j < word_length[i]; ++j)
putchar('+');
putchar('\n');
}
printf("\nHistograma Verticala :\n\n");
max_count = 0;
for (i = 0; i <= MAX_LENGTH; ++i)
if (word_length[i] > max_count)
max_count = word_length[i];
for (i = 0; i < max_count; ++i) {
printf(" %2u | ", max_count - i);
for (j = 0; j <= MAX_LENGTH; ++j)
if (word_length[j] >= max_count - i)
printf(" +");
else
printf(" ");
printf("\n");
}
printf(" ------");
for (i = 0; i <= MAX_LENGTH; ++i)
printf("---");
printf("--\n");
printf(" ");
for (i = 0; i < MAX_LENGTH;)
printf(" %2u", ++i);
printf(" >%2u", MAX_LENGTH);
printf("\n");
return 0;
}
Aplicaţie propusă 13*. Modificați programul de la
Aplicația rezolvată 15 astfel încât afișarea să fie
reprezentată de două coloane, pe prima coloană să fie
8
lungimea cuvintelor citite pe intrare, iar pe a doua numărul de cuvinte de acea lungime.
Aplicaţie rezolvată 16*. Scrieţi un program care să afişeze o histogramă a frecvenţei diferitelor caractere citite
pe intrare.
#include <stdio.h>
#define NUMCHARS 128 /* numarul de caractere in codul ASCII-I */

int main(void)
{
int i,c, chars[NUMCHARS];

for (c = 0; c < NUMCHARS; ++c)


chars[c] = 0;

while ((c = getchar()) != EOF)


chars[c] += 1;

/* histograma orizontala */
for (c = 0; c < NUMCHARS; ++c) {
if (chars[c] > 0) {
if (c == '\n') /* new line*/
printf("\\n");
else if (c == '\t') /* tab */
printf("\\t");
else /* toate celelalte caractere */
printf("%2c", c);
/* cod ASCII & frecventa */
printf(" (%3d): %3d |", c, chars[c]);
for(i=1;i<=chars[c];i++) printf("+");
printf("\n");
}
}
return 0;
}

Aplicație propusă 14*. Modificați programul de la


Aplicație rezolvată 16 pentru a afișa pe două coloane:
1. codul ASCII al caracterelor apărute pe intrare și
2. numărul de apariții al acelui caracter.

Aplicație propusă 15*. Modificați programul de la Aplicație


rezolvată 16 pentru a afișa pe trei coloane:
1. caracterele apărute pe intrare,
2. codul ASCII corespunzător fiecărui caracter şi
3. numărul de apariții al acelui caracter.

VI. APLICAȚII cu numere

Aplicație rezolvată 17. Se citește un număr n natural nenul. Să se afișeze cifrele sale începând cu cifra cea mai
puțin semnificativă (cifra unităților). Exemplu: n = 9301 => 1 0 3 9
#include <stdio.h>
main() /* cifrele unui numar */
{
int n, c;
printf("numarul este = "); scanf("%d", &n);
while (n > 0) {
c = n % 10;
printf("cifra = %d\n", c);
n = n / 10;
}

9
}
Aplicație propusă 16. Se citește n număr natural nenul. Afișați cifrele sale pare începând cu cifra cea mai puțin
semnificativă. Exemplu: n = 2518 => 8 2 Indicație: instrucțiunea printf("cifra = %d\n", c); se va
înlocui cu if (c%2 == 0) printf("cifra = %d\n", c);

Aplicație propusă 17. Același enunț, dar să se afișeze cifrele impare. Exemplu: n = 2518 => 1 5

Aplicație rezolvată 18. Se citește un număr n natural. Să se afișeze suma cifrelor sale. Exemplu: n = 9201 =>
s = 12 (1+0+2+9)
#include <stdio.h>
main() /* suma cifrelor unui numar natural */
{
int n, s, c;
printf("numarul este = "); scanf("%d", &n);
s = 0;
while (n > 0) {
c = n % 10;
s = s + c;
n = n / 10;
}
printf(" suma cifrelor = %d\n", s);
}

Aplicație propusă 18. Se citește un număr n natural. Să se afișeze produsul cifrelor sale. Exemplu: n = 5231
=> p = 30 (5*2*3*1)

Aplicație rezolvată 19. Aflați cifra maximă a unui număr n natural dat. Exemplu: n = 3901 => max = 9
#include <stdio.h>
main()
{/* cifra maxima a unui numar natural */
int n, max, c, temp;
printf("numarul este = "); scanf("%d", &n);
temp = n;
max = 0;
while ( temp != 0 ) {
c = temp % 10;
if ( max < c )
max = c;
temp = temp / 10;
}
printf("cifra maxima din %d este = %d\n", n, max);
}

Aplicație propusă 19. Aflați cifra minimă a unui număr n natural dat. Exemplu: n = 3937 => min = 3

Aplicație rezolvată 20. Se dă un număr natural n de minim două cifre. Să se determine cel mai mare număr
format din cifra minimă și cea maximă a acestuia. Exemplu: n = 2725 => maxim = 72 (cifra maximă = 7, cifra
minimă = 2)
#include <stdio.h>
main() { /* cifra minimă si maxima a unui numar natural */
int n, cif_max = 0, cif_min = 9, c, max;
printf("n = "); scanf("%d",&n);
while( n != 0 ){
c = n % 10;
if(c > cif_max)
cif_max = c;
if(c < cif_min)
cif_min = c;
n = n /10;
}
max = cif_max * 10 + cif_min;
printf("maxim = %d \n", max);
10
}
Aplicație propusă 20. Se dă un număr natural n de minim două cifre. Să se determine cel mai mic număr
format din cifra minimă și cea maximă a acestuia. Exemplu: n = 3931 => minim = 19

Aplicație rezolvată 21. Se citesc pe intrare cele n (n  0, natural) cifre ale unui număr de la cifra cea mai
semnificativă până la cifra cea mai puțin semnificativă. Formați numărul din cifrele sale și afișați-l. Exemplu:
numarul de cifre = 5, cifra = 2, cifra = 3, cifra = 1, cifra = 9, cifra = 7 => numarul = 23179

#include <stdio.h> /* formarea unui număr din cifrele sale */


main()
{
int c, n, x, i;
x = 0;
printf("Cate cifre are numarul? = "); scanf("%d", &n);
for ( i = 1; i <= n; ++i ){
printf("cifra %d este = ", i); scanf("%d", &c);
x = x * 10 + c;
}
printf("numarul format din cifrele sale este = %d\n", x);
}

Aplicație propusă 21. Același enunț, dar scrieți o implementare echivalentă a algoritmului în limbajul C
folosind instrucțiunea while() în loc de for(). Indicație: în loc de: for(i=1; i<=n; ++i){...}. Se va scrie:
i=1; while(i<=n){... ++i;}

Aplicație propusă 22. Rescrieți programul cu while() eliminând variabila i. Indicație: în loc de:
i = 1; while ( n-- ){
while ( i <= n ){ printf("cifra = "); scanf("%d", &c);
... se va scrie: x = x * 10 + c;
++i; }
}

Aplicație propusă 23. Rescrieți programul anterior cu while() fără variabila i, înlocuind while() cu for().
Indicație: în loc de:

while ( n-- ){ for ( ; n--; ){


printf("cifra = "); scanf("%d", &c); se va printf("cifra = "); scanf("%d", &c);
x = x * 10 + c; scrie: x = x * 10 + c;
} }

Aplicație rezolvată 22. Se citește un număr întreg n. Să se afișeze numărul inversat (oglindit).
Exemplu: n = 174 => 471
#include <stdio.h>
main()
{ /* inversarea unui numar natural */
int n, invers, temp;
printf("numarul de inversat = "); scanf("%d", &n);
temp = n;
invers = 0;
while ( temp != 0 ){
invers = invers * 10 + temp % 10;
temp = temp / 10;
}
printf("inversul lui %d este = %d\n", n, invers);
}

11
Aplicație rezolvată 23. Se citește un număr întreg n. Să se verifice dacă numărul este palindrom (i.e. este egal
cu inversul său). Exemple: n = 174 => nu este palindrom; n = 17471 => palindrom
#include <stdio.h> /* verificare palindrom */
main()
{
int n, invers = 0, temp;
printf("Introduceti nr ce trebuie verificat ca e sau nu palindrom\n");
scanf("%d",&n);
temp = n;
while ( temp != 0 ) {
invers = invers * 10 + temp%10;
temp = temp / 10;
}
if ( n == invers )
printf("%d este palindrom\n", n);
else
printf("%d nu este palindrom\n", n);
}

REZOLVĂRI

Aplicaţie propusă 1. Modificați programul de la Aplicația rezolvată 1 astfel încât ieșirea lui să afișeze un
antet Fahrenheit Celsius la cele două coloane.
#include <stdio.h>
/* print Fahrenheit-Celsius table for fahr = 0, 20, ..., 300; floating-point version */
main()
{
float fahr, celsius;
float lower, upper, step;
lower = 0; /* lower limit of temperature scale */
upper = 300; /* upper limit */
step = 20; /* step size */
fahr = lower;
printf("Fahrenheit Celsius\n");
while (fahr <= upper) {
celsius = (5.0/9.0) * (fahr-32.0);
printf("%3.0f %15.1f\n", fahr, celsius);
fahr = fahr + step;
}
}

Aplicaţie propusă 2. Scrieţi un program care să afişeze tabelul corespondenţelor


temperaturilor de la scara Celsius la scara Fahrenheit folosind formula:
F˚ = C˚ * (9/5) + 32
#include <stdio.h>
/* print Celsius-Fahrenheit table for celsius = 0, 20, ..., 300 */
main()
{
float fahr, celsius;
float lower, upper, step;
lower = 0.; /* lower limit of temperature scale */
upper = 300.; /* upper limit */
step = 20.; /* step size */
celsius = lower;
printf("Celsius Fahrenheit\n");
while (celsius <= upper) {
fahr = celsius * (9./5.) + 32.;
printf("%3.0f %15.1f\n", celsius, fahr);
celsius = celsius + step;
}
}

12
Aplicație propusă 3. Scrieți un program care să citească și să afișeze o dată calendaristică în forma: 25 dec
2016.
#include
<stdio.h>

main()
{
int zi, an;
char luna[20];

printf("Introduceti data calendaristica in format (12 dec 2016) = ");


scanf("%d %s %d", &zi, luna, &an);
printf("ziua = %d\n", zi);
printf("luna = %s\n", luna);
printf("anul = %d\n", an);
}

Aplicație propusă 4. Scrieți un program care să citească și să afișeze o dată calendaristică în forma: zz/ll/aa.
#include
<stdio.h>

main()
{
int zi, luna, an;

printf("Introduceti data calendaristica in format (25/12/2016) = ");


scanf("%d/%d/%d", &zi, &luna, &an);
printf("ziua = %d\n", zi);
printf("luna = %d\n", luna);
printf("anul = %d\n", an);
}

Aplicație propusă 5. Modificați corespunzător programul pentru a afișa tabela conversiei


temperaturilor din scara Fahrenheit în scara Celsius în ordine inversată, de la 300˚F la 0˚F.
#include <stdio.h>
main()/* print reverse Fahrenheit-Celsius table */
{
int fahr;
for (fahr = 300; fahr >= 0; fahr = fahr - 20)
printf("%3d %6.1f\n", fahr, (5.0/9.0)*(fahr-32));
}

Aplicație propusă 6. Scrieți un program în care verificați că expresia getchar() != EOF este 0 sau 1.
#include <stdio.h>
main()
{
printf("Tastati un caracter, el poate fi ^Z == EOF sau altceva \n" );
printf("Valoare expresie (getchar() != EOF) = %d \n", getchar() != EOF );
}

Aplicație propusă 7. Scrieţi un program pentru a afișa


valoarea lui EOF.
#include <stdio.h>
main()
{
printf("Varianta 1 cu afisarea tastarii lui EOF \n \n" );
printf("Tastati ^Z == EOF \n" );

13
printf("Valoare EOF = %d \n", getchar() );

printf("\n\nVarianta 2 cu afisarea lui EOF \n\n" );


printf("Valoare EOF = %d \n", EOF);

Aplicaţia propusă 8: Scrieți un program care să numere blank-urile (’ ’), tab-urile (’\t’) şi newline-urile
(’\n’).
#include <stdio.h>
main(void)
{
int c, bl, tl, nl;
bl = 0;
tl = 0;
nl = 0;

printf("Introduceti caractere cu spatii, tab-uri si Enter, pentru finalizare:


Ctrl+Z.\n");
while ((c = getchar()) != EOF)
if (c == ' ')
++bl;
else if (c == '\t')
++tl;
else if (c == '\n')
++nl;

printf("Nr blank-uri= %d, Nr tab-uri= %d, Nr newline-uri= %d.\n", bl, tl, nl);

Aplicaţia propusă 9: Scrieți un program care să copieze intrarea sa pe ieșirea sa, înlocuind fiecare șir de
caractere de unul sau mai multe blank-uri cu un singur blank.

#include <stdio.h>
main(void)
{
int c, nr_blank;
nr_blank = 0;
printf("Introduceti caractere cu spatii intre ele, pentru finalizare: Ctrl+Z.\n");
while ((c = getchar()) != EOF)
if (c == ' ') {
if (!nr_blank) {
nr_blank = 1;
putchar(c);
}
} else {
nr_blank = 0;
putchar(c);
}
}

Aplicaţia propusă 10: Scrieți un program care să copieze intrarea sa pe ieșirea sa, înlocuind fiecare tab prin
\t, fiecare blank prin \b şi fiecare backslash prin \\. Acest program va determina vizualizarea tab-urilor şi
blank-urilor într-un mod clar.

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

while ((c = getchar()) != EOF) {


if (c == '\t') {
14
putchar('\\');
c = 't';
}
if (c == ' ') {
putchar('\\');
c = 'b';
}
if (c == '\\') {
putchar('\\');
c = '\\';
}
putchar(c);
}
}

Aplicaţia propusă 11: Cum ați testa corectitudinea programului de mai sus? Ce tipuri de intrări sunt cele mai
susceptibile de a descoperi bug-uri dacă există ?

Tipurile de intrări cele mai susceptibile de a descoperi bug-uri dacă există sunt:
- intrări de lungime zero;
- intrări mai lungi decât valoarea maximă a unui int;
- intrări cu cuvinte de lungime 1.

Aplicaţia propusă 12: Scrieți un program care afișează intrările sale sub forma unui cuvânt pe câte o linie.

#include <stdio.h>
main(void)
{
int c, linestart;

linestart = 0;
printf("Introduceti cuvinte cu spatii si taburi intre ele, pt oprire: Ctrl+Z.\n");
while ((c = getchar()) != EOF)
if (c == ' ' || c == '\t' || c == '\n') {
if (!linestart) {
putchar('\n');
linestart = 1;
}
} else {
putchar(c);
linestart = 0;
}
}

Aplicaţie propusă 13. Modificați programul de la Aplicația rezolvată 15 astfel încât afișarea să fie reprezentată
de două coloane, pe prima coloană să fie lungimea cuvintelor citite pe intrare, iar pe a doua numărul de cuvinte
de acea lungime.
#include <stdio.h>
#define MAX_LENGTH 15
#define IN_WORD 1
#define OUT_WORD 0
int main(void)
{
int c, word_in_out;
int word_length[MAX_LENGTH + 1];
int l;
int i, j;
unsigned int max_count;

for (i = 0; i <= MAX_LENGTH; ++i)


word_length[i] = 0;

word_in_out = OUT_WORD;
printf("Introduceti cateva cuvinte, la final Ctrl+Z.\n");
15
while (1) {
c = getchar();
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
if (word_in_out == OUT_WORD) {
l = 0;
word_in_out = IN_WORD;
}
++l;
} else {
if (word_in_out == IN_WORD) {
if (l <= MAX_LENGTH)
++word_length[l - 1];
else
++word_length[MAX_LENGTH];
word_in_out = OUT_WORD;
}
if (c == EOF)
break;
}
}

printf(" lungime| numar\n");


printf(" cuvant | aparitii\n");
for (i = 0; i <= MAX_LENGTH; ++i) {
if (i != MAX_LENGTH)
printf(" %2d | ", i + 1);
else
printf(" >%2d | ", MAX_LENGTH);
printf("%d\n", word_length[i]);
}

return 0;
}

Aplicație propusă 14. Modificați programul de la Aplicație rezolvată 16 pentru a afișa pe două coloane:
1. codul ASCII al caracterelor apărute pe intrare şi
2. numărul de apariții al acelui caracter.
#include <stdio.h>
#define NUM_CHARS 128
#define IN_WORD 1
#define OUT_WORD 0

int main(void)
{
int c;
int char_frequencies[NUM_CHARS + 1];
int i;

for (i = 0; i <= NUM_CHARS; ++i)


char_frequencies[i] = 0;

printf("Introduceti caractere, finalizare Ctrl+Z.\n");


while ((c = getchar()) != EOF)
++char_frequencies[c];

printf("\n Cod ASCII | Nr aparitii\n");


for (i = 0; i <= NUM_CHARS; ++i)
if (char_frequencies[i] > 0)
printf(" %5d : %5d\n", i, char_frequencies[i]);

return 0;
}

Aplicație propusă 15. Modificați programul de la Aplicație rezolvată 16 pentru a afișa pe trei coloane:
1. caracterele apărute pe intrare,
2. codul ASCII corespunzător fiecărui caracter și
16
3. numărul de apariții al acelui caracter.
#include <stdio.h>
#define NUMCHARS 128 /* numarul de caractere in codul ASCII-I */

int main(void)
{
int i,c, chars[NUMCHARS];

for (c = 0; c < NUMCHARS; ++c)


chars[c] = 0;

while ((c = getchar()) != EOF)


chars[c] += 1;

printf("\nCaracter | Cod ASCII | Nr aparitii\n");


for (c = 0; c < NUMCHARS; ++c) {
if (chars[c] > 0) {
if (c == '\n') /* new line*/
printf(" \\n");
else if (c == '\t') /* tab */
printf(" \\t");
else /* toate celelalte caractere */
printf(" %2c", c);
/* cod ASCII & frecventa */
printf(" | %3d | %3d", c, chars[c]);
printf("\n");
}
}
return 0;
}

17

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