Limbaj de programare C12

download Limbaj de programare C12

of 35

Transcript of Limbaj de programare C12

  • 7/31/2019 Limbaj de programare C12

    1/35

    1

    Cursul XII-XIII

    Limbaje de programare

    Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    2/35

    Functia de iesire printf()

    Are doua proprietati importante care permit o folosireflexibila:

    poate tipari o lista de argumente cu o lungime arbitrara;

    afisarea este controlata de specificari de conversie simpli.

    Lista de argumente a lui "printf()" are doua parti:

    sirul_de_control si celelalte_argumente

    2 Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    3/35

    Functia de iesire printf()

    printf( "Produsul %d %s $%f\n", 2, "costa", 3.77);

    avem sirul_de_control: "Produsul %d %s $%f\n"

    celelalte_argumente: 2, "costa", 3.77

    Expresiile din 'celelalte_argumente' sunt evaluate si convertiteconform specificatorilor din sirul de control si apoi plasate insirul de iesire. Caracterele din sirul de control care nu facparte dintr-un format sunt plasate direct in sirul de iesire.

    Simbolul % introduce un specificator de format:

    %[flags] [width] [.precision] [{h | l | L}]type

    3 Limbaje de programare Conf.dr. L. STOLERIU [email protected]

    http://ms-help//MS.VSCC/MS.MSDNVS/vclib/html/_crt_flag_directives.htmhttp://ms-help//MS.VSCC/MS.MSDNVS/vclib/html/_crt_printf_width_specification.htmhttp://ms-help//MS.VSCC/MS.MSDNVS/vclib/html/_crt_precision_specification.htmhttp://ms-help//MS.VSCC/MS.MSDNVS/vclib/html/_crt_printf_type_field_characters.htmhttp://ms-help//MS.VSCC/MS.MSDNVS/vclib/html/_crt_printf_type_field_characters.htmhttp://ms-help//MS.VSCC/MS.MSDNVS/vclib/html/_crt_precision_specification.htmhttp://ms-help//MS.VSCC/MS.MSDNVS/vclib/html/_crt_printf_width_specification.htmhttp://ms-help//MS.VSCC/MS.MSDNVS/vclib/html/_crt_flag_directives.htm
  • 7/31/2019 Limbaj de programare C12

    4/35

    Functia printf() type c un caracter

    d, i un intreg zecimal

    u un intreg zecimal fara semn

    o un intreg octal fara semn

    x, X un intreg hexazecimal fara semn

    e un numar in virgula mobila; (ex: 7.123000e+00) E un numar in virgula mobila; (ex: 7.123000E+00)

    f un numar in virgula mobila; (ex: 7.123000)

    g, G in formatul cel mai scurt dintre "e(E) sau "f"

    s un sir

    p un pointer catre void; sa se va tipari ca intreg hexazecimal % cu formatul %% se va afisa un singur caracter % in sirul de

    iesire; nu avem argumente ce trebuie convertite

    4 Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    5/35

    printf() width, precision

    In specificarile de conversie pot fi incluse informatii deformatare explicite. Daca ele nu apar, atunci sunt folosite celeimplicite. De exemplu, formatul %f cu argumentul 3.77 va afisa

    3.770000.

    Intre % (care specifica inceputul unei specificari de conversie)si caracterul de conversie de la sfarsit, pot sa apara zero sau

    mai multe caractere (flag) care modifica intelesul specificarii deconversie;

    5 Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    6/35

    printf() width, precision

    un intreg pozitiv optional care specifica minimul lungimiicampului (WIDTH) a argumentului.

    Daca argumentul convertit are mai putine caractere decat lungimeacampului specificat, atunci acesta se va completa cu spatii (la stangasau dreapta).

    Daca argumentul convertit are mai multe caractere decat lungimeacampului specificat, atunci lungimea campului se va mari cu cat estenecesar.

    Daca intregul care defineste lungimea campului incepe cu zero si

    argumentul ce se tipareste este ajustat dreapta in campul sau, atuncipentru umplerea sa se vor folosi zerouri in loc de spatii;

    6 Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    7/35

    printf() width, precision

    o "precizie" optionala, care este specificata de un punct urmatde un intreg nenegativ.

    Pentru conversii d, i, o, u, x si X aceasta specifica numarul minim decifre ce trebuie afisate.

    Pentru conversii e, E si f aceasta specifica numarul de cifre de ladreapta punctului zecimal.

    Pentru conversii g si G aceasta specifica numarul maxim de cifresemnificative.

    Pentru conversie cu s, aceasta specifica numarul maxim de caractere

    ce trebuie tiparite dintr-un sir;

    7 Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    8/35

    printf() width, precision

    h sau l optional, care este un modificator "short" sau "long",respectiv. Daca h este urmat de un d, i, o, u, x sau X, atunciaceasta este o specificare de conversie relativ la "short int"sau "unsigned short int". Daca l este urmat de d, i, o, u, x sau X,atunci specificarea de conversie se aplica unui argument "longint" sau "unsigned long int".

    L optional, care este un modificator "lung". Daca L este urmatde e, E, f, g sau G, specificarea de conversie se aplica unui

    argument "long double".

    8 Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    9/35

    printf() flags

    semnul "-" va implica alinierea spre stanga a argumentuluiconvertit in campul sau. Daca nu gasim nici un semn "-", atuncialinierea argumentului convertit se face la dreapta campului.

    semnul "+" va implica afisarea semnului "+" in cazul numerelor

    pozitive (functioneaza pentru d, i, e, E, f, g si G). Toate numerelenegative vor incepe cu semnul minus.

    un spatiu, care semnifica ca un numar pozitiv (ce provine dintr-o conversie unsigned) are la inceput un spatiu;

    9 Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    10/35

    printf() flags

    un "#", care semnifica ca rezultatul trebuie convertit. Dacacaracterul de conversie este "o", atunci "#" cauzeaza afisareaunui zero in fata numarului octal. Intr-o conversie x sau X, "#"cauzeaza 0x, respectiv 0X, in fata numarului hexazecimal. Inconversiile g si G, acesta cauzeaza tiparirea unor zerouri la

    coada (pana la un anumit numar de zecimale, de obicei 5). Inconversiile e, E, f, g sau G, aceasta cauzeaza tiparirea punctuluizecimal, chiar si cu precizia 0.

    un "0" (zero), care inseamna ca in loc de spatii sunt folosite

    zerouri. Cu caracterele de conversie d, i, o, u, x, X, e, E, f, g si G,aceasta poate produce zerouri nesemnificative (in fatanumarului).

    10 Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    11/35

    printf() flags

    Intr-un format, lungimea campului sau precizia (sau ambele),pot fi specificate folosind *, in loc de un intreg, lucru careindica ca o valoare se obtine din lista de argumente.

    int m, n;double x = 333.7777777;

    . . . . . . . . . . .

    /* citim m si n (sau le calculam cumva) */

    . . . . . . . . . . .

    printf("x = %*.*f\n", m, n, x);

    11 Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    12/35

    printf() flags

    char c = 'A', s[] = "Luna rosie!";

    12

    Format Argument Afisat Obs.

    %c c "A" Lungimea 1 implicit

    %2c c " A" Lungimea 2, aliniat

    %-3c c "A " Lungimea 3, aliniat

    %s s "Luna rosie!" Lungimea 11 implicit

    %13s s " Luna rosie!" Spatii suplimentare

    %.6s s "Luna r" Precizia 6%-11.8s s "Luna ros " Precizie 8, aliniere stanga

    Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    13/35

    printf() flags

    int i = 123;double x = 0.123456789;

    13

    Format Argument Afisat Obs.

    %d i "123" Lungimea 3 implicit

    %05d i "00123" Adaugat 0-uri nesemnificative

    %7o i " 173" Aliniere dreapta, octal

    %-9x i "7b " Aliniere stanga, hexazecimal

    %-#9x i "0x7b " Aliniere stanga, hexazecimal%10.5f x " 0.12346" Lungime 10, precizie 5

    %-12.5e x "1.23457e-01 " Aliniere stanga

    Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    14/35

    Functia scanf()

    Are doua proprietati importante care permit o folosireflexibila la un nivel inalt:

    poate citi o lista de argumente de lungime arbitrara;

    intrarea este controlata de specificari de conversie simpli.

    Functia "scanf()" citeste caractere din fisierul standard "stdin".Lista de argumente a functiei "scanf()" are, la fel, doua parti:

    sir_de_control si celelalte_argumente

    14 Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    15/35

    Functia scanf()

    Sirul de control din "scanf()" este compus din trei tipuri de"directive":

    caractere ordinare

    spatii goale

    specificari de conversie

    Caracterele din sirul de control (diferite de spatiile goale sicaracterele din specificarile de conversie) sunt numite

    "caractere ordinare". Caracterele ordinare trebuie sa seregaseasca (potriveasca) cu cele din sirul de la intrare.

    15 Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    16/35

    Functia scanf()

    float suma;

    scanf("$%f", &suma);

    Caracterul $ este ordinar. Deci trebuie sa intalnim $ in sirul de

    la intrare. Daca are loc o potrivire cu succes, atunci spatiilegoale (daca exista) se vor sari, si caracterele care urmeaza sevor potrivi la o valoare (in virgula mobila). Valoarea convertitava fi plasata in memorie la adresa variabilei "suma".

    16 Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    17/35

    Functia scanf()

    Caracterele spatii goale din sirul de control care nu fac partedintr-o specificare de conversie se potrivesc cu orice spatiuliber din sirul de intrare.

    char c1, c2, c3;

    scanf(" %c %c %c", &c1, &c2, &c3);

    Daca sirul de la intrare contine literele "a", "b", si "c", atunci c1,c2 si c3 vor avea valorile a, b, c. O directiva spatiu liberinseamna ca spatiile goale (daca exista) sa fie ignorate din sirulde intrare.

    scanf(" %c %c %c", &c1, &c2, &c3);scanf("\t%c \t %c\n%c", &c1, &c2, &c3);

    17 Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    18/35

    Functia scanf()

    Intr-un sir de control pentru "scanf()", o directiva despecificare de conversie incepe cu un "%" si se termina cu uncaracter de conversie. Aceasta determina modurile depotrivire si de convertire a caracterelor din sirul de intrare.

    Caracterele de control (type) sunt aceleasi ca la printf() cu o

    excepie:

    [] - multime de scanare. Aceasta determina ce se potriveste siface citirile respective. Argumentul corespunzator este un

    pointer catre sirul de caractere ce este suficient de marepentru a pastra caracterele cu care s-a potrivit, apoi va adaugaautomat terminatorul '\0'

    18 Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    19/35

    Functia scanf()

    %s sare spatiile goale si apoi citeste caractere diferite despatiu pana cand se gaseste spatiu sau EOF.

    %5s sare spatiile goale, apoi citeste caracterele diferite despatiu, dar cel mult 5 caractere sau pana la EOF. Cand se

    citeste un sir de caractere, se presupune ca in memorie estedeja rezervat suficient spatiu pentru el (cu tot cu \0).

    Formatul %nc (unde "n" este intreag) foloseste la citireaurmatoarelor n caractere, inclusiv spatii goale (se presupune

    ca s-a rezervat suficient spatiu in memorie pentru ele, iarcaracterul \0 nu se adauga).

    19 Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    20/35

    scanf() multime de scanare

    O specificare de conversie de forma %[sir] indica ca un sirspecial poate fi citit. Multimea de caractere dintre parantezelepatrate se numeste "multime de scanare". Daca primulcaracter din multimea de scanare nu este caracterul "^", atuncisirul trebuie sa fie construit numai din caractere ce apartinmultimii de scanare.

    1. Formatul %[abc] va citi orice sir care contine literele "a", "b" si

    "c" si se va opri daca orice alt caracter va apare in sirul deintrare, inclusiv un spatiu (ex. scanf(%[abc]s, m)).

    20 Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    21/35

    scanf() multime de scanare

    2. Formatul %[^abc] va citi orice ce se va termina cu "a", "b" sau "c",dar nu si spatiu.

    3. char m[30];

    scanf("%29[AB \t\n]", m);

    va produce citirea in "m" a unui sir de cel mult 29 caractere. Sirulconsta din literele A, B, spatiu, tab, newline. La sfarsit, se va scrie \0.

    4. Un mod (elegant) de a citi o linie de text este folosirea unei multimide scanare potrivita:

    char linie[256];scanf(" %[^\n]", linie);

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

    21 Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    22/35

    sprintf(), sscanf()

    "sprintf()" si "sscanf()" sunt versiuni ce folosesc siruri ale functiei

    "printf()" si "scanf()", respectiv.int sprintf(char *s, const char *format, ...);

    int sscanf(const char *s, const char *format, ...);

    Punctele ... indica faptul ca functia poate avea un numar variabil de

    argumente. O instructiune de forma:

    sprintf(sir, sir_de_control, alte_argumente);

    scrie rezultatul in sirul de caractere "sir".

    Intr-o maniera similara, o instructiune de forma:sscanf(sir, sir_de_control, alte_argumente);

    citeste rezultatul din sirul de caractere "sir".

    22 Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    23/35

    fprintf(), fscanf()

    "fprintf()" si "fscanf()" sunt versiunile pentru fisiere. Fisierul

    "stdio.h" contine un numar de constructii referitoare la fisiere.In acest fisier exista tipul FILE a carui membrii descriu stareacurenta a unui fisier. Tot in acest fisier, sunt definiti trei pointerila fisier, "stdin", "stdout" si "stderr".

    stdin standard input file conectat la tastatura stdout standard output file conectat la ecran

    stderr standard error file conectat la ecran

    int fprintf(FILE *ofp, const char *format, ...);

    int fscanf(FILE *ifp, const char *format, ...); fprintf(stdout, ...);este echivalent cu printf(...);

    "fscanf(stdin, ...); este echivalent cu scanf(...);

    23 Limbaje de programare Conf.dr. L. STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    24/35

    Directive de precompilare #include

    #include fisier

    Preprocesorul va inlocui aceasta linie cu o copie a fisierului

    precizat. Mai intai cautarea se face in directorul curent, apoi inalte locuri dependente de sistem.

    ... inseamna de obicei directorul curent (pentru fisiere

    proprii) iar este destinat fisierelor de sistem (de ex.#include )

    24 Limbaje de programare Conf.dr. L.STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    25/35

    #define #define identificator definitie

    #define identificator(id,...,id) definitie

    O definitie lunga (pe care nu dorim sa o scriem pe aceeasilinie poate fi continuata pe linia urmatoare punand un \

    (backslash) la sfarsitul liniei curente).

    In primul caz, compilatorul va inlocui fiecare aparitie a"identificatorului" prin definitie" in restul fisierului (de la

    pozitia curenta in jos) cu exceptia aparitiilor incadrateintre ghilimele sau apostroafe.

    25 Limbaje de programare Conf.dr. L.STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    26/35

    #define identificator definitie

    Exemplu:

    #define EQ ==

    #define do /* nimic altceva decat un spatiu */

    De exemplu, acum putem simula instructiunea "while" din Cca un "while do" din Pascal.

    while (i EQ 1) do

    { . . . . . }

    echivalent cu

    while (i == 1)

    { . . . . . }

    26 Limbaje de programare Conf.dr. L.STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    27/35

    #define identif(id,...) definitie #define identificator(id,...,id) sir_atomi

    #define SQ(x) x*x //!!! Corect? !!!

    Identificatorul x din #define este un parametru care va fisubstituit in textul ce urmeaza. Substitutia se face faraconsiderarea corectitudinii sintactice.

    De exemplu SQ(7) este inlocuit cu 7*7

    27 Limbaje de programare Conf.dr. L.STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    28/35

    #define identif(id,...) definitie

    Dar SQ(7+w)?

    Este inlocuit cu 7+w*7+w //!!!!!!!!!!

    Mai corect ar fi fost de scris definitia

    #define SQ(x) (x)*(x) //!!!!!

    Atunci SQ(7+w) este inlocuit cu (7+w)*(7+w)

    28 Limbaje de programare Conf.dr. L.STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    29/35

    #define identif(id,...) definitie

    Cu adevarat corect ar fi fost de scris definitia

    #define SQ(x) ((x)*(x))

    Atunci SQ(SQ(*p)) este echivalent cu

    ((((*p) * (*p))) * (((*p) * (*p))))

    #define SQ(x) ((x)*(x)); //!!!!!!!!!!

    29 Limbaje de programare Conf.dr. L.STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    30/35

    #define identif(id,...) definitie Macrourile cu argumente sunt folosite de obicei pentru a

    inlocui apelurile functiilor cu cod liniar (scurte si fara variabilesuplimentare).

    #define min(x, y) (((x) < (y)) ? (x) : (y))

    O expresie de forma m = min(u, v) se poate expanda de catrepreprocesor la

    m = (((u) < (v)) ? (u) : (v))

    #define min4(a,b,c,d) min(min(a,b), min(c, d))

    30 Limbaje de programare Conf.dr. L.STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    31/35

    #define identif(id,...) definitie

    O macro-definitie poate folosi functii si macrouri in corpulsau.

    #define SQ(x) ((x) * (x)) #define CUB(x) (SQ(x) * (x))

    #define F_POW(x) sqrt(sqrt(CUB(x)))

    #define parte_fractionara(x) (x - (int) x)

    #define caracter_aleator() (rand() % 26 + 'a')

    #define real_aleator() (rand() % 100 / 10.0)

    31 Limbaje de programare Conf.dr. L.STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    32/35

    Compilare conditionata Preprocesorul are directive pentru compilare conditionata.

    Acestea pot fi folosite pentru dezvoltarea programelor sipentru scrierea codului mai portabil de la o masina la alta.

    Fiecare directiva de forma

    #if expresie_integrala_constanta#ifdef identificator

    #ifndef identificator

    implica compilarea conditionata a codului care urmeaza pana ladirectiva de precompilare

    #endif

    32 Limbaje de programare Conf.dr. L.STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    33/35

    Compilare conditionata

    Uneori "printf()" este utila in scopuri de depanare.

    Presupunem ca la inceputul unui fisier am scris

    #define DEBUG 1

    si in unele zone ale programului am scris

    #if DEBUG

    printf("debug: a = %d\n", a);

    #endif

    33 Limbaje de programare Conf.dr. L.STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    34/35

    Operatorii # si ## Operatorul unar # cauzeaza transformarea in sir a unui

    parametru formal dintr-o macro-definitie.#define mesaj_pentru(a, b) \

    printf(#a " si " #b ": Bafta!\n")

    void main()

    { mesaj_pentru(Carolina, Nicoleta); }

    La apel fiecare parametru este inlocuit cu argumentulcorespunzator, iar # cauzeaza ca argumentele sa fie puse intreghilimele:

    void main()

    { printf("Carolina" " si " "Nicoleta" ": Bafta!\n"); }

    34 Limbaje de programare Conf.dr. L.STOLERIU [email protected]

  • 7/31/2019 Limbaj de programare C12

    35/35

    Operatorii # si ##

    Operatorul binar ## este folosit la impartirea in tokenurilexicale.

    #define X(i) x ## i

    X(1) = X(2) = X(3);

    va deveni dupa preprocesare

    x1 = x2 = x3;

    35 Limbaje de programare Conf dr L STOLERIU LSTOLER@UAIC RO