curs 5phys.ubbcluj.ro/~vasile.chis/cursuri/info/c05ppt.pdfcurs 5 funcţii de intrare/ieşire...

38
CURS 5 Funcţii de intrare/ieşire Funcţia printf - folosită pentru a scrie date la dispozitivul standard de ieşire (monitor), sub un anumit format. - converteşte, formatează şi tipăreşte argumentele cu care este apelată, în conformitate cu formatul specificat - returnează numărul de caractere tipărite. Şirul care defineşte formatul funcţiei conţine două tipuri de obiecte: a) caractere ordinare - copiate ca atare la ieşirea standard b) specificatoare de conversie şi formatare Prototipul funcţiei printf - se găseşte în <stdio.h> int printf(char *format, arg1, arg2, ...); Apelul functiei printf printf("control",arg1,arg2,.....,argn); arg1, arg2,...,argn - variabile sau expresii ale căror valori se tipăresc în conformitate cu specificatorii de format prezenţi în parametrul "control" al funcţiei. Parametrul control- şir de caractere care defineşte textele şi formatele datelor care se scriu. - poate conţine fie numai specificatori, fie numai carcatere.

Upload: others

Post on 26-Dec-2019

9 views

Category:

Documents


0 download

TRANSCRIPT

CURS 5 Funcţii de intrare/ieşire Funcţia printf - folosită pentru a scrie date la dispozitivul standard de ieşire (monitor), sub un anumit format. - converteşte, formatează şi tipăreşte argumentele cu care este apelată, în conformitate cu formatul specificat - returnează numărul de caractere tipărite.

Şirul care defineşte formatul funcţiei conţine două tipuri de obiecte: a) caractere ordinare - copiate ca atare la ieşirea standard b) specificatoare de conversie şi formatare

Prototipul funcţiei printf - se găseşte în <stdio.h>

int printf(char *format, arg1, arg2, ...);

Apelul functiei printf printf("control",arg1,arg2,.....,argn);

arg1, arg2,...,argn - variabile sau expresii ale căror valori se tipăresc în conformitate cu specificatorii de format prezenţi în parametrul "control" al funcţiei. Parametrul “control” - şir de caractere care defineşte textele şi formatele datelor care se scriu. - poate conţine fie numai specificatori, fie numai carcatere.

1. Numărul specificatorilor din parametrul control trebuie să fie egal cu numărul argumentelor funcţiei şi să corespundă tipului acestora.

2. Datele tipărite se încadrează într-un câmp (un anumit număr de

caractere) şi se aliniază implicit în dreapta acestui câmp.

Specificator de format

- începe întotdeauna cu caracterul % şi se termină cu una sau două litere, dar mai poate conţine:

- are ca efect încadradrea datelor scrise în stânga câmpului

[ - ]

[şir de cifre zecimale]

- defineşte dimensiunea minimă a câmpului în care se afişează datele

Litera g este folosită ca şi litera f pentru conversia valorilor care se afişează la tipul real şi tipărirea valorilor respective fără zerourile nesemnificative.

[.şir de cifre zecimale]

- defineşte precizia datei care se scrie, adică numărul de cifre zecimale sau numărul de caractere care se scriu dacă data este un şir de caractere

% [ - , 0 , cifre.cifre ]l [l]

Litera c este folosită pentru afişarea unui caracter. Litera s este folosită pentru afişarea unui şir de caractere. Litera d se foloseşte pentru afişarea valorilor variabilelor de tip întreg, în sistemul de numeraţie zecimal. Litera o se foloseşte pentru afişarea valorilor variabilelor de tip întreg, în sistemul de numeraţie octal. Literele x şi X se folosesc pentru convertirea şi afişarea valorilor unor variabile de tip întreg în sistemul de numeraţie hexazecimal. Litera u este folosită pentru conversia valorilor la tipul întreg unsigned şi tipărirea lor. Litera f este folosită pentru conversia la tipul float şi afişarea valorilor cu 6 cifre zecimale. Literele e şi E sunt folosite pentru tipărirea valorilor de tip float, double sau long double în format ştiinţific. Literele g şi G sunt folosite pentru afişarea datelor de tip float, double sau long double pe un număr minim de caractere (fără zerouri nesemnificative). Literele l şi L realizează conversii la tipul long, respectiv la tipul long double şi se folosesc împreună cu literele f, e, E, g sau G. lf, Lf – realizează afişarea datelor fără exponent, cu 6 cifre zecimale. le, lE, Le, LE – realizează tipărirea valorilor în format ştiinţific. lg, lG, Lg, LG – realizează tipărirea datelor într-unul din formatele precedente care asigură o afişare cu un număr minim de caractere.

Funcţia scanf - folosită pentru citirea datelor introduse de la dispozitivul standard de intrare (tastatura) ş - converteste datele în conformitate cu formatul specificat - returnează numărul câmpurilor citite corect, adică în conformitate cu tipul specificat. Prototipul funcţie scanf se găseşte în <stdio.h>

int scanf(char *format, arg1, arg2,...argn)

Apelul funcţiei scanf

scanf("control",&par1, &par2,...,&parn);

&par1, &par2, ... , &parn sunt adresele de început ale locaţiilor de memorie în care se păstrează

valorile corespunzătoare lui par1, par2, ... , parn.

Astfel, dacă v este o variabilă, atunci &v reprezintă adresa primului octet al locaţiei de memorie la care se stochează valoarea variabilei v. Şirul control conţine specificatori de tip folosiţi pentru controlul conversiei datelor citite.

Specificatorul %c este folosit pentru citirea unui caracter. Specificatorul %s este folosit pentru citirea unui şir de caractere. - citirea sirului se încheie la primul caracter citit după care urmează un caracter alb (spaţiu, tab (\t), rând

nou (\n), carriage return, tab vertical (\v) şi avans de pagină la imprimantă (\f)) sau la caracterul prin care se ajunge la lungimea maximă de caractere indicată de specificatorul de format.

Specificatorul %d permite citirea unor valori şi conversia acestora spre tipul întreg - citirea se încheie la primul caracter citit după care urmează un caracter alb sau la caracterul prin care se

ajunge la lungimea maximă de caractere indicată de specificatorul respectiv.

Specificatorul %o este folosit pentru citirea unor valori întregi în sistemul de numeraţie octal. Specificatorul %u se foloseşte pentru citirea întregilor de tip unsigned. Specificatorul %f este folosit la citirea unor date de tip real şi conversia acestora spre tipul float. Litera l poate precede literele d, o, x, X, u sau f şi converteşte datele citite spre tipul long (în cazul d, o, x, X, u) sau spre tipul double dacă precede litera f. Litera L poate precede litera f şi are ca efect convertirea datelor citite spre tipul long double.

Specificatori de tip

Alte functii de intrare iesire

Intrare: getch, getche, getc, gets, getchar Ieşire: putch, putc, puts, putchar.

Tema! Termen: 17.04.2019

Operatori

a) operatori unari, care se aplică unui singur operand b) operatori binari, care se aplică la doi operanzi

- folosiţi la construcţia expresiilor matematice şi logice - exercită diferite acţiuni asupra operanzilor expresiilor şi sunt de două feluri:

operatori aritmetici operatori de relaţie operatori de forţare a tipului

operatori de atribuire operatori logici operatorii paranteze

operatori de incrementare şi decrementare operatorul adresă operatorul *

operatori de dimensiune operatorul virgulă operatori logici pe biţi

operatori condiţionali operatorul ->

operatorul ∙ operatori de egalitate

Clase de operatori

- folosiţi la efectuarea calculelor aritmetice cu date de diferite tipuri - se împart în următoarele categorii:

Operatori aritmetici

1) operatorii unari + şi –; operatorul unar + nu are nici un efect, iar operatorul unar – negativează valoarea operandului căruia i se aplică.

2) operatorii binari aditivi + şi – 3) operatorii binari multiplicativi *, / şi %. operatorul * realizează produsul operanzilor operatorul / realizează împărţirea operanzilor operatorul % (modulo) se aplică numai la operanzi întregi şi returnează restul împărţirii întregi a operanzilor. Operatorii unari sunt mai prioritari decât cei binari, iar cei multiplicativi sunt mai prioritari decât cei aditivi.

Dacă un operator se aplică la doi operanzi cu tipuri diferite, operandul de tip inferior se converteşte spre tipul superior al celuilalt operand şi rezultatul este de tipul superior. Dacă un operator se aplică la doi operanzi de acelaşi tip atunci tipul rezultatului coincide cu tipul comun al operanzilor. Dacă rezultatul are o valoare ce depăşeşte limitele tipului respectiv, atunci rezultatul este imprevizibil.

Exemple (1) float a;

double b; int i;

b = 3*a-i; Valoarea 3 (de tip int) se converteşte la float (adică valoarea 3 se extinde pe 4 octeţi) şi rezultatul este de tip float. Apoi se converteşte i la float şi apoi se scade din rezultat. In final, rezultatul se converteşte la double.

(2) int a, b, c;

...

a = 30000;

b = 29000;

c = a+b;

Valoarea lui c este imprevizibilă deoarece depăşeşte limitele tipului int.

Operatori de relaţie (relaţionali)

==, >, >=, <, <= - acţiunea lor constă în a compara în sens algebric valorile a doi operanzi întregi

sau în virgulă mobilă - au aceeaşi prioritate (mai mică decât a operatorilor aditivi)

E1 operator relaţional E2 unde E1 şi E2 sunt expresii, are valoarea 0 (fals) sau 1 (adevărat). În C şi C++ se consideră că o expresie este falsă dacă valoarea ei este 0 şi se consideră că este adevărată dacă valoarea ei este diferită de zero (este egală cu 1).

Exemple

#include <stdio.h>

int main( )

{

float a, b;

scanf("%f %f",&a,&b);

printf("%g\t%g\t%d", a, b, a>b);

return 0;

}

printf("\n%g\t%g\t%d",a,b,(a>b)*10);

printf("\n%g\t%g\t%d",a,b,(a>b)+1)

Operatori de egalitate

== (egal) şi!= (diferit) - verifică dacă valorile a doi operanzi sunt egale sau nu - au aceeaşi prioritate (mai mică decât a operatorilor de relaţie)

E1 operator de egalitate E2 unde E1 şi E2 sunt expresii, are valoarea 0 sau 1.

Exemple b == a*a are valoarea 1 dacă b=a2 şi 0 dacă b≠a2 a%4!=0 are valoarea 1 dacă a nu este multiplu de 4 şi 0 în caz contrar getchar()==EOF are valoarea 1 dacă s-a citit caracterul de sfârşit de fişier şi 0 dacă s-a citit un alt caracter.

float x;

scanf("%f",&x)==1

are valoarea 1 (adevărat) dacă funcţia scanf a citit o valoare de tip float (sau convertibilă la float) şi zero în caz contrar int m, x, y, z;

scanf("%d%d%d%d",&m,&x,&y,&z)==4

are valoarea 1 dacă s-au citit 4 valori de tip întreg şi zero în caz contrar

Operatorul de atribuire

= - atribuie valoarea unei expresii la o anumită variabilă (dacă este cazul se face şi conversia

necesară) - are cea mai mică prioritate - se foloseşte sub forma: v = expresie;

v poate fi o variabilă simplă, un element de tablou sau de structură, un apel de funcţie, etc.

În limbajul C este permis: V1=V2= expresie;

sau V1=V2=.....Vi=Vn= expresie;

Operatorul de atribuire - poate fi însoţit de un operator binar aritmetic sau logic pe biţi => operatori prescurtaţi sau operatori compuşi +=, -=, *=, /=, %=, >>=, <<=, &=, |=, ^=, ~= - produc conciziune în scrierea expresiilor

V op=(expresie) V = V op (expresie)

Exemple

int a; a=10; // variabilei a i se atribuie valoarea 10 a+=10; // variabilei a i se atribuie vechea sa valoare la care s-a adăugat 10 i=i+1; // este echivalentă cu expresia i+=1; a*=(b/c)+d // este echivalentă cu expresia a=a*((b/c)+d) a&=0x00FF // este echivalentă cu expresia a=a&0x00FF //vezi operatori logici pe biţi (FF)16=(255)10 sir[i*j]=sir[i*j]*5; // elementului de pe poziţia i*j al tabloului şir i se multiplică valoarea cu 5 sir [i*j]*=5; // această expresie este echivalentă cu cea de mai sus dar în //acest caz compilatorul crează un cod mai eficient // deoarece multiplicarea i*j se efectuează o singură dată

Operatori logici

! - operator unar de negaţie logică && - şi logic || - sau logic - folosiţi pentru construirea unor expresii relaţionale

Negaţia logică (!) - are aceeaşi prioritate ca şi ceilalţi operatori unari, imediat mai mare decât a operatorilor multiplicativi. Expresia: ! operand are valoarea 0 (fals) dacă operand ≠ 0 şi valoarea 1 (adevărat) dacă operand = 0 (fals).

Şi logic (&&) - are prioritate mai mică decât a operatorilor de egalitate Expresia: E1 && E2 are valoarea 1 (adevărat) dacă E1 şi E2 au simultan valori diferite de zero şi are valoarea 0 (fals) dacă E1 şi/sau E2 au valoarea 0.

Sau logic (||) - are prioritate imediat mai mică decât &&. Expresia: E1|| E2 unde E1 şi E2 sunt expresii, are valorile: 1 (adevărat) dacă E1 şi/sau E2 ≠ 0 0 (fals) dacă E1 şi E2 = 0

Operatorii logici (&& şi ||) se evaluează de la stânga la dreapta. Dacă la evaluarea unei expresii se ajunge într-un punct în care se poate cunoaşte valoarea de adevăr a întregii expresii, atunci restul expresiei (aflată în dreapta) nu se mai evaluează.

Exemple

Fie atribuirea: d=c>='0'&&c<='9'; În acest caz d are valoarea 1 dacă c este cifră şi d are valoarea 0 dacă c nu este cifră.

a&&b = 1 dacă a ≠ 0 şi b ≠ 0 !a&&b = 1 dacă a = 0 şi b ≠ 0 (prima dată se evaluează !a)

Program exemplu: convertirea unui şir de cifre într-un număr întreg #include <stdio.h>

int atoi(char s[])

{

int i,n=0;

for(i=0;s[i]>='0'&&s[i]<='9';i++)

n=10*n+(s[i]-'0');

return n;

}

int main( )

{

char s[20];

int n;

gets(s);

printf("%d",atoi(s));

return 0;

}

#include <stdio.h>

double x;

int main ( )

{

printf("Introduceti o valoarea reala: ");

scanf("%lf",&x);

printf("x = %lg\t %d",x,(x>=500)&&(x<=800));

return 0;

}

-> 235

0+2=2

10*2+3=23

10*230+5=235

Operatori de incrementare şi decrementare

- operatori unari - operatorul ++

- operator de incrementare - măreşte valoarea operandului căruia i se aplică cu valoarea 1

- operatorul -- - operator de decrementare - micşorează valoarea operandului cu 1.

Pot fi: i) prefixaţi, când sunt aplicaţi sub forma ++ operand sau -- operand

- se foloseşte valoarea operandului la care s-a aplicat operatorul respectiv. ii) postfixaţi, când sunt aplicaţi sub forma operand++ sau operand -- - se foloseşte valoarea operandului de dinaintea aplicării operatorului.

Exemplu a = 5; b = ++ a; => a primeşte valoarea 6 şi apoi b ia valoarea 6. b = a++ ; => variabila b ia valoarea 5 şi apoi lui a i se atribuie valoarea 6.

Operatorul de forţare a tipului (conversie implicită)

- operator unar - este folosit la conversia valorii unui operand spre un alt tip - se aplică sub forma: (tip)(operand)

int k; scanf("%d",&k); printf("\n k/k+1 = %.15g",(double)k/(k+1)); printf("\n k/k+1 = %.15g",(double)(k/(k+1)));

Exemple

int n;

double f(float x)

{

.................

}

f((float)(n));

Operatorul dimensiune (sizeof)

- determină dimensiunea în octeţi a unei date sau a unui tip de date - se aplică sub forma: sizeof (data) sau sizeof(tip) data - nume de variabilă simplă, nume de tablou sau element de tablou, nume de structură

sau de element al unei structuri tip - cuvânt cheie corespunzător unui tip de bază sau unui tip de utilizator

Exemplu int i,d,x,y,z,v,u;

float f;

long double sir[10];

int vd;

vd=sizeof(double);

d = sizeof(i);

x = sizeof(sir[3]);

y = sizeof(sir);

z = sizeof(float);

v = 2*sizeof(float);

u = sizeof (char);

printf("\nint: %d\nfloat: %d\ndouble: %d\ny= %d\nlong double: %d\nv= %d\nchar

%d",d,z,vd,y,x,v,u);

Operatorul adresă (&) - determină adresa de început a zonei de memorie alocată unei date - operator unar - numit şi operator de referenţiere - folosit la citirea valorilor datelor cu funcţia scanf şi de asemenea este folosită cu pointeri - se aplică sub forma: &nume unde nume este numele unei variabile simple, al unui tablou sau al unei structuri

Exemplu

int n, *pi;

printf("Introduceti o valoare intreaga: ");

scanf("%d",&n);

pi=&n;

printf("Valoarea citita este %d\nLocatie de memorie rezervata ei incepe la

adresa %X",n,pi);

Operatorii paranteză () - sunt de prioritate maximă - au ca efect impunerea ordinii de evaluare a expresiilor - nu pot fi folosiţi cu operatorii de incrementare şi decrementare şi cu operatorul adresă

Operatori condiţionali (? şi :)

- permit construirea expresiilor condiţionale, adică a unor expresii a căror valoare depinde de valoarea unei alte expresii

- se folosesc împreună în ordinea indicată de formatul expresiei condiţionale

Expresia: E?E1:E0 are valoarea şi tipul lui E1 dacă E are valoarea 1 (adevărat), altfel are valoarea şi tipul lui E0 (dacă E = 0 (fals) ).

Exemplu

max = (a>b)?a:b; min=a<b?a:b; caz=x==y?”egale”:”diferite”;

if(a>b) max=a; else max=b;

Operatorul virgulă (,)

- leagă două expresii în una singură - are cea mai mică prioritate dintre toţi operatorii limbajului C - se utilizează când într-un anumit punct al unui program este necesar să se realizeze un

calcul complex exprimat în mai multe expresii - folosit si pentru separarea listei de argumente ale unei funcţii

Expresia: exp1, exp2,......, expn este o expresie a cărui tip şi valoare coincide cu tipul şi valoarea ultimei expresii. Evaluarea expresiilor de genul celei de mai sus se evaluează de la stânga la dreapta.

Program exemplu: tipărirea maximului a două valori absolute, folosind operatorii condiţionali şi operatorul virgulă. #include<stdio.h>

int main ()

{

int a, b, c, d;

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

printf("a=%d\tb=%d\tmax(|a|,|b|)=%d",a,b,((c=a<0?-a:a),(d=b<0?-b:b),

(c>d?c:d)));

//c = |a| d = |b| tipăreşte c sau d

return 0;

}

Operatorul * - se foloseşte pentru a accesa conţinutul unei zone de memorie definită prin adresa ei - se numeşte şi operator de dereferenţiere. Exemple de folosire a acestui operator vor fi date la discuţia pointerilor.

Operatorii . si -> - utilizaţi pentru a accesa componentele structurilor - sunt de prioritate maximă. Exemple de utilizare a acestor operatori vor fi date la discuţia structurilor.

Operatori pe biţi - folosiţi pentru manipularea biţilor - utili pentru scrierea softului de sistem

Limbajul C oferă următorii operatori pe biţi: operatorul ŞI logic pe biţi: & (AND) operatorul SAU logic pe biţi: | (OR inclusiv) are valoare 1 când cel puţin unul dintre biţi este 1 operatorul SAU exclusiv: ^ (OR exclusiv) are valoare 1 când cei doi biţi sunt diferiţi şi zero în caz contrar operatorul de deplasare spre stânga: << (left shift) operatorul de deplasare spre dreapta: >> (right shift) operatorul de complementare faţă de 1: ~

O1 O2 O1&O2 O1|O2 O1^O2 ~O1

0 0 0 0 0 1

1 0 0 1 1 0

0 1 0 1 1 1

1 1 1 1 0 0

biţii de rang oarecare "i" ai celor doi operanzi cărora li se aplică operatorul logic pe biţi

Program exemplu: testarea operatorilor logici pe biţi

#include <stdio.h>

void binar(unsigned int v)

{

long int i,s[100],j,r,c,dim;

double val;

j=0;

do

{

c=v/2;

r=v%2;

s[j]=r;

j++;

v=c;

}

while(c>0);

val=0;

for(dim=j-1;dim>=0;dim--)

val=10.0*val+(s[dim]);

printf("%016.0lf",val);

}

int main()

{

long int a,b,c,i,o1,o2,rez;

printf("Program pentru testarea operatorilor logici pe biti:\n");

printf("Introduceti o1: ");

scanf("%ld",&o1);

printf("Introduceti o2: ");scanf("%ld",&o2);

binar(o1);

printf("\to1= %ld\n",o1);

binar(o2);

printf("\to2= %ld\n",o2);

//Testarea operatorului &

rez=o1&o2;

binar(rez);

printf("\to1&o2= %ld\n",rez);

//Testarea operatorului |

rez=o1|o2;

binar(rez);

printf("\to1|o2= %ld\n",rez);

//Testarea operatorului ^

rez=o1^o2;

binar(rez);

printf("\to1^o2= %ld\n",rez);

//Testarea operatorului <<

printf("\n");

binar(o1);

printf("\to1= %d\n",o1);

for(i=1;i<=3;i++)

{

binar(o1<<i);

printf("\to1<<%ld= %ld\n",i,o1 << i);

}

//Testarea operatorului <<=

printf("\n");

binar(o2);

printf("\to2= %ld\n",o2);

binar(o2<<=1);

printf("\to2<<=1= %ld\n",o2);

binar(o2<<=2);

printf("\to2<<=2= %ld\n",o2);

binar(o2<<=3);

printf("\to2<<=3= %ld\n",o2);

}

//Testarea operatorului >>

binar(o1);

printf("\to1= %ld\n",o1);

for(i=1;i<=3;i++)

{

binar(o1>>i);

printf("\to1>>%ld= %ld\n",i,o1 >> i);

}

//Testarea operatorului ~

printf("\n");

binar(o1);

printf("\to1= %ld\n",o1);

b=~o1;

binar(b);

printf("\t~o1= %ld\n",b);

return 0;

}

o1>>=2 ???

Exerciţiu Scrieţi un program care să transforme în binar valori de tip int (stocate pe 16 biţi)

folosind o masca pentru biţi. (vezi Mark Burgess, C Programming Tutorial, Faculty of

Engineering, Oslo College, www.it.uc3m.es/pbasanta/asng/course_notes/ctut.pdf, pag. 191-195) Ce se întâmplă dacă folosiţi ca şi mască de biţi valoarea lui 1 (unu)?

Explicati!!! Pentru a înţelege mai uşor programul, urmăriţi figura de mai jos: