Cum Se Scrie Un Program (in C)

download Cum Se Scrie Un Program (in C)

If you can't read please download the document

description

informatica

Transcript of Cum Se Scrie Un Program (in C)

Cum se scrie un program (in C) ?Programele sunt scrise pentru a instrui masinile sa lucreze cu taskuri specifice sau sa rezolve probleme specifice. O procedura (descrisa pas cu pas) asociata unui task se numestealgoritm. Programarea este activitatea de comunicare (codificare) a algoritmilor in calculatoare. Procesul de programare are (in general) patru pasi:

1. Specificarea task-ului;2. Descoperirea unui algoritm pentru solutia sa;3. Codificarea algoritmului in C;4. Testarea codului.

Un calculator este o masina electronica digitala compusa din trei componente:

1. procesor (central processing unit sau CPU);2. memorie;3. dispozitive de intrare/iesire.

Procesorul lucreaza cu instructiuni care sunt inregistrate in memorie. Pe langa aceste instructiuni, in memorie sunt pastrate si date. Dispozitivele de intrare/iesire iau informatii de la agenti externi catre masina si produc informatii pentru acesti agenti.

Dispozitivele de intrare sunt (de obicei):

1. tastatura;2. discheta;3. banda;4. CD-ROM.

Dispozitivele de iesire sunt (de obicei):

1. ecranul terminalului;2. imprimanta;3. discheta;4. banda;5. CD-ROM.

Sistemul de operare consta intr-o colectie de programe speciale si are doua scopuri principale:

1. coordoneaza resursele (memoria, procesorul, imprimanta) masinii. De exemplu, daca un fisier este creat pe disc sistemul de operare are grija de detaliile localizarii acestuia si memoreaza numele, lungimea si data creearii;2. produce instrumente necesare utilizatorilor, multe dintre ele sunt folositoare utilizatorilor C. De exemplu, doua dintre acestea sunt un editor de texte si un compilator de C.

Un cod C se numestecod sursa, iar un fisier ce contine un cod sursa se numestefisier sursa. Dupa ce a fost creat un fisier sursa, atunci se invoca un compilator de C. De exemplu, pentru sistemele MS-DOS se poate da comanda:

bc ex1.csautcc ex1.c

iar pentru unele sisteme UNIX:

cc ex1.c

Daca nu sunt erori in ex1.c, atunci aceasta comanda produce fisierul executabil asociat (ex1.exe). Acum acesta poate fi rulat (executat) cu numele sau (ex1 sau ex1.exe).In continuare, vom preciza trei dintre trasaturile procesului de compilare (mentionam ca asupra acestor notiuni, vom reveni cu detalii interesante intr-un capitol viitor):

1. invocarea preprocesorului;2. invocarea compilatorului;3. invocarea incarcatorului.

Preprocesorul modifica o copie a codului sursa prin includerea altor fisiere si facand alte schimbari. Compilatorul traduce aceasta in cod obiect folosit de incarcator pentru producerea fisierului executabil final. Fisierul care contine codul obiect se numeste fisier obiect. Fisierele obiect, spre deosebire de fisierele sursa, nu se pot intelege asa usor. Cand spunem deci compilare, de fapt invocam preprocesorul, compilatorul si apoi incarcatorul.

Dupa ce scriem un program, acesta trebuie compilat si testat. Daca sunt necesare modificari, atunci codul sursa trebuie editat din nou. Asadar, partea proceselor de programare consta din ciclul:

1. editare > 2. compilare > 3. executie

1.1 Un prim program

O sa incepem cu un exemplu de program C necesar pentru tiparirea unui sir pe ecran.

#include

main(){printf("azi am inceput laboratoarele de C\n");}

Folosind un editor de texte, presupunem ca am scris si salvat acest fisier numit "ex1.c". Cand programul este compilat si rulat atunci va apare pe ecran sirul:

azi am inceput laboratoarele de C

Explicatii:

1. #include

Liniile care incep cu "#" se numesc directive de preprocesare (precompilare). Acestea comunica cu preprocesorul. Aceasta directiva "#include" determina preprocesorul sa includa o copie a fisierului header "stdio.h" in acest punct al codului. Parantezele unghiulare din "" indica ca acest fisier se gaseste in biblioteca C (pentru compilatorul Borland 3.1 pentru MS-DOS, acesta se gaseste in subdirectorul BC31/INCLUDE). Am inclus acest fisier deoarece acesta contine informatii despre functia "printf()".

2. main()

Fiecare program are o functie numita "main", care se executa intai. Parantezele ce urmeaza dupa "main" indica compilatorului ca aceasta este o functie.

3. {

Acolada stanga incepe corpul fiecarei functii. O acolada dreapta corespunzatoare trebuie sa fie la sfarsitul functiei.

4. printf()

Sistemul C contine o biblioteca standard de functii care poate fi utilizata in programe. "printf()" este o functie din biblioteca care tipareste pe ecran. Aceasta este o functie descrisa in biblioteca"stdio.h" (care se numeste prototipul functiei "printf()").

5. "azi am inceput laboratoarele de C\n"

Un sir constant in C consta dintr-un numar de caractere incadrate intre ghilimele. Acest sir este un argument al functiei "printf()". Caracterele \n de la sfarsitul sirului (se citesc "backslash n"), reprezinta, de fapt, un singur caracter numit "newline".

O forma echivalenta a programului de mai sus:

#includemain(){printf("azi am inceput ");printf("laboratoarele de C\n");}

Observatii:

1. Primul "printf" contine la sfarsit un spatiu.

1.2 Variabile, expresii si asignari

In urmatorul exemplu vom ilustra folosirea variabilelor pentru manipularea valorilor intregi. Variabilele sunt folosite sa memoreze valori. Din moment ce diferite tipuri de variabile sunt folosite sa memoreze diferite tipuri de date, tipul fiecarei variabile trebuie specificat.

Pentru a ilustra aceasta idee vom calcula cate ore si minute contin un anumit numar de zile. Algoritmul ar fi:

1. asigneaza un numar de zile unei variabile;2. calculeaza numarul de ore si memoreaza-l intr-o variabila;3. calculeaza numarul de minute si memoreaza-l intr-o variabila;4. afiseaza numarul de zile, ore si minute pe ecran.

Urmatorul program scris in C reprezinta implementarea algoritmului precedent:

#includemain(){int zile, ore, minute;zile=7;ore=24*zile;minute=60*ore;printf("O saptamana are %d ore, %d minute.\n",ore, minute);}

Cand compilam si rulam acest program, pe ecran va apare mesajul:

O saptamana are 168 ore, 10080 minute.

Explicatii:

1. Linia:int zile, ore, minute:

Reprezinta o declaratie de variabile. Variabilele zile, ore, minute sunt declarate de tip "int", unul dintre cele mai importante tipuri din C. O variabila de tip "int" poate lua o valoare intreaga intre -32678 si 32677. Toate variabilele dintrr-un program trebuie declarate inainte de a fi utilizate. Declaratiile, la fel ca si instructiunile, au la sfarsit ";".

2. Linia:zile=7:

Reprezinta o instructiune de atribuire (sau asignare). Semnul "=" este operatorul de asignare de baza in C. Valoarea expresiei din partea dreapta a simbolului "=" este atribuita variabilei din partea stanga.

3. Instructiunea:printf("O saptamana are %d ore, %d minute.\n",ore, minute);

Este similara celei prezentate in exemplul precedent, dar are trei argumente. Primul argument, intotdeauna un sir de caractere, se numeste sir de control. Aici, intalnim specificarea de conversie (care se mai numeste format) "%d". Formatele "%d" determina tiparirea valorilor expresiilor corespunzatoare (al doilea si al treilea argument) in formatul intregilor zecimali. Asadar, primul format "%d" corespunde cu valoarea variabilei "ore", iar cel de-al doilea format "%d" cu valoarea variabilei "minute".

In C, toate variabilele trebuie declarate inainte de a fi utilizate in expresii si instructiuni. Forma generala a unui program simplu este:

Directive de precompilare:

main(){declaratiiinstructiuni}

Un nume de variabila, numit si identificator, consta dintr-o secventa de litere, cifre si "underscore", dar fara a incepe cu cifra. Cuvintele cheie, numite si cuvinte rezervate, nu pot fi utilizate ca nume de variabile. Exemple de cuvinte cheie: char, int, float.

Operatorii binari:+ - * / %

Sunt folositi pentru adunare, scadere, inmultire, impartire sau modul.

Exemple:5 % 2 = 1 si 7 % 4 = 3.Evident, in expresia a % b, b nu trebuie sa fie zero, din moment ce nu se poate face impartirea cu zero.

1.3 Un exemplu de utilizare a variabilelor de tip float

#include

main(){float x, y;

x = 1.0;y = 2.0;printf("Suma dintre x si y este %f.\n", x+y);}

Pe ecran se va afisa:

Suma dintre x si y este 3.000000.

Observatii:

1. Linia:float x, y;

Semnifica declararea variabilelor x si y de tip "float" (deci de tip real). In realitate sunt numere rationale din intervalul[-10^{308},-10^{-308}] U [10^{-308},10^{308}].

2. Linia:printf("Suma dintre x si y este %f.\n", x+y);

Are doua argumente si reprezinta o tiparire la ecran. De remarcat, ca spre deosebire de exemplele precedente (unde foloseam formatul %d), aici folosim formatul pentru numere reale, care este "%f".

3. Precizarea tipului variabilelor este esential.De exemplu, daca, sa zicem, ca x=7.0 si y=2.0, sunt declarati ca fiind de tip float, atunci x/y se evalueaza la 3.5. Daca, insa x=7 si y=2, sunt declarati ca fiind de tip int, atunci x/y se evalueaza la 3 (ramane doar partea intreaga).

1.4 Initializarea variabilelor

Initializarea variabilelor se poate face si cand se declara acestea. De exemplu, putem scrie:

char c='A';int i=1;

Putem astfel modifica programul precedent, inlocuind liniileint zile, ore, minute;zile=7;cuint zile=7, ore, minute;

Observatii:

1. De obicei, pentru initializarea unei variabile se folosesc constante sau expresii constante. Se pot insa folosi si variabile care au deja valoarea precizata. De exemplu, urmatoarea secventa de program este corecta:int zile=7, ore=zile * 24, minute=ore * 60;

1.5 Folosirea directivei #define

Reamintim ca in procesul de compilare a programelor C, intai este invocat preprocesorul. De exemplu, pot fi incluse fisiere, sau anumite siruri de caractere specificate pot fi modificate in alte siruri. Directivele de preprocesare incep cu caracterul # (in C traditional, acesta trebuie pus pe prima coloana, pe cand in ANSI C poate fi precedat de spatii). Se recomanda scrierea # pe prima coloana, iar a directivelor de precompilare la inceputul programului. Iata cateva exemple de folosire a directivei "#define":

#define LIMIT 100#define PI 3.14159

Observatii:

1. Daca aceste directive de preprocesare apar la inceputul fisierului, atunci in momentul compilarii preprocesorul schimba toate aparitiile identificatorului LIMIT la 100 si a lui PI cu 3.14159. Singurele care raman neschimbate sunt sirurile constante.

De exemplu, preprocesorul va schimba:

printf("PI = %f\n", PI); in printf("PI = %f\n", 3.14159);

Deoarece identificatorul PI se va inlocui peste tot (cu exceptia sirurilor constante) in 3.14159, atunci acesta se va numi constanta simbolica.

2. Directiva #define poate aparea oriunde in program, dar ea afecteaza numai liniile care urmeaza acesteia.

3. Prin conventie, identificatorii care trebuie schimbati de preprocesor se scriu cu majuscule.

Avantaje ale folosirii directivei #define

1. Lizibilitate marita. Se refera la citirea si intelegerea rapida a fisierului sursa (PI stim ce inseamna si ne amintim ca este 3.ceva, deci nu trebuie sa scriem de fiecare data valoarea sa);2. Schimbarile ulterioare ale unor valori constante se face foarte usor. De exemplu, vrem sa modificam valoarea lui LIMIT la 10000.

In locul liniei:

#define LIMIT 100scriem#define LIMIT 10000

Daca nu am fi folosit acest mod de definire a constantei LIMIT, atunci ar fi trebuit sa modificam peste tot in program 100 cu 10000.

1.6 Folosirea functiilor printf() si scanf()

Functiile de tiparire, respectiv de citire, "printf()" si "scanf()" au urmatoarele argumente:sir_de_control si celelalte_argumenteunde sir_de_control este un sir care poate contine specificatii de conversie, sau formate. O specificare de conversie incepe cu caracterul % si se termina cu caracterul de conversie. De exemplu, in formatul %d, litera "d" este caracterul de conversie.

Folosirea lui printf()

Reamintim ca formatul %d este folosit pentru scrierea valorii unei expresii ca un intreg zecimal. In mod similar:

- %c este folosit pentru tiparirea unei expresii ca un caracter- %f este folosit pentru tiparirea unei expresii reale- %s este folosit pentru tiparirea unui sir de caractere

Exemplu: Fie instructiunea:

printf("Multime de argumente: %s %d %f %c%c\n","one",2,2.33,'G','O');

Argumentele lui "printf()" sunt separate de virgula, deci avem sase argumente. Primul argument este sirul de control. Obtinem corespondenta:%s "one"%d 2%f 2.33%c 'G'%c 'O'

Cand se executa programul ce contine aceasta instructiune, obtinem:

Multime de argumente: one 2 2.330000 GO

Observatii:

1. Daca instructiunea "printf()" contine prea multe caractere, atunci se poate scrie aceasta pe mai multe linii, separate prin virgula. De exemplu, putem scrie:printf("%s%s\n",

"Aceasta instructiune se va scrie ","pe o linie de text foarte lunga.\n");

Tabelul de mai jos descrie cum caracterele de conversie afecteaza argumentele corespunzatoare.printf()

Caracter de conversie: Cum este tiparit argumentul corespunzator ?

c- ca un caracterd- ca un intreg zecimale- ca un numar in virgula flotanta in notatia stiintificaf- ca un numar in virgula flotantag- in format e sau f (alegand cel mai scurt dintre ele)s- ca un sir

Cand un argument este tiparit, locul unde este tiparit se numeste campul sau, iar numarul de caractere ale acestui camp se numeste lungimea campului. Aceasta lungime poate fi specificata intr-un format ca un intreg plasat intre caracterul % si caracterul de conversie. De exemplu, instructiunea:printf("%c%3c%7c\n", 'A', 'B', 'C');va tipari:A B CPentru numerele in virgula flotanta, putem controla precizia (numarul de cifre zecimale), la fel ca lungimea campului. Forma generala a formatului este:%m.nfsi semnifica ca m este lungimea campului, iar n precizia. Formatul %mf specifica doar lungimea campului, iar formatul %.nf numai precizia. De exemplu, instructiunile:printf("Numere1: %.1f %.2f %.3f\n", 1.0, 2.0, 3.0);printf("Numere2: %7.1f %7.2f %7.3f\n", 4.0, 5.0, 6.0);vor avea ca efect afisarea:Numere1: 1.0 2.00 3.000Numere2: 4.0 5.00 6.000

Folosirea lui scanf()

Functia "scanf()" este asemanatoare cu "printf()", dar este folosita pentru intrari in loc de iesiri. Primul sau argument este un sir de control care are formatele corespunzatoare cu variatele moduri de interpretare a sirurilor de intrare. Dupa sirul de control urmeaza adresele variabilelor. Adresa unei variabile este locul din memorie unde este memorata variabila (vom reveni in capitolele viitoare). Simbolul "&" reprezinta operatorul de adresa. De exemplu,scanf("%d", &x);

Atentie ! Functia "prinf()" foloseste formatul %f pentru tiparirea numerelor float si double, pe cand ""scanf()" foloseste formatul %f pentru citirea unui float si %lf pentru citirea unui double.

Exemplu: Aria unui cerc.

#include#define PI 3.141592653589793main(){double raza;printf("\n%s\n\n%s","Acest program calculeaza aria cercului","Dati raza:");scanf("%lf", &raza);printf("\n%s\n%s%.2f%s%.2f%s%.2f\n%s%.5f\n\n","Aria = PI * raza * raza"," = ", PI, " * ", raza, " * ", raza," = ", PI * raza * raza);}

Presupunem ca la executia programului introducem raza egala cu 2.333. Atunci vor apare pe ecran:Acest program calculeaza aria cercului

Dati raza: 2.333

Aria = PI * raza * raza = 3.14 * 2.33 * 2.33 = 17.09934.

Daca am calcula separat (pe hartie), am obtine Aria = 3.14 * 2.33 * 2.33 = 17.046746, numar care nu coincide cu cel furnizat de calculator. Justificarea este aceea ca PI si raza sunt tiparite doar cu doua zecimale, pe cand valorile lor sunt pastrate in memorie cu precizie mai mare.

1.7 Instructiunea "while"

Instructiunea while face parte din categoria actiunilor repetitive. Pentru a intelege aceasta instructiune, vom face un exemplu de adunare a numerelor de la 1 la 10.

Exemplu:

#includemain(){int i=1, suma=0;while (i