Documente Academic
Documente Profesional
Documente Cultură
PROGRAMARE
antet
corpul funcţiei
funcţie funcţie
apelantă apelată
apel functie
9 Programarea în limbajul C
Exemplul 1.1
Primul program C
#include ”stdio.h”
void main(void)
{
printf(”\nPrimul program C!”);
}
Se observă că programul este alcătuit dintr-o singură funcţie, funcţia main() şi foloseşte funcţia
standard printf() cu prototipul în ”stdio.h”.
11 Programarea în limbajul C
TESTE DE CONTROL
a) Niklaus Wirth
b) Dennis Ritchie
c) Brian Kernighan
1.3 În C, o funcţie:
1.5 În C, o funcţie:
RĂSPUNSURI
LFABETUL LIMBAJULUI
Observaţii:
· Tab orizontal înseamnă saltul cursorului cu un număr de coloane,
iar tab vertical saltul cursorului cu un număr de linii.
· Notaţia octală foloseşte cifre în baza 8 (adică 0,1,2,3,4,5,6,7), iar
notaţia hexazecimală cifre în baza 16 (adică 0,1,2,3,4,5,
6,7,8,9,A,B,C,D,E,F). Se observă că literele A,B,C,D,E,F corespund
respectiv numerelor 10,11,12,13,14,15. Secvenţele ”\ddd” permit
scrierea oricărui caracter din setul ASCII
ca un număr octal format din trei cifre, iar secvenţele ”\xdd” ca un
număr hexazecimal format din două cifre. De exemplu, caracterul
backspace poate fi scris ca ”\010” sau ”\x08”.
Capitolul 2 – Elemente de bază ale limbajului C 13
OCABULARUL LIMBAJULUI
· identificatori (nume)
· constante
· operatori
· semne de punctuaţie
· simboluri special
IDENTIFICATORI
CONSTANTE
OPERATORI
! NOT logic
& adresă, +I pe bit
* indirectare, înmulţire
/ împărţire
+ adunare
- scădere, negaţie aritmetică
<< deplasare logică pe bit la stînga
>> deplasare logică pe bit la dreapta
== egalitate
!= neegalitate
< mai mic
> mai mare
<= mai mic sau egal cu
>= mai mare sau egal cu
^ SAU exclusiv pe bit
ô SAU pe bit
&& +I logic
|| SAU logic
?: operator condiţional
= atribuire simplă
op= atribuire compusă
% modul
, virgula (operator de secvenţiere)
SEMNE DE PUNCTUAŢIE
SIMBOLURI SPECIALE
Exemplu:
/*
Acest program calculeaza produsul a doua matrici. Matricile de
intrare A(4x3) si B(3x2) se citesc de la tastatura, iar matricea produs
rezultata este C(4x2).
*/
Comentariile nu pot fi imbricate (incluse unul în altul). De
exemplu, următoarea construcţie este eronată:
/* Un comentariu care include
/* un comentariu inclus */
*/
Modul în care sunt aranjaţi atomii lexicali într-un program este
impus de specificul problemei şi de regulile de sintaxă ale limbajului.
Capitolul 2 – Elemente de bază ale limbajului C 19
TESTE DE CONTROL
2.4 În C există:
a) o constantă în bază 10
b) o constantă în bază 8
c) o constantă în bază 16
a) un identificator
b) o constantă hexazecimală
c) şi una şi alta
a) un şir
b) un caracter
2.10 Secvenţa
’Citirea matricii A’
reprezintă:
a) un şir
b) un comentariu
c) nici una, nici alta
2.11 Construcţiile
’a’
şi
”a”:
a) reprezintă acelaşi lucru
b) reprezintă un şir, respectiv un caracter
c) reprezintă un caracter, respectiv un şir
RĂSPUNSURI
N-1 N-2 ^ 1 0
Observaţii:
Exemplu:
const double pi=3.1415926536;
const ore_zi=24;
unde:
· sir_format poate conţine: mesaje pentru utilizator,
secvente escape şi descriptori de format pentru valorile
care se afişează;
· lista_de_argumente reprezintă variabile sau expresii al
Precizări:
Descriptori Utilizare
%u
numere întregi zecimale fără semn
%d sau %i numere întregi zecimale cu semn
%c
caracter
%f
numere reale în notaţie uzuală
%e sau % E numere reale în notaţie ştiinţifică
(e sau E)
%x sau %X hexazecimal fără semn (litere mici sau
majuscule)
%o
octal fără semn
%s
şir de caractere
%g sau %G se alege reprezentarea cu numărul
cel mai mic de caractere dintre cea în
notaţie uzuală şi cea în notaţie
30
Capitolul 3 - Expresii în C. Funcţii de intrare/ieşire uzuale pentru consolă
cu litere mari.
Dacă se foloseşte %e litera ”e” din notaţia ştiinţifică apare
ca e, iar dacă se foloseşte %E, apare ca majusculă (litera E).
Valorile de tip long int se afişează utilizând
%ld,%li,%lu,%lo sau %lx.
void main(void)
{
int x=10, y=-43;
printf ("\n\tx=%d\t\y=%d\n\t suma=%i", x,y, x+y);
}
32
Capitolul 3 - Expresii în C. Funcţii de intrare/ieşire uzuale pentru consolă
void main(void)
{
const x=4529;
printf("\n numarul este=%d\n",x);
printf("\n valoarea in octal este=%o",x);
printf("\n valoarea in hexazecimal este=%x",x);
}
void main(void)
{
char a='Q';
printf("\n caracterul %c are codul ASCII=%i\a",a,a);
}
33
Capitolul 3 - Expresii în C. Funcţii de intrare/ieşire uzuale pentru consolă
void main(void)
{
char ch;
short k;
int i;
long int j;
float x;
clrscr();
ch='A';
printf("\n Caracterul %c are codul ASCII = %i",ch,ch);
/* Caracterul A are codul ASCII = 65 */
k=250;
printf("\n k=%hu",k); /* k=250 */
i=4567;
printf("\n i=%i",i); /* i=4567 */
printf("\n i=%u",i); /* i=4567 */
printf("\n -i=%i",-i); /* -i=-4567 */
printf("\n i=%i",i); /* i=4567 */
printf(" are valoarea hexazecimala %x",i);
/* are valoarea hexazecimala 11d7 */
printf(" sau echivalent, %X",i);
/* sau echivalent, 11D7 */
printf("\n i=%i",i); /* i=4567 */
printf(" are valoarea octala %o",i);
/* are valoarea octala 10727 */
j=123456;
printf("\n j=%li",j); /* j=123456 */
x=76.5432;
printf("\n x=%f",x); /* x=76.543198 */
printf("\n x=%e",x); /* x=7.65320e+01 */
printf("\n x=%E",x); /* x=7.65320E+01 */
printf("\n x=%g",x); /* x=76.543200 */
printf("\n x=%G",x); /* x=76.543200 */
x=-0.123456789;
printf("\n x=%f",x); /* x=-0.123457 */
printf("\n x=%e",x); /* x=-1.234568e-01 */
printf("\n x=%E",x); /* x=-1.234568E-01 */
printf("\n x=%g",x); /* x=-0.123457 */
printf("\n x=%G",x); /* x=-0.123457 */
printf("\n %s","testare");
}
34
Capitolul 3 - Expresii în C. Funcţii de intrare/ieşire uzuale pentru consolă
void main(void)
{
int i;
float x;
i=4567;
printf("\n i=%4i",i); /* i=4567 */
printf("\n i=%6i",i); /* i= 4567 */
printf("\n i=%3i",i); /* i=4567 */
printf("\n i=%06i",i); /* i=004567 */
x=76.123001;
printf("\n x=%10f",x); /* x= 76.123001 */
printf("\n x=%010f",x); /* x=076.123001 */
void main(void)
{
int i;
double x;
i=4567;
printf("\n i=%3.7i",i); /* i=0004567 */
printf("\n i=%7.3i",i); /* i= 4567 */
printf("\n i=%-7.3i",i); /* i=4567 */
x=76.123401;
printf("\n x=%10.3f",x); /* x= 76.123 */
printf("\n x=%-10.3f",x); /* x=76.123 */
printf("\n x=%3.7f",x); /* x=76.1234010 */
printf("\n x=%10.2e",x); /* x= 7.61e+01 */
printf("\n x=%-10.1E",x); /* x=7.6E+01 */
printf("\n x=%10.3g",x); /* x= 76.1 */
printf("\n x=%-10.4G",x); /* x=76.12 */
printf("\n %.4s","testare"); /* test */
printf("\n %10.4s","testare"); /* test */
printf("\n %-10.4s","testare");/* test */
printf("\n %-1.10s","testare");/* testare */
}
unde:
· sir_format poate conţine descriptori de format, caractere
void main(void)
{
float x,X;
printf("\n Tastati doua numere separate prin spatiu ");
scanf("%f %f",&x,&X);
X=X*x;
printf("\n Produsul X*x este = %e", X);
}
Observaţii:
#include "stdio.h"
#include "conio.h"
void main(void)
{
char x;
printf("\n Tastati o litera! ");
x=getche();
printf("\n Multumesc! Ati tastat litera ");
putch(x);
getch();
}
PERATORI. CLASIFICARE
CLASE DE PRECEDENŢĂ
x=y=z=s=0;
De exemplu,
expresia y=++x; e echivalentă cu secvenţa x=x+1;
y=x;
iar
expresia y=x++; e echivalentă cu secvenţa y=x;
x=x+1;
Să observăm că cele două secvenţe vor produce aceeaşi
valoare pentru x şi valori diferite pentru y.
Folosirea operatorilor de incrementare şi decrementare
este recomandabilă nu doar din raţiuni de simplificare a scrierii
programelor ci şi datorită faptului că majoritatea
compilatoarelor C generează coduri obiect foarte rapide în
astfel de cazuri.
înlocuieşte secvenţa
w=x<y;
z=x+y;
OPERATORI ARITMETICI
următoarele observaţii:
52
Capitolul 3 - Expresii în C. Funcţii de intrare/ieşire uzuale pentru consolă
void main(void)
{
float x=0, y=2.3;
printf("\n x<y are valoarea %d",x<y) ; /*1*/
printf("\n x<=y are valoarea %d",x<=y); /*1*/
printf("\n x>y are valoarea %d",x>y) ; /*0*/
printf("\n x>=y are valoarea %d",x>=y); /*0*/
printf("\n x==y are valoarea %d",x==y); /*0*/
printf("\n x!=y are valoarea %d",x!=y); /*1*/
getch();
}
! NU logic
&& SI logic
|| SAU logic
54
Capitolul 3 - Expresii în C. Funcţii de intrare/ieşire uzuale pentru consolă
Observaţii:
Observaţii:
Exemplu:
stânga
i
variabila >> numar intreg, pentru deplasare la
dreapta.
Aici, numar_intreg se referă la numărul de poziţii cu care
vor fi deplasaţi spre stânga, respectiv spre dreapta biţii
variabilelor.
Deplasarea biţilor spre un capăt sau altul poate produce
pierderea unui număr de biţi de la respectiva extremitate. Cu
ce se completează biţii rămaşi liberi?
Dacă deplasarea este spre stânga, biţii liberi din dreapta
se completează cu 0.
60
Capitolul 3 - Expresii în C. Funcţii de intrare/ieşire uzuale pentru consolă
Exemplu:
TESTE DE CONTROL
3.3 Declaraţiile
char x;
şi
signed char x;
a) sunt echivalente
b) sunt greşite
c) sunt corecte
65
Capitolul 3 - Expresii în C. Funcţii de intrare/ieşire uzuale pentru consolă
3.4 Declaraţiile
short int x;
şi
int x;
a) sunt echivalente
b) sunt greşite
c) sunt corecte
3.5 Declaraţia
float x,y;
a) este echivalentă cu float x;float y;
b) este greşită
c) este echivalentă cu x,y:float;
d) este echivalentă cu real x,y;
c) este greşită
b) este greşită
c) afişează i=%10,j=%20
c) este greşită
c) afişează x=10.50000
a) unari, binari
b) unari, binari, ternari
c) unari, binali, termali
a) numai unari
b) numai binari
c) unari sau binari
71
Capitolul 3 - Expresii în C. Funcţii de intrare/ieşire uzuale pentru consolă
A=B*b;
V=A*h;
3.30 Expresia
x+=1;
a) este greşită
b) este corectă şi echivalentă cu x=x+1;
c) este corectă şi echivalentă cu x++;
d) este corectă şi echivalentă cu ++x;
3.31 Expresia
y=--x;
a) este greşită
b) este corectă şi echivalentă cu secvenţa
x=x-1;
y=x;
73
Capitolul 3 - Expresii în C. Funcţii de intrare/ieşire uzuale pentru consolă
3.32 Expresia
y=x--;
a) este greşită
b) este corectă şi echivalentă cu secvenţa
x=x-1;
y=x;
c) este corectă şi echivalentă cu secvenţa
y=x;
x=x-1;
a) a<b||c>d
b) a<(b||c)>d
c) c>d||a<b
3.36 În secvenţa de program
int x=3,y=4,a,b,z;
scanf(”%i %i”,&a,&b);
z=(y>x)||(a<b);
variabila z va lua
a) o valoare nedefinită
b) valoarea 1
c) o valoare care depinde de a şi b
variabila z va lua
a) o valoare nedefinită
b) valoarea 0
c) o valoare care depinde de a şi b
a) x ia valoarea 7
b) y ia valoarea 7
c) z ia valoarea 7
75
Capitolul 3 - Expresii în C. Funcţii de intrare/ieşire uzuale pentru consolă
a) a|b ia valoarea 1
b) a&b ia valoarea 1
c) a^b ia valoarea 0
d) ~a ia valoarea 0
a) a|b ia valoarea 1
b) a&b ia valoarea 0
c) a^b ia valoarea 1
d) ~b ia valoarea 1
a) ~i
b) 1-i
3.44 Complementul faţă de 2 al numărului întreg i se obţine
ca:
a) ~i+1
b) ~i-1
c) 2-i
3.45 Operaţia x<<3 echivalează cu:
a) o înmulţire a lui x cu 3
b) o împărţire a lui x la 3
c) o înmulţire a lui x cu 23
d) o impărţire a lui x cu 23
a) o înmulţire a lui x cu 2
b) o împărţire a lui x la 2
c) o înmulţire a lui x cu 22
d) o impărţire a lui x cu 22
77
Capitolul 3 - Expresii în C. Funcţii de intrare/ieşire uzuale pentru consolă
RĂSPUNSURI
NSTRUCŢIUNI EXPRESIE
NSTRUCŢIUNI DE DECIZIE
INSTRUCŢIUNEA IF
Instrucţiune_2 Instrucţiune_1
instrucţiunii if.
Capitolul 4 - Instrucţiuni de control ale programului 62
void main(void)
{
float x,y;
printf("\n Introduceti x=");
scanf("%f",&x);
if (x<=0)
printf("\n Calcul imposibil");
else
{
y=sqrt(x);
printf("\n y=%f",y);
}
getch();
}
Observaţii:
· Sintaxa generală a instrucţiunii if cere pe ambele alternative
câte o instrucţiune. În situaţia în care pe o alternativă sunt
necesare mai multe instrucţiuni acestea vor fi grupatecu
ajutorul acoladelor într-o instrucţiune bloc. Astfel, în exemplul
de mai sus, secvenţa
{
y=sqrt(x);
printf("\n y=%f",y);
}
Instrucţiune
void main(void)
{
float x,y,max;
printf("\n x=");
scanf("%f",&x);
printf("\n y=");
scanf("%f",&y);;
max=x;
if (max<y)
max=y;
printf("\n Maximul dintre x=%.2f si y=%.2f
este=%.2f",x,y,max);
getch();
}
void main(void)
{
float x,y;
printf("\n abscisa x=");
scanf("%f",&x);
printf("\n ordonata y=");
scanf("%f",&y);
if (x>=0 && y>=0)
printf("\n Numarul apartine cadranului I");
else if (x<0 && y>=0)
printf("\n Numarul apartine cadranului II");
else if(x<0 && y<0)
printf("\n Numarul apartine cadranului III");
else
printf("\n Numarul apartine cadranului IV");
getch();
}
este echivalentă cu
if(expr)
instructiune;
b) if(x)
if(y)
printf(”\n x si y nenuli”);
else;
else
printf(”\n x nul”);
c) if(x&&y)
Capitolul 4 - Instrucţiuni de control ale programului 68
printf(”\n x si y nenuli”);
else
if(!x)
printf(”\n x nul”);
OPERATORUL CONDIŢIONAL ? :
void main(void)
{
int a,b;
printf("\n a=");
scanf("%i",&a);
printf("\n b=");
scanf("%i",&b);
printf("\n Maximul dintre a=%i si b=%i este
%i",a,b,a<b?b:a);
getch();
}
INSTRUCŢIUNEA SWITCH
unde:
· expresie este expresia selectoare care trebuie să fie
de tip întreg;
· c1,c2,...,cn sunt constante de tip întreg distincte între
ele;
· default este o etichetă opţională;
void main(void)
{
printf("\n Tastati una din literele:a,A,m,M,p,P ");
switch(getch())
{
case 'a':
case 'A':printf("\n Aurel,Ana,Andrei"); break;
case 'm':
case 'M':printf("\n Maria,Mihai,Marin"); break;
case 'p':
case 'P':printf("\n Paula,Petre,Pavel"); break;
default :printf("\n Ati tastat gresit !");
}
getch();
}
NSTRUCŢIUNI ITERATIVE
INSTRUCŢIUNEA WHILE
unde:
· conditie poate fi orice expresie;
Fals
Condiţie
Adevărat
Instrucţiune
Observaţii:
void main(void)
{
int i=0;
printf("\n Tastati un sir:\n");
while (getche()!='\r')
i++;
printf("\n Lungimea sirului =%d",i);
getch();
}
INSTRUCŢIUNEA FOR
contor.
Instrucţiunea for este echivalentă cu secvenţa de
instrucţiuni
initializare
while(conditie)
{
instructiune
actualizare
}
void main(void)
{
float s=0,x;
int i,n;
printf("\n n=");
scanf("%i",&n);
for (i=0;i<n;i++)
{
printf("\n x[%i]=",i);
scanf("%f",&x);
s+=x;
}
printf("\n Suma este =%f",s);
getch();
}
Observaţii:
for(s=0,i=0;i<n;++i)
{
. . . . . .
}
. . . . . .
void main(void)
{
int a,b,c,m,i;
printf("\n Limita de afisare =");
scanf("%i",&m);
printf("\n Termenii sirului Fibonacci < %i\n",m);
printf("\n 1 1 ");
for (i=3,a=b=1,c=2;c<m;i++)
{
printf("%i ",c);
a=b;b=c;
c=a+b;
}
getch();
}
Capitolul 4 - Instrucţiuni de control ale programului 79
Exemple:
INSTRUCŢIUNEA DO-WHILE
Instrucţiune
Adevărat Fals
Condiţie
Observaţii:
Exemplul 4.9.
void main(void
{
float a,b;
char c;
do
{
printf("\n a=");
scanf("%f",&a);
printf("\n b=");
scanf("%f",&b);
printf("\n Suma a+b=%.2f",a+b);
printf("\n Continuati? (d/n) ");
c=getch();
}
while (c == 'D' || c == 'd');
}
Capitolul 4 - Instrucţiuni de control ale programului 83
void main(void)
{
float a,b;
char ch;
printf("\n a=");scanf("%f",&a);
printf("\n b=");scanf("%f",&b);
printf("\n + Adunare");
printf("\n - Scadere");
printf("\n * Inmultire");
printf("\n / Impartire");
printf("\n r Renunta!");
printf("\n Introduceti optiunea dvs:");
do
{
ch=getchar();
switch(ch)
{
case '+' :printf("\n a+b=%.2f",a+b); break;
void main(void)
{
float x;
do
Capitolul 4 - Instrucţiuni de control ale programului 85
{
printf("\n x=");
scanf("\n %f",&x);
}
while (x<0);
printf("\n Radical din x=%.2f este y=%.4f",x,sqrt(x));
getch();
}
void main(void)
{
int i,j;
for (i=1;i<=5;i++)
{
for (j=1;j<=i;j++)
printf("%2d",j);
printf("\n");
};
getch();
}
void main(void)
{
int x,i;
char ch;
do
{
printf("\n x=");
scanf("%i",&x);
while (x)
{
for (i=0;i<5;i++)
printf("%5d",x+i);
printf("\n x=");
scanf("%i",&x);
}
printf("\n Continuati ? (d/n)");
ch=getch();
}
while (ch == 'd' || ch == 'D');
}
NSTRUCŢIUNI DE SALT
INSTRUCŢIUNEA BREAK
void main(void)
{
int i,x;
for (i=0;i<20;i++)
{
x=rand()%20+1;
printf("\n %i. S-a extras numarul %i",i+1,x);
if (x==10) break;
}
getch();
}
Capitolul 4 - Instrucţiuni de control ale programului 89
void main(void)
{
int i,j;
for (i=0;i<10;i++)
{
printf("\n");
for (j=0;j<10;j++)
{
printf("%5d",rand()%10+1);
if (j>=7) break;
}
}
getch();
}
Capitolul 4 - Instrucţiuni de control ale programului 90
INSTRUCŢIUNEA CONTINUE
void main(void)
{
int i,x,s;
for (i=s=0;i<10;i++)
{
printf("\n x=");
scanf("%i",&x);
if (x<=0) continue;
s+=x;
}
printf("\n Suma este=%d",s);
getch();
}
Capitolul 4 - Instrucţiuni de control ale programului 91
INSTRUCŢIUNEA GOTO
EXEMPLUL 4.17
INSTRUCŢIUNEA RETURN
TESTE DE CONTROL
if(y)
y=3;
}
else
y=5;
d) nici una din secvenţele a), b), c)
if(x>=3)
y=sqrt(x-3);
expresie, nu o variabilă.
c) amic
Amare
}
a) afişează 3 2 1 0
b) afişează 3 2 1
c) afişează valorile 0 1 2
d) afişeaza valoarea 3
e) conţine o buclă eternă afişându-se permanent valoarea
0
f) conţine o buclă eternă şi nu afişează nimic
a) este greşită
b) conţine o buclă eternă
c) afişează 1 2 3
do
j=3;
while (j<=4);
{
printf(”%3i”,j);
j++;
}
a) afişează valoarea 3
b) afişează valorile 3 4
b) i=1 j=1
i=1 j=2
i=2 j=1
Capitolul 4 - Instrucţiuni de control ale programului 103
i=2 j=2
c) i=1 j=1
i=2 j=1
i=1 j=2
i=2 j=2
RĂSPUNSURI
ABLOURI UNIDIMENSIONALE
unde:
· tip reprezintă tipul de bază al elementelor indexate;
tabloului.
Capitolul 5 - Tablouri, şiruri de caractere 97
Observaţii:
y[0] componenta_1
y[1] componenta_2
. . . . . . . .
y[9] componenta_10
Capitolul 5 - Tablouri, şiruri de caractere 98
void main(void)
{
int x[50],i,n,c;
/* comutarea elementelor */
for (i=0;i<n/2;i++)
c=x[i];
x[i]=x[n-1-i];
x[n-1-i]=c;
}
/* afisarea elementelor vectorului comutat */
for (i=0;i<n;i++)
printf("\n componenta x[%i] este %i",i,x[i]);
getch();
}
Capitolul 5 - Tablouri, şiruri de caractere 99
ABLOURI MULTIDIMENSIONALE
Observaţii:
#include "stdio.h"
#include "conio.h"
void main(void)
{
int a[10][10],b[10][10],c[10][10];
short i,j,m,n;
for (j=0;j<n;j++)
c[i][j]=a[i][j]+b[i][j];
NIŢIALIZAREA TABLOURILOR
1 2
3 4
5 6
Pentru a sugera modul de iniţializare al tablourilor
multidimensionale se pot folosi acolade despărţitoare în
interiorul listei de valori.
Astfel, matricea a se poate scrie mai sugestiv
int b[3][2]= {
{1, 2},
{3, 4},
{5, 6},
};
În general, iniţializarea elementelor unui tablou
multidimensional se face după regula <ultimul indice variază
cel mai rapid>, care este o generalizare a regulii de memorare
<pe linii>. Astfel, cele douăsprezece componente ale tabloului
b[3][2][2] vor fi iniţializate astfel:
b[0][0][0]=1
b[0][0][1]=2
b[0][1][0]=3
b[0][1][1]=4
b[1][0][0]=5
b[1][0][1]=6
b[1][1][0]=7
b[1][1][1]=8
b[2][0][0]=9
b[2][0][1]=10
b[2][1][0]=11
b[2][1][1]=12
lista de iniţializare.
· Dacă dim=nval_in iniţializarea tabloului decurge normal
după regula de mai sus.
· Dacă dim<nval_in se va produce o eroare, iar dacă
dim>nval_in restul de elemente sunt iniţializate cu zero.
void main(void)
{
int i;
char sir[]="aAbBcCdD";
printf("\n Sirul este: %s",sir);
printf("\n Literele mici din sir sunt: ");
for (i=0;sir[i];i+=2)
printf("%c",sir[i]);
getch();
}
Capitolul 5 - Tablouri, şiruri de caractere 106
CARACTERE
void main(void)
{
char nume[25],prenume[25];
printf("\n Numele=");
scanf("%s",nume);
printf("\n Prenumele=");
scanf("%s",prenume);
printf("\n %s %s",prenume,nume);
getch();
}
void main(void)
{
char min[20],x[20];
printf("\n Introduceti siruri de caractere ! ");
printf("\n La sfarsit tastati STOP \n");
strcpy(min,gets(x));
while (strcmp(x,"stop"))
{
strcmp(min,x)<0 ? min : strcpy(min,x);
gets(x);
}
printf("\n Sirul minim este "); puts(min);
printf("\n si are lungimea %i",strlen(min));
getch();
}
Capitolul 5 - Tablouri, şiruri de caractere 109
TESTE DE CONTROL
5.1 Declaraţia
float x[100];
înseamnă
a) rezervarea în memorie a 100 locaţii la adrese
consecutive
b) rezervarea în memorie a 100 locaţii la adrese
întâmplătoare
c) rezervarea a 100 de octeţi pentru variabila reală x
5.2 Secvenţa de program
int x[m][n],m=3,n=2;
5.7 Iniţializarea
int a[3][2]={1,2,3,4,5,6};
{1,4},
{2,5},
{3,6},
};
5.8 Iniţializarea
float x[2][3]={1,2,3,4,5,6};
este echivalentă cu
a) float x[][]={1,2,3,4,5,6};
b) float x[][3]={1,2,3,4,5,6};
c) float x[2][]={1,2,3,4,5,6};
afişeaz[ mesajul
a) Lungimea sirului=20
b) Lungimea sirului=4
c) Lungimea sirului=5
5.13 Secvenţa de program
char x[]= ”rac”;
char y[]= ”arc”;
printf(”%d”,strcmp(x,y));
afişează o valoare
a) egală cu zero
b) mai mică strict decât zero
c) mai mare strict decât zero
afişează
a) acar
b) arac
5.15 În secvenţa de program
Capitolul 5 - Tablouri, şiruri de caractere 113
char x[20];
x=”Ploiesti”;
atribuirea
x=”Ploiesti”;
a) este greşită
b) este greşită, iar copierea şirului ”Ploiesti” în variabila
x se realizează prin strcpy(x,”Ploiesti”);
c) este corectă
RĂSPUNSURI
PERATORII & ŞI *
void main(void)
{
int x,*x_ptr;
x=10;
x_ptr=&x;
printf("\n Adresa lui x este=%p",&x);
printf("\n Valoarea lui x este=%i",x);
printf("\n Valoarea lui x_ptr=%p",x_ptr);
printf("\n Valoarea lui x=%i",*x_ptr);
getch();
}
free(p);
Observaţii:
CARACTERE
sir poate avea mai multe interpretări: pointer către char, şir de
Observaţii:
orice i=0,1,…,n-1
iar
*(x+i) e echivalent cu x[i]
Capitolul 6 – Pointeri 123
void main(void)
{
int x[7]={1,2,3,4,5,6,7},i,*p,y;
void main(void)
{
int x[7]={1,2,3,4,5,6,7},i,*p,*q,y;
p1=&t[i1];
p2=&t[i2];
atunci
p1-p2 semnifică adresa i1-i2 din tabloul t.
void main(void)
{
int x[]={5,4,3,2,1},*p;
p=x;
printf("\n Valoarea=%i",*p++); /* val=5 */
printf("\n Valoarea=%i",*p); /* val=4 */
p=x;
printf("\n Valoarea=%i",(*p)++); /* val=5 */
printf("\n Valoarea=%i",*p); /* val=6 */
p=x;
printf("\n Valoarea=%i",*++p); /* val=4 */
p=x;
printf("\n Valoarea=%i",++*p); /* val=7 */
getch();
}
Capitolul 6 – Pointeri 126
Pointer Pointer
Adresă Adresă Valoare
Exemplu:
int **p,*q,x;
x=10;
q=&x;
p=&q;
Observaţie:
TESTE DE CONTROL
a) o adresă de memorie
b) o variabilă care poate memora adrese de memorie
c) o zonă de memorie dinamică
atribuirea este:
atribuirea este:
a) corectă
b) incorectă, deoarece pointerul p nu indică nici o locaţie
c) este corectă şi echivalentă cu p=p*x;
a) afişează valoarea 11
b) este greşită, deoarece în expresia
p=q=&x;
p=x;
6.12 Declaraţia
int (*x)[10];
a) este greşită
b) este echivalentă cu
int *x[10];
pointerul p:
a) afişează valoarea 3
b) afişează valoarea 2
Capitolul 6 – Pointeri 134
a) x[i]
b) x+i
c) &x[i]
d) *(x+i)
6.16 Valoarea componentei i a unui tablou x[0],0<=i<=9 se
poate obţine folosind notaţia
a) x[i]
b) x+i
c) &x[i]
d) *(x+i)
RĂSPUNSURI
TRUCTURI
unde:
· nume_camp1,nume_camp2,…,nume_campn sunt nume de
struct rand_tel
{
char nume[15];
char prenume[20];
char adresa[50];
unsigned long int telefon;
}pers1,pers2;
Aici, pers1 şi pers2 sunt nume de variabile care vor avea tipul
struct rand_tel. Această declaraţie este echivalentă cu:
struct rand_tel
{
char nume[15];
char prenume[20];
char adresa[50];
unsigned long int telefon;
};
struct rand_tel pers1,pers2;
este echivalentă cu
strcpy(pers1.nume,pers2.nume);
strcpy(pers1.prenume,pers2.prenume);
strcpy(pers1.adresa,pers2.adresa);
pers1.telefon=pers2.telefon;
/*
programul creaza si afiseaza o lista simplu inlantuita
dintr-un sir de date cu marcatorul de sfirsit 0
*/
void main(void)
{
int x;
struct nod
{
int data;
struct nod *leg;
}*p,*q;
q=NULL;
printf("\nIntroduceti elementele listei\n\a");
printf("\nx=");
scanf("%d",&x);
while (x)
{
p=(struct nod *)malloc(sizeof(struct nod));
p->data=x;
p->leg=q;
q=p;
printf("\nx=");
scanf("%i",&x);
}
void main(void)
{
short i,j,l,n;
struct catalog
{
char npr[30];
short nota;
}stud[30],studint;
Capitolul 7 – Structuri, uniuni, enumerări, declaraţii typedef 138
/* introducerea datelor */
printf("\n n=");
scanf("%i",&n);
for (i=0;i<n;i++)
{
printf("\n Nume=");
scanf("%s",&stud[i].npr);
printf("\n Nota=");
scanf("%i",&stud[i].nota);
}
/* ordonarea alfabetica a catalogului */
for (i=0;i<n-1;i++)
{
l=i;
for (j=i+1;j<n;j++)
strcmp(stud[j].npr,stud[l].npr)<0 ? l=j : l;
studint=stud[i];
stud[i]=stud[l];
stud[l]=studint;
}
CÂMPURI DE BIŢI
tip nume_campn:lungime;
}lista_variabile;
unsigned comp5:1;
unsigned comp6:1;
}stare;
NIUNI
v. i
v. f
Exemplul 7.3.
void main(void)
{
struct biti
{
unsigned prim :1;
unsigned :6;
unsigned ultim:1;
};
union char_bit
{
char x;
struct biti y;
}tasta;
printf("\n Tastati un caracter: ");
tasta.x=getche();
if (tasta.y.prim)
printf("\n Primul bit are valoarea 1");
else
printf("\n Primul bit are valoarea 0");
if (tasta.y.ultim)
printf("\n Ultimul bit are valoarea 1");
else
printf("\n Ultimul bit are valoarea 0");
getch();
}
void main(void)
{
char disci[10],ch;
int i,k,n;
typedef struct lista
{
char disc[10];
int noter;
struct lista *leg;
}list;
list *res;
struct catalog
{
char npr[30];
char tip;
union
{
int nota;
int note[5];
struct lista *resta;
}var;
}stud[30];
/* introducerea datelor */
printf("\nN=");
scanf("%i",&n);
for (i=0;i<n;++i)
{
printf("\nNume Prenume=");
scanf("%s",&stud[i].npr);
do
{
printf("\nTip informatie (m,e,r)=");
ch=getche();
}
while (ch != 'm' && ch != 'e' && ch != 'r');
stud[i].tip=ch;
switch (stud[i].tip)
Capitolul 7 – Structuri, uniuni, enumerări, declaraţii typedef 147
{
case 'm':printf("\nMedia = ");
scanf("%i",&stud[i].var.nota);
break;
case 'e':printf("\nIntroduceti notele \n");
for (k=0;k<5; k++)
{
printf("\nNota[%i]=",k);
scanf("%d",&stud[i].var.note[k]);
}
break;
case 'r':res=NULL;
printf("\nDiscipline restante si note;");
printf(" pentru terminare tastati stop ");
printf("\n Disciplina =");
scanf("%s",disci);
while (strcmp(disci,"stop"))
{
stud[i].var.resta=(list*)malloc(sizeof(list));
strcpy(stud[i].var.resta->disc,disci);
printf("\n Nota restanta=");
scanf("%d",&stud[i].var.resta->noter);
stud[i].var.resta->leg=res;
res=stud[i].var.resta;
printf("\n Disciplina =");
scanf("%s",disci);
}
break;
} /* end switch*/
} /* end for*/
/* afisarea informatiei */
for (i=0;i<n;i++)
{
printf("\nNume Prenume=%s",stud[i].npr);
switch(stud[i].tip)
{
case 'm':printf("\n Media la
examene=%i",stud[i].var.nota);
break;
case 'e':printf("\n Notele la examen sunt: \n");
for (k=0;k<5;k++)
printf("\n
Nota[%i]=%i",k,stud[i].var.note[k]);
break;
case 'r':printf("\n Disciplinele restante
sunt: \n");
res=stud[i].var.resta;
while(res)
Capitolul 7 – Structuri, uniuni, enumerări, declaraţii typedef 148
{
printf("\n Disciplina=%s",res->disc);
printf("\n Nota restanta = %d",
res->noter);
res=res->leg;
}
break;
} /* end switch */
} /* end for */
getch();
}
NUMERĂRI
De exemplu, construcţia
enum culoare culoarea_ta;
void main(void)
{
enum culoare{rosu,alb,verde,albastru} culoarea_mea;
culoarea_mea=alb;
switch (culoarea_mea)
{
case rosu:printf("\n rosu"); break;
case alb:printf("\n alb"); break;
case verde:printf("\n verde"); break;
case albastru:printf("\n albastru"); break;
}
getch();
}
ECLARAŢII TYPEDEF
Exemplu:
typedef short int scurt_in;
typedef struct
{
float re;
float in;
}complex;
typedef enum{false,true}boolean;
sunt compatibile.
De asemenea, se pot folosi mai multe declaraţii typedef
pentru a crea diferite nume noi pentru acelaşi tip, ca în
exemplul următor:
typedef int integer;
typedef integer intreg;
typedef intreg intr;
TESTE DE CONTROL
a) *p.x
b) (*p).x
c) *p.(x)
7.4 Atribuirea informaţiei dintr-o variabilă structură x unei alte
variabile structură y de acelaşi tip se poate face:
a) scriind y=x;
b) atribuind valorile câmpurilor structurii x câmpurilor
corespunzătoare din y
7.6 Structura
struct persoana
{
int salariu;
struct persoana *p;
struct inform
Capitolul 7 – Structuri, uniuni, enumerări, declaraţii typedef 155
{
long int telefon;
char *adresa;
}inf;
}pers;
este:
a) greşită, deoarece câmpul pointer p indică către
structura din care face parte
b) corectă
c) greşită, deoarece structura persoana include o altă
structură (structura inform)
7.8 Structura
struct a
{
int x;
float y[3][2];
}a;
este:
a) incorectă deoarece componentele tabloului maga[5]
sunt de tip struct
b) incorectă deoarece câmpurile pu şi valoare nu sunt
declarate sub forma
float pu;
float valoare;
c) este corectă
7.11 Structura
struct a
{
unsigned adm:1;
int nota;
}elev;
7.12 Structura
struct a
{
unsigned:4;
unsigned x:2;
float y:3;
};
este greşită deoarece
a) primul câmp de biţi nu are nume
b) al treilea câmp de biţi nu este de tip unsigned sau
signed
a) numai la structuri
b) la structuri şi la uniuni
c) numai la uniuni
RĂSPUNSURI
EFINIŢIA FUNCŢIILOR
void mesaj1(int x)
{
if(x)
printf(”\n Ati tastat bine!”);
157 Programarea în limbajul C
else
printf(”\n Ati tastat gresit!”);
}
void mesaj2(void)
{
printf(”\n Intrerupeti executia
programului!”);
}
}
se scrie echivalent în forma clasică
minim(x,y,z)
int x,y,z;
{
instructiuni
}
void main(void)
{
float r;
printf("\n Raza cercului=");
scanf("%f",&r);
printf("\n Aria cercului este %lf",aria(r));
getch();
}
/* prototipul functiei */
float f(float);
void main(void)
{
float y,x;
161 Programarea în limbajul C
printf("\n x=");
scanf("%f",&x);
y=f(x)+2.5;
printf("\n y=%f",y);
getch();
}
/*definitia functiei f */
float f(float x)
{
if (x>0)
return exp(x)+1.45;
else
return sqrt(-x)+2.3;
}
PELUL FUNCŢIILOR
nume_functie(lista_parametri)
unde:
· nume_functie este numele funcţiei care se apelează;
· lista_parametri reprezintă listă de valori actuale sau
efective care vor fi transmise funcţiei. Din acest motiv,
parametrii din lista-parametri se mai numesc actuali sau
efectivi.
La apelul funcţiei, între parametrii actuali şi parametrii formali
se face o corespondenţă poziţională. Parametrii actuali şi formali
situaţi pe poziţii identice trebuie să aibă tipuri identice sau
compatibile. Dacă funcţia apelată nu are prototip, din raţiuni care ţin
de definirea iniţială a limbajului C, se fac implicit următoarele
conversii de tip: char şi short la int, float la double, tablou la
pointer. Dacă funcţia are prototip, tipurile precizate în prototip
rămân neschimbate. În acest caz, compilatorul este de cele mai multe
ori în măsură să sesizeze prompt orice încercare de conversie
nepermisă între tipul parametrilor actuali şi tipul parametrilor formali
corespunzători. De asemenea, compilatorul va sesiza lipsa de
identitate dintre numărul parametrilor actuali şi formali. Conversiile
permise aici sunt cele considerate la operaţiile de atribuire.
Transferul informaţiei între funcţia apelantă şi funcţia apelată
se poate face prin valoare sau prin referinţă.
Transferul prin valoare constă în copierea valorii
parametrului actual în zona de memorie a parametrului formal
corespunzător în momentul efectuării apelului. Practic, la apelul
funcţiei, valoarea parametrului actual va fi depusă în stivă (stack)
odată cu variabilele locale ale funcţiei şi cu adresele de revenire în
funcţia apelantă. Dacă funcţia apelată are prototip, valoarea
parametrului actual se converteşte la tipul parametrului formal
corespunzător indicat în prototip (exact ca în cazul unei atribuiri). În
cazul unei incompatibilităţi între tipuri se semnalează eroare.
Dacă funcţia nu are prototip (lucru nerecomandat), la apelare, tipurile
char şi short sunt convertite la int, float la double, iar tablou la
pointer.
Să remarcăm faptul că, în cazul transferului prin valoare,
valorile parametrilor actuali nu sunt afectate de prelucrările din
163 Programarea în limbajul C
void main(void)
{
int a,b;
a=3;
b=5;
comut1(a,b);
printf("\nRezultate comut1 a=%d,b=%d",a,b);
comut2(&a,&b);
printf("\nRezultate comut2 a=%d,b=%d",a,b);
getch();
}
void comut1(int x,int y)
{
int z=x;
x=y;
y=z;
}
a=3 x=5 a à 5 ß x
b=5 y= 3 b à 3 ß y
suma(int x[4][3]);
void main(void)
{
int a[4][3],i,j,s;
for (j=0;j<3;j++)
{
printf("\n a[%i][%i]=",i,j);
scanf("%d",&a[i][j]);
}
/*
calculul sumei elementelor matricii a
folosind functia suma()
*/
s=suma(a);
/* afisarea sumei */
printf("\n Suma=%d",s);
getch();
}
suma(int x[4][3])
{
int i,j,s=0;
for (i=0;i<4;i++)
for (j=0;j<3;j++)
s+=x[i][j];
return s;
}
void main(void)
{
int a[4][3],i,j,m,n,s;
/* citirea valorilor m si n */
167 Programarea în limbajul C
do
{
printf("\n m=");
scanf("%i",&m);
printf("\n n=");
scanf("%i",&n);
}
while (m<1 || m>4 || n<1 || n>3);
for (i=0;i<m;i++)
for (j=0;j<n;j++)
{
printf("\n a[%i][%i]=",i,j);
scanf("%d",&a[i][j]);
}
/*
calculul sumei elementelor matricii a
folosind functia suma()
*/
s=suma(a,m,n );
/* afisarea sumei */
printf("\n suma=%d",s);
getch();
}
este clar că, la compilare, cea de-a doua dimensiune a matricii trebuie
să fie cunoscută (în cazul nostru e egală cu 3). În consecinţă, un
declarator al funcţiei de forma
suma(int x[][],int m,int n)
este greşit.
void main(void)
{
int a[4][3],i,j,m,n,s;
/* citirea valorilor m si n */
do
{
printf("\n m=");
scanf("%i",&m);
printf("\n n=");
scanf("%i",&n);
}
while (m<1 || m>4 || n<1 || n>3);
/*
calculul sumei elementelor matricii a
folosind functia suma()
*/
169 Programarea în limbajul C
s=suma(a,m,n);
/* afisarea sumei */
printf("\n Suma=%d",s);
getch();
}
void main(void)
{
int x[20],n;
do
{
printf("\n n=");
scanf("%d",&n);
}
while (n<1 || n>20);
citv(x,n);
sortv(x,n);
171 Programarea în limbajul C
afisv(x,n);
getch();
}
void sortv(int x[],int n)
{
int i,k,min,l;
for (i=0;i<n-1;i++)
{
min=x[i];
l=i;
for (k=i+1;k<n;k++)
if (x[k]<min)
{
l=k;
min=x[k];
}
x[l]=x[i];
x[i]=min;
}
}
typedef struct
{
char *nume;
int nota;
}CATALOG;
void main(void)
{
CATALOG x={"Ion",10};
afis(x);
getch();
}
void afis(CATALOG y)
{
printf("\n %s are nota %i",y.nume,y.nota);
}
Exemplul 8.10
Se iniţializează o variabilă structură în main() şi se face
modificarea unui câmp de-al ei în funcţia modi(). Transmiterea se
face prin referinţă.
#include "stdio.h"
#include "conio.h"
typedef struct
{
char *nume;
int nota;
}CATALOG;
void main(void)
{
CATALOG x={"Vasile",8};
printf("\n Mesaj initial: ");
afis(x);
modi(&x);
printf("\n Mesaj modificat: ");
afis(x);
getch();
}
void afis(CATALOG y)
{
printf("%s are nota=%i",y.nume,y.nota);
}
Observaţii:
· Funcţia toupper() are forma generală
int toupper(int c);
şi are ca efect convertirea literei c în literă mare, dacă e cazul.
· Funcţia care converteşte o literă mare în literă mică este
tolower() şi are forma generală:
int tolower(int c);
· În situaţia în care argumentul nu este literă, cele două funcţii
lasă caracterul c neschimbat.
Oricare din membrii unei structuri poate fi transmis unei
funcţii, fie prin valoare, fie prin referinţă.
typedef struct
{
char *nume;
int nota;
}CATALOG;
void main(void)
176 Programarea în limbajul C
{
CATALOG x={"Gheorghe",7};
afis_val(x.nota);
afis_ref(&x.nota);
getch();
}
void afis_val(int y)
{
printf("\n Mesaj afis_val: Nota este=%i",y);
}
OINTERI LA FUNCŢII
void main(void)
{
int i,a=8,b=2;
int (*t[])(int,int)={adunare,scadere,inmultire,
impartire};
char *nume_t[]={"adunare","scadere","inmultire",
"impartire"};
for (i=0;i<4;i++)
{
printf("\n S-a selectat functia %s",nume_t[i]);
printf("\n Rezultatul este %d",(*t[i])(a,b));
}
getch();
}
void main(void)
{
float x;
int a=9,b=4;
printf("\nx=");
scanf("%f",&x);
if (x>0)
f(x,a,b,sum);
else
f(x,a,b,dif);
getch();
}
{
return a-b;
}
UNCŢII RECURSIVE
tip tip
f(lista_declaratii_parametri) g(lista_declaratii_parametri)
{ {
apel g() apel f()
} }
182 Programarea în limbajul C
Stiva
(Stack)
Variabile dinamice
(Heap)
Variabile
globale
Cod program
x
x
V`r f x
{
return(n>1)?n*f(n-1):1;
}
Să considerăm apelul f(4). Acest apel va activa succesiv
instrucţiunea n*f(n-1) pentru n=4,3,2. Pentru fiecare din aceste
apeluri în stivă se vor depune parametrii actuali 4,3,2,1. Apelul
f(1) furnizează rezultatul 1 pentru rezolvarea instrucţiunii amânate
2*f(1), care este valoarea lui f(2).
Cu această valoare se calculează valoarea f(3)=3*f(2) şi în final
valoarea f(4)=4*f(3). Se observă că rezolvarea fiecărui autoapel
înseamnă deplasarea pe un nivel inferior al stivei, adică parcurgerea
în ordine inversă a şirului de parametri actuali 4,3,2,1.
Schematic, la fiecare apel, stiva va arăta succesiv astfel:
ä 1
ä 2 2
ä 3 3 3
ä 4 4 4 4
Stivă vidă Apel f(4) Apel f(3) Apel f(2) Apel f(1)
æ1
2 æ 2
3 3 æ 3
4 4 4 æ 4
f(1)=1 f(2)=1*2 f(3)=1*2*3 f(4)=1*2*3*4 Stiva vidă
Figura 8.4 Stările succesive ale stivei după ieşirea din autoapel
185 Programarea în limbajul C
void main(void)
{
int x=6;
g(x);
getch();
}
void g(int x)
{
if (x)
{
g(x-2);
printf("%2i",x);
}
}
{
int x=6 if(6) if(4) if(2) if(0)
g(6); { { { iesire
din
getch(); g(4); g(2); g(0); autoapel
} printf printf printf
("%i",x) ("%i",x); ("%i",x)
; } ;
} }
a b c
n-1
1
a b c
n-1
n <=> 1
n
188 Programarea în limbajul C
void main(void)
{
int n;
clrscr();
printf("\n Numarul de discuri, n=");
scanf("%i",&n);
TESTE DE CONTROL
a) de tip int
b) de tip float
c) de orice tip diferit de tipul int
8.11 În declaraţia unei funcţii
a) la întâmplare
193 Programarea în limbajul C
b) poziţional
8.17 Parametrii actuali şi formali care au aceeaşi poziţie în lista de
parametri trebuie să aibă obligatoriu
a) acelaşi tip
b) tipuri compatibile
8.18 Transferul informaţiei între funcţia apelantă şi funcţia apelată se
poate face
a) numai prin valoare
b) numai prin referinţă
c) şi prin valoare şi prin referinţă
8.19 Transferul prin valoare constă în
void main(void)
{
int x=7;
f(x);
printf(”\nx= %d”,x);
}
void f(int x)
{
x=10;
}
a) este greşită, deoarece parametrul formal şi actual au acelaşi
nume
b) este corectă şi afişează x=10
c) este corectă şi afişează x=7
194 Programarea în limbajul C
void main(void)
{
int x=7;
f(&x);
printf(”\n x=%d”,x);
}
void main(void)
{
int y[2][4]={1,2,3,4,5,6,7,8},sum;
sum=s(y);
printf(”\n Suma=%d”,sum);
}
s(int x[2][3])
{
int i,sum=0;
for(i=0;i<2;i++)
for(j=0;j<3;j++)
sum+=x[i][j];
return sum;
}
a) este corectă şi afişează suma=24
b) este corectă şi afişează suma=21
c) este incorectă, deoarece parametrul formal x =i parametrul
formal y trebuie să aibă aceeaşi dimensiune
195 Programarea în limbajul C
void main(void)
{
int y[3]={1,2,3},m=3,suma;
suma=s(y,m);
printf(”\n Suma=%d”,sum);
}
s(int x[],int m)
{
int i,sum=0;
for(i=0;i<m;i++)
sum+=x[i];
return sum;
}
a) este greşită, deoarece parametrul formal x nu are precizată
dimensiunea
b) este corectă, deoarece la apel se transmite numele tabloului
(care este pointer către prima componentă a tabloului) şi
dimensiunea sa
196 Programarea în limbajul C
void main(void)
{
int y[2][3]={1,2,3,4,5,6},m=1,n=3;
afis(y,m,n);
}
void main(void)
{
int y[10];
. . . . . .
f(y[2]);
}
void f(int x)
{
int z;
z=x;
. . . . . .
}
197 Programarea în limbajul C
a) este corectă
b) este greşită, deoarece parametrul actual al funcţiei f() este o
componentă de tablou
8.26 Secvenţa de program
void f(int y[2]);
void main(void)
{
int x[2]={3,4};
f(x);
printf(”\n x[0]=%d,x[1]=%d”,x[0],x[1]);
}
8.30 Declaraţiile
float (*p)(float,int);
şi
float *p (float,int);
a) sunt echivalente
b) nu sunt echivalente: prima reprezintă un pointer către o
funcţie de tip float, care are un parametru de tip float şi unul
de tip int, iar a doua reprezintă prototipul funcţiei p() de tip
pointer către float, care are un parametru de tip float şi unul
de tip int
c) sunt corecte
8.31 Secvenţa de program
void f(int x);
void main(void)
{
int x=7;
f(x);
}
void f(int x)
{
printf(”%3i”,x);
if(x)
f(x-1);
}
afişează
a) 7 6 5 4 3 2 1 0
b) 0 1 2 3 4 5 6 7
8.32 Secvenţa de program
void f(int x);
void main(void)
{
int x=7;
f(x);
}
199 Programarea în limbajul C
void f(int x)
{
if(x)
f(x-1);
printf(”%3i”,x);
}
afişează
a) 7 6 5 4 3 2 1 0
b) 0 1 2 3 4 5 6 7
8.33 Secvenţa de program
void f(int x);
void main(void)
{
int x=7;
f(x);
}
void f(int x)
{
f(x-1);
printf(”%3i”,x);
}
a) afişează 7 6 5 4 3 2 1 0
b) afişează 0 1 2 3 4 5 6 7
c) apelează de o infinitate de ori funcţia f()
8.34 Secvenţa de program
void f(void)
{
float x=23.5;
printf(”\n x=%f”,x);
}
void main(void)
{
f();
printf(”\n x=%f”,x);
}
200 Programarea în limbajul C
a) afişează x=23.500000
b) afişează x=23.500000
x=23.500000
c) este greşită, deoarece în main() se utilizează variabila x care
nu este declarată aici
RĂSPUNSURI
void main(void)
{
int n;
printf("\n n=");
scanf("%i",&n);
citeste(n);
getch();
}
void citeste(int n)
{
if (n==1)
{
int x;
printf("\n x=");
scanf("%i",&x);
}
else
{
int x[100],i;
for (i=0;i<n;i++)
{
printf("\n x[%i]= ",i);
scanf("%i",&x[i]);
Capitolul 9 – Clase de memorare pentru variabile 202
}
}
printf("\n S-au alocat %i octeti
",sizeof(int)*n);
}
suma(void);
void main(void)
{
int n,i,y;
printf("\n Numarul de elemente din suma=");
scanf("%i",&n);
for (i=1,y=1;i<n;i++)
y+=suma();
printf("\n Suma primelor %i numere impare este
%i",n,y);
getch();
}
suma(void)
{
static int s=1;
s+=2;
return s;
}
/* variabila globala s */
int s=1;
suma(void); Capitolul 9 – Clase de memorare pentru variabile 206
void main(void)
{
int n,i,y;
printf("\n Numarul de elemente din suma=");
scanf("%i",&n);
for (i=1,y=1;i<n;i++)
y+=suma();
printf("\n Suma primelor %i numere impare
este %i",n,y);
getch();
}
suma(void)
{
s+=2;
return s;
}
#include "stdio.h"
#include "conio.h"
/* variabila globala s */
int s=1;
suma(void);
void main(void)
{
int n,i,y;
printf("\n Numarul de elemente din suma=");
scanf("%i",&n);
for (i=1,y=1;i<n;i++)
Capitolul 9 – Clase de memorare pentru variabile 208
y+=suma();
printf("\n Suma primelor %i numere impare este
%i",n,y);
getch();
}
/* fisierul sum.c */
/* variabila globala s */
extern int s;
suma(void)
{
s+=2;
return s;
}
Exemplul 9.5
#include "stdio.h"
#include "conio.h"
/* variabila globala s */
int s=0;
suma(void);
void init(int);
void main(void)
{
int n,i;
printf("\n Doriti suma primelor numere pare(P)
sau impare(I)? ");
if (toupper(getche()) == 'P' )
init(-2);
else
init(-1);
printf("\n Numarul de termeni ai sumei=");
scanf("%i",&n);
for (i=0;i<n;i++)
Capitolul 9 – Clase de memorare pentru variabile 210
s+=suma();
printf("\n Suma numerelor este %i",s);
getch();
}
/* fisier sum_init.c */
static int s;
suma(void)
{
s+=2;
return s;
}
#include "stdio.h"
#include "conio.h"
/* variabila globala x */
int x=1;
Capitolul 9 – Clase de memorare pentru variabile 211
void main(void)
{
/* variabila locala x */
float x=1.42;
printf("\n x=%.2f",x);
getch();
}
void main(void)
{
float x=4.13;
printf("\n x=%.2f",x);
{
int x=3;
printf("\n x=%i",x);
}
getch();
}
Capitolul 9 – Clase de memorare pentru variabile 212
TESTE DE CONTROL
a) stiva
b) memoria heap
a) register
b) auto
c) extern
RĂSPUNSURI
#include "stdio.h"
#include "conio.h"
/* scrierea fisierului */
printf("\n Tastati un sir de caractere! \n");
while ( (ch=getchar()) != '\n')
putc(ch,f);
fclose(f);
/* Deschiderea fisierului pentru citire */
if ( !(f=fopen(argv[1],"r")) )
{
puts("\n Nu se poate deschide fisierul");
exit(1);
}
void main(void)
{
int n;
char x[200],*fc;
char numefis[11];
FILE *f;
printf("\n Dati numele fisierului: ");
gets(numefis);
printf("\n Dati lungimea liniilor de afisare: ");
Capitolul 10 – Funcţii pentru prelucrarea fişierelor 220
scanf("%i",&n);
if ( (f=fopen(numefis,"a")) == NULL)
{
printf("\n Nu se poate deschide fisierul");
exit(1);
}
printf("\n Adaugati siruri?(d/n)");
if (tolower(getche()) == 'd')
{
printf("\n Tastati siruri caractere despartite
prin Enter,");
printf(" pentru sfarsit tastati cuvantul stop\n");
gets(x);
while (strcmp(x,"stop"))
{
fputs(x,f);
gets(x);
}
fclose(f);
/* afisarea fisierului */
printf("\n Fisierul in linii de %d caractere
este:\n",n);
fc=fgets(x,n+1,f);
while (fc)
{
puts(x);
fc=fgets(x,n+1,f);
}
fclose(f);
}
getch();
}
Capitolul 10 – Funcţii pentru prelucrarea fişierelor 221
void main(void)
{
FILE *f;
int n,i;
typedef struct catalog
{
char nume[15];
char prenume[20];
short nota;
}struc;
struc x;
if ( !(f=fopen("grupa","w")) )
Capitolul 10 – Funcţii pentru prelucrarea fişierelor 222
{
printf("\n Nu se poate deschide fisierul");
exit(1);
}
printf("\n Introduceti numarul de studenti din grupa
");
scanf("%i",&n);
if ( !(f=fopen("grupa","r")) )
{
printf("\n Nu se poate deschide fisierul!");
exit(1);
}
UNCŢIA feof()
Funcţia feof() permite determinarea momentului când a fost
întâlnit sfârşitul fişierului. Acest lucru este util deoarece în anumite
situaţii returnarea valorii EOF poate avea şi alte cauze. Astfel, s-a
văzut că funcţia fgetc() returnează EOF atât la întâlnirea sfârşitului
Capitolul 10 – Funcţii pentru prelucrarea fişierelor 224
UNCŢIA rewind()
Funcţia rewind() poziţionează indicatorul de poziţie al
fişierului la începutul fişierului. Prototipul său este:
void rewind(FILE *fp);
{
FILE *f;
int i,n;
/* crearea fisierului */
for (i=0;i<n;i++)
{
printf("\n Nume=");
scanf("%s",x.nume);
printf("\n Prenume=");
scanf("%s",x.prenume);
printf("\n Nota=");
scanf("%i",&x.nota);
if (fwrite(&x,sizeof(x),1,f) != 1)
{
printf("\n Eroare la scriere");
exit(1);
}
}
/* aducerea indicatorului de pozitie la valoarea 0 */
rewind(f);
fclose(f);
}
nume semnificaţie
SEEK_SET începutul
fişierului
SEEK_CUR poziţia curentă
SEEK_END sfârşitul fişierului
void main(void)
{
char numefis[8];
long int *p;
int k;
FILE *f;
f=fopen(numefis,"r+b");
else
printf("\nInregistrarea nu este in fisier!");
printf("\n Inregistrarile din fisier sunt:\n");
fseek(f,0,SEEK_SET);
while( !feof(f) )
{
fread(&x,sizeof(struc),1,f);
if ( !feof(f) )
printf("\nNume=%s Prenume=%s Nota=%d",
x.nume,x.pren,x.nota);
}
fclose(f);
getch();
}
Capitolul 10 – Funcţii pentru prelucrarea fişierelor 229
TESTE DE CONTROL
b) getch()
c) getc()
10.7 Apelurile de funcţii
fgetc(stdin);
şi
getch();
a) au acelaşi efect: ambele citesc un caracter de la tastatură
b) au efecte diferite
10.8 Pentru scrierea unui caracter într-un fişier pe disc se poate folosi
funcţia
a) fputc()
b) putc()
c) putch()
10.9 Apelurile de funcţii
fputc(stdout,nume_caracter);
şi
putch(nume_caracter);
a) au acelaşi efect: ambele afişează un caracter pe monitor
b) au efecte diferite
10.10 Pentru citirea unui şir de caractere dintr-un fişier creat pe disc
se poate folosi funcţia
a) fgets()
b) gets()
10.11 Pentru scrierea unui şir de caractere într-un fişier creat pe disc
se poate folosi funcţia
a) puts()
b) fputs()
10.12 Apelurile de funcţii
fgets(nume_sir,nr_caractere,stdin);
şi
gets(nume_sir);
a) au acelaşi efect: ambele citesc un şir de caractere de la
tastatură
Capitolul 10 – Funcţii pentru prelucrarea fişierelor 231
b) au efecte diferite
10.13 Funcţiile fprintf() şi fscanf()
a) transferă blocuri de date
b) transferă date formatate
10.14 Care afirmaţie de mai jos este adevărată?
a) apelul fscanf(stdin, ...) are acelaşi efect cu apelul scanf()
b) apelul fprintf(stdout, ...) are acelaşi efect cu apelul printf()
10.15 Pentru transferul unui volum mare de date este recomandabilă
folosirea funcţiilor
a) fread() şi fwrite()
b) fscanf() şi fprintf()
10.16 Funcţia feof()
a) întoarce valoarea adevarat dacă nu s-a atins sfârşitul
fişierului şi fals în caz contrar
b) întorce valoarea fals dacă nu s-a atins sfârşitul fişierului şi
adevarat în caz contrar
10.17 Funcţia rewind() poziţionează indicatorul de poziţie al
fişierului
a) la începutul său
b) la sfârşitul său
10.18 Funcţia fseek()
a) poziţionează indicatorul de poziţie al fişierului la o valoare
calculată relativ faţă de una din valorile de referinţă:
începutul fişierului, sfârşitul fişierului, poziţia curentă în
fişier
b) setează valoarea indicatorului de poziţie la o valoare dată
c) memorează valoarea indicatorului de poziţie într-un obiect
din memorie
10.19 Care afirmaţii sunt adevărate?
a) funcţia fgetpos() setează valoarea indicatorului de poziţie la
o valoare dată
Capitolul 10 – Funcţii pentru prelucrarea fişierelor 232
RĂSPUNSURI
unde:
nume_macro reprezintă identificatorul care va fi înlocuit în
#define M 20
#define eroared ”eroare la scriere pe disc”
int x[M],i;
. . . . .
for(i=0;i<M;i++)
printf(”%i”,x[i]);
if(y)
printf(eroare);
. . . . .
efectul directivelor #define constă în înlocuirea identificatorilor
M şi eroared prin secvenţele 20, respectiv ”eroare la scriere
Exemplu:
#define LUNG ”Acest sir este insuportabil \
de lung”
Exemplu:
#define B 20
#define C 30
#define D 40
#define ARIA B*C
#define VOLUM ARIA*D
#define EROARE printf(”\n Eroare”)
. . . . .
v=VOLUM
. . . . .
if (x<11)
EROARE;
. . . . .
. . . . .
A=C*D
. . . . .
Corect este:
#define B 20
#define C (B+5)
#define D 10
. . . . .
A=C*D
macroului
y=3*f(2);
y=3*f(3-1);
altfel iniţial.
Folosirea unui macro în locul unei funcţii are avantajul
reducerii timpului de execuţie, deoarece apelul funcţiei implică
>urcarea> în stivă la apel şi >coborârea> în stivă la revenirea
în programul principal. Pe de altă parte, folosirea
macrodefiniţiei este avantajoasă şi din punct de vedere al
memoriei folosite numai dacă textul care reprezintă funcţia nu
Capitolul 11 – Directive către preprocesor 239
#undef nume_macro
Exemplu:
#define M 20
#undef M
#define M 30
#if expresie_constanta
sectiune_program
#endif
Capitolul 11 – Directive către preprocesor 242
/* forme de iteratie:
0 se foloseste while
1 se foloseste for
*/
#define ITER 0
void main(void)
{
int x,s=0;
#if ITER
{
int i,n;
printf("\n n=");
scanf("%i",&n);
for (i=0;i<n;i++)
{
printf("\n x=");
scanf("%i",&x);
s+=x;
}
}
#else
{
printf("\n x=");
scanf("\n %i",&x);
while (x)
{
Capitolul 11 – Directive către preprocesor 244
s+=x;
printf("\n x=");
scanf("\n %i", &x);
}
}
#endif
printf("\n Suma este %i",s);
getch();
}
void main(void)
{
#ifdef M
printf("\n Este definit M");
#else
printf("\n M nu e definit");
#endif
getch();
}
void main(void)
{
#if defined(M)
printf("\n Este definit M");
#else
printf("\n M nu e definit");
Capitolul 11 – Directive către preprocesor 246
#endif
getch();
}
TESTE DE CONTROL
11.1 Directiva
#define N 10
#define A 10
#define B A+20
#define X 10
#define Y X+5
. . . . . .
int v;
v=X+3*Y;
. . . . . .
Capitolul 11 – Directive către preprocesor 248
#define M 20
se foloseşte
a) #define
b) #define M
c) #undef
11.5 Directiva
are ca efect
RĂSPUNSURI
CARACTERELOR
eroare.
int puts(const char *sir);
spaţiu
int islower(int c); testează dacă c este litera mică
inclusiv spaţiu
int ispcmct(int c); testează dacă c este caracter tipăribil
NL, spaţiu
corespunzătoare
corespunzătoare
=0 dacă sir1=sir2
UNCŢII MATEMATICE
aparţinând domeniul de
definiţie
double sin(double x); sinus de x
struct tm
{
int tm_sec;/* secunde 0...59 */
int tm_min;/* minute 0...59 */
int tm_hour;/* ore 0...23 */
int tm_mday;/* ziua din luna 1...31 */
int tm_mon;/* luna 0...11 */
int tm_year;/* anul >=1900 */
int tm_wday;/* ziua saptamanii 0...6 */
int tm_yday;/* ziua din an 0...365 */
int tm_isdst;/* indicator al orei de vara este:
>0 daca functioneaza
=0 daca nu functioneaza
<0 daca nu exista informatii in domeniu */
}
B F F F C C C C
unde:
unde mod poate lua una din valorile BW40 (40 coloane alb-
negru), C40 (40 coloane color), BW80 (80 coloane alb-negru),
C80 (80 coloane color), MONO (80 coloane monocrom), LASTMODE
FERESTRELOR
int cprintf();
CONTROLUL ECRANULUI
MANEVRAREA IMAGINILOR
void far getimage(int x1, int y1, int x2, int y2,
void far *buf);
MANEVRAREA PIXELILOR
GRAFIC
orizontal
vertical
void far bar(int x1, int y1, int x2, int y2);