Differences

This shows you the differences between two versions of the page.

Link to this comparison view

programare:laboratoare:lab03 [2020/10/12 11:26]
george.muraru [Extra]
programare:laboratoare:lab03 [2025/10/15 18:08] (current)
darius.neatu [PCLP Laborator03: Funcții. Recursivitate. Clase de stocare]
Line 1: Line 1:
-===== Instructiunile limbajului C. =====+===== PCLP Laborator03:​ FuncțiiRecursivitate. Clase de stocare  ​=====
  
 **Responsabili:​** **Responsabili:​**
-  * [[neatudarius@gmail.com|Darius Neațu (CA 2019-2020)]] +  * [[neatudarius@gmail.com|Darius Neațu (2019 - prezent)]] 
-  * [[ion_dorinel.filip@cti.pub.ro|Dorinel Filip (CA 2019-2020)]] +  * [[ion_dorinel.filip@cti.pub.ro|Dorinel Filip (2019 - prezent)]] 
-  * [[emil.racec@gmail.com|Emil Racec (2012)]] +  * [[andrei.parvu@cti.pub.ro|Andrei Pârvu]] 
-  * [[octavian.rinciog@gmail.com|Octavian Rînciog (2010)]]+
  
 ==== Obiective ==== ==== Obiective ====
  
-În urma parcurgerii acestui laborator studentul va fi capabil ​+În urma parcurgerii acestui laboratorstudentul va fi capabil: 
-  * scrie programe ​utilizând structuri condiţionale si de repetiţie+ 
 +  * să declare şi să definească o funcţie în limbajul ​C 
 +  * să apeleze funcţii definite în acelaşi fişier sursă, cât şi funcţii din alte fişiere sursă sau biblioteci 
 +  * să distingă între parametrii formali şi cei efectivi, între cei transmişi prin valoare şi cei transmişi prin adresa ​de memorie 
 +  * să explice rolul funcţiei ''​main()''​ într-un program 
 +  * să folosească clasele de stocare în declaraţiile unor funcţii
  
 ==== Noţiuni teoretice ==== ==== Noţiuni teoretice ====
  
-=== Instrucţiuni condiţionale ===+Funcţiile împart taskuri complexe în bucăţi mici mai uşor de înţeles şi de programat. Acestea pot fi refolosite cu alte ocazii, în loc să fie rescrise de la zero. De asemenea, funcţiile sunt utile pentru a ascunde detalii de funcţionare ale anumitor părţi ale programului,​ ajutând la modul de lucru al acestuia. Utilizând funcţii, care reprezintă unitatea fundamentală de execuţie a programelor C, se obţine o divizare logică a programelor mari şi complexe.
  
-== If-else ==+Împărţirea programelor în funcţii este arbitrară şi depinde de modul de gândire a celui care le creează. De obicei, funcţiile cuprind o serie de instrucţiuni care efectuează un calcul, realizează o acţiune, implementează un algoritm, etc. Crearea funcţiilor trebuie să se bazeze pe următoarele principii: ''​claritate'',​ ''​lizibilitate'',​ ''​uşurinţă în întreţinere'',​ ''​reutilizabilitate''​.
  
-''​if...else''​ este cea mai simplă instrucţiune condiţională. Poate fi folosită ​în mai multe forme:+==== Definirea şi apelul unei funcţii în C ====
  
-<code c> +Caracteristicile definitorii ale unei funcţii în C sunt: numele, parametrii de apel şi valorea returnată.  
-if (condition) { +Sintaxa standard de **declarare** a unei funcţii este:
-  // instructions +
-  //... +
-} +
-</​code>​+
  
-<​code ​c> +<​code ​bashtip_returnat nume_functie ​(tip_param1 nume_param1 , tip_param2 nume_param2, ​...); </​code>​
-if (condition) { +
-  // instructions +
-  // ... +
-} else { +
-  // other instructions +
-  // ... +
-+
-</​code>​+
  
-<code c> +Această declarare poartă numele de **antetul funcţiei** ​(**function signature** sau simplu** signature**). Lista de parametri **poate** lipsi.
-if (condition1+
-  ​..+
-} else if (condition2) { +
-  ... +
-+
-  ... +
-else if (conditionN) { +
-  ... +
-+
-</​code>​+
  
-Instrucţiunea evaluează expresia ''​condition''​ şi execută instrucţiunile dintre acolade doar dacă rezultatul este nenul. În varianta cu ''​else''​pentru rezultat nul este executat blocul de instrucţiuni aflat după ''​else''​.+Odată declarată, o funcţie trebuie **definită**în sensul că trebuie expandat corpul acesteia cu instrucţiunile pe care trebuie să le execute 
 + 
 +Definirea unei funcţii are forma: ​
  
-În al treilea caz, sunt evaluate pe rând condiţiile şi este executat blocul corespunzător primei condiţii adevărate. Un exemplu de folosire este: 
  
 <code c> <code c>
-if (a == b) { +tip_returnat nume_functie(tip_param1 nume_param1,​ tip_param2 nume_param2,​ ...) { 
-  ​printf("​Numerele sunt egale"​)+  ​declaratii de variabile si instructiuni
-} else if (a > b) { +   
-  ​printf("​A este mai mare")+  ​return expresie
-}+
 </​code>​ </​code>​
  
-== Switch ==+Limbajul C permite separarea declaraţiei unei funcţii de definiţia acesteia (codul care o implementează). Pentru ca funcţia să poată fi folosită, este obligatorie doar declararea acesteia înainte de codul care o apelează. Definiţia poate apărea mai departe în fişierul sursă, sau chiar într-un alt fişier sursă sau bibliotecă.
  
-''​switch''​ este o instrucţiune menită să simplifice structurile condiţionale cu mai multe condiţii.+Diferite părţi din definirea unei funcţii pot lipsiAstfel, o funcţie minimală este:
  
-<code c> +<code c> dummy() {} </​code>​
-switch ​(expression) { +
-  case constant1:​ +
-    // instructions1 +
-  case constant2:​ +
-    // instructions2 +
-  ... +
-  default: +
-    // instructions +
-} +
-</​code>​+
  
-Valoarea ''​expression''​ este evaluată la un tip intregapoi această valoare este comparată cu fiecare constantă; este rulat blocul ​de instrucţiuni ​al valorii găsite. În caz ca numărul nu este egal cu nici una dintre constante, ​este executat blocul aflat după ''​default''​.+Funcţia de mai sus nu face absolut nimic, nu întoarce nici o valoare şi nu primeşte nici un argumentînsă din punct de vedere ​al limbajului C este perfect validă.
  
-<note important>​ +Tipul returnat de o funcţie poate fi orice tip **standard** sau **definit** de utilizator (**struct**-uri - acoperite într-un laborator următor)inclusiv tipul **void** (care înseamnă că funcția nu returnează nimic).
-După executarea ultimei instrucţiuni dintr-un bloc ''​case''​execuţia nu continua după blocul ''​switch'',​ ci la inceputul următorului bloc ''​case //​constant//''​ sau ''​default''​. Pentru a ieşi din blocul ''​switch'',​ se foloseşte instrucţiunea ''​break''​. +
-</​note>​+
  
-<code c> +Orice funcţie care întoare un rezultat trebuie să conţină instrucţiunea:​ 
-int main() { + 
-  char c; +<code c> return expression; </code
-  printf("​Alegeţi o opţiune:\n\t[a] afişare\n\t[s] ştergere\n\t[e] ​ieşire\n"​);​ + 
-  scanf("​%c"​&c); +Expresia este evaluată şi convertită la tipul de date care trebuie returnat de funcţie. Această instrucţiune termină şexecuţia funcţiei, **indiferent** dacă după aceasta mai urmează sau nu alte instrucţiuni. Dacă este cazul, se pot folosi mai multe instrucţiuni **return** pentru ​determina mai multe puncte de ieşire ​din funcţieîn raport cu evoluţia funcţiei. 
-  ​printf("​Aţi ales"); + 
-  +Exemplu
-  ​switch (c) { + 
-    case '​a':​ +<code c declarare.c> 
-      printf("​afişare"​); +int min(int x, int y); 
-      ​break;​ +</​code>​ 
-  + 
-    case '​s':​ +<code c definire.c>​ 
-      ​printf("​ştergere"​); +int min(int x, int y{ 
-      ​break;​ +  ​if ​(x < y{ 
-  +    ​return x;
-    case '​e':​ +
-      printf("​ieşire"​)+
-      break; +
-  +
-    ​default: +
-      printf("​O opţiune inexistentă"​);​ +
-      break;+
   }   }
-  return ​0;+  ​ 
 +  ​return ​y;
 } }
 </​code>​ </​code>​
 +
 +Apelul unei funcţii se face specificând **parametrii efectivi** (parametrii care apar în declararea funcţiei se numesc **parametri formali**).
  
 <code c> <code c>
 int main() { int main() {
-  int nn2+  int ab, minimum
-  ​printf("​Introduceţi o valoare între 0 şi 5:"); +  ​//​........... 
-  ​scanf("​%d",​ &n)+  ​x = 2
-  ​n2 1+  ​5
-  ​switch ​(n) { +  ​minimum = min(x, 4)
-    case 5: +  printf("​Minimul dintre ​%d si 4 este%d", ​xminimum); 
-      n2 *= 2; +  printf("​Minimul dintre %d si %d este: %d", x, y, min(x, y));
-      /* fără breakcontinuă la următoarea instrucţiune */ +
-    case 4+
-      n2 *= 2+
-    case 3: +
-      n2 *= 2; +
-    case 2: +
-      n2 *= 2; +
-    case 1: +
-      n2 *= 2; +
-    case 0: +
-      ​printf("​2 la puterea ​%d este %d\n", ​nn2); +
-      ​break;​ +
-  +
-    default: +
-      ​printf( "Valoare invalidă\n" )+
-  } +
-  return 0;+
 } }
 </​code>​ </​code>​
  
-=== Instrucţiuni de repetiţie ​===+==== Transmiterea parametrilor ==== 
 + 
 + 
 +Apelul unei funcţii se face specificând parametrii care se transmit acesteia. În limbajul C, dar şi în alte limbaje ​de programare există ** 2 moduri de transmitere a parametrilor**. Deoarece nu avem încă cunoștințele necesare pentru a înțelege ambele moduri, astăzi vom studia doar unul, urmând ca în laboratorul 8 să revenim și să îl explicăm și pe al doilea. 
 + 
 +=== Transmiterea parametrilor prin valoare ​===
  
-== while ==+Funcţia va lucra cu **o copie** a variabilei pe care a primit-o şi **orice** modificare din cadrul funcţiei va opera asupra aceste copii. La sfârşitul execuţiei funcţiei, copia va fi **distrusă** şi astfel se va pierde orice modificare efectuată. ​
  
-''​while''​ execută un bloc de instrucţiuni atâta timp cât o anumită condiţie este adevărată. Forma generală a unui ciclu while este:+Pentru a nu pierde modificările făcute se foloseşte ​instrucţiunea **return**, care poate întoarce, la terminarea funcţiei, noua valoare a variabilei. Problema apare în cazul în care funcţia modifică mai multe variabile şi se doreşte ca rezultatul lor să fie disponibil şi la terminarea execuţiei funcţiei
  
 +Exemplu de transmitere a parametrilor prin valoare:
 <code c> <code c>
-while (expression+min(x, 4) // ​se face o copie lui x
-  // ​instructions +
-}+
 </​code>​ </​code>​
  
-Câtă vreme ''​expression'' ​are o valoare nenulă, instrucţiunile din blocul ​de după ''​while'' ​sunt executateExpresia este reevaluată după fiecare ciclu. Un astfel ​de ciclu poate să se execute o dată, ​de mai multe ori sau niciodată, ​în funcţie ​de valoarea la care se evaluează expresia.+<note tip> 
 +Până acum aţi folosit în programele voastre funcţii care trimit valorile atât prin valoare (de exemplu ​''​printf()''​) cât şi prin intermediul adresei ​de memorie (de exemplu ​''​scanf()''​)Mecanismul ​de transfer al valorilor prin intermediul adresei ​de memorie unde sunt stocate va fi complet „elucidat” ​în laboratorul ​de pointeri. 
 +</​note>​
  
-== do ... while ==+==== Funcţii recursive ====
  
-''​do ..while''​ este instrucţiune repetitivă similara cu cea precedentă, singura diferenţa fiind că expresia este evaluată după executarea instrucţiunilornu înainte. Astfelblocul va fi executat cel puţin o dată.+O funcţie poate să apeleze la rândul ei alte funcţiiDacă funcţie se apelează pe sine **însăşi**atunci funcţia este **recursivă**. Pentru ​evita un număr infinit de apeluri recursive, trebuie ca funcţia să includă în corpul ei o **condiţie de oprire**astfel cala un moment ​dat, recurenţa să se oprească şi să se revină succesiv din apeluri.
  
-<code c> +Condiţia trebuie să fie una generică, şi să oprească recurenţa în orice situaţie. Această condiţie se referă în general a parametrii de intrare, pentru care la un anumit moment, răspunsul poate fi returnat direct, fără a mai fi necesar un apel recursiv suplimentar. ​
-do { +
-  // instructions +
-} while (expression);​ +
-</​code>​+
  
-== for == +''​Exemplu'': ​Calculul recursiv al factorialului
- +
-''​for'' ​reprezintă o formă mai simplă de a scrie un while însotit de o expresie iniţiala şi de o expresie de incrementare. Forma sa este:+
  
 <code c> <code c>
-for (expression1;​ expression2;​ expression3) { +int fact(int n) { 
-  ​// instructions+  ​if (n == 0) { 
 +    return 1; 
 +  } else { 
 +    return n * fact(n - 1); 
 +  }
 } }
 </​code>​ </​code>​
  
-Secvenţa de cod de mai sus este echivalentă cu:+sau, într-o formă ​mai compactă:
  
 <code c> <code c>
-expression1 +int fact(int n) { 
-while (expression2) { +  ​return (n >= 1) ? n * fact(n - 1) : 1;
-  ​// instructions +
-  expression3+
 } }
 </​code>​ </​code>​
  
-În cazul instrucţiunii ''​for''​oricare dintre cele 3 expresii ​poate lipsiLipsa expresiei condiţionale este echivalentă cu buclă infinită, cum ar fi:+Întotdeauna trebuie avut grijă în lucrul cu funcţii recursive deoarece, la fiecare apel recursiv, contextul este salvat pe stivă pentru a putea fi refăcut la revenirea din recursivitate. ​În acest fel, în funcţie de numărul apelurilor recursive şi de dimensiunea contextului (variabiledescriptori de fişier, etc.) stiva se poate umple foarte rapid, generând o eroare de tip [[http://en.wikipedia.org/​wiki/​Stack_overflow | stack overflow]] (vezi şi [[http://​en.wikipedia.org/​wiki/​Infinite_recursion | Infinite recursion pe Wikipedia]]). 
 + 
 +==== Funcţia main ==== 
 + 
 +Orice program C conţine cel puţin ​funcţie, şi anume cea principală, numită ''​main()''​. Aceasta are un format special de definire:
  
 <code c> <code c>
-for ; ; ) { +int main(int argc, char *argv[]) 
-  /* instrucţiunile de aici sunt intr-o buclă infinită */+
 +    // some code 
 +    return 0;
 } }
 </​code>​ </​code>​
  
-<note important>​ +Primul parametru''​argc'',​ reprezintă numărul de argumente primite de către program la linia de comandă, incluzând numele ​cu care a fost apelat programul. Al doilea parametru, ''​argv'',​ este un pointer către conţinutul listei de parametri al căror număr este dat de ''​argc''​. ​Lucrul cu parametrii liniei de comandă va fi reluat într-un laborator viitor. ​
-În acest cazieşirea din buclă trebuie făcută explicit, cu ajutorul instrucţiunii ''​break''​. +
-</​note>​+
  
-Exemplul următor prezintă un ciclu cu funcţionalitate identică (tipărirea primelor 10 numere naturale)folosind cele 3 instrucţiuni repetitive:+Atunci când nu este necesară procesarea parametrilor de la linia de comandă, se poate folosi forma prescurtată a definiţiei ​funcţiei ''​main''​şi anume:
  
 <code c> <code c>
-int main() ​{ +int main(void
-  short i; +
-  printf("​Ciclu for\n"​);​ +    ​// some code 
-  +    ​return ​0;
-  for (i = 1; i <= 10; i++) +
-    ​printf("​i=%d\n",​ i); +
-  } +
-  +
-  printf("​Ciclu while\n"​);​ +
-  i = 1; +
-  while (i <= 10) { +
-    ​printf("​i=%d\n",​ i); +
-    i++; +
-  } +
-  +
-  printf("​Ciclu do while\n"​);​ +
-  i = 0+
-  do { +
-    i++; +
-    printf("​i=%d\n",​ i); +
-  } while(i < 10);+
 } }
 </​code>​ </​code>​
  
-Pentru blocuri de singură instrucţiune (cum este si cazul instructiunii executate ​de for in exemplul de mai sus) nu este nevoie sa folosim acoladeTotusifolosirea acoladelorchiar si in aceasta situatieeste recomandata pentru ​depanare mai usoara si o lizibilitate mai buna a programelor.+În ambele cazuri, standardul impune ca ''​main''​ să întoarcă ​valoare de tip întreg, care să reprezinte codul execuţiei programului şi care va fi pasată înapoi sistemului ​de operare, la încheierea execuţiei programuluiAstfelinstrucţiunea ''​return''​ în funcţia ''​main''​ va însemna şi terminarea execuţiei programului.  
 + 
 +În mod normalorice program care se execută corect va întoarce 0şi valoare diferită de 0 în cazul în care apar erori. Aceste coduri ar trebui documentate pentru ca apelantul programului să ştie cum să adreseze eroarea respectivă.
  
-=== Instrucţiuni speciale ​===+==== Tipul de date void ====
  
-== break ==+Tipul de date ''​void''​ are mai multe întrebuinţări.
  
-''​break''​pe lângă utilizarea descrisă la instrucţiunea switch, poate fi folosită pentru a ieşi forţat dintr-instrucţiune de repetiţieSecventa următoare este echivalentă cu cele de mai sus:+Atunci când este folosit ca tip returnat de o funcţiespecifică faptul că funcţia nu întoarce nici valoareExemplu:
  
 <code c> <code c>
-i = 0; +void print_nr(int number) { 
-for; ; ) { +  printf("​Numarul este %d", ​number);
-  i++; +
-  if (i > 10) { +
-    break; /* ieşire forţată din bucla */ +
-  } +
-  printf( "i=%d\n", ​);+
 } }
 </​code>​ </​code>​
  
-== continue == +Atunci când este folosit în declaraţia unei funcţii, ''​void'' ​semnifică faptul că funcţia nu primeşte nici un parametruExemplu:
- +
-''​continue''​ forţează terminarea iteraţiei curente a buclei si trecerea la iteraţia următoare. În cazul instrucţiunii ''​for''​, acest lucru presupune executarea instrucţiunii de incrementare;​ apoi se evaluează condiţia de continuare a bucleiExemplul următor demonstrează implementarea unei bucle infinite cu ajutorul instrucţiunii ''​continue''​:+
  
 <code c> <code c>
-for (i = 0; i < 10; ) { +int init(void) { 
-  ​if (i == 0) { +  ​return 1;
-    continue; +
-  } +
-  i++;+
 } }
 </​code>​ </​code>​
  
-== return == +<note important>​ 
- +Această declaraţie nu este similară cu următorul caz:
-''​return''​ este instrucţiunea de terminare a funcţiei curente. Aceasta poate fi apelată in forma ''​return'';​ în cazul funcţiilor care returnează ''​void''​ şi în forma ''​return //​result//'';​ pentru funcţiile care întorc o valoare. +
- +
-== goto == +
- +
-''​goto'' ​este o instrucţiune de salt a execuţiei. Instrucţiunea primeşte ca parametru o etichetăurmătoarea instrucţiune executată după ''​goto''​ este cea de la eticheta dată.+
  
 <code c> <code c>
-int main() { +int init() { 
-  goto et;  +  return ​1;
-  printf("​Asta nu apare la executie\n"​);​ +
-  +
-et: +
-  printf("​Asta apare la rulare\n"​);​ +
-  return ​0;+
 } }
 </​code>​ </​code>​
  
-<note important>​ +În cel de-al doilea cazcompilatorul ​nu verifică dacă funcţia este într-adevăr apelată fără nici un parametru. Apelul celei de-a doua funcţii ​cu un număr arbitrar de parametri nu va produce nici o eroare, în schimb apelul primei funcţii cu un număde parametri diferit ​de zero va produce o eroare de tipul: 
-În majoritatea cazurilorutilizarea instrucţiunii ''​goto'' ​nu este recomandată şi poate fi evitată folosind alte instrucţiuni de control şi funcţii. Programele care folosesc această instrucţiune pentru a sări între secvenţe îndepărtate ​de cod sunt dificil ​de depanat şi analizat.+ 
 +''​too many arguments to function''​.
 </​note>​ </​note>​
  
  
 +==== Clase de stocare. Fişiere antet vs. biblioteci ====
 +<note tip>
 +Această secţiune este importantă pentru înţelegerea modului de lucru cu mai multe fişiere sursă şi cu bibliotecile oferite de GCC. Deşi în continuare sunt discutate în contextul funcţiilor,​ lucrurile se comportă aproximativ la fel şi în cazul variabilelor globale (a căror utilizare este, oricum, descurajată).
 +</​note>​
  
-==== Exerciții Laborator CB/CD ====+După cum se ştie, într-un fişier sursă (.c) pot fi definite un număr oarecare de funcţii. În momentul în care programul este compilat, din fiecare fişier sursă se generează un fişier obiect (.o), care conţine codul compilat al funcţiilor respective. Aceste funcţii pot apela la rândul lor alte funcţii, care pot fi definite în acelaşi fişier sursă, sau în alt fişier sursă. În orice caz, compilatorul nu are nevoie să ştie care este definiţia funcţiilor apelate, ci numai semnătura acestora (cu alte cuvinte, ''​declaraţia''​ lor), pentru a şti cum să realizeze instrucţiunile de apel din fişierul obiect. Acest lucru explică de ce, pentru a putea folosi o funcţie, trebuie ''​declarată''​ înaintea codului în care este folosită.
  
-  - Primul exercitiu presupune modificarea/​adaugarea ​de instructiuni unui cod pentru a realiza anumite lucruriIn momentul actual programul afiseaza daca un numar este prim, iar in caz contrar afiseaza divizorii nebanali. +''​Fişierele antet''​ conţin o colecţie ​de declaraţii de funcţii, grupate după funcţionalitatea pe care acestea o oferăAtunci când includem ​un fişier antet (.h) într-un fişier sursă (.c), compilatorul va cunoaşte toate semnăturile funcţiilor de care are nevoie, şi va fi în stare să genereze codul obiect pentru fiecare fişier sursă în parte(NOTĂ: Astfel nu are sens includerea unui fişier ​.c în alt fişier ​.c; se vor genera două fişiere obiect care vor conţine definiţii comune, şi astfel va apărea un conflict de nume la editarea legăturilor).
-    *Nu uitati ca trebuie sa utilizam ​un [[http://​ocw.cs.pub.ro/​courses/​programare/​coding-style| coding style]] adecvat atunci cand scriem sursele. +
-<​code ​ex1.c+
-#include <stdio.h>+
  
-int main(void) +Cu toate acesteapentru a realiza un fişier executabiltrebuie ca fiecare funcţie să fie ''​definită''​. Acest lucru este realizat de către editorul de legăturicu alte cuvinte, fiecare funcţie folosită în program trebuie să fie conţinută în fişierul executabil. Acesta caută în fişierele obiect ale programului definiţiile funcţiilor de care are nevoie fiecare funcţie care le apelează, şi construieşte un singur fişier executabil care conţine toate aceste informaţii. ''​Bibliotecile''​ sunt fişiere obiect speciale, al căror unic scop este să conţină definiţiile funcţiilor oferite de către compilator, pentru a fi integrate în executabil de către editorul de legături.
-+
-    int nri; +
-    int prim = 1; +
-  +
-    scanf("​%d"​&nr);+
  
-    for (i = 2; i < nr; i+++''​Clasele de stocare''​ intervin în acest pas al editării de legături. O clasă de stocare aplicată unei funcţii indică dacă funcţia respectivă poate fi folosită şi de către alte fişiere obiect ​(adică este ''​externă''​), sau numai în cadrul fişierului obiect generat din fişierul sursă în care este definită ​(în acest caz funcţia este ''​statică''​). Dacă nu este specificată nici o clasă de stocareo funcţie este implicit externă.
-        if (nr % i == 0+
-     printf("​%d "i); +
-     prim = 0; +
-+
-    }+
  
-    if (nr > 1 && prim) { +Cuvintele cheie ''​extern''​ şi ''​static''​puse în faţa definiţiei funcţiei, îi specifică clasa de stocare. De exemplu, pentru a defini o funcţie internă, se poate scrie:
-        printf("​Numarul %d este numar prim"nr); +
-    } +
- +
-    printf("​\n"​);​ +
-  +
-    return 0; +
-}+
  
 +<code c>
 +static int compute_internally(int,​ int);
 </​code>​ </​code>​
  
-Cerinte: +Funcţia ''​compute_internally'' ​nu va putea fi folosită decât ​de către funcţiile definite ​în acelaşfişier sursă şi nu va fi vizibilă de către alte fişiere sursă, în momentul editării  legăturilor.
-  *Modificati codul astfel incat sa se afiseze doar daca un numar este prim sau nu+
-  *Trebuie sa adaugati o instructiune repetitiva astfel incat programul sa afiseze daca numerele din intervalul [1; n] sunt prime sau nu (pentru fiecare numar din interval se va verifica daca este prim sau nu). +
-  *Sariti peste numar daca acesta are restul impartirii la 5 egal cu 4. +
-  *Realizati urmatoarele actiuni in functie de restul impartirii numarului la 10: +
-     ​*Restul 1: Afisati numarul; +
-     ​*Restul 2: Afisati numarul / 10; +
-     ​*Restul 3: Afisati daca numarul este prim sau nu; +
-     ​*Restul 5: Cresteti limita for-ului cu 1. +
-     *Daca restul impartirii numarului la 10 nu se afla in cazurile specificate atunci nu faceti nimic (prelucrati urmatorul numar) +
- +
-**Următoarele două probleme vă vor fi date de asistent în cadrul laboratorului.** +
- +
-[[https://​drive.google.com/​drive/​folders/​1qB6EZLGVubKbuTXMtMue06egH_8fo25M|Tasks laborator 3]] +
- +
-<spoiler Cum se foloseste checkerul>​ +
-Pentru utilizarea checkerului:​ +
-  *Se va scrie cate un fisier sursa pentru fiecare problema; +
-  *La finalul fiecarui printf utilizat pentru afisarea rezultatului trebuie sa existe un newline; +
-  *Sursa nu trebuie sa contina alte printf-uri in afara de cele care scriu rezultatul asteptat la stdout. +
-  *Se va dezarhiva arhiva specifica exercitiului;​ +
-  *In directorul curent se afla checkerul, executabilul generat, folderele de input si output specifice problemei;​ +
-  *Se va rula “bash checker.sh <​executabil>​” unde <​executabil>​ este numele executabilului generat; +
- +
-</​spoiler>​ +
- +
-==== Probleme ==== +
- +
-  - [1.5p] Se citeşte de la tastatură un număr întreg si pozitiv N. Să se scrie un program care determină care număr cuprins intre 2 si N are suma divizorilor nebanali maximă (adică printre divizori nu sunt considerate numerele 1 si N). Dacă există mai multe asemenea numere se va afişa numai primul dintre ele.\\ **Exemplu** <​code>​ +
-N=100 +
-OUT: 96 //are suma divizorilor 155 +
-</​code>​ +
-  - [1.5p] De la tastatură se introduc mai multe numere întregi si pozitive, terminate printr-un număr negativ. După fiecare număr introdus, se va afişa lista divizorilor lui nebanali sau textul PRIM. La sfârşit se va afişa numărul ​de numere prime găsite.\\ **Exemplu** <​code>​35 +
-OUT: 5 7 +
-36 +
-OUT: 2 3 4 6 9 12 18 +
-17 +
-OUT: PRIM +
-+
-OUT: PRIM +
-12 +
-OUT: 2 3 4 6 +
-25 +
-OUT: 5 +
-53 +
-OUT: PRIM +
--4 +
-OUT: S-au găsit 3 numere prime. +
-</​code>​ +
-  - [2p] Fie funcţia ''​f:​[u,​v] − > [min,​max],​f(x) = a * x2 + b * x + c''​ , în care a, b, c, u si v sunt date. Determinaţmin si max, apoi rezolvaţi ecuaţia f(x)=0 în mulţimea numerelor reale. Afişaţi doar rădăcinile din intervalul ''​[u,​v]''​. +
-  - [2p] Scrieţi un program care să convertească numere din baza 2 în baza 10 şi invers. Numerele se introduc de la tastatură până la intâlnirea unui număr negativ. Pentru fiecare număr introdus, se va afişa pe o linie rezultatul. +
-  - [3p] Scrieţi un program care verifică dacă un număr citit de la tastatură este palindrom. Un număr se consideră palindrom dacă citit invers este identic cu numărul iniţial. +
- +
-=== Bonus === +
- +
-  - [2p] De la tastatură se introduc N(fiind dat şi el de la tastatură) numere citite pe rând. Găsiţi cel mai mare divizor comun al acestor N numerefără a folosi vectori.+
  
-==== Extra ====+==== Exerciții ​==== 
 +Exercițiile pentru laborator se găsesc pe [[https://​acs-pclp.github.io/​laboratoare/​03 | PCLP Laborator03 - Funcții. Recursivitate. Clase de stocare]].
  
-  * [[https://​github.com/​cs-pub-ro/​ComputerProgramming/​blob/​master/​Laboratories/​Lab3/​cheatsheet.pdf|Cheatsheet]] 
  
 +===== Referinţe =====
  
-==== Referinţe ====+  * [[http://​www.tutorialspoint.com/​ansi_c/​c_using_functions.htm | C - Using Functions]] 
 +  * [[https://​github.com/​cs-pub-ro/​ComputerProgramming/​blob/​master/​Laboratories/​Lab4/​Lab4.pdf | Cheatsheat Functii]]
  
-  * [[http://​www.tutorialspoint.com/​ansi_c/​c_control_statements.htm|C - Control Statements]] 
programare/laboratoare/lab03.1602491187.txt.gz · Last modified: 2020/10/12 11:26 by george.muraru
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0