<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ro">
	<id>http://wiki.dcae.pub.ro/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Vpopescu</id>
	<title>WikiLabs - Contribuții utilizator [ro]</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.dcae.pub.ro/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Vpopescu"/>
	<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php/Special:Contribu%C8%9Bii/Vpopescu"/>
	<updated>2026-05-26T11:25:03Z</updated>
	<subtitle>Contribuții utilizator</subtitle>
	<generator>MediaWiki 1.35.14</generator>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4242</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4242"/>
		<updated>2016-01-10T17:34:57Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: /* Exerciții */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8: &amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură. Dacă rulăm programul vom obține ca rezultat numărul &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;, indiferent de ce a fost introdus de la tastatură. Ne propunem să descoperim bug-ul folosind GDB.&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Comanda de mai sus lansează în execuție numai debugger-ul, nu și programul &amp;#039;&amp;#039;suma_fact&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Putem observa că am pornit debugger-ul prin faptul că fiecare rând nou din linia de comandă începe acum astfel:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Punem un &amp;#039;&amp;#039;breakpoint&amp;#039;&amp;#039; la linia 20, unde se citește valoarea lui n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) b 20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1 at 0x80484c2: file suma_fact.c, line 20.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pornim programul în interiorul debugger-ului:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) run&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Starting program: /home/student/Desktop/suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1, main () at suma_fact.c:20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;20	        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Trecem mai departe și introducem o valoare pentru n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Introduceti un numar natural mai mic sau egal cu 8: 6 &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;21	    }while(n&amp;lt;0 || n&amp;gt;8);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Vom parcurge programul pas cu pas până la apelarea funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;22	    unsigned int suma = 0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=0) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;5	        return 1;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;13	}&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;main () at suma_fact.c:23&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=1) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;8	    unsigned int fact=0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;10	        fact *= i;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;12	    return fact;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) print fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;$1 = 0&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Observăm că valoarea returnată de funcția &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039; pentru orice număr nenul este &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Acest lucru se datorează inițializării variabilei &amp;#039;&amp;#039;fact&amp;#039;&amp;#039; cu valoarea &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; la începutul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;. Putem ieși din debugger pentru a modifica linia 8 din fișierul sursă suma_fact.c:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) q&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;A debugging session is active.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;  	Inferior 1 [process 4279] will be killed.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Quit anyway? (y or n) y &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Pentru a putea intra în interiorul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039; este absolut necesar să se folosească comanda &amp;#039;&amp;#039;&amp;#039;step&amp;#039;&amp;#039;&amp;#039; și nu comanda &amp;#039;&amp;#039;&amp;#039;next&amp;#039;&amp;#039;&amp;#039; care ar trece peste acea linie 24 fără a intra în corpul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exerciții ==&lt;br /&gt;
&amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;Să se citească de la tastatură un număr întreg fără semn n. Să se implementeze o funcție recursivă care returnează suma primelor n numere naturale și să se afișeze rezultatul apelării acestei funcții.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți o funcție recursivă care șterge dintr-un vector elementul de pe o anumită poziție; funcția primește ca parametri vectorul, numărul de elemente din vector și poziția elementului ce urmează a fi șters.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Să se citească de la tastatură un număr întreg fără semn n. Să se implementeze o funcție recursivă care calculează termenul de pe o poziție dată din șirul lui Fibonacci și să se afișeze primii n termeni, știind că șirul lui Fibonacci este definit astfel:&lt;br /&gt;
* F(0) = 0;&lt;br /&gt;
* F(1) = 1;&lt;br /&gt;
* F(i) = F(i-1) + F(i-2), pentru i&amp;gt;=2.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți o funcție recursivă care calculează 2 la puterea n, unde n este un număr întreg fără semn introdus de la tastatură.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți o funcție recursivă care descompune un număr întreg fără semn n într-o sumă de puteri ale lui 2. Afișați această descompunere.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți o funcție recursivă care descompune un număr întreg fără semn n într-o sumă de termeni din șirul lui Fibonacci. Afișați termenii din care este compus numărul.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Tema_3&amp;diff=4145</id>
		<title>PC Tema 3</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Tema_3&amp;diff=4145"/>
		<updated>2015-12-21T16:59:04Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: /* Algoritm */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Multe aplicații foarte puternice din informatică, de la instrumente de simulare, până la algoritmi de bioinformatică se bazează pe noțiuni de algebră liniară.&lt;br /&gt;
&lt;br /&gt;
= Introducere =&lt;br /&gt;
&lt;br /&gt;
Să de amintim de la orele de algebră: pe determinantul unei matrice pătratice se pot face operați liniare între două linii sau coloane influentând valoarea determinantului astfel:&lt;br /&gt;
* înmulțirea unei linii sau coloane cu o constantă face și valoarea determinantul să se înmulțească cu aceeași constantă;&lt;br /&gt;
* adunarea sau scăderea a două linii sau două coloane între ele păstrează constantă valoarea determinantului.&lt;br /&gt;
&lt;br /&gt;
= Cerință =&lt;br /&gt;
&lt;br /&gt;
Dându-se un număr &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt; întreg, în intervalul [2; 255], și o matrice pătratică de &amp;lt;code&amp;gt;n x n&amp;lt;/code&amp;gt; valori raționale, să se scrie o funcție recursivă care să calculeze determinantul acestei matrice.&lt;br /&gt;
&lt;br /&gt;
= Date de intrare =&lt;br /&gt;
&lt;br /&gt;
Numărul &amp;lt;code&amp;gt;n&amp;lt;/code&amp;gt;, valoare întreagă, în intervalul [2; 255] urmat de n * n numere de tip double, reprezentând conținutul matricei.&lt;br /&gt;
&lt;br /&gt;
== Exemplu ==&lt;br /&gt;
&lt;br /&gt;
 3&lt;br /&gt;
 1 1 2&lt;br /&gt;
 3 1 4&lt;br /&gt;
 2 3 1&lt;br /&gt;
&lt;br /&gt;
= Date de ieșire =&lt;br /&gt;
&lt;br /&gt;
O singură valoare de tip double, reprezentând valoarea determinantului matricei, în format științific, litere mici și două zecimale precizie.&lt;br /&gt;
&lt;br /&gt;
== Exemplu (pentru intrarea de mai sus) ==&lt;br /&gt;
&lt;br /&gt;
 8.00e+00&lt;br /&gt;
&lt;br /&gt;
= Algoritm =&lt;br /&gt;
&lt;br /&gt;
Pașii pentru realizarea acestui algoritm, implică, pentru matricea de &amp;lt;code&amp;gt;n x n&amp;lt;/code&amp;gt;, eliminarea prin operații liniare a elementelor de pe prima linie, lăsând o valoare nenulă doar pe prima poziție și memorând constantele cu care s-au înmulțit coloanele. Apoi, se apelează recursiv funcția de calcul al determinantului pentru o submatrice de &amp;lt;code&amp;gt;n-1 x n-1&amp;lt;/code&amp;gt;. Fie coloanele matricei de &amp;lt;code&amp;gt;n x n&amp;lt;/code&amp;gt; numerotate de la 0 la n-1.&lt;br /&gt;
# Daca coloana de pe poziția 0 are pe prima linie 0, se caută prima coloană care are pe prima linie o valoare nenulă și se adună la coloana 0 (dacă nu există nici una, determinantul e 0).&lt;br /&gt;
# Pentru coloanele de la 1 la n - 1, se înmulțește fiecare coloană cu valoarea din colțul din stânga sus și se împarte la primul element de pe coloană. Dacă coloana are deja 0 pe prima linie, ea nu se procesează. Produsul factorilor se memorează. Rezultatul va fi că pe prima linie din matrice va fi aceeași valoare.&lt;br /&gt;
# Pentru coloanele de la 1 la n - 1 se scade coloana 0, astfel, se obține o matrice unde pe prima linie toatele elementele mai puțin primul sunt 0.&lt;br /&gt;
# Valoarea determinantului este egală cu valoarea din stânga sus, împărțită la valoarea memorată, înmulțită cu valoarea determinantului submatricei de la (1,1) la (n-1, n-1).&lt;br /&gt;
&lt;br /&gt;
== Exemplu (pentru matricea de mai sus) ==&lt;br /&gt;
&lt;br /&gt;
1. Pentru coloanele de la 1 la 2, se înmulțește fiecare coloană cu valoarea din colțul din stânga sus (1) și se împarte la primul element de pe coloană.&lt;br /&gt;
&lt;br /&gt;
 1 1 2     1 1*(1/1) 2*(1/2)                                              1 1 1&lt;br /&gt;
 3 1 4 =&amp;gt;  3 1*(1/1) 4*(1/2) (se memorează factorii 1/1 * 1/2 = 0.5) =&amp;gt;   3 1 2&lt;br /&gt;
 2 3 1     2 3*(1/1) 1*(1/2)                                              2 3 0.5&lt;br /&gt;
&lt;br /&gt;
2. Pentru coloanele de la 1 la 2 se scade coloana 0.&lt;br /&gt;
&lt;br /&gt;
 1  0  0&lt;br /&gt;
 3 -2 -1&lt;br /&gt;
 2  1 -1.5&lt;br /&gt;
&lt;br /&gt;
3. Valoarea determinantului este colțul din stânga sus împărțit la produsul memorat, înmulțit cu determinantul submatricei următoare:&lt;br /&gt;
&lt;br /&gt;
                          -2   -1&lt;br /&gt;
 Det(m) = 1 / 0.5 *  Det(         ) = 8&lt;br /&gt;
                           1  -1.5&lt;br /&gt;
&lt;br /&gt;
4. Dacă matricea e mai mare de 3 x 3, pentru calculul submatricei următoare, se folosește recursiv același algoritm.&lt;br /&gt;
&lt;br /&gt;
= Observații =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt;Formatul textului de la ieșire trebuie să fie identic cu cel de la secțiunea &amp;quot;Date de ieșire&amp;quot; pentru a evita depunctarea de către programul de evaluare.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;li&amp;gt; &amp;#039;&amp;#039;&amp;#039;Atenție:&amp;#039;&amp;#039;&amp;#039; Nu afișați în consolă nimic altceva decât se cere explicit în problemă. Mai concret, nu printați nimic înainte de citirea textului de la tastatură (ex: Introduceți textul: ).&lt;br /&gt;
 &amp;lt;li&amp;gt;Pentru a vă ușura introducerea datelor, puteți scrie matricea de test într-un fișier, în formatul specificat la [[#Date de intrare]], și la execuție puteți redirecta stream-ul standard de intrare să citească din fișier, în loc de tastatură:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
./exec &amp;lt;inputFile.txt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unde &amp;lt;code&amp;gt;inputFile.txt&amp;lt;/code&amp;gt; este numele fișierului ce conține matricea de intrare, iar &amp;lt;code&amp;gt;exec&amp;lt;/code&amp;gt; este numele executabilului vostru.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Nu uitați de condiția de oprire pentru funcțiile recursive&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Restricții =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: red; font-weight: bold&amp;quot;&amp;gt;Obligatoriu se va implementa următoarea funcție:&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; inline&amp;gt;double computeDeterminant(double matrix[][], unsigned char start, unsigned char end);&amp;lt;/syntaxhighlight&amp;gt; - unde &amp;lt;code&amp;gt;matrix&amp;lt;/code&amp;gt; reprezinta matricea, &amp;lt;code&amp;gt;start&amp;lt;/code&amp;gt; reprezintă coordonata punctului din stânga sus din matrice de unde începe calculul determinantului, iar &amp;lt;code&amp;gt;end&amp;lt;/code&amp;gt; va fi colțul din dreapta jos unde se termină calculul determinantului și care va fi în permanență n-1; această funcție se va apela prima oară cu argumentele &amp;lt;code&amp;gt;matrix, 0, n-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
= Livrabile și modalitate de predare =&lt;br /&gt;
&lt;br /&gt;
Predarea se face pe platforma [http://homework.dcae.pub.ro:8888/Web-CAT/WebObjects/Web-CAT.woa Web-Cat] și constă în upload-ul unui singur fișier sursă C care să implementeze funcționalitatea cerută.&lt;br /&gt;
&lt;br /&gt;
= Notare =&lt;br /&gt;
&lt;br /&gt;
Pentru această temă se pot acorda 10 puncte:&lt;br /&gt;
* 7 puncte pentru comportamentul aplicației, care se acordă automat de către platforma de testare, imediat după predare, în funcție de calitatea temei;&lt;br /&gt;
* 3 puncte pentru stilul de scriere a programului, alinierea codului, nume lizibile de variabile, etc., care se acordă ulterior de către un cadru didactic.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;color: red; font-weight: bold;&amp;quot;&amp;gt;Atenție: &amp;lt;/span&amp;gt; Pentru această temă se pot SCĂDEA 11 puncte, dacă aceasta se dovedește că este copiată.&lt;br /&gt;
&lt;br /&gt;
= Termen limită =&lt;br /&gt;
&lt;br /&gt;
Termenul limită pentru depunerea temei este 31 decembrie, ora 23:55. Apoi, pentru fiecare zi întârziere, veți fi penalizați cu un punct.&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4050</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4050"/>
		<updated>2015-12-10T09:23:37Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: /* Exerciții */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8: &amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură. Dacă rulăm programul vom obține ca rezultat numărul &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;, indiferent de ce a fost introdus de la tastatură. Ne propunem să descoperim bug-ul folosind GDB.&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Comanda de mai sus lansează în execuție numai debugger-ul, nu și programul &amp;#039;&amp;#039;suma_fact&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Putem observa că am pornit debugger-ul prin faptul că fiecare rând nou din linia de comandă începe acum astfel:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Punem un &amp;#039;&amp;#039;breakpoint&amp;#039;&amp;#039; la linia 20, unde se citește valoarea lui n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) b 20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1 at 0x80484c2: file suma_fact.c, line 20.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pornim programul în interiorul debugger-ului:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) run&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Starting program: /home/student/Desktop/suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1, main () at suma_fact.c:20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;20	        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Trecem mai departe și introducem o valoare pentru n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Introduceti un numar natural mai mic sau egal cu 8: 6 &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;21	    }while(n&amp;lt;0 || n&amp;gt;8);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Vom parcurge programul pas cu pas până la apelarea funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;22	    unsigned int suma = 0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=0) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;5	        return 1;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;13	}&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;main () at suma_fact.c:23&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=1) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;8	    unsigned int fact=0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;10	        fact *= i;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;12	    return fact;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) print fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;$1 = 0&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Observăm că valoarea returnată de funcția &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039; pentru orice număr nenul este &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Acest lucru se datorează inițializării variabilei &amp;#039;&amp;#039;fact&amp;#039;&amp;#039; cu valoarea &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; la începutul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;. Putem ieși din debugger pentru a modifica linia 8 din fișierul sursă suma_fact.c:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) q&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;A debugging session is active.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;  	Inferior 1 [process 4279] will be killed.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Quit anyway? (y or n) y &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Pentru a putea intra în interiorul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039; este absolut necesar să se folosească comanda &amp;#039;&amp;#039;&amp;#039;step&amp;#039;&amp;#039;&amp;#039; și nu comanda &amp;#039;&amp;#039;&amp;#039;next&amp;#039;&amp;#039;&amp;#039; care ar trece peste acea linie 24 fără a intra în corpul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exerciții ==&lt;br /&gt;
&amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;Să se citească de la tastatură un număr întreg fără semn n. Să se implementeze o funcție recursivă care returnează suma primelor n numere naturale și să se afișeze rezultatul apelării acestei funcții.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți o funcție recursivă care șterge dintr-un vector elementul de pe o anumită poziție; funcția primește ca parametri vectorul, numărul de elemente din vector și poziția elementului ce urmează a fi șters.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Să se citească de la tastatură un număr întreg fără semn n. Să se implementeze o funcție recursivă care calculează termenul de pe o poziție dată din șirul lui Fibonacci și să se afișeze primii n termeni, știind că șirul lui Fibonacci este definit astfel:&lt;br /&gt;
* F(0) = 0;&lt;br /&gt;
* F(1) = 1;&lt;br /&gt;
* F(i) = F(i-1) + F(i-2), pentru i&amp;gt;=2.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți o funcție care calculează 2 la puterea n, unde n este un număr întreg fără semn introdus de la tastatură.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți o funcție recursivă care descompune un număr întreg fără semn n într-o sumă de puteri ale lui 2. Afișați această descompunere.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți o funcție recursivă care descompune un număr întreg fără semn n într-o sumă de termeni din șirul lui Fibonacci. Afișați termenii din care este compus numărul.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4049</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4049"/>
		<updated>2015-12-10T09:23:15Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: /* Exerciții */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8: &amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură. Dacă rulăm programul vom obține ca rezultat numărul &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;, indiferent de ce a fost introdus de la tastatură. Ne propunem să descoperim bug-ul folosind GDB.&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Comanda de mai sus lansează în execuție numai debugger-ul, nu și programul &amp;#039;&amp;#039;suma_fact&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Putem observa că am pornit debugger-ul prin faptul că fiecare rând nou din linia de comandă începe acum astfel:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Punem un &amp;#039;&amp;#039;breakpoint&amp;#039;&amp;#039; la linia 20, unde se citește valoarea lui n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) b 20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1 at 0x80484c2: file suma_fact.c, line 20.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pornim programul în interiorul debugger-ului:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) run&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Starting program: /home/student/Desktop/suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1, main () at suma_fact.c:20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;20	        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Trecem mai departe și introducem o valoare pentru n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Introduceti un numar natural mai mic sau egal cu 8: 6 &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;21	    }while(n&amp;lt;0 || n&amp;gt;8);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Vom parcurge programul pas cu pas până la apelarea funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;22	    unsigned int suma = 0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=0) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;5	        return 1;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;13	}&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;main () at suma_fact.c:23&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=1) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;8	    unsigned int fact=0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;10	        fact *= i;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;12	    return fact;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) print fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;$1 = 0&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Observăm că valoarea returnată de funcția &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039; pentru orice număr nenul este &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Acest lucru se datorează inițializării variabilei &amp;#039;&amp;#039;fact&amp;#039;&amp;#039; cu valoarea &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; la începutul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;. Putem ieși din debugger pentru a modifica linia 8 din fișierul sursă suma_fact.c:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) q&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;A debugging session is active.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;  	Inferior 1 [process 4279] will be killed.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Quit anyway? (y or n) y &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Pentru a putea intra în interiorul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039; este absolut necesar să se folosească comanda &amp;#039;&amp;#039;&amp;#039;step&amp;#039;&amp;#039;&amp;#039; și nu comanda &amp;#039;&amp;#039;&amp;#039;next&amp;#039;&amp;#039;&amp;#039; care ar trece peste acea linie 24 fără a intra în corpul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exerciții ==&lt;br /&gt;
&amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;Să se citească de la tastatură un număr întreg fără semn n. Să se implementeze o funcție recursivă care returnează suma primelor n numere naturale și să se afișeze rezultatul apelării acestei funcții.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți o funcție recursivă care șterge dintr-un vector elementul de pe o anumită poziție; funcția primește ca parametri vectorul, numărul de elemente din vector și poziția elementului ce urmează a fi șters.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Să se citească de la tastatură un număr întreg fără semn n. Să se implementeze o funcție recursivă care calculează termenul de pe o poziție dată din șirul lui Fibonacii și să se afișeze primii n termeni, știind că șirul lui Fibonacci este definit astfel:&lt;br /&gt;
* F(0) = 0;&lt;br /&gt;
* F(1) = 1;&lt;br /&gt;
* F(i) = F(i-1) + F(i-2), pentru i&amp;gt;=2.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți o funcție care calculează 2 la puterea n, unde n este un număr întreg fără semn introdus de la tastatură.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți o funcție recursivă care descompune un număr întreg fără semn n într-o sumă de puteri ale lui 2. Afișați această descompunere.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți o funcție recursivă care descompune un număr întreg fără semn n într-o sumă de termeni din șirul lui Fibonacci. Afișați termenii din care este compus numărul.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4048</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4048"/>
		<updated>2015-12-10T09:18:07Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: /* Exerciții */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8: &amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură. Dacă rulăm programul vom obține ca rezultat numărul &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;, indiferent de ce a fost introdus de la tastatură. Ne propunem să descoperim bug-ul folosind GDB.&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Comanda de mai sus lansează în execuție numai debugger-ul, nu și programul &amp;#039;&amp;#039;suma_fact&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Putem observa că am pornit debugger-ul prin faptul că fiecare rând nou din linia de comandă începe acum astfel:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Punem un &amp;#039;&amp;#039;breakpoint&amp;#039;&amp;#039; la linia 20, unde se citește valoarea lui n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) b 20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1 at 0x80484c2: file suma_fact.c, line 20.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pornim programul în interiorul debugger-ului:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) run&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Starting program: /home/student/Desktop/suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1, main () at suma_fact.c:20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;20	        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Trecem mai departe și introducem o valoare pentru n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Introduceti un numar natural mai mic sau egal cu 8: 6 &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;21	    }while(n&amp;lt;0 || n&amp;gt;8);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Vom parcurge programul pas cu pas până la apelarea funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;22	    unsigned int suma = 0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=0) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;5	        return 1;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;13	}&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;main () at suma_fact.c:23&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=1) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;8	    unsigned int fact=0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;10	        fact *= i;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;12	    return fact;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) print fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;$1 = 0&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Observăm că valoarea returnată de funcția &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039; pentru orice număr nenul este &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Acest lucru se datorează inițializării variabilei &amp;#039;&amp;#039;fact&amp;#039;&amp;#039; cu valoarea &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; la începutul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;. Putem ieși din debugger pentru a modifica linia 8 din fișierul sursă suma_fact.c:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) q&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;A debugging session is active.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;  	Inferior 1 [process 4279] will be killed.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Quit anyway? (y or n) y &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Pentru a putea intra în interiorul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039; este absolut necesar să se folosească comanda &amp;#039;&amp;#039;&amp;#039;step&amp;#039;&amp;#039;&amp;#039; și nu comanda &amp;#039;&amp;#039;&amp;#039;next&amp;#039;&amp;#039;&amp;#039; care ar trece peste acea linie 24 fără a intra în corpul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exerciții ==&lt;br /&gt;
&amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;Să se citească de la tastatură un număr întreg fără semn n. Să se implementeze o funcție recursivă care returnează suma primelor n numere naturale și să se afișeze rezultatul apelării acestei funcții.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți o funcție recursivă care șterge dintr-un vector elementul de pe o anumită poziție; funcția primește ca parametri vectorul, numărul de elemente din vector și poziția elementului ce urmează a fi șters.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Să se citească de la tastatură un număr întreg fără semn n. Să se implementeze o funcție recursivă care să afișeze primii n termeni din șirul lui Fibonacii, știind că șirul lui Fibonacci este definit astfel:&lt;br /&gt;
* F(0) = 0;&lt;br /&gt;
* F(1) = 1;&lt;br /&gt;
* F(i) = F(i-1) + F(i-2), pentru i&amp;gt;=2.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți o funcție care calculează 2 la puterea n, unde n este un număr întreg fără semn introdus de la tastatură.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți o funcție recursivă care descompune un număr întreg fără semn n într-o sumă de puteri ale lui 2. Afișați această descompunere.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți o funcție recursivă care descompune un număr întreg fără semn n într-o sumă de termeni din șirul lui Fibonacci. Afișați termenii din care este compus numărul.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4021</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4021"/>
		<updated>2015-12-09T01:02:28Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8: &amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură. Dacă rulăm programul vom obține ca rezultat numărul &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;, indiferent de ce a fost introdus de la tastatură. Ne propunem să descoperim bug-ul folosind GDB.&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Comanda de mai sus lansează în execuție numai debugger-ul, nu și programul &amp;#039;&amp;#039;suma_fact&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Putem observa că am pornit debugger-ul prin faptul că fiecare rând nou din linia de comandă începe acum astfel:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Punem un &amp;#039;&amp;#039;breakpoint&amp;#039;&amp;#039; la linia 20, unde se citește valoarea lui n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) b 20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1 at 0x80484c2: file suma_fact.c, line 20.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pornim programul în interiorul debugger-ului:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) run&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Starting program: /home/student/Desktop/suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1, main () at suma_fact.c:20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;20	        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Trecem mai departe și introducem o valoare pentru n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Introduceti un numar natural mai mic sau egal cu 8: 6 &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;21	    }while(n&amp;lt;0 || n&amp;gt;8);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Vom parcurge programul pas cu pas până la apelarea funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;22	    unsigned int suma = 0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=0) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;5	        return 1;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;13	}&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;main () at suma_fact.c:23&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=1) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;8	    unsigned int fact=0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;10	        fact *= i;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;12	    return fact;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) print fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;$1 = 0&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Observăm că valoarea returnată de funcția &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039; pentru orice număr nenul este &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Acest lucru se datorează inițializării variabilei &amp;#039;&amp;#039;fact&amp;#039;&amp;#039; cu valoarea &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; la începutul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;. Putem ieși din debugger pentru a modifica linia 8 din fișierul sursă suma_fact.c:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) q&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;A debugging session is active.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;  	Inferior 1 [process 4279] will be killed.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Quit anyway? (y or n) y &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Pentru a putea intra în interiorul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039; este absolut necesar să se folosească comanda &amp;#039;&amp;#039;&amp;#039;step&amp;#039;&amp;#039;&amp;#039; și nu comanda &amp;#039;&amp;#039;&amp;#039;next&amp;#039;&amp;#039;&amp;#039; care ar trece peste acea linie 24 fără a intra în corpul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exerciții ==&lt;br /&gt;
&amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;Să se citească de la tastatură un număr întreg fără semn n. Să se implementeze o funcție recursivă care returnează suma primelor n numere naturale și să se afișeze rezultatul apelării acestei funcții.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți o funcție care șterge dintr-un vector elementul de pe o anumită poziție; funcția primește ca parametri vectorul, numărul de elemente din vector și poziția elementului ce urmează a fi șters.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Să se citească de la tastatură un număr întreg fără semn n. Să se implementeze o funcție recursivă care să afișeze primii n termeni din șirul lui Fibonacii, știind că șirul lui Fibonacci este definit astfel:&lt;br /&gt;
* F(0) = 0;&lt;br /&gt;
* F(1) = 1;&lt;br /&gt;
* F(i) = F(i-1) + F(i-2), pentru i&amp;gt;=2.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți o funcție care calculează 2 la puterea n, unde n este un număr întreg fără semn introdus de la tastatură.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți o funcție recursivă care descompune un număr întreg fără semn n într-o sumă de puteri ale lui 2. Afișați această descompunere.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți o funcție recursivă care descompune un număr întreg fără semn n într-o sumă de termeni din șirul lui Fibonacci. Afișați termenii din care este compus numărul.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4020</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4020"/>
		<updated>2015-12-09T00:19:53Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8: &amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură. Dacă rulăm programul vom obține ca rezultat numărul &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;, indiferent de ce a fost introdus de la tastatură. Ne propunem să descoperim bug-ul folosind GDB.&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Comanda de mai sus lansează în execuție numai debugger-ul, nu și programul &amp;#039;&amp;#039;suma_fact&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Putem observa că am pornit debugger-ul prin faptul că fiecare rând nou din linia de comandă începe acum astfel:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Punem un &amp;#039;&amp;#039;breakpoint&amp;#039;&amp;#039; la linia 20, unde se citește valoarea lui n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) b 20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1 at 0x80484c2: file suma_fact.c, line 20.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pornim programul în interiorul debugger-ului:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) run&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Starting program: /home/student/Desktop/suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1, main () at suma_fact.c:20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;20	        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Trecem mai departe și introducem o valoare pentru n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Introduceti un numar natural mai mic sau egal cu 8: 6 &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;21	    }while(n&amp;lt;0 || n&amp;gt;8);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Vom parcurge programul pas cu pas până la apelarea funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;22	    unsigned int suma = 0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=0) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;5	        return 1;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;13	}&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;main () at suma_fact.c:23&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=1) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;8	    unsigned int fact=0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;10	        fact *= i;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;12	    return fact;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) print fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;$1 = 0&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Observăm că valoarea returnată de funcția &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039; pentru orice număr nenul este &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Acest lucru se datorează inițializării variabilei &amp;#039;&amp;#039;fact&amp;#039;&amp;#039; cu valoarea &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; la începutul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;. Putem ieși din debugger pentru a modifica linia 8 din fișierul sursă suma_fact.c:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) q&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;A debugging session is active.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;  	Inferior 1 [process 4279] will be killed.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Quit anyway? (y or n) y &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Pentru a putea intra în interiorul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039; este absolut necesar să se folosească comanda &amp;#039;&amp;#039;&amp;#039;step&amp;#039;&amp;#039;&amp;#039; și nu comanda &amp;#039;&amp;#039;&amp;#039;next&amp;#039;&amp;#039;&amp;#039; care ar trece peste acea linie 24 fără a intra în corpul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exerciții ==&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4019</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4019"/>
		<updated>2015-12-08T22:42:35Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8: &amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură. Dacă rulăm programul vom obține ca rezultat numărul &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;, indiferent de ce a fost introdus de la tastatură. Ne propunem să descoperim bug-ul folosind GDB.&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Comanda de mai sus lansează în execuție numai debugger-ul, nu și programul &amp;#039;&amp;#039;suma_fact&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Putem observa că am pornit debugger-ul prin faptul că fiecare rând nou din linia de comandă începe acum astfel:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Punem un &amp;#039;&amp;#039;breakpoint&amp;#039;&amp;#039; la linia 20, unde se citește valoarea lui n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) b 20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1 at 0x80484c2: file suma_fact.c, line 20.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pornim programul în interiorul debugger-ului:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) run&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Starting program: /home/student/Desktop/suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1, main () at suma_fact.c:20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;20	        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Trecem mai departe și introducem o valoare pentru n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Introduceti un numar natural mai mic sau egal cu 8: 6 &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;21	    }while(n&amp;lt;0 || n&amp;gt;8);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Vom parcurge programul pas cu pas până la apelarea funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;22	    unsigned int suma = 0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=0) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;5	        return 1;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;13	}&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;main () at suma_fact.c:23&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=1) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;8	    unsigned int fact=0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;10	        fact *= i;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;12	    return fact;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) print fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;$1 = 0&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Observăm că valoarea returnată de funcția &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039; pentru orice număr nenul este &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Acest lucru se datorează inițializării variabilei &amp;#039;&amp;#039;fact&amp;#039;&amp;#039; cu valoarea &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; la începutul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;. Putem ieși din debugger pentru a modifica linia 8 din fișierul sursă suma_fact.c:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) q&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;A debugging session is active.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;  	Inferior 1 [process 4279] will be killed.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Quit anyway? (y or n) y &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Pentru a putea intra în interiorul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039; este absolut necesar să se folosească comanda &amp;#039;&amp;#039;&amp;#039;step&amp;#039;&amp;#039;&amp;#039; și nu comanda &amp;#039;&amp;#039;&amp;#039;next&amp;#039;&amp;#039;&amp;#039; care ar trece peste acea linie 24 fără a intra în corpul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4018</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4018"/>
		<updated>2015-12-08T22:41:52Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8: &amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură. Dacă rulăm programul vom obține ca rezultat numărul &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;, indiferent de ce a fost introdus de la tastatură. Ne propunem să descoperim bug-ul folosind GDB.&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Comanda de mai sus lansează în execuție numai debugger-ul, nu și programul &amp;#039;&amp;#039;suma_fact&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Putem observa că am pornit debugger-ul prin faptul că fiecare rând nou din linia de comandă începe acum astfel:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Punem un &amp;#039;&amp;#039;breakpoint&amp;#039;&amp;#039; la linia 20, unde se citește valoarea lui n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) b 20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1 at 0x80484c2: file suma_fact.c, line 20.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pornim programul în interiorul debugger-ului:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) run&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Starting program: /home/student/Desktop/suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1, main () at suma_fact.c:20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;20	        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Trecem mai departe și introducem o valoare pentru n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Introduceti un numar natural mai mic sau egal cu 8: 6 &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;21	    }while(n&amp;lt;0 || n&amp;gt;8);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Vom parcurge programul pas cu pas până la apelarea funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;22	    unsigned int suma = 0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=0) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;5	        return 1;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;13	}&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;main () at suma_fact.c:23&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=1) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;8	    unsigned int fact=0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;10	        fact *= i;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;12	    return fact;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) print fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;$1 = 0&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Observăm că valoarea returnată de funcția &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039; pentru orice număr nenul este &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Acest lucru se datorează inițializării variabilei &amp;#039;&amp;#039;fact&amp;#039;&amp;#039; cu valoarea &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; la începutul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;. Putem ieși din debugger pentru a modifica linia 8 din fișierul sursă suma_fact.c:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) q&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;A debugging session is active.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;  	Inferior 1 [process 4279] will be killed.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Quit anyway? (y or n) y &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Pentru a putea intra în interiorul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039; este absolut necesar să se folosească comanda &amp;#039;&amp;#039;step&amp;#039;&amp;#039; și nu comanda &amp;#039;&amp;#039;next&amp;#039;&amp;#039; care ar trece peste acea linie 24 fără a intra în corpul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4017</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4017"/>
		<updated>2015-12-08T22:37:00Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8: &amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură. Dacă rulăm programul vom obține ca rezultat numărul &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;, indiferent de ce a fost introdus de la tastatură. Ne propunem să descoperim bug-ul folosind GDB.&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Comanda de mai sus lansează în execuție numai debugger-ul, nu și programul &amp;#039;&amp;#039;suma_fact&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Putem observa că am pornit debugger-ul prin faptul că fiecare rând nou din linia de comandă începe acum astfel:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Punem un &amp;#039;&amp;#039;breakpoint&amp;#039;&amp;#039; la linia 20, unde se citește valoarea lui n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) b 20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1 at 0x80484c2: file suma_fact.c, line 20.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pornim programul în interiorul debugger-ului:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) run&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Starting program: /home/student/Desktop/suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1, main () at suma_fact.c:20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;20	        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Trecem mai departe și introducem o valoare pentru n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Introduceti un numar natural mai mic sau egal cu 8: 6 &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;21	    }while(n&amp;lt;0 || n&amp;gt;8);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Vom parcurge programul pas cu pas până la apelarea funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;22	    unsigned int suma = 0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=0) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;5	        return 1;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;13	}&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;main () at suma_fact.c:23&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=1) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;8	    unsigned int fact=0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;10	        fact *= i;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;12	    return fact;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) print fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;$1 = 0&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Observăm că valoarea returnată de funcția &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039; pentru orice număr nenul este &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Acest lucru se datorează inițializării variabilei &amp;#039;&amp;#039;fact&amp;#039;&amp;#039; cu valoarea &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; la începutul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;. Putem ieși din debugger pentru a modifica linia 8 din fișierul sursă suma_fact.c:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) q&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;A debugging session is active.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;  	Inferior 1 [process 4279] will be killed.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Quit anyway? (y or n) y &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt;&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4016</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4016"/>
		<updated>2015-12-08T22:35:49Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8: &amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură. Dacă rulăm programul vom obține ca rezultat numărul &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;, indiferent de ce a fost introdus de la tastatură. Ne propunem să descoperim bug-ul folosind GDB.&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Comanda de mai sus lansează în execuție numai debugger-ul, nu și programul &amp;#039;&amp;#039;suma_fact&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Putem observa că am pornit debugger-ul prin faptul că fiecare rând nou din linia de comandă începe acum astfel:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Punem un &amp;#039;&amp;#039;breakpoint&amp;#039;&amp;#039; la linia 20, unde se citește valoarea lui n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) b 20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1 at 0x80484c2: file suma_fact.c, line 20.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pornim programul în interiorul debugger-ului:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) run&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Starting program: /home/student/Desktop/suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1, main () at suma_fact.c:20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;20	        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Trecem mai departe și introducem o valoare pentru n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Introduceti un numar natural mai mic sau egal cu 8: 6 &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;21	    }while(n&amp;lt;0 || n&amp;gt;8);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Vom parcurge programul pas cu pas până la apelarea funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;22	    unsigned int suma = 0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=0) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;5	        return 1;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;13	}&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;main () at suma_fact.c:23&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=1) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;8	    unsigned int fact=0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;10	        fact *= i;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;12	    return fact;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) print fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;$1 = 0&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Observăm că valoarea returnată de funcția &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039; pentru orice număr nenul este &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Acest lucru se datorează inițializării variabilei &amp;#039;&amp;#039;fact&amp;#039;&amp;#039; cu valoarea &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; la începutul funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;. Putem ieși din debugger pentru a modifica linia 8 din fișierul sursă suma_fact.c:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) q&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;A debugging session is active.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;  	Inferior 1 [process 4279] will be killed.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Quit anyway? (y or n) y &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4015</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4015"/>
		<updated>2015-12-08T22:32:59Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8: &amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură. Dacă rulăm programul vom obține ca rezultat numărul &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;, indiferent de ce a fost introdus de la tastatură. Ne propunem să descoperim bug-ul folosind GDB.&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Comanda de mai sus lansează în execuție numai debugger-ul, nu și programul &amp;#039;&amp;#039;suma_fact&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Putem observa că am pornit debugger-ul prin faptul că fiecare rând nou din linia de comandă începe acum astfel:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Punem un &amp;#039;&amp;#039;breakpoint&amp;#039;&amp;#039; la linia 20, unde se citește valoarea lui n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) b 20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1 at 0x80484c2: file suma_fact.c, line 20.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pornim programul în interiorul debugger-ului:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) run&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Starting program: /home/student/Desktop/suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1, main () at suma_fact.c:20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;20	        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Trecem mai departe și introducem o valoare pentru n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Introduceti un numar natural mai mic sau egal cu 8: 6 &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;21	    }while(n&amp;lt;0 || n&amp;gt;8);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Vom parcurge programul pas cu pas până la apelarea funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;22	    unsigned int suma = 0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=0) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;5	        return 1;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;13	}&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;main () at suma_fact.c:23&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=1) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;8	    unsigned int fact=0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;10	        fact *= i;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;12	    return fact;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) print fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;$1 = 0&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Observăm că valoarea returnată de funcția &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039; pentru orice număr nenul este &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039;. Acest lucru se datorează inițializării variabilei &amp;#039;&amp;#039;fact&amp;#039;&amp;#039; cu valoarea &amp;#039;&amp;#039;&amp;#039;0&amp;#039;&amp;#039;&amp;#039; la începutul funcției &amp;#039;&amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;&amp;#039;. Putem ieși din debugger pentru a modifica linia 8 din fișierul sursă suma_fact.c:&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4014</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4014"/>
		<updated>2015-12-08T22:20:49Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8: &amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură. Dacă rulăm programul vom obține ca rezultat numărul &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;, indiferent de ce a fost introdus de la tastatură. Ne propunem să descoperim bug-ul folosind GDB.&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Comanda de mai sus lansează în execuție numai debugger-ul, nu și programul &amp;#039;&amp;#039;suma_fact&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Putem observa că am pornit debugger-ul prin faptul că fiecare rând nou din linia de comandă începe acum astfel:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Punem un &amp;#039;&amp;#039;breakpoint&amp;#039;&amp;#039; la linia 20, unde se citește valoarea lui n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) b 20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1 at 0x80484c2: file suma_fact.c, line 20.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pornim programul în interiorul debugger-ului:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) run&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Starting program: /home/student/Desktop/suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1, main () at suma_fact.c:20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;20	        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Trecem mai departe și introducem o valoare pentru n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Introduceti un numar natural mai mic sau egal cu 8: 6 &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;21	    }while(n&amp;lt;0 || n&amp;gt;8);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Vom parcurge programul pas cu pas până la apelarea funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;22	    unsigned int suma = 0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=0) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;5	        return 1;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;13	}&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;main () at suma_fact.c:23&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;23	    for(i=0; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;24	        suma += factorial(i);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;factorial (n=1) at suma_fact.c:4&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;4	    if(n==0){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;8	    unsigned int fact=0;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;10	        fact *= i;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;9	    for(i=1; i&amp;lt;=n; i++){&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;12	    return fact;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) print fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;$1 = 0&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4013</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4013"/>
		<updated>2015-12-08T22:13:23Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8: &amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură. Dacă rulăm programul vom obține ca rezultat numărul &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;, indiferent de ce a fost introdus de la tastatură. Ne propunem să descoperim bug-ul folosind GDB.&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Comanda de mai sus lansează în execuție numai debugger-ul, nu și programul &amp;#039;&amp;#039;suma_fact&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Putem observa că am pornit debugger-ul prin faptul că fiecare rând nou din linia de comandă începe acum astfel:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Punem un &amp;#039;&amp;#039;breakpoint&amp;#039;&amp;#039; la linia 20, unde se citește valoarea lui n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) b 20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1 at 0x80484c2: file suma_fact.c, line 20.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Pornim programul în interiorul debugger-ului:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) run&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Starting program: /home/student/Desktop/suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1, main () at suma_fact.c:20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;20	        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Trecem mai departe și introducem o valoare pentru n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Introduceti un numar natural mai mic sau egal cu 8: 6 &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;21	    }while(n&amp;lt;0 || n&amp;gt;8);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Vom parcurge programul pas cu pas până la apelarea funcției &amp;#039;&amp;#039;factorial&amp;#039;&amp;#039;:&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4012</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4012"/>
		<updated>2015-12-08T22:03:58Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8:&amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură. Dacă rulăm programul vom obține ca rezultat numărul &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;, indiferent de ce a fost introdus de la tastatură. Ne propunem să descoperim bug-ul folosind GDB.&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Comanda de mai sus lansează în execuție numai debugger-ul, nu și programul &amp;#039;&amp;#039;suma_fact&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Putem observa că am pornit debugger-ul prin faptul că fiecare rând nou din linia de comandă începe acum astfel:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Punem un &amp;#039;&amp;#039;breakpoint&amp;#039;&amp;#039; la linia 20, unde se citește valoarea lui n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) b 20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Pornim programul în interiorul debugger-ului:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) run&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Starting program: /home/student/work/lab10/suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1, main () at suma_fact.c:20&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;20	        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8:&amp;quot;);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4011</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4011"/>
		<updated>2015-12-08T22:01:29Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8:&amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură. Dacă rulăm programul vom obține ca rezultat numărul &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;, indiferent de ce a fost introdus de la tastatură. Ne propunem să descoperim bug-ul folosind GDB.&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Comanda de mai sus lansează în execuție numai debugger-ul, nu și programul &amp;#039;&amp;#039;suma_fact&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Putem observa că am pornit debugger-ul prin faptul că fiecare rând nou din linia de comandă începe acum astfel:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Punem un &amp;#039;&amp;#039;breakpoint&amp;#039;&amp;#039; la linia 19, unde se afișează în consolă (prima comandă propriu-zisă):&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) b 19&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Pornim programul în interiorul debugger-ului:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) run&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Starting program: /home/student/work/lab10/suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;Breakpoint 1, main () at suma_fact.c:19&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;19	        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8:&amp;quot;);&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) &amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4010</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4010"/>
		<updated>2015-12-08T21:54:58Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8:&amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură. Dacă rulăm programul vom obține ca rezultat numărul &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;, indiferent de ce a fost introdus de la tastatură. Ne propunem să descoperim bug-ul folosind GDB.&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Comanda de mai sus lansează în execuție numai debugger-ul, nu și programul &amp;#039;&amp;#039;suma_fact&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Putem observa că am pornit debugger-ul prin faptul că fiecare rând nou din linia de comandă începe acum astfel:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Punem un &amp;#039;&amp;#039;breakpoint&amp;#039;&amp;#039; la linia 19, unde se afișează în consolă (prima comandă propriu-zisă):&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) b 19&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Pornim programul în interiorul debugger-ului:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) run&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4009</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4009"/>
		<updated>2015-12-08T21:46:01Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8:&amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură. Dacă rulăm programul vom obține ca rezultat numărul &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;, indiferent de ce a fost introdus de la tastatură. Ne propunem să descoperim bug-ul folosind GDB.&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Comanda de mai sus lansează în execuție numai debugger-ul, nu și programul &amp;#039;&amp;#039;suma_fact&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Putem observa că am pornit debugger-ul prin faptul că fiecare rând nou din linia de comandă începe acum astfel:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Punem un &amp;#039;&amp;#039;breakpoint&amp;#039;&amp;#039; la linia 20, linia unde este citită valoarea lui n:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) b 20&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4008</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4008"/>
		<updated>2015-12-08T21:37:00Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8:&amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură. Dacă rulăm programul vom obține ca rezultat numărul &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;, indiferent de ce a fost introdus de la tastatură. Ne propunem să descoperim bug-ul folosind GDB.&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Comanda de mai sus lansează în execuție numai debugger-ul, nu și programul &amp;#039;&amp;#039;suma_fact&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Putem observa că am pornit debugger-ul prin faptul că fiecare rând nou din linia de comandă începe acum astfel:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb)&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4007</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4007"/>
		<updated>2015-12-08T21:36:37Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8:&amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură. Dacă rulăm programul vom obține ca rezultat numărul &amp;#039;&amp;#039;&amp;#039;1&amp;#039;&amp;#039;&amp;#039;, indiferent de ce a fost introdus de la tastatură. Ne propunem să descoperim bug-ul folosind GDB&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Comanda de mai sus lansează în execuție numai debugger-ul, nu și programul &amp;#039;&amp;#039;suma_fact&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Putem observa că am pornit debugger-ul prin faptul că fiecare rând nou din linia de comandă începe acum astfel:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb)&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4006</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4006"/>
		<updated>2015-12-08T21:34:48Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8:&amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură.&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Comanda de mai sus lansează în execuție numai debugger-ul, nu și programul &amp;#039;&amp;#039;suma_fact&amp;#039;&amp;#039;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Putem observa că am pornit debugger-ul prin faptul că fiecare rând nou din linia de comandă începe acum astfel:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb)&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4005</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4005"/>
		<updated>2015-12-08T21:28:15Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8:&amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Programul își propune să calculeze suma factorialelor de la 0 la n, unde n este introdus de la tastatură.&amp;lt;br&amp;gt;&lt;br /&gt;
Compilăm sursa, adăugând simboluri de debug în executabil, după care lansăm în execuție debugger-ul:&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g suma_fact.c -o suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb suma_fact&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4004</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4004"/>
		<updated>2015-12-08T21:05:41Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemplu de depanare ===&lt;br /&gt;
Se dă fișierul sursă &amp;#039;&amp;#039;suma_fact.c&amp;#039;&amp;#039;, care conține următoarele instrucțiuni:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8:&amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4003</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4003"/>
		<updated>2015-12-08T21:01:15Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
unsigned int factorial(int n){&lt;br /&gt;
    if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int i;&lt;br /&gt;
    unsigned int fact=0;&lt;br /&gt;
    for(i=1; i&amp;lt;=n; i++){&lt;br /&gt;
        fact *= i;&lt;br /&gt;
    }&lt;br /&gt;
    return fact;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    int n, i;&lt;br /&gt;
    do{&lt;br /&gt;
        printf(&amp;quot;Introduceti un numar natural mai mic sau egal cu 8:&amp;quot;);&lt;br /&gt;
        scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
    }while(n&amp;lt;0 || n&amp;gt;8);&lt;br /&gt;
    unsigned int suma = 0;&lt;br /&gt;
    for(i=0; i&amp;lt;=n; i++){&lt;br /&gt;
        suma += factorial(i);&lt;br /&gt;
    }&lt;br /&gt;
    printf(&amp;quot;%u\n&amp;quot;, suma);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4002</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4002"/>
		<updated>2015-12-08T20:13:50Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Cele mai multe dintre aceste comenzi pot fi apelate doar prin prima literă a numelui lor. &amp;lt;/div&amp;gt;&lt;br /&gt;
Spre exemplu, următoarea comandă:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) next&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
este identică cu:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;(gdb) n&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Dacă se apasă pe enter fără a scrie o comandă, se repetă ultima comandă specificată.&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4001</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4001"/>
		<updated>2015-12-08T19:49:08Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;br /&gt;
Cea mai folosită modalitate de a porni tool-ul de depanare este de a scrie &amp;#039;&amp;#039;&amp;#039;gdb&amp;#039;&amp;#039;&amp;#039; în terminal, urmat de numele executabilului ce se dorește a fi depanat.&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gdb hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
O parte din comenzile cele mai utilizate ale GDB sunt următoarele (pentru lista completă studiați pagina de manual GDB - man gdb):&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție &amp;lt;br&amp;gt; &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;break&amp;lt;/code&amp;gt; [nume_fișier:] număr_linie || Setează un breakpoint (punct de întrerupere) la începutul funcției &amp;#039;&amp;#039;nume_funcție&amp;#039;&amp;#039; sau la linia specificată prin &amp;#039;&amp;#039;număr_linie&amp;#039;&amp;#039; din fișierul specificat prin &amp;#039;&amp;#039;nume_fișier&amp;#039;&amp;#039;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;run&amp;lt;/code&amp;gt; [listă_argumente] || Pornește programul în execuție (cu lista de argumente, dacă au fost specificate).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;bt&amp;lt;/code&amp;gt; || Backtrace: afișează stiva de program.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;print&amp;lt;/code&amp;gt; expresie || Afișează valoarea unei expresii (valoarea stocată într-o variabilă, valoarea returnată de o funcție etc.).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;c&amp;lt;/code&amp;gt; || Continuă execuția programului (după ce a fost oprit, spre exemplu după un breakpoint).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;next&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), sărind peste orice apel de funcție care se găsește în această linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;list&amp;lt;/code&amp;gt; [nume_fișier:] nume_funcție || Afișează liniile de cod ale programului din vecinătatea locului unde este oprit acum.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;step&amp;lt;/code&amp;gt; || Execută următoarea linie de program (după oprire), intrând în orice funcție apelată de acea linie.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;help&amp;lt;/code&amp;gt; [nume] || Afișează informații despre comanda GDB &amp;#039;&amp;#039;nume&amp;#039;&amp;#039; sau informații generale despre utilizarea GDB.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;quit&amp;lt;/code&amp;gt; || Iese din GDB.&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4000</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=4000"/>
		<updated>2015-12-08T01:34:24Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Comenzi specifice GDB ===&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=3999</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=3999"/>
		<updated>2015-12-08T01:31:15Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Pentru a putea folosi debugger-ul, la generarea fișierului executabil trebuie folosită opțiunea &amp;#039;&amp;#039;&amp;#039;-g&amp;#039;&amp;#039;&amp;#039;, care adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. (vezi [http://wiki.dcae.pub.ro/index.php/PC_Laborator_1 Laboratorul 1])&amp;lt;/div&amp;gt;&lt;br /&gt;
Exemplul unei comenzi de compilare în vederea depanării:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -g hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=3998</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=3998"/>
		<updated>2015-12-08T01:16:47Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&amp;lt;br&amp;gt;&lt;br /&gt;
GDB este capabil de a face 4 mari categorii de operații (și alte tipuri de operații ce duc la îndeplinirea celor 4):&lt;br /&gt;
* să pornească programul, specificând orice ar putea interveni în buna funcționare a acestuia;&lt;br /&gt;
* să facă programul să se oprească din execuție în anumite condiții specificate de utilizator;&lt;br /&gt;
* să examineze ce s-a întâmplat în momentul opririi programului;&lt;br /&gt;
* să schimbe anumite lucruri în program pentru a putea corecta efectele unui bug și a investiga urmările altuia.&amp;lt;br&amp;gt;&lt;br /&gt;
Odată pornit, GDB citește comenzi din terminal până la întâlnirea comenzii de ieșire &amp;quot;quit&amp;quot;.&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=3997</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=3997"/>
		<updated>2015-12-08T00:43:58Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului să vadă ce se întâmplă în interiorul unui alt program în timp ce acesta se execută sau ce s-a întâmplat cu programul în momentul în care acesta a dat crash.&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=3996</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=3996"/>
		<updated>2015-12-08T00:41:20Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Tool-ul de depanare GDB ==&lt;br /&gt;
Depanatorul GNU, cunoscut drept GDB (GNU debugger), este depanatorul standard pentru sistemul de software GNU.&amp;lt;br&amp;gt;&lt;br /&gt;
Scopul unui depanator precum GDB este de a permite utilizatorului s&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=3995</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=3995"/>
		<updated>2015-12-07T23:38:39Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: /* Funcții recursive */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate directă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Exemplu de recursivitate indirectă ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=3994</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=3994"/>
		<updated>2015-12-07T23:28:48Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: /* Funcții recursive */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este imaginarea unui proces în execuție în care una dintre instrucțiuni este repetarea procesul în sine. O metodă și mai ușoară de a înțelege acest concept este compararea funcțiilor recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu de recursivitate directă&amp;#039;&amp;#039;&amp;#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu de recursivitate indirectă&amp;#039;&amp;#039;&amp;#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=3993</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=3993"/>
		<updated>2015-12-07T23:04:01Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: /* Funcții recursive */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este aceea de a ne imagina un proces în execuție în care una dintre instrucțiuni este aceea de a repeta procesul în sine. O metodă și mai ușoară de a înțelege acest concept este aceea de a compara funcțiile recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu de recursivitate directă&amp;#039;&amp;#039;&amp;#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu de recursivitate indirectă&amp;#039;&amp;#039;&amp;#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=3992</id>
		<title>PC Laborator 10</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_10&amp;diff=3992"/>
		<updated>2015-12-07T22:59:55Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: Pagină nouă: __TOC__ == Obiective == La sfârșitul acestui laborator studenții vor fi capabili: * să înțeleagă funcționarea funcțiilor recursive; * să implementeze și să apeleze func...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea funcțiilor recursive;&lt;br /&gt;
* să implementeze și să apeleze funcții recursive;&lt;br /&gt;
* să folosească tool-ul de depanare GDB.&lt;br /&gt;
&lt;br /&gt;
== Funcții recursive ==&lt;br /&gt;
Un obiect se definește în mod recursiv dacă în cadrul definiției sale există o referire la el însuși.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea este un procedeu de programare în care o funcție se apelează pe ea însăși; o funcție care se auto-apelează poartă numele de funcție recursivă. O metodă de a înțelege mai ușor funcțiile recursive este aceea de a ne imagina un proces în execuție în care una dintre instrucțiuni este aceea de a repeta procesul în sine. O metodă și mai ușoară de a înțelege acest concept este aceea de a compara funcțiile recursive cu [https://ro.wikipedia.org/wiki/Matrio%C8%99ka papușile Matrioska], unde o păpușă conține în interiorul său una sau mai multe păpuși de același fel, excepție făcând ultima păpușă, cea mai mică dintre ele, care este goală.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea se folosește și în matematică - un exemplu ar fi șirul lui Fibonacci, care se folosește de ultimii doi termeni din șir pentru a afla termenul curent. Utilitatea recursivității, atât în matematică, cât și în cadrul programării, provine din posibilitatea de a defini un set infinit de termeni sau obiecte folosind o singură relație.&amp;lt;br&amp;gt;&lt;br /&gt;
Recursivitatea diferă de structurile iterative, deși ambele concepte presupun execuția repetată a unei porțiuni de cod. În cadrul execuției unei funcții recursive se verifică o condiție a cărei nerealizare duce la o altă execuție a funcției, fără a termina execuția curentă care va fi suspendată. În momentul satisfacerii condiției se revine la execuția curentă, fiecare apel suspendat fiind reluat și încheiat, în ordine invers cronologică.&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Orice apel recursiv al unei funcții trebuie condiționat de o decizie care să împiedice apelarea funcției în buclă infinită.&amp;lt;/div&amp;gt;&lt;br /&gt;
Recursivitatea poate fi de două feluri:&lt;br /&gt;
* recursivitate directă (în care o funcție conține o referință către ea însăși);&lt;br /&gt;
* recursivitate indirectă (în care o funcție X conține o referință către o funcție Y, funcția Y conținând la rândul ei o referință către funcția X).&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu de recursivitate directă&amp;#039;&amp;#039;&amp;#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = n*factorial(n-1)&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu de recursivitate indirectă&amp;#039;&amp;#039;&amp;#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int factorial(int n){&lt;br /&gt;
    if(n&amp;lt;0){&lt;br /&gt;
        return 0;&lt;br /&gt;
    }else if(n==0){&lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    int rez;&lt;br /&gt;
    rez = inmul_fact(n, n-1);&lt;br /&gt;
    return rez;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int inmul_fact(int a, int b){&lt;br /&gt;
    int prod;&lt;br /&gt;
    prod = a*factorial(b);&lt;br /&gt;
    return prod;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_8&amp;diff=3837</id>
		<title>PC Laborator 8</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_8&amp;diff=3837"/>
		<updated>2015-11-25T20:16:12Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: /* Afișarea unui șir de caractere */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Obiective == &lt;br /&gt;
  &lt;br /&gt;
în urma acestui laborator, studentul va fi capabil să: &lt;br /&gt;
*înțeleagă cum funcționează șirurile de caractere &lt;br /&gt;
*facă operații cu șiruri de caractere&lt;br /&gt;
&lt;br /&gt;
== Șiruri de caractere == &lt;br /&gt;
  &lt;br /&gt;
În C, tipul de dată șir nu există în mod implicit. Singurul mod prin care putem opera cu șiruri este folosind tablourile unidimensionale, vectorii. Ne amintim că un vector este definit complet prin intermediul a trei caracteristici: tipul de date conținute, numele vectorului și numărul său de elemente. Așadar, putem declara un vector al cărui tip de data să fie char, caz în care acel vector va fi denumit șir (de caractere). &lt;br /&gt;
Declararea unui șir de caractere se face astfel: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
char numele_sirului [numarul_de_caractere];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Spre deosebire de vectorii studiați în laboratorul anterior, ale căror elemente sunt precizate explicit, șirurile au un caracter special, implicit, numit end of string și reprezentat astfel: \0.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Operații cu șiruri == &lt;br /&gt;
  &lt;br /&gt;
Toate proprietățile vectorilor, studiate în laboratorul anterior, sunt valabile și în cazul șirurilor. De asemenea, toate operațiile pe care le putem face cu vectori sunt posibile și în cazul șirurilor. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Există  anumite operații asociate exclusiv șirurilor, precum căutarea unor caractere sau a unui șir într-un alt șir, concatenarea, etc. Toate aceste operații au funcții predefinite, care pot fi găsite într-un header specific, string.h. &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Aflarea lungimii unui șir de caractere === &lt;br /&gt;
Pe lângă metoda clasică, discutată în capitolul anterior, ce presupune parcurgerea șirului și numărarea elementelor acestuia, avem și o metodă proprie șirurilor. Ea presupune apelarea funcției strlen(), predefinita în biblioteca string.h, care va întoarce numărul de elemente al șirului. &lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Caracterul &amp;#039;\0&amp;#039; marchează sfârșitul șirului, iar acolo se oprește numărarea.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Sintaxa generala:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
lungime_sir = strlen (sir_de_caractere);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Citirea unui șir de caractere === &lt;br /&gt;
Există mai multe variante pentru a citi un șir de caractere, unele asemănătoare vectorilor, altele specifice șirurilor de caractere. &lt;br /&gt;
&lt;br /&gt;
1. Sintaxa generala:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
char sir_de_caractere[MAX_SIZE];&lt;br /&gt;
int i;&lt;br /&gt;
for (i = 0; i &amp;lt; MAX_SIZE; i++) {&lt;br /&gt;
    scanf (&amp;quot;%c&amp;quot;, &amp;amp;sir_de_caractere [i]);&lt;br /&gt;
    /* 10 este codul ascii pentru \n, adica enter */&lt;br /&gt;
    if(sir_de_caractere [i] == 10) {&lt;br /&gt;
        sir_de_caractere [i] = &amp;#039;\0&amp;#039;;&lt;br /&gt;
        break;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Sintaxa generala&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
char sir_de_caractere[MAX_SIZE];&lt;br /&gt;
scanf (&amp;quot;%s&amp;quot;, sir_de_caractere);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Sintaxa generala:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
char sir_de_caractere[MAX_SIZE];&lt;br /&gt;
fgets(sir_de_caractere, MAX_SIZE, stdin);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Afișarea unui șir de caractere === &lt;br /&gt;
Analog citirii unui șir de caractere, afișarea se poate face și ea în mai multe moduri, după cum urmează:&lt;br /&gt;
  &lt;br /&gt;
1. Sintaxa generala:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
char sir_de_caractere[MAX_SIZE];&lt;br /&gt;
int i;&lt;br /&gt;
for (i = 0; i &amp;lt; MAX_SIZE &amp;amp;&amp;amp; sir_de_caractere [i] != &amp;#039;\0&amp;#039;; i++) {&lt;br /&gt;
    printf (&amp;quot;%c&amp;quot;, sir_de_caractere [i]);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Sintaxa generala&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
char sir_de_caractere[MAX_SIZE];&lt;br /&gt;
printf (&amp;quot;%s&amp;quot;, sir_de_caractere);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
3. Sintaxa generala:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
char sir_de_caractere[MAX_SIZE];&lt;br /&gt;
puts(sir_de_caractere);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;: Fie șirul de caractere sir[10]. Citiți următoarea frază folosind toate cele 3 metode, apoi afișați conținutul șirului folosind puts();. Ce observați? Explicați.&lt;br /&gt;
&lt;br /&gt;
=== Căutarea unui caracter într-un șir de caractere === &lt;br /&gt;
Funcția folosită: strchr(); &lt;br /&gt;
Sintaxa generala:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
char sir_de_caractere[MAX_SIZE], char caracterul_cautat;&lt;br /&gt;
int pozitie;&lt;br /&gt;
pozitie = strchr (sir_de_caractere, caracterul_cautat) - sir_de_caractere;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Funcția strchr NU oferă toate pozițiile pe care se află caracterul_căutat, ci doar prima poziție. &lt;br /&gt;
*Pentru a afla ultima poziție pe care se află un caracter căutat, se va folosi funcția strrchr(), sintaxa fiind identică. &lt;br /&gt;
*Pentru a caută un șir de caractere într-un alt șir de caractere, se va folosi funcția strstr(), sintaxa fiind aceeași. &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Copierea unui șir de caractere  în altul === &lt;br /&gt;
Funcția folosită: strcpy (); &lt;br /&gt;
Sintaxa:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
char destinatie[MAX_SIZE1], sursa[MAX_SIZE2];&lt;br /&gt;
strcpy (destinatie, sursa);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; șirul sursă se copiază în șirul destinație. Dacă lungimea șirului destinație este mai mică decât a șirului sursă, atunci copierea se face cu erori. Trebuie deci să punem următoarea condiție: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
MAX_SIZE1 &amp;gt;= strlen (sursa);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Concatenarea unor șiruri de caractere ===&lt;br /&gt;
Funcția folosită: srtcat();&lt;br /&gt;
Sintaxa generala:&lt;br /&gt;
char destinatie[MAX_SIZE1], sursa[MAX_SIZE2];&lt;br /&gt;
strcat (destinatie, sursa); &lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; Concatenarea se face adăugând șirul sursă la șirul destinație. Este deci necesar ca șirul sursă să &amp;quot;încăpă&amp;quot; în șirul destinație. Matematic, asta se traduce astfel: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
MAX_SIZE1 &amp;gt;= strlen (sursa) + strlen (destinatie); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Compararea  a doua șiruri de caractere ===&lt;br /&gt;
Funcția folosită: strcmp();&lt;br /&gt;
Sintaxa generala:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
char sir1 [MAX_SIZE1], sir2 [MAX_SIZE2];&lt;br /&gt;
int rezultat;&lt;br /&gt;
rezultat = strcmp (sir1, sir2);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Funcția strcmp(); întoarce următoarele valori: &lt;br /&gt;
* -1 dacă sir1 este înainte din punct de vedere alfabetic; &lt;br /&gt;
* 0 dacă cele două șiruri sunt identice; &lt;br /&gt;
* +1 dacă sir2 este înainte din punct de vedere alfabetic. &lt;br /&gt;
 &lt;br /&gt;
=== Inserția unui șir de caractere într-un alt șir === &lt;br /&gt;
Pentru această operație nu există o funcție specializată în biblioteca string.h. Ceea ce vom face va fi să folosim procedee învățate la vectori, cât și funcții menționate anterior. Etapele sunt următoarele: &lt;br /&gt;
* declarăm cele două șiruri; &lt;br /&gt;
* verificăm dacă șirul ce urmează să fie introdus încape în șirul inițial; &lt;br /&gt;
* găsim poziția unde dorim să adăugăm șirul ce urmează să fie introdus; &lt;br /&gt;
* începând cu acea poziție, mutăm toate caracterele la dreaptă cu un număr de poziții egal cu lungimea șirului ce urmează să fie introdus; &lt;br /&gt;
* pe pozițiile rămase &amp;quot;goale&amp;quot; introducem șirul nou. &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu:&amp;#039;&amp;#039;&amp;#039;  &lt;br /&gt;
Transformați fraza &amp;quot;Studentul a picat examenul final.&amp;quot; în &amp;quot;Studentul nu a picat examenul final.&amp;quot; &lt;br /&gt;
Date necesare: sir_inițial[50] = &amp;quot;Sudentul a picat examenul final.&amp;quot;, sir_nou[3] = &amp;quot;nu &amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Observații și exemple==&lt;br /&gt;
&lt;br /&gt;
=== strlen vs sizeof ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
	char str1[20] = &amp;quot;StringLab&amp;quot;;&lt;br /&gt;
	int len,size;&lt;br /&gt;
&lt;br /&gt;
	len = strlen(str1);&lt;br /&gt;
	size = sizeof(str1); &lt;br /&gt;
	printf(&amp;quot;Lungimea str1: %d\n&amp;quot;, len);&lt;br /&gt;
	printf(&amp;quot;Lungimea total alocata str1: %d\n&amp;quot;, size);&lt;br /&gt;
&lt;br /&gt;
     return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== strchr vs strrchr ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    	char str1[40] = &amp;quot;Cautare de caracter printre caractere&amp;quot;;&lt;br /&gt;
    	printf (&amp;quot;Caz1: %s\n&amp;quot;, strchr(str1, &amp;#039;a&amp;#039;));&lt;br /&gt;
    	printf (&amp;quot;Caz2: %s\n&amp;quot;, strrchr(str1, &amp;#039;a&amp;#039;));&lt;br /&gt;
        printf (&amp;quot;Caz3: %s\n&amp;quot;, strstr(str1, &amp;quot;de&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
     return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemple operații cu șiruri===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main () {&lt;br /&gt;
&lt;br /&gt;
   char str1[10] = &amp;quot;Hello&amp;quot;;&lt;br /&gt;
   char str2[10] = &amp;quot;String Lab&amp;quot;;&lt;br /&gt;
   char str3[10];&lt;br /&gt;
   int  len ;&lt;br /&gt;
&lt;br /&gt;
   /* copiaza str1 in str3 */&lt;br /&gt;
   strcpy(str3, str1);&lt;br /&gt;
   printf(&amp;quot;strcpy( str3, str1) :  %s\n&amp;quot;, str3 );&lt;br /&gt;
&lt;br /&gt;
   /* concateneaza str1 str2 */&lt;br /&gt;
   strcat( str1, str2);&lt;br /&gt;
   printf(&amp;quot;strcat( str1, str2):   %s\n&amp;quot;, str1 );&lt;br /&gt;
&lt;br /&gt;
   /* lungimea str1 dupa concatenare */&lt;br /&gt;
   len = strlen(str1);&lt;br /&gt;
   printf(&amp;quot;strlen(str1) :  %d\n&amp;quot;, len );&lt;br /&gt;
&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Model de concatenare fără a utiliza strcat ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
&lt;br /&gt;
   char str1[10], str2[10], str3[20];&lt;br /&gt;
   int i, poz;&lt;br /&gt;
   printf(&amp;quot;Introduceti sir1: &amp;quot;);&lt;br /&gt;
   scanf(&amp;quot;%s&amp;quot;,str1);&lt;br /&gt;
   printf(&amp;quot;Introduceti sir2: &amp;quot;);&lt;br /&gt;
   scanf(&amp;quot;%s&amp;quot;,str2);&lt;br /&gt;
&lt;br /&gt;
	for (i = 0; i &amp;lt; strlen(str1); i++)&lt;br /&gt;
		str3[i] = str1[i];&lt;br /&gt;
		poz=i;&lt;br /&gt;
	for (i = 0; i &amp;lt; strlen(str2); i++)&lt;br /&gt;
		str3[poz+i] = str2[i];&lt;br /&gt;
		str3[poz+i] =&amp;#039;\0&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
   printf(&amp;quot;Sir concatenat: %s\n&amp;quot;,str3); &lt;br /&gt;
&lt;br /&gt;
return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Exemple gets/puts ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    char nume[30];&lt;br /&gt;
    printf(&amp;quot;Numele este: &amp;quot;);&lt;br /&gt;
   /* Citește string de la utilizator */&lt;br /&gt;
    fgets(nume, 30, stdin);     &lt;br /&gt;
    printf(&amp;quot;Nume: &amp;quot;);&lt;br /&gt;
   /* Afișează string */&lt;br /&gt;
    puts(nume);    &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Exerciții ==&lt;br /&gt;
&lt;br /&gt;
#Să se scrie un program care șterge toate caracterele dintr-o linie citită de la tastatură cu excepția literelor.&lt;br /&gt;
#Să se scrie un program care afișează pe ecran frecvența de apariție a unui caracter citit de la tastatură.&lt;br /&gt;
#Se citeşte de la tastatură o propoziţie (şir de caractere) terminată cu punct.Să se afişeze fiecare cuvânt din propoziţie pe câte o linie separată.&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_6&amp;diff=3748</id>
		<title>PC Laborator 6</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_6&amp;diff=3748"/>
		<updated>2015-11-11T17:19:29Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea blocurilor repetitive;&lt;br /&gt;
* să conceapă programe care folosesc blocuri repetitive.&lt;br /&gt;
&lt;br /&gt;
== Structura repetitivă ==&lt;br /&gt;
Structura repetitivă, cunoscută și sub numele de loop sau buclă, reprezintă o bucată de cod care poate fi executată în mod repetat. Structurile repetitive trebuie sa aibă o condiție de continuare. La fiecare iterație a codului această condiție este verificată, iar în momentul în care condiția devine falsă se oprește execuția buclei și se trece mai departe în program.&lt;br /&gt;
Există 2 tipuri de structuri repetitive:&lt;br /&gt;
* structuri repetitive cu număr cunoscut de pași;&lt;br /&gt;
* structuri repetitive cu număr necunoscut de pași.&lt;br /&gt;
&lt;br /&gt;
=== Structuri repetitive cu număr cunoscut de pași ===&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;for&amp;#039;&amp;#039; creează o structură repetitivă cu număr cunoscut de pași. Sintaxa instrucțiunii &amp;#039;&amp;#039;for&amp;#039;&amp;#039; este următoarea:&amp;lt;br/&amp;gt;&lt;br /&gt;
a)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
for (inițializare contor; condiție logică; modificare contor)&lt;br /&gt;
        instrucțiune;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
for (inițializare contor; condiție logică; modificare contor){&lt;br /&gt;
        instrucțiune1;&lt;br /&gt;
        instrucțiune2;&lt;br /&gt;
..............................&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;for&amp;#039;&amp;#039; se parcurge conform schemei următoare:&amp;lt;br/&amp;gt;[[Fișier:For.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce va afisa acest program?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
  int x;&lt;br /&gt;
  for (x = 0; x &amp;lt; 10; x++) {&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, x);&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Structuri repetitive cu număr necunoscut de pași ===&lt;br /&gt;
Există două instrucțiuni pentru a crea structuri repetitive cu număr necunoscut de pași:&lt;br /&gt;
* instrucțiunea &amp;#039;&amp;#039;while&amp;#039;&amp;#039;;&lt;br /&gt;
* instrucțiunea &amp;#039;&amp;#039;do..while&amp;#039;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
==== Instrucțiunea &amp;#039;&amp;#039;while&amp;#039;&amp;#039; ====&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;while&amp;#039;&amp;#039; verifică înainte de fiecare iterație condiția de intrare: dacă această condiție este îndeplinită se execută codul din corpul instrucțiunii, iar dacă nu se îndeplinește condiția se iese din această buclă. Sintaxa instrucțiunii este următoarea:&amp;lt;br/&amp;gt;&lt;br /&gt;
a)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
while (condiție)&lt;br /&gt;
        instrucțiune;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
while (condiție){&lt;br /&gt;
        instrucțiune1;&lt;br /&gt;
        instrucțiune2;&lt;br /&gt;
..............................&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Organigrama instrucțiunii &amp;#039;&amp;#039;while&amp;#039;&amp;#039; se regăsește în imaginea următoare:&amp;lt;br/&amp;gt;[[Fișier:While.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce va afișa următorul cod în urma execuției?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
  int x = 0;  &lt;br /&gt;
  while (x &amp;lt; 10){&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, x);&lt;br /&gt;
    x++;       &lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Instrucțiunea &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; ====&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; verifică după fiecare iterație condiția de continuare. Sintaxa instrucțiunii &amp;quot;do while&amp;#039;&amp;#039; este următoarea:&amp;lt;br/&amp;gt;&lt;br /&gt;
a)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
do{&lt;br /&gt;
      instrucțiune;&lt;br /&gt;
}while (condiție);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
do{&lt;br /&gt;
      instrucțiune1;&lt;br /&gt;
      instrucțiune2;&lt;br /&gt;
..............................&lt;br /&gt;
}while (condiție);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Se observă că sintaxa instrucțiunii &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; este puțin diferită:&lt;br /&gt;
* indiferent de numărul de instrucțiuni din cadrul structurii repetitive, se folosesc acoladele;&lt;br /&gt;
* după condiția de continuitate se folosește obligatoriu semnul de punctuație &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;;&amp;#039;&amp;#039;&amp;#039;&amp;lt;/font&amp;gt; .&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Organigrama instrucțiunii &amp;#039;&amp;#039;do-while&amp;#039;&amp;#039; se regăsește în imaginea următoare:&amp;lt;br/&amp;gt;[[Fișier:Do_while.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Se observă că datorită faptului că se verifică abia la sfârșitul structurii condiția de continuitate, orice structură iterativă de tip &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; va fi executată întotdeauna cel puțin o dată.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce se va afișa în urma execuției?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
  int x;&lt;br /&gt;
  x = 0;&lt;br /&gt;
  do{&lt;br /&gt;
    printf( &amp;quot;Hello, world!\n&amp;quot; );&lt;br /&gt;
  }while (x != 0);&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Cuvintele cheie &amp;#039;&amp;#039;&amp;#039;break&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039; ==&lt;br /&gt;
Pentru structurile repetitive există două cuvinte cheie de mare importanță: &amp;#039;&amp;#039;&amp;#039;break&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;break&amp;#039;&amp;#039;&amp;#039; va ieși din bucla cea mai apropiată indiferent de condițiile de continuare ale acesteia. Utilitatea acestei instrucțiuni apare atunci când trebuie părăsită bucla în anumite circumstanțe.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039; oprește iterația curentă, face update contorului (în cazul buclei &amp;#039;&amp;#039;for&amp;#039;&amp;#039;) și continuă cu execuția structurii repetitive de la prima instrucțiune. Cu alte cuvinte, &amp;#039;&amp;#039;continue&amp;#039;&amp;#039; ignoră tot ceea ce urmează după el în cadrul buclei și trece la următoarea iterație a buclei.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce va afisa acest program?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
int main () {&lt;br /&gt;
   int a = 10;&lt;br /&gt;
   while( a &amp;lt; 20 ) {&lt;br /&gt;
      printf(&amp;quot;value of a: %d\n&amp;quot;, a);&lt;br /&gt;
      a++;&lt;br /&gt;
      if( a == 13) {&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      if( a &amp;gt; 16) {&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Exerciții==&lt;br /&gt;
&amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;Să se afișeze pe o linie toate literele în ordine alfabetică, scrise cu majuscule, și pe o altă linie toate literele în ordine invers alfabetică, scrise cu litere mici. Rezolvați exercițiul în 3 moduri (folosind toate tipurile de bucle).&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Să se citească un număr întreg fără semn n&amp;lt;20 de la tastatură. Afișați rezultatul operației n!.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Să se citească un număr întreg fără semn de la tastatură și să se verifice dacă acesta este palindrom.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Să se citească un număr întreg fără semn n de la tastatură. Să se afișeze primele n numere impare.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Să se citească un număr întreg fără semn n de la tastatură. Să se citească apoi n numere întregi de la tastatură și să se afișeze suma numerelor pare introduse.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refaceți exercițiul anterior în așa fel încât să folosiți instrucțiunea &amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Să se citească de la tastatură o serie de numere întregi până la întâlnirea numărului 0. Să se afișeze apoi media aritmetică a acestor numere.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Verificați dacă un număr întreg fără semn introdus de la tastatură este prim.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Să se afișeze cmmdc și cmmmc a două numere întregi fără semn citite de la tastatură.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Să se citească un număr întreg fără semn n de la tastatură. Să se afișeze primele n numere prime.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Să se citească un număr întreg fără semn n de la tastatură. Să se convertească în baza 2.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Să se realizeze un joc în care un jucător introduce un număr între 1 și 100 de la tastatură, apoi alt jucător încearcă să-l ghicească. Calculatorul va oferi indicii (&amp;quot;prea mic&amp;quot;, &amp;quot;prea mare&amp;quot;), până la ghicirea numărului. La final se va afișa numărul de încercări de care a fost nevoie pentru a ghici numărul.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_6&amp;diff=3684</id>
		<title>PC Laborator 6</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_6&amp;diff=3684"/>
		<updated>2015-11-07T10:12:08Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: /* Exerciții */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea blocurilor repetitive;&lt;br /&gt;
* să conceapă programe care folosesc blocuri repetitive.&lt;br /&gt;
&lt;br /&gt;
== Structura repetitivă ==&lt;br /&gt;
Structura repetitivă, cunoscută și sub numele de loop sau buclă, reprezintă o bucată de cod care poate fi executată în mod repetat. Structurile repetitive trebuie sa aibă o condiție de continuare. La fiecare iterație a codului această condiție este verificată, iar în momentul în care condiția devine falsă se oprește execuția buclei și se trece mai departe în program.&lt;br /&gt;
Există 2 tipuri de structuri repetitive:&lt;br /&gt;
* structuri repetitive cu număr cunoscut de pași;&lt;br /&gt;
* structuri repetitive cu număr necunoscut de pași.&lt;br /&gt;
&lt;br /&gt;
=== Structuri repetitive cu număr cunoscut de pași ===&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;for&amp;#039;&amp;#039; creează o structură repetitivă cu număr cunoscut de pași. Sintaxa instrucțiunii &amp;#039;&amp;#039;for&amp;#039;&amp;#039; este următoarea:&amp;lt;br/&amp;gt;&lt;br /&gt;
a)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
for (inițializare contor; condiție logică; modificare contor)&lt;br /&gt;
        instrucțiune;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
for (inițializare contor; condiție logică; modificare contor){&lt;br /&gt;
        instrucțiune1;&lt;br /&gt;
        instrucțiune2;&lt;br /&gt;
..............................&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;for&amp;#039;&amp;#039; se parcurge conform schemei următoare:&amp;lt;br/&amp;gt;[[Fișier:For.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce va afisa acest program?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
  int x;&lt;br /&gt;
  for (x = 0; x &amp;lt; 10; x++) {&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, x);&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Structuri repetitive cu număr necunoscut de pași ===&lt;br /&gt;
Există două instrucțiuni pentru a crea structuri repetitive cu număr necunoscut de pași:&lt;br /&gt;
* instrucțiunea &amp;#039;&amp;#039;while&amp;#039;&amp;#039;;&lt;br /&gt;
* instrucțiunea &amp;#039;&amp;#039;do..while&amp;#039;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
==== Instrucțiunea &amp;#039;&amp;#039;while&amp;#039;&amp;#039; ====&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;while&amp;#039;&amp;#039; verifică înainte de fiecare iterație condiția de intrare: dacă această condiție este îndeplinită se execută codul din corpul instrucțiunii, iar dacă nu se îndeplinește condiția se iese din această buclă. Sintaxa instrucțiunii este următoarea:&amp;lt;br/&amp;gt;&lt;br /&gt;
a)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
while (condiție)&lt;br /&gt;
        instrucțiune;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
while (condiție){&lt;br /&gt;
        instrucțiune1;&lt;br /&gt;
        instrucțiune2;&lt;br /&gt;
..............................&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Organigrama instrucțiunii &amp;#039;&amp;#039;while&amp;#039;&amp;#039; se regăsește în imaginea următoare:&amp;lt;br/&amp;gt;[[Fișier:While.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce va afișa următorul cod în urma execuției?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
  int x = 0;  &lt;br /&gt;
  while (x &amp;lt; 10){&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, x);&lt;br /&gt;
    x++;       &lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Instrucțiunea &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; ====&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; verifică după fiecare iterație condiția de continuare. Sintaxa instrucțiunii &amp;quot;do while&amp;#039;&amp;#039; este următoarea:&amp;lt;br/&amp;gt;&lt;br /&gt;
a)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
do{&lt;br /&gt;
      instrucțiune;&lt;br /&gt;
}while (condiție);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
do{&lt;br /&gt;
      instrucțiune1;&lt;br /&gt;
      instrucțiune2;&lt;br /&gt;
..............................&lt;br /&gt;
}while (condiție);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Se observă că sintaxa instrucțiunii &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; este puțin diferită:&lt;br /&gt;
* indiferent de numărul de instrucțiuni din cadrul structurii repetitive, se folosesc acoladele;&lt;br /&gt;
* după condiția de continuitate se folosește obligatoriu semnul de punctuație &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;;&amp;#039;&amp;#039;&amp;#039;&amp;lt;/font&amp;gt; .&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Organigrama instrucțiunii &amp;#039;&amp;#039;while&amp;#039;&amp;#039; se regăsește în imaginea următoare:&amp;lt;br/&amp;gt;[[Fișier:Do_while.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Se observă că datorită faptului că se verifică abia la sfârșitul structurii condiția de continuitate, orice structură iterativă de tip &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; va fi executată întotdeauna cel puțin o dată.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce se va afișa în urma execuției?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
  int x;&lt;br /&gt;
  x = 0;&lt;br /&gt;
  do{&lt;br /&gt;
    printf( &amp;quot;Hello, world!\n&amp;quot; );&lt;br /&gt;
  }while (x != 0);&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Cuvintele cheie &amp;#039;&amp;#039;&amp;#039;break&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039; ==&lt;br /&gt;
Pentru structurile repetitive există două cuvinte cheie de mare importanță: &amp;#039;&amp;#039;&amp;#039;break&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;break&amp;#039;&amp;#039;&amp;#039; va ieși din bucla cea mai apropiată indiferent de condițiile de continuare ale acesteia. Utilitatea acestei instrucțiuni apare atunci când trebuie părăsită bucla în anumite circumstanțe.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039; oprește iterația curentă, face update contorului (în cazul buclei &amp;#039;&amp;#039;for&amp;#039;&amp;#039;) și continuă cu execuția structurii repetitive de la prima instrucțiune. Cu alte cuvinte, &amp;#039;&amp;#039;continue&amp;#039;&amp;#039; ignoră tot ceea ce urmează după el în cadrul buclei și trece la următoarea iterație a buclei.&lt;br /&gt;
&lt;br /&gt;
==Exerciții==&lt;br /&gt;
&amp;lt;ol&amp;gt;&amp;lt;li&amp;gt;Să se afișeze pe o linie toate literele în ordine alfabetică, scrise cu majuscule, și pe o altă linie toate literele în ordine invers alfabetică, scrise cu litere mici. Rezolvați exercițiul în 3 moduri (folosind toate tipurile de bucle).&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Să se citească un număr întreg fără semn n&amp;lt;20 de la tastatură. Afișați rezultatul operației n!.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Să se citească un număr întreg fără semn de la tastatură și să se verifice dacă acesta este palindrom.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Să se citească un număr întreg fără semn n de la tastatură. Să se afișeze primele n numere impare.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Să se citească un număr întreg fără semn n de la tastatură. Să se citească apoi n numere întregi de la tastatură și să se afișeze suma numerelor pare introduse.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Refaceți exercițiul anterior în așa fel încât să folosiți instrucțiunea &amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Să se citească de la tastatură o serie de numere întregi până la întâlnirea numărului 0. Să se afișeze apoi media aritmetică a acestor numere.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Verificați dacă un număr întreg fără semn introdus de la tastatură este prim.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Să se afișeze cmmdc și cmmmc a două numere întregi fără semn citite de la tastatură.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Să se citească un număr întreg fără semn n de la tastatură. Să se afișeze primele n numere prime.&amp;lt;/li&amp;gt;&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_6&amp;diff=3683</id>
		<title>PC Laborator 6</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_6&amp;diff=3683"/>
		<updated>2015-11-07T10:08:54Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea blocurilor repetitive;&lt;br /&gt;
* să conceapă programe care folosesc blocuri repetitive.&lt;br /&gt;
&lt;br /&gt;
== Structura repetitivă ==&lt;br /&gt;
Structura repetitivă, cunoscută și sub numele de loop sau buclă, reprezintă o bucată de cod care poate fi executată în mod repetat. Structurile repetitive trebuie sa aibă o condiție de continuare. La fiecare iterație a codului această condiție este verificată, iar în momentul în care condiția devine falsă se oprește execuția buclei și se trece mai departe în program.&lt;br /&gt;
Există 2 tipuri de structuri repetitive:&lt;br /&gt;
* structuri repetitive cu număr cunoscut de pași;&lt;br /&gt;
* structuri repetitive cu număr necunoscut de pași.&lt;br /&gt;
&lt;br /&gt;
=== Structuri repetitive cu număr cunoscut de pași ===&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;for&amp;#039;&amp;#039; creează o structură repetitivă cu număr cunoscut de pași. Sintaxa instrucțiunii &amp;#039;&amp;#039;for&amp;#039;&amp;#039; este următoarea:&amp;lt;br/&amp;gt;&lt;br /&gt;
a)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
for (inițializare contor; condiție logică; modificare contor)&lt;br /&gt;
        instrucțiune;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
for (inițializare contor; condiție logică; modificare contor){&lt;br /&gt;
        instrucțiune1;&lt;br /&gt;
        instrucțiune2;&lt;br /&gt;
..............................&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;for&amp;#039;&amp;#039; se parcurge conform schemei următoare:&amp;lt;br/&amp;gt;[[Fișier:For.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce va afisa acest program?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
  int x;&lt;br /&gt;
  for (x = 0; x &amp;lt; 10; x++) {&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, x);&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Structuri repetitive cu număr necunoscut de pași ===&lt;br /&gt;
Există două instrucțiuni pentru a crea structuri repetitive cu număr necunoscut de pași:&lt;br /&gt;
* instrucțiunea &amp;#039;&amp;#039;while&amp;#039;&amp;#039;;&lt;br /&gt;
* instrucțiunea &amp;#039;&amp;#039;do..while&amp;#039;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
==== Instrucțiunea &amp;#039;&amp;#039;while&amp;#039;&amp;#039; ====&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;while&amp;#039;&amp;#039; verifică înainte de fiecare iterație condiția de intrare: dacă această condiție este îndeplinită se execută codul din corpul instrucțiunii, iar dacă nu se îndeplinește condiția se iese din această buclă. Sintaxa instrucțiunii este următoarea:&amp;lt;br/&amp;gt;&lt;br /&gt;
a)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
while (condiție)&lt;br /&gt;
        instrucțiune;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
while (condiție){&lt;br /&gt;
        instrucțiune1;&lt;br /&gt;
        instrucțiune2;&lt;br /&gt;
..............................&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Organigrama instrucțiunii &amp;#039;&amp;#039;while&amp;#039;&amp;#039; se regăsește în imaginea următoare:&amp;lt;br/&amp;gt;[[Fișier:While.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce va afișa următorul cod în urma execuției?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
  int x = 0;  &lt;br /&gt;
  while (x &amp;lt; 10){&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, x);&lt;br /&gt;
    x++;       &lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Instrucțiunea &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; ====&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; verifică după fiecare iterație condiția de continuare. Sintaxa instrucțiunii &amp;quot;do while&amp;#039;&amp;#039; este următoarea:&amp;lt;br/&amp;gt;&lt;br /&gt;
a)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
do{&lt;br /&gt;
      instrucțiune;&lt;br /&gt;
}while (condiție);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
do{&lt;br /&gt;
      instrucțiune1;&lt;br /&gt;
      instrucțiune2;&lt;br /&gt;
..............................&lt;br /&gt;
}while (condiție);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Se observă că sintaxa instrucțiunii &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; este puțin diferită:&lt;br /&gt;
* indiferent de numărul de instrucțiuni din cadrul structurii repetitive, se folosesc acoladele;&lt;br /&gt;
* după condiția de continuitate se folosește obligatoriu semnul de punctuație &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;;&amp;#039;&amp;#039;&amp;#039;&amp;lt;/font&amp;gt; .&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Organigrama instrucțiunii &amp;#039;&amp;#039;while&amp;#039;&amp;#039; se regăsește în imaginea următoare:&amp;lt;br/&amp;gt;[[Fișier:Do_while.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Se observă că datorită faptului că se verifică abia la sfârșitul structurii condiția de continuitate, orice structură iterativă de tip &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; va fi executată întotdeauna cel puțin o dată.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce se va afișa în urma execuției?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
  int x;&lt;br /&gt;
  x = 0;&lt;br /&gt;
  do{&lt;br /&gt;
    printf( &amp;quot;Hello, world!\n&amp;quot; );&lt;br /&gt;
  }while (x != 0);&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Cuvintele cheie &amp;#039;&amp;#039;&amp;#039;break&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039; ==&lt;br /&gt;
Pentru structurile repetitive există două cuvinte cheie de mare importanță: &amp;#039;&amp;#039;&amp;#039;break&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;break&amp;#039;&amp;#039;&amp;#039; va ieși din bucla cea mai apropiată indiferent de condițiile de continuare ale acesteia. Utilitatea acestei instrucțiuni apare atunci când trebuie părăsită bucla în anumite circumstanțe.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039; oprește iterația curentă, face update contorului (în cazul buclei &amp;#039;&amp;#039;for&amp;#039;&amp;#039;) și continuă cu execuția structurii repetitive de la prima instrucțiune. Cu alte cuvinte, &amp;#039;&amp;#039;continue&amp;#039;&amp;#039; ignoră tot ceea ce urmează după el în cadrul buclei și trece la următoarea iterație a buclei.&lt;br /&gt;
&lt;br /&gt;
==Exerciții==&lt;br /&gt;
1. Să se afișeze pe o linie toate literele în ordine alfabetică, scrise cu majuscule, și pe o altă linie toate literele în ordine invers alfabetică, scrise cu litere mici. Rezolvați exercițiul în 3 moduri (folosind toate tipurile de bucle).&amp;lt;br/&amp;gt;&lt;br /&gt;
2. Să se citească un număr întreg fără semn n&amp;lt;20 de la tastatură. Afișați rezultatul operației n!.&amp;lt;br/&amp;gt;&lt;br /&gt;
3. Să se citească un număr întreg fără semn de la tastatură și să se verifice dacă acesta este palindrom.&amp;lt;br/&amp;gt;&lt;br /&gt;
4. Să se citească un număr întreg fără semn n de la tastatură. Să se afișeze primele n numere impare.&amp;lt;br/&amp;gt;&lt;br /&gt;
5. Să se citească un număr întreg fără semn n de la tastatură. Să se citească apoi n numere întregi de la tastatură și să se afișeze suma numerelor pare introduse.&amp;lt;br/&amp;gt;&lt;br /&gt;
6. Refaceți exercițiul anterior în așa fel încât să folosiți instrucțiunea &amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039;.&amp;lt;br/&amp;gt;&lt;br /&gt;
7. Să se citească de la tastatură o serie de numere întregi până la întâlnirea numărului 0. Să se afișeze apoi media aritmetică a acestor numere.&amp;lt;br/&amp;gt;&lt;br /&gt;
8. Verificați dacă un număr întreg fără semn introdus de la tastatură este prim.&amp;lt;br/&amp;gt;&lt;br /&gt;
9. Să se afișeze cmmdc și cmmmc a două numere întregi fără semn citite de la tastatură.&amp;lt;br/&amp;gt;&lt;br /&gt;
10. Să se citească un număr întreg fără semn n de la tastatură. Să se afișeze primele n numere prime.&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_6&amp;diff=3682</id>
		<title>PC Laborator 6</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_6&amp;diff=3682"/>
		<updated>2015-11-06T12:44:48Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: /* Instrucțiunea do while */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea blocurilor repetitive;&lt;br /&gt;
* să conceapă programe care folosesc blocuri repetitive.&lt;br /&gt;
&lt;br /&gt;
== Structura repetitivă ==&lt;br /&gt;
Structura repetitivă, cunoscută și sub numele de loop sau buclă, reprezintă o bucată de cod care poate fi executată în mod repetat. Structurile repetitive trebuie sa aibă o condiție de continuare. La fiecare iterație a codului această condiție este verificată, iar în momentul în care condiția devine falsă se oprește execuția buclei și se trece mai departe în program.&lt;br /&gt;
Există 2 tipuri de structuri repetitive:&lt;br /&gt;
* structuri repetitive cu număr cunoscut de pași;&lt;br /&gt;
* structuri repetitive cu număr necunoscut de pași.&lt;br /&gt;
&lt;br /&gt;
=== Structuri repetitive cu număr cunoscut de pași ===&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;for&amp;#039;&amp;#039; creează o structură repetitivă cu număr cunoscut de pași. Sintaxa instrucțiunii &amp;#039;&amp;#039;for&amp;#039;&amp;#039; este următoarea:&amp;lt;br/&amp;gt;&lt;br /&gt;
a)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
for (inițializare contor; condiție logică; modificare contor)&lt;br /&gt;
        instrucțiune;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
for (inițializare contor; condiție logică; modificare contor){&lt;br /&gt;
        instrucțiune1;&lt;br /&gt;
        instrucțiune2;&lt;br /&gt;
..............................&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;for&amp;#039;&amp;#039; se parcurge conform schemei următoare:&amp;lt;br/&amp;gt;[[Fișier:For.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce va afisa acest program?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
  int x;&lt;br /&gt;
  for (x = 0; x &amp;lt; 10; x++) {&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, x);&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Structuri repetitive cu număr necunoscut de pași ===&lt;br /&gt;
Există două instrucțiuni pentru a crea structuri repetitive cu număr necunoscut de pași:&lt;br /&gt;
* instrucțiunea &amp;#039;&amp;#039;while&amp;#039;&amp;#039;;&lt;br /&gt;
* instrucțiunea &amp;#039;&amp;#039;do..while&amp;#039;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
==== Instrucțiunea &amp;#039;&amp;#039;while&amp;#039;&amp;#039; ====&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;while&amp;#039;&amp;#039; verifică înainte de fiecare iterație condiția de intrare: dacă această condiție este îndeplinită se execută codul din corpul instrucțiunii, iar dacă nu se îndeplinește condiția se iese din această buclă. Sintaxa instrucțiunii este următoarea:&amp;lt;br/&amp;gt;&lt;br /&gt;
a)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
while (condiție)&lt;br /&gt;
        instrucțiune;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
while (condiție){&lt;br /&gt;
        instrucțiune1;&lt;br /&gt;
        instrucțiune2;&lt;br /&gt;
..............................&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Organigrama instrucțiunii &amp;#039;&amp;#039;while&amp;#039;&amp;#039; se regăsește în imaginea următoare:&amp;lt;br/&amp;gt;[[Fișier:While.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce va afișa următorul cod în urma execuției?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
  int x = 0;  &lt;br /&gt;
  while (x &amp;lt; 10){&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, x);&lt;br /&gt;
    x++;       &lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Instrucțiunea &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; ====&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; verifică după fiecare iterație condiția de continuare. Sintaxa instrucțiunii &amp;quot;do while&amp;#039;&amp;#039; este următoarea:&amp;lt;br/&amp;gt;&lt;br /&gt;
a)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
do{&lt;br /&gt;
      instrucțiune;&lt;br /&gt;
}while (condiție);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
do{&lt;br /&gt;
      instrucțiune1;&lt;br /&gt;
      instrucțiune2;&lt;br /&gt;
..............................&lt;br /&gt;
}while (condiție);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Se observă că sintaxa instrucțiunii &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; este puțin diferită:&lt;br /&gt;
* indiferent de numărul de instrucțiuni din cadrul structurii repetitive, se folosesc acoladele;&lt;br /&gt;
* după condiția de continuitate se folosește obligatoriu semnul de punctuație &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;;&amp;#039;&amp;#039;&amp;#039;&amp;lt;/font&amp;gt; .&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Organigrama instrucțiunii &amp;#039;&amp;#039;while&amp;#039;&amp;#039; se regăsește în imaginea următoare:&amp;lt;br/&amp;gt;[[Fișier:Do_while.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Se observă că datorită faptului că se verifică abia la sfârșitul structurii condiția de continuitate, orice structură iterativă de tip &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; va fi executată întotdeauna cel puțin o dată.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce se va afișa în urma execuției?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
  int x;&lt;br /&gt;
  x = 0;&lt;br /&gt;
  do{&lt;br /&gt;
    printf( &amp;quot;Hello, world!\n&amp;quot; );&lt;br /&gt;
  }while (x != 0);&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Cuvintele cheie &amp;#039;&amp;#039;&amp;#039;break&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039; ==&lt;br /&gt;
Pentru structurile repetitive există două cuvinte cheie de mare importanță: &amp;#039;&amp;#039;&amp;#039;break&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;break&amp;#039;&amp;#039;&amp;#039; va ieși din bucla cea mai apropiată indiferent de condițiile de continuare ale acesteia. Utilitatea acestei instrucțiuni apare atunci când trebuie părăsită bucla în anumite circumstanțe.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039; oprește iterația curentă, face update contorului (în cazul buclei &amp;#039;&amp;#039;for&amp;#039;&amp;#039;) și continuă cu execuția structurii repetitive de la prima instrucțiune. Cu alte cuvinte, &amp;#039;&amp;#039;continue&amp;#039;&amp;#039; ignoră tot ceea ce urmează după el în cadrul buclei și trece la următoarea iterație a buclei.&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_6&amp;diff=3681</id>
		<title>PC Laborator 6</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_6&amp;diff=3681"/>
		<updated>2015-11-06T12:43:58Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: /* Instrucțiunea while */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea blocurilor repetitive;&lt;br /&gt;
* să conceapă programe care folosesc blocuri repetitive.&lt;br /&gt;
&lt;br /&gt;
== Structura repetitivă ==&lt;br /&gt;
Structura repetitivă, cunoscută și sub numele de loop sau buclă, reprezintă o bucată de cod care poate fi executată în mod repetat. Structurile repetitive trebuie sa aibă o condiție de continuare. La fiecare iterație a codului această condiție este verificată, iar în momentul în care condiția devine falsă se oprește execuția buclei și se trece mai departe în program.&lt;br /&gt;
Există 2 tipuri de structuri repetitive:&lt;br /&gt;
* structuri repetitive cu număr cunoscut de pași;&lt;br /&gt;
* structuri repetitive cu număr necunoscut de pași.&lt;br /&gt;
&lt;br /&gt;
=== Structuri repetitive cu număr cunoscut de pași ===&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;for&amp;#039;&amp;#039; creează o structură repetitivă cu număr cunoscut de pași. Sintaxa instrucțiunii &amp;#039;&amp;#039;for&amp;#039;&amp;#039; este următoarea:&amp;lt;br/&amp;gt;&lt;br /&gt;
a)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
for (inițializare contor; condiție logică; modificare contor)&lt;br /&gt;
        instrucțiune;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
for (inițializare contor; condiție logică; modificare contor){&lt;br /&gt;
        instrucțiune1;&lt;br /&gt;
        instrucțiune2;&lt;br /&gt;
..............................&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;for&amp;#039;&amp;#039; se parcurge conform schemei următoare:&amp;lt;br/&amp;gt;[[Fișier:For.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce va afisa acest program?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
  int x;&lt;br /&gt;
  for (x = 0; x &amp;lt; 10; x++) {&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, x);&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Structuri repetitive cu număr necunoscut de pași ===&lt;br /&gt;
Există două instrucțiuni pentru a crea structuri repetitive cu număr necunoscut de pași:&lt;br /&gt;
* instrucțiunea &amp;#039;&amp;#039;while&amp;#039;&amp;#039;;&lt;br /&gt;
* instrucțiunea &amp;#039;&amp;#039;do..while&amp;#039;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
==== Instrucțiunea &amp;#039;&amp;#039;while&amp;#039;&amp;#039; ====&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;while&amp;#039;&amp;#039; verifică înainte de fiecare iterație condiția de intrare: dacă această condiție este îndeplinită se execută codul din corpul instrucțiunii, iar dacă nu se îndeplinește condiția se iese din această buclă. Sintaxa instrucțiunii este următoarea:&amp;lt;br/&amp;gt;&lt;br /&gt;
a)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
while (condiție)&lt;br /&gt;
        instrucțiune;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
while (condiție){&lt;br /&gt;
        instrucțiune1;&lt;br /&gt;
        instrucțiune2;&lt;br /&gt;
..............................&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Organigrama instrucțiunii &amp;#039;&amp;#039;while&amp;#039;&amp;#039; se regăsește în imaginea următoare:&amp;lt;br/&amp;gt;[[Fișier:While.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce va afișa următorul cod în urma execuției?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
  int x = 0;  &lt;br /&gt;
  while (x &amp;lt; 10){&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, x);&lt;br /&gt;
    x++;       &lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Instrucțiunea &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; ====&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; verifică după fiecare iterație condiția de continuare. Sintaxa instrucțiunii &amp;quot;do while&amp;#039;&amp;#039; este următoarea:&amp;lt;br/&amp;gt;&lt;br /&gt;
a)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
do{&lt;br /&gt;
      instrucțiune;&lt;br /&gt;
}while (condiție);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
do{&lt;br /&gt;
      instrucțiune1;&lt;br /&gt;
      instrucțiune2;&lt;br /&gt;
..............................&lt;br /&gt;
}while (condiție);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Se observă că sintaxa instrucțiunii &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; este puțin diferită:&lt;br /&gt;
* indiferent de numărul de instrucțiuni din cadrul structurii repetitive, se folosesc acoladele;&lt;br /&gt;
* după condiția de continuitate se folosește obligatoriu semnul de punctuație &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;;&amp;#039;&amp;#039;&amp;#039;&amp;lt;/font&amp;gt; .&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Organigrama instrucțiunii &amp;#039;&amp;#039;while&amp;#039;&amp;#039; se regăsește în imaginea următoare:&amp;lt;br/&amp;gt;[[Fișier:Do_while.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Se observă că datorită faptului că se verifică abia la sfârșitul structurii condiția de continuitate, orice structură iterativă de tip &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; va fi executată întotdeauna cel puțin o dată.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce se va afișa în urma execuției?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int x;&lt;br /&gt;
x = 0;&lt;br /&gt;
do{&lt;br /&gt;
      printf( &amp;quot;Hello, world!\n&amp;quot; );&lt;br /&gt;
}while (x != 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Cuvintele cheie &amp;#039;&amp;#039;&amp;#039;break&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039; ==&lt;br /&gt;
Pentru structurile repetitive există două cuvinte cheie de mare importanță: &amp;#039;&amp;#039;&amp;#039;break&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;break&amp;#039;&amp;#039;&amp;#039; va ieși din bucla cea mai apropiată indiferent de condițiile de continuare ale acesteia. Utilitatea acestei instrucțiuni apare atunci când trebuie părăsită bucla în anumite circumstanțe.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039; oprește iterația curentă, face update contorului (în cazul buclei &amp;#039;&amp;#039;for&amp;#039;&amp;#039;) și continuă cu execuția structurii repetitive de la prima instrucțiune. Cu alte cuvinte, &amp;#039;&amp;#039;continue&amp;#039;&amp;#039; ignoră tot ceea ce urmează după el în cadrul buclei și trece la următoarea iterație a buclei.&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_6&amp;diff=3680</id>
		<title>PC Laborator 6</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_6&amp;diff=3680"/>
		<updated>2015-11-06T12:42:56Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: /* Structuri repetitive cu număr cunoscut de pași */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea blocurilor repetitive;&lt;br /&gt;
* să conceapă programe care folosesc blocuri repetitive.&lt;br /&gt;
&lt;br /&gt;
== Structura repetitivă ==&lt;br /&gt;
Structura repetitivă, cunoscută și sub numele de loop sau buclă, reprezintă o bucată de cod care poate fi executată în mod repetat. Structurile repetitive trebuie sa aibă o condiție de continuare. La fiecare iterație a codului această condiție este verificată, iar în momentul în care condiția devine falsă se oprește execuția buclei și se trece mai departe în program.&lt;br /&gt;
Există 2 tipuri de structuri repetitive:&lt;br /&gt;
* structuri repetitive cu număr cunoscut de pași;&lt;br /&gt;
* structuri repetitive cu număr necunoscut de pași.&lt;br /&gt;
&lt;br /&gt;
=== Structuri repetitive cu număr cunoscut de pași ===&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;for&amp;#039;&amp;#039; creează o structură repetitivă cu număr cunoscut de pași. Sintaxa instrucțiunii &amp;#039;&amp;#039;for&amp;#039;&amp;#039; este următoarea:&amp;lt;br/&amp;gt;&lt;br /&gt;
a)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
for (inițializare contor; condiție logică; modificare contor)&lt;br /&gt;
        instrucțiune;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
for (inițializare contor; condiție logică; modificare contor){&lt;br /&gt;
        instrucțiune1;&lt;br /&gt;
        instrucțiune2;&lt;br /&gt;
..............................&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;for&amp;#039;&amp;#039; se parcurge conform schemei următoare:&amp;lt;br/&amp;gt;[[Fișier:For.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce va afisa acest program?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
  int x;&lt;br /&gt;
  for (x = 0; x &amp;lt; 10; x++) {&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, x);&lt;br /&gt;
  }&lt;br /&gt;
  return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Structuri repetitive cu număr necunoscut de pași ===&lt;br /&gt;
Există două instrucțiuni pentru a crea structuri repetitive cu număr necunoscut de pași:&lt;br /&gt;
* instrucțiunea &amp;#039;&amp;#039;while&amp;#039;&amp;#039;;&lt;br /&gt;
* instrucțiunea &amp;#039;&amp;#039;do..while&amp;#039;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
==== Instrucțiunea &amp;#039;&amp;#039;while&amp;#039;&amp;#039; ====&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;while&amp;#039;&amp;#039; verifică înainte de fiecare iterație condiția de intrare: dacă această condiție este îndeplinită se execută codul din corpul instrucțiunii, iar dacă nu se îndeplinește condiția se iese din această buclă. Sintaxa instrucțiunii este următoarea:&amp;lt;br/&amp;gt;&lt;br /&gt;
a)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
while (condiție)&lt;br /&gt;
        instrucțiune;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
while (condiție){&lt;br /&gt;
        instrucțiune1;&lt;br /&gt;
        instrucțiune2;&lt;br /&gt;
..............................&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Organigrama instrucțiunii &amp;#039;&amp;#039;while&amp;#039;&amp;#039; se regăsește în imaginea următoare:&amp;lt;br/&amp;gt;[[Fișier:While.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce va afișa următorul cod în urma execuției?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int x = 0;  &lt;br /&gt;
while (x &amp;lt; 10){&lt;br /&gt;
      printf(&amp;quot;%d\n&amp;quot;, x);&lt;br /&gt;
      x++;       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Instrucțiunea &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; ====&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; verifică după fiecare iterație condiția de continuare. Sintaxa instrucțiunii &amp;quot;do while&amp;#039;&amp;#039; este următoarea:&amp;lt;br/&amp;gt;&lt;br /&gt;
a)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
do{&lt;br /&gt;
      instrucțiune;&lt;br /&gt;
}while (condiție);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
do{&lt;br /&gt;
      instrucțiune1;&lt;br /&gt;
      instrucțiune2;&lt;br /&gt;
..............................&lt;br /&gt;
}while (condiție);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Se observă că sintaxa instrucțiunii &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; este puțin diferită:&lt;br /&gt;
* indiferent de numărul de instrucțiuni din cadrul structurii repetitive, se folosesc acoladele;&lt;br /&gt;
* după condiția de continuitate se folosește obligatoriu semnul de punctuație &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;;&amp;#039;&amp;#039;&amp;#039;&amp;lt;/font&amp;gt; .&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Organigrama instrucțiunii &amp;#039;&amp;#039;while&amp;#039;&amp;#039; se regăsește în imaginea următoare:&amp;lt;br/&amp;gt;[[Fișier:Do_while.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Se observă că datorită faptului că se verifică abia la sfârșitul structurii condiția de continuitate, orice structură iterativă de tip &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; va fi executată întotdeauna cel puțin o dată.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce se va afișa în urma execuției?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int x;&lt;br /&gt;
x = 0;&lt;br /&gt;
do{&lt;br /&gt;
      printf( &amp;quot;Hello, world!\n&amp;quot; );&lt;br /&gt;
}while (x != 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Cuvintele cheie &amp;#039;&amp;#039;&amp;#039;break&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039; ==&lt;br /&gt;
Pentru structurile repetitive există două cuvinte cheie de mare importanță: &amp;#039;&amp;#039;&amp;#039;break&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;break&amp;#039;&amp;#039;&amp;#039; va ieși din bucla cea mai apropiată indiferent de condițiile de continuare ale acesteia. Utilitatea acestei instrucțiuni apare atunci când trebuie părăsită bucla în anumite circumstanțe.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039; oprește iterația curentă, face update contorului (în cazul buclei &amp;#039;&amp;#039;for&amp;#039;&amp;#039;) și continuă cu execuția structurii repetitive de la prima instrucțiune. Cu alte cuvinte, &amp;#039;&amp;#039;continue&amp;#039;&amp;#039; ignoră tot ceea ce urmează după el în cadrul buclei și trece la următoarea iterație a buclei.&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_5&amp;diff=3679</id>
		<title>PC Laborator 5</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_5&amp;diff=3679"/>
		<updated>2015-11-05T17:12:44Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: /* Exerciții */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Obiective == &lt;br /&gt;
  &lt;br /&gt;
în urma acestui laborator, studentul va fi capabil să: &lt;br /&gt;
* 	 înțeleagă cum funcționează o structură decizională; &lt;br /&gt;
* 	 scrie programe în C folosind construcții decizionale. &lt;br /&gt;
  &lt;br /&gt;
== Structura decizională == &lt;br /&gt;
  &lt;br /&gt;
Se întâmplă adesea ca evoluția unui program să depindă de o anumită condiție. Ea poate lua însă diverse forme, rolul programatorului fiind să conducă execuția programului pe calea corectă, ținând cont de acea condiție logică. Apare astfel structura decizionala if, care ramifică evoluția programului în funcție de valoarea de adevăr  a condiției testate.  &lt;br /&gt;
  &lt;br /&gt;
=== 	 Schema logică === &lt;br /&gt;
Prima etapă din parcurgerea unei structuri decizionale de tipul if-else o reprezintă testarea condiției logice. în cazul în care aceasta este evaluată ca adevărată se execută instructiunea1, cea asociată ramurii if. în cazul în care condiția logică este evaluată ca falsă se execută instructiunea2, cea asociată ramurii else. După executarea instrucțiunii asociate, structura if-else se încheie și programul se continuă cu linia următoare blocului decizional.&lt;br /&gt;
 &lt;br /&gt;
[[Fișier:structura_decizionala.png]]&lt;br /&gt;
&lt;br /&gt;
=== Sintaxă generală ===&lt;br /&gt;
a)	&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (conditie) instructiune;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (conditie) {&lt;br /&gt;
	 instructiune1;&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
	 instructiune2;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
c)	&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (conditie1) {&lt;br /&gt;
	instructiune 1;&lt;br /&gt;
}&lt;br /&gt;
else if (conditie2) {&lt;br /&gt;
	instructiune 2;&lt;br /&gt;
}&lt;br /&gt;
else if (conditie 3) {&lt;br /&gt;
	instructiune3;&lt;br /&gt;
}&lt;br /&gt;
................................&lt;br /&gt;
else {&lt;br /&gt;
	instructiune;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asocierea ramurilor if-else===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; în cazul în care un if are mai multe ramuri, un else se asociază celui mai apropiat if.&amp;lt;/div&amp;gt; &lt;br /&gt;
Această observație ne conduce la următoarele două cazuri: &lt;br /&gt;
  &lt;br /&gt;
* 	 dacă nu există blocuri de instrucțiuni, un else este legat de if-ul imediat anterior; &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (a &amp;gt; 5) &lt;br /&gt;
    if (b &amp;gt; a) &lt;br /&gt;
	printf (&amp;quot;b este mai mare ca a&amp;quot;);&lt;br /&gt;
    else &lt;br /&gt;
	printf (&amp;quot;b este mai mic sau egal cu a&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*	dacă există blocuri de instrucțiuni, un else este legat de ultimul if fără pereche.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (a &amp;gt; 5) {&lt;br /&gt;
	if (b &amp;gt; a)&lt;br /&gt;
	      	printf (&amp;quot;b este mai mare ca a&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
else &lt;br /&gt;
    printf (&amp;quot;a nu este mai mare ca 5&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Ce va afișa acest program prost indentat? &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int number = 4; &lt;br /&gt;
double alpha = -1.0; &lt;br /&gt;
if (number &amp;gt; 0) &lt;br /&gt;
	if (alpha &amp;gt; 0)&lt;br /&gt;
		printf( &amp;quot;Here I am!\n&amp;quot;);&lt;br /&gt;
else &lt;br /&gt;
	printf( &amp;quot;No, I’m here!\n&amp;quot;); &lt;br /&gt;
printf(&amp;quot;No, actually, I’m here!\n&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Evaluarea expresiilor logice == &lt;br /&gt;
  &lt;br /&gt;
Am stabilit deja că o condiție logică, prin valoarea ei de adevăr, ramifică evoluția programului. &lt;br /&gt;
  &lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Adevărat în C înseamnă orice rezultat diferit de 0 (nul) al unei evaluări, în timp ce despre fals vorbim când o expresie este evaluată la 0 (nul). &lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
  &lt;br /&gt;
În C, condiția  poate avea mai multe reprezentări, după cum urmează &lt;br /&gt;
  &lt;br /&gt;
=== Operandul === &lt;br /&gt;
  &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu:&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
Verificați că un număr citit de la tastatură poate fi numitorul unei fracții.&lt;br /&gt;
&lt;br /&gt;
=== Operația cu operatori relaționali (==, !=, &amp;lt;=, &amp;lt;, &amp;gt;, &amp;gt;=) === &lt;br /&gt;
  &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu:&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
Asociați o valoare variabilei cost în funcție de valoarea variabilei distance după cum urmează: &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align: center;&amp;quot; |distance&lt;br /&gt;
! style=&amp;quot;text-align: center;&amp;quot; |cost&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | Intre 0 si 100&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 5.50&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | Peste 100, dar mai putin de 500&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 8.00&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | Peste 500, dar nu mai mult de 1000&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 10.50&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 1000 sau mai mult&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 13.00&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Operația cu operatori logici (&amp;amp;&amp;amp;, ||, !) === &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu:&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
Folosind operatori logici, aduceți următoarea structură decizională la forma cea mai simplă: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (doesSignificantWork) { &lt;br /&gt;
	if (makesBreakthrough) &lt;br /&gt;
		nobelPrizeCandidate = true; &lt;br /&gt;
	else&lt;br /&gt;
		 nobelPrizeCandidate = false; &lt;br /&gt;
} &lt;br /&gt;
else if (!doesSignificantWork) {&lt;br /&gt;
	nobelPrizeCandidate = false;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; Cuvântul cheie &amp;#039;&amp;#039;&amp;#039;bool&amp;#039;&amp;#039;&amp;#039;, ca și valorile &amp;#039;&amp;#039;&amp;#039;true&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;false&amp;#039;&amp;#039;&amp;#039;, au fost introduse în standardul C99, deci dacă doriți să-l folosiți codul trebuie compilat cu &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;--std=c99&amp;lt;/code&amp;gt; ca argument al compilatorului (gcc).&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a putea lucra cu operatorii logici, este necesar să ne reamintim modul în care aceștia operează. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; | Tabelul operatorilor logici&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | a&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | b&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | !a&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | a &amp;amp;&amp;amp; b&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | a ll b&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 1&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 1&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0 &lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 1 &lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; În tabel remarcăm că operatorul logic &amp;#039;&amp;#039;&amp;#039;SI ( &amp;amp;&amp;amp; )&amp;#039;&amp;#039;&amp;#039; întoarce 1 dacă și numai dacă ambele expresii, &amp;#039;&amp;#039;a&amp;#039;&amp;#039; și &amp;#039;&amp;#039;b&amp;#039;&amp;#039; în cazul nostru, întorc o valoare nenulă. în orice alt caz, operatorul &amp;#039;&amp;#039;&amp;#039;SI&amp;#039;&amp;#039;&amp;#039; întoarce 0. Așadar, pentru a optimiza timpul de execuție a programului, expresia a doua, &amp;#039;&amp;#039;b&amp;#039;&amp;#039; în cazul nostru, va fi evaluată dacă și numai dacă prima expresie, &amp;#039;&amp;#039;a&amp;#039;&amp;#039;, a întors o valoare nenulă. &lt;br /&gt;
În mod asemănător lucrează și operatorul &amp;#039;&amp;#039;&amp;#039;SAU ( || )&amp;#039;&amp;#039;&amp;#039;. &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;: Ce va afișa următorul program? &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int a=5,b=10;&lt;br /&gt;
    if(++a||++b) {&lt;br /&gt;
         printf(&amp;quot;%d  %d&amp;quot;,a,b);&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
         printf(&amp;quot;Wayne Rooney&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Alternative la if-else ==&lt;br /&gt;
&lt;br /&gt;
=== Operatorul condițional (  ?  :  ) === &lt;br /&gt;
Singurul operator ternar din C, operatorul condițional funcționează asemenea unui if cu o singură ramură de tip else if. Sintaxa operatorului condițional este următoarea: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
(conditie) ? (expresie1) : (expresie2)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aşadar, blocul decizional&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (a&amp;gt;b)&lt;br /&gt;
	printf (&amp;quot;a este mai mare decat b&amp;quot;);&lt;br /&gt;
else&lt;br /&gt;
	printf (&amp;quot;a este mai mic sau egal cu b&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
poate fi înlocuit astfel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
printf(a &amp;gt; b ? &amp;quot;a este mai mare decat b&amp;quot; : &amp;quot;a este mai mic sau egal cu b&amp;quot;);&lt;br /&gt;
//sau&lt;br /&gt;
(a&amp;gt;b) ? ( printf (&amp;quot;a este mai mare decat b&amp;quot;)) : ( printf (&amp;quot;a este mai mic sau egal cu b&amp;quot;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; Deși prima variantă este cea recunoscută ca fiind corectă, remarcăm că și a două variantă se comportă la fel ca prima. Asta se datorează modului în care funcționează operatorul condițional: el cere ca ambele expresii, &amp;#039;&amp;#039;expresie1&amp;#039;&amp;#039; și &amp;#039;&amp;#039;expresie2&amp;#039;&amp;#039;, să întoarcă &amp;quot;valori&amp;quot;. A doua variantă funcționează deoarece funcția &amp;#039;&amp;#039;printf()&amp;#039;&amp;#039; întoarce întotdeauna o [http://www.tutorialspoint.com/c_standard_library/c_function_printf.htm valoare].&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Structura decizională switch-case === &lt;br /&gt;
Această instrucțiune de decizie este similară unui if cu mai multe ramuri de tip else-if. Sintaxa este următoarea: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
switch (variabilaTestata)	{&lt;br /&gt;
	case valoare1:	 instructiune1;&lt;br /&gt;
				 [break;]&lt;br /&gt;
				&lt;br /&gt;
	case valoare2:	 instructiune2;&lt;br /&gt;
				 [break;]&lt;br /&gt;
				&lt;br /&gt;
	case valoare3:	 instructiune3;&lt;br /&gt;
				 [break;]&lt;br /&gt;
				&lt;br /&gt;
.........................................................................&lt;br /&gt;
	default:		instructiune;&lt;br /&gt;
				&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Valorile &amp;#039;&amp;#039;valoare1&amp;#039;&amp;#039;, &amp;#039;&amp;#039;valoare2&amp;#039;&amp;#039; etc. sunt proprii tipului de dată întreg, la fel ca &amp;#039;&amp;#039;variabilaTestata&amp;#039;&amp;#039;. Ne reamintim însă că întreg nu înseamnă doar variabile de tip &amp;#039;&amp;#039;&amp;#039;int&amp;#039;&amp;#039;&amp;#039;, astfel că &amp;#039;&amp;#039;variabilaTestata&amp;#039;&amp;#039; poate fi de tip &amp;#039;&amp;#039;&amp;#039;char&amp;#039;&amp;#039;&amp;#039;. &lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; instrucțiunea &amp;#039;&amp;#039;break&amp;#039;&amp;#039; este opțională. Modul  care  switch-case funcționează este următorul: &lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;se compară valoarea variabilei &amp;#039;&amp;#039;variabilaTestata&amp;#039;&amp;#039; cu &amp;#039;&amp;#039;valoarea1&amp;#039;&amp;#039;;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;dacă cele două sunt egale, se execută &amp;#039;&amp;#039;instructiune1&amp;#039;&amp;#039;. Apoi există două cazuri:&lt;br /&gt;
&amp;lt;ol type=&amp;quot;i&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;dacă există &amp;#039;&amp;#039;break;&amp;#039;&amp;#039; structura switch-case se încheie și se sare pe linia urmatoare întregului bloc decizional;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;dacă nu există &amp;#039;&amp;#039;break;&amp;#039;&amp;#039; execuția se continuă până se întalnește un &amp;#039;&amp;#039;break;&amp;#039;&amp;#039; sau până când se încheie structura switch-case. Până la acel moment se vor executa toate instrucțiunile întâlnite pe parcurs (&amp;#039;&amp;#039;instructiune2, instructiune3&amp;#039;&amp;#039; etc.);&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;dacă valoarea variabilei &amp;#039;&amp;#039;variabilaTestata&amp;#039;&amp;#039; nu este egală cu niciuna dintre valorile &amp;#039;&amp;#039;valoare1, valoare2&amp;#039;&amp;#039; etc atunci se execută &amp;#039;&amp;#039;instructiune&amp;#039;&amp;#039;, asociată etichetei default.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a verifica echivalența dintre if-else și switch-case, rezolvați folosind ambele structuri decizionale următoarea problemă:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu:&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
Un microbist vrea să afle situația Grupei F de calificare la EURO2016. Astfel, el va introduce o cifră pentru a vedea ce &amp;quot;națională&amp;quot; ocupă acel loc. Folosind următoarea listă, informați-l corect pe suporter.  &lt;br /&gt;
&lt;br /&gt;
1.	Irlanda de Nord&lt;br /&gt;
2.	România&lt;br /&gt;
3.	Ungaria&lt;br /&gt;
4.	Finlanda&lt;br /&gt;
5.	Insulele Feroe&lt;br /&gt;
6.	Grecia&lt;br /&gt;
&lt;br /&gt;
== Exerciții ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ce va afișa următorul program? &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int a=100;&lt;br /&gt;
    if(a&amp;gt;10) {&lt;br /&gt;
         printf(&amp;quot;Tiberiu Soare &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else if(a&amp;gt;20) {&lt;br /&gt;
         printf(&amp;quot;Horia Andreescu &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else if(a&amp;gt;30) {&lt;br /&gt;
           printf(&amp;quot;Iosif Ion Prunner &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Ştiind că un student primește 350 lei/lună dacă are media cel puțin 8.50, 450 lei/lună pentru o medie mai mare sau egală cu 9.50 și 600 lei/lună dacă are media cel puțin 9.70, scrieți un program prin care studentul să afle ce bursă urmează să primească (media va fi citită de la tastatură). &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Ce va afișa următorul program? &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int m=5,n=10,q=20;&lt;br /&gt;
    if(q/n*m)&lt;br /&gt;
         printf(&amp;quot;Bill Gates &amp;quot;);&lt;br /&gt;
    else&lt;br /&gt;
         printf(&amp;quot;Amancio Ortega &amp;quot;);&lt;br /&gt;
         printf(&amp;quot;Carlos Slim Helu &amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți un program care citește de la tastatură notele unui elev la limba română, matematică și informatică și afișează dacă elevul a promovat sau nu bacalaureatul. &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Fie a și b două numere întregi citite de la tastatură. Scrieți un algoritm care să verifice dacă a si b sunt numere consecutive.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Se citesc de la tastatură 3 numere reprezentând lungimea cele 3 laturi ale unui triunghi. Să se afișeze dacă triunghiul este dreptunghic.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Se citește de la tastatură un număr întreg fără semn de 8 biți. Să se afișeze dacă numărul este sau nu un palindrom (dacă are aceeași valoare citit și de la stânga la dreapta si de la dreapta la stanga; de exemplu 101, sau 242).&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_5&amp;diff=3678</id>
		<title>PC Laborator 5</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_5&amp;diff=3678"/>
		<updated>2015-11-05T17:11:01Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: /* Operația cu operatori logici (&amp;amp;&amp;amp;, ||, !) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Obiective == &lt;br /&gt;
  &lt;br /&gt;
în urma acestui laborator, studentul va fi capabil să: &lt;br /&gt;
* 	 înțeleagă cum funcționează o structură decizională; &lt;br /&gt;
* 	 scrie programe în C folosind construcții decizionale. &lt;br /&gt;
  &lt;br /&gt;
== Structura decizională == &lt;br /&gt;
  &lt;br /&gt;
Se întâmplă adesea ca evoluția unui program să depindă de o anumită condiție. Ea poate lua însă diverse forme, rolul programatorului fiind să conducă execuția programului pe calea corectă, ținând cont de acea condiție logică. Apare astfel structura decizionala if, care ramifică evoluția programului în funcție de valoarea de adevăr  a condiției testate.  &lt;br /&gt;
  &lt;br /&gt;
=== 	 Schema logică === &lt;br /&gt;
Prima etapă din parcurgerea unei structuri decizionale de tipul if-else o reprezintă testarea condiției logice. în cazul în care aceasta este evaluată ca adevărată se execută instructiunea1, cea asociată ramurii if. în cazul în care condiția logică este evaluată ca falsă se execută instructiunea2, cea asociată ramurii else. După executarea instrucțiunii asociate, structura if-else se încheie și programul se continuă cu linia următoare blocului decizional.&lt;br /&gt;
 &lt;br /&gt;
[[Fișier:structura_decizionala.png]]&lt;br /&gt;
&lt;br /&gt;
=== Sintaxă generală ===&lt;br /&gt;
a)	&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (conditie) instructiune;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (conditie) {&lt;br /&gt;
	 instructiune1;&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
	 instructiune2;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
c)	&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (conditie1) {&lt;br /&gt;
	instructiune 1;&lt;br /&gt;
}&lt;br /&gt;
else if (conditie2) {&lt;br /&gt;
	instructiune 2;&lt;br /&gt;
}&lt;br /&gt;
else if (conditie 3) {&lt;br /&gt;
	instructiune3;&lt;br /&gt;
}&lt;br /&gt;
................................&lt;br /&gt;
else {&lt;br /&gt;
	instructiune;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asocierea ramurilor if-else===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; în cazul în care un if are mai multe ramuri, un else se asociază celui mai apropiat if.&amp;lt;/div&amp;gt; &lt;br /&gt;
Această observație ne conduce la următoarele două cazuri: &lt;br /&gt;
  &lt;br /&gt;
* 	 dacă nu există blocuri de instrucțiuni, un else este legat de if-ul imediat anterior; &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (a &amp;gt; 5) &lt;br /&gt;
    if (b &amp;gt; a) &lt;br /&gt;
	printf (&amp;quot;b este mai mare ca a&amp;quot;);&lt;br /&gt;
    else &lt;br /&gt;
	printf (&amp;quot;b este mai mic sau egal cu a&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*	dacă există blocuri de instrucțiuni, un else este legat de ultimul if fără pereche.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (a &amp;gt; 5) {&lt;br /&gt;
	if (b &amp;gt; a)&lt;br /&gt;
	      	printf (&amp;quot;b este mai mare ca a&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
else &lt;br /&gt;
    printf (&amp;quot;a nu este mai mare ca 5&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Ce va afișa acest program prost indentat? &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int number = 4; &lt;br /&gt;
double alpha = -1.0; &lt;br /&gt;
if (number &amp;gt; 0) &lt;br /&gt;
	if (alpha &amp;gt; 0)&lt;br /&gt;
		printf( &amp;quot;Here I am!\n&amp;quot;);&lt;br /&gt;
else &lt;br /&gt;
	printf( &amp;quot;No, I’m here!\n&amp;quot;); &lt;br /&gt;
printf(&amp;quot;No, actually, I’m here!\n&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Evaluarea expresiilor logice == &lt;br /&gt;
  &lt;br /&gt;
Am stabilit deja că o condiție logică, prin valoarea ei de adevăr, ramifică evoluția programului. &lt;br /&gt;
  &lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Adevărat în C înseamnă orice rezultat diferit de 0 (nul) al unei evaluări, în timp ce despre fals vorbim când o expresie este evaluată la 0 (nul). &lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
  &lt;br /&gt;
În C, condiția  poate avea mai multe reprezentări, după cum urmează &lt;br /&gt;
  &lt;br /&gt;
=== Operandul === &lt;br /&gt;
  &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu:&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
Verificați că un număr citit de la tastatură poate fi numitorul unei fracții.&lt;br /&gt;
&lt;br /&gt;
=== Operația cu operatori relaționali (==, !=, &amp;lt;=, &amp;lt;, &amp;gt;, &amp;gt;=) === &lt;br /&gt;
  &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu:&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
Asociați o valoare variabilei cost în funcție de valoarea variabilei distance după cum urmează: &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align: center;&amp;quot; |distance&lt;br /&gt;
! style=&amp;quot;text-align: center;&amp;quot; |cost&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | Intre 0 si 100&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 5.50&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | Peste 100, dar mai putin de 500&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 8.00&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | Peste 500, dar nu mai mult de 1000&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 10.50&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 1000 sau mai mult&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 13.00&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Operația cu operatori logici (&amp;amp;&amp;amp;, ||, !) === &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu:&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
Folosind operatori logici, aduceți următoarea structură decizională la forma cea mai simplă: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (doesSignificantWork) { &lt;br /&gt;
	if (makesBreakthrough) &lt;br /&gt;
		nobelPrizeCandidate = true; &lt;br /&gt;
	else&lt;br /&gt;
		 nobelPrizeCandidate = false; &lt;br /&gt;
} &lt;br /&gt;
else if (!doesSignificantWork) {&lt;br /&gt;
	nobelPrizeCandidate = false;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; Cuvântul cheie &amp;#039;&amp;#039;&amp;#039;bool&amp;#039;&amp;#039;&amp;#039;, ca și valorile &amp;#039;&amp;#039;&amp;#039;true&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;false&amp;#039;&amp;#039;&amp;#039;, au fost introduse în standardul C99, deci dacă doriți să-l folosiți codul trebuie compilat cu &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;--std=c99&amp;lt;/code&amp;gt; ca argument al compilatorului (gcc).&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a putea lucra cu operatorii logici, este necesar să ne reamintim modul în care aceștia operează. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; | Tabelul operatorilor logici&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | a&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | b&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | !a&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | a &amp;amp;&amp;amp; b&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | a ll b&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 1&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 1&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0 &lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 1 &lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; În tabel remarcăm că operatorul logic &amp;#039;&amp;#039;&amp;#039;SI ( &amp;amp;&amp;amp; )&amp;#039;&amp;#039;&amp;#039; întoarce 1 dacă și numai dacă ambele expresii, &amp;#039;&amp;#039;a&amp;#039;&amp;#039; și &amp;#039;&amp;#039;b&amp;#039;&amp;#039; în cazul nostru, întorc o valoare nenulă. în orice alt caz, operatorul &amp;#039;&amp;#039;&amp;#039;SI&amp;#039;&amp;#039;&amp;#039; întoarce 0. Așadar, pentru a optimiza timpul de execuție a programului, expresia a doua, &amp;#039;&amp;#039;b&amp;#039;&amp;#039; în cazul nostru, va fi evaluată dacă și numai dacă prima expresie, &amp;#039;&amp;#039;a&amp;#039;&amp;#039;, a întors o valoare nenulă. &lt;br /&gt;
În mod asemănător lucrează și operatorul &amp;#039;&amp;#039;&amp;#039;SAU ( || )&amp;#039;&amp;#039;&amp;#039;. &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;: Ce va afișa următorul program? &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
int main(){&lt;br /&gt;
    int a=5,b=10;&lt;br /&gt;
    if(++a||++b) {&lt;br /&gt;
         printf(&amp;quot;%d  %d&amp;quot;,a,b);&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
         printf(&amp;quot;Wayne Rooney&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Alternative la if-else ==&lt;br /&gt;
&lt;br /&gt;
=== Operatorul condițional (  ?  :  ) === &lt;br /&gt;
Singurul operator ternar din C, operatorul condițional funcționează asemenea unui if cu o singură ramură de tip else if. Sintaxa operatorului condițional este următoarea: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
(conditie) ? (expresie1) : (expresie2)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aşadar, blocul decizional&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (a&amp;gt;b)&lt;br /&gt;
	printf (&amp;quot;a este mai mare decat b&amp;quot;);&lt;br /&gt;
else&lt;br /&gt;
	printf (&amp;quot;a este mai mic sau egal cu b&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
poate fi înlocuit astfel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
printf(a &amp;gt; b ? &amp;quot;a este mai mare decat b&amp;quot; : &amp;quot;a este mai mic sau egal cu b&amp;quot;);&lt;br /&gt;
//sau&lt;br /&gt;
(a&amp;gt;b) ? ( printf (&amp;quot;a este mai mare decat b&amp;quot;)) : ( printf (&amp;quot;a este mai mic sau egal cu b&amp;quot;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; Deși prima variantă este cea recunoscută ca fiind corectă, remarcăm că și a două variantă se comportă la fel ca prima. Asta se datorează modului în care funcționează operatorul condițional: el cere ca ambele expresii, &amp;#039;&amp;#039;expresie1&amp;#039;&amp;#039; și &amp;#039;&amp;#039;expresie2&amp;#039;&amp;#039;, să întoarcă &amp;quot;valori&amp;quot;. A doua variantă funcționează deoarece funcția &amp;#039;&amp;#039;printf()&amp;#039;&amp;#039; întoarce întotdeauna o [http://www.tutorialspoint.com/c_standard_library/c_function_printf.htm valoare].&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Structura decizională switch-case === &lt;br /&gt;
Această instrucțiune de decizie este similară unui if cu mai multe ramuri de tip else-if. Sintaxa este următoarea: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
switch (variabilaTestata)	{&lt;br /&gt;
	case valoare1:	 instructiune1;&lt;br /&gt;
				 [break;]&lt;br /&gt;
				&lt;br /&gt;
	case valoare2:	 instructiune2;&lt;br /&gt;
				 [break;]&lt;br /&gt;
				&lt;br /&gt;
	case valoare3:	 instructiune3;&lt;br /&gt;
				 [break;]&lt;br /&gt;
				&lt;br /&gt;
.........................................................................&lt;br /&gt;
	default:		instructiune;&lt;br /&gt;
				&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Valorile &amp;#039;&amp;#039;valoare1&amp;#039;&amp;#039;, &amp;#039;&amp;#039;valoare2&amp;#039;&amp;#039; etc. sunt proprii tipului de dată întreg, la fel ca &amp;#039;&amp;#039;variabilaTestata&amp;#039;&amp;#039;. Ne reamintim însă că întreg nu înseamnă doar variabile de tip &amp;#039;&amp;#039;&amp;#039;int&amp;#039;&amp;#039;&amp;#039;, astfel că &amp;#039;&amp;#039;variabilaTestata&amp;#039;&amp;#039; poate fi de tip &amp;#039;&amp;#039;&amp;#039;char&amp;#039;&amp;#039;&amp;#039;. &lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; instrucțiunea &amp;#039;&amp;#039;break&amp;#039;&amp;#039; este opțională. Modul  care  switch-case funcționează este următorul: &lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;se compară valoarea variabilei &amp;#039;&amp;#039;variabilaTestata&amp;#039;&amp;#039; cu &amp;#039;&amp;#039;valoarea1&amp;#039;&amp;#039;;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;dacă cele două sunt egale, se execută &amp;#039;&amp;#039;instructiune1&amp;#039;&amp;#039;. Apoi există două cazuri:&lt;br /&gt;
&amp;lt;ol type=&amp;quot;i&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;dacă există &amp;#039;&amp;#039;break;&amp;#039;&amp;#039; structura switch-case se încheie și se sare pe linia urmatoare întregului bloc decizional;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;dacă nu există &amp;#039;&amp;#039;break;&amp;#039;&amp;#039; execuția se continuă până se întalnește un &amp;#039;&amp;#039;break;&amp;#039;&amp;#039; sau până când se încheie structura switch-case. Până la acel moment se vor executa toate instrucțiunile întâlnite pe parcurs (&amp;#039;&amp;#039;instructiune2, instructiune3&amp;#039;&amp;#039; etc.);&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;dacă valoarea variabilei &amp;#039;&amp;#039;variabilaTestata&amp;#039;&amp;#039; nu este egală cu niciuna dintre valorile &amp;#039;&amp;#039;valoare1, valoare2&amp;#039;&amp;#039; etc atunci se execută &amp;#039;&amp;#039;instructiune&amp;#039;&amp;#039;, asociată etichetei default.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a verifica echivalența dintre if-else și switch-case, rezolvați folosind ambele structuri decizionale următoarea problemă:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu:&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
Un microbist vrea să afle situația Grupei F de calificare la EURO2016. Astfel, el va introduce o cifră pentru a vedea ce &amp;quot;națională&amp;quot; ocupă acel loc. Folosind următoarea listă, informați-l corect pe suporter.  &lt;br /&gt;
&lt;br /&gt;
1.	Irlanda de Nord&lt;br /&gt;
2.	România&lt;br /&gt;
3.	Ungaria&lt;br /&gt;
4.	Finlanda&lt;br /&gt;
5.	Insulele Feroe&lt;br /&gt;
6.	Grecia&lt;br /&gt;
&lt;br /&gt;
== Exerciții ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ce va afișa următorul program? &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void main(){&lt;br /&gt;
    int a=100;&lt;br /&gt;
    if(a&amp;gt;10) {&lt;br /&gt;
         printf(&amp;quot;Tiberiu Soare &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else if(a&amp;gt;20) {&lt;br /&gt;
         printf(&amp;quot;Horia Andreescu &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else if(a&amp;gt;30) {&lt;br /&gt;
           printf(&amp;quot;Iosif Ion Prunner &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Ştiind că un student primește 350 lei/lună dacă are media cel puțin 8.50, 450 lei/lună pentru o medie mai mare sau egală cu 9.50 și 600 lei/lună dacă are media cel puțin 9.70, scrieți un program prin care studentul să afle ce bursă urmează să primească (media va fi citită de la tastatură). &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Ce va afișa următorul program? &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
void main(){&lt;br /&gt;
    int m=5,n=10,q=20;&lt;br /&gt;
    if(q/n*m)&lt;br /&gt;
         printf(&amp;quot;Bill Gates &amp;quot;);&lt;br /&gt;
    else&lt;br /&gt;
         printf(&amp;quot;Amancio Ortega &amp;quot;);&lt;br /&gt;
         printf(&amp;quot;Carlos Slim Helu &amp;quot;);&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți un program care citește de la tastatură notele unui elev la limba română, matematică și informatică și afișează dacă elevul a promovat sau nu bacalaureatul. &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Fie a și b două numere întregi citite de la tastatură. Scrieți un algoritm care să verifice dacă a si b sunt numere consecutive.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Se citesc de la tastatură 3 numere reprezentând lungimea cele 3 laturi ale unui triunghi. Să se afișeze dacă triunghiul este dreptunghic.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Se citește de la tastatură un număr întreg fără semn de 8 biți. Să se afișeze dacă numărul este sau nu un palindrom (dacă are aceeași valoare citit și de la stânga la dreapta si de la dreapta la stanga; de exemplu 101, sau 242).&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_5&amp;diff=3677</id>
		<title>PC Laborator 5</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_5&amp;diff=3677"/>
		<updated>2015-11-05T17:09:56Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: /* Operația cu operatori logici (&amp;amp;&amp;amp;, ||, !, ^) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Obiective == &lt;br /&gt;
  &lt;br /&gt;
în urma acestui laborator, studentul va fi capabil să: &lt;br /&gt;
* 	 înțeleagă cum funcționează o structură decizională; &lt;br /&gt;
* 	 scrie programe în C folosind construcții decizionale. &lt;br /&gt;
  &lt;br /&gt;
== Structura decizională == &lt;br /&gt;
  &lt;br /&gt;
Se întâmplă adesea ca evoluția unui program să depindă de o anumită condiție. Ea poate lua însă diverse forme, rolul programatorului fiind să conducă execuția programului pe calea corectă, ținând cont de acea condiție logică. Apare astfel structura decizionala if, care ramifică evoluția programului în funcție de valoarea de adevăr  a condiției testate.  &lt;br /&gt;
  &lt;br /&gt;
=== 	 Schema logică === &lt;br /&gt;
Prima etapă din parcurgerea unei structuri decizionale de tipul if-else o reprezintă testarea condiției logice. în cazul în care aceasta este evaluată ca adevărată se execută instructiunea1, cea asociată ramurii if. în cazul în care condiția logică este evaluată ca falsă se execută instructiunea2, cea asociată ramurii else. După executarea instrucțiunii asociate, structura if-else se încheie și programul se continuă cu linia următoare blocului decizional.&lt;br /&gt;
 &lt;br /&gt;
[[Fișier:structura_decizionala.png]]&lt;br /&gt;
&lt;br /&gt;
=== Sintaxă generală ===&lt;br /&gt;
a)	&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (conditie) instructiune;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (conditie) {&lt;br /&gt;
	 instructiune1;&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
	 instructiune2;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
c)	&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (conditie1) {&lt;br /&gt;
	instructiune 1;&lt;br /&gt;
}&lt;br /&gt;
else if (conditie2) {&lt;br /&gt;
	instructiune 2;&lt;br /&gt;
}&lt;br /&gt;
else if (conditie 3) {&lt;br /&gt;
	instructiune3;&lt;br /&gt;
}&lt;br /&gt;
................................&lt;br /&gt;
else {&lt;br /&gt;
	instructiune;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asocierea ramurilor if-else===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; în cazul în care un if are mai multe ramuri, un else se asociază celui mai apropiat if.&amp;lt;/div&amp;gt; &lt;br /&gt;
Această observație ne conduce la următoarele două cazuri: &lt;br /&gt;
  &lt;br /&gt;
* 	 dacă nu există blocuri de instrucțiuni, un else este legat de if-ul imediat anterior; &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (a &amp;gt; 5) &lt;br /&gt;
    if (b &amp;gt; a) &lt;br /&gt;
	printf (&amp;quot;b este mai mare ca a&amp;quot;);&lt;br /&gt;
    else &lt;br /&gt;
	printf (&amp;quot;b este mai mic sau egal cu a&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*	dacă există blocuri de instrucțiuni, un else este legat de ultimul if fără pereche.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (a &amp;gt; 5) {&lt;br /&gt;
	if (b &amp;gt; a)&lt;br /&gt;
	      	printf (&amp;quot;b este mai mare ca a&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
else &lt;br /&gt;
    printf (&amp;quot;a nu este mai mare ca 5&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Ce va afișa acest program prost indentat? &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int number = 4; &lt;br /&gt;
double alpha = -1.0; &lt;br /&gt;
if (number &amp;gt; 0) &lt;br /&gt;
	if (alpha &amp;gt; 0)&lt;br /&gt;
		printf( &amp;quot;Here I am!\n&amp;quot;);&lt;br /&gt;
else &lt;br /&gt;
	printf( &amp;quot;No, I’m here!\n&amp;quot;); &lt;br /&gt;
printf(&amp;quot;No, actually, I’m here!\n&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Evaluarea expresiilor logice == &lt;br /&gt;
  &lt;br /&gt;
Am stabilit deja că o condiție logică, prin valoarea ei de adevăr, ramifică evoluția programului. &lt;br /&gt;
  &lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Adevărat în C înseamnă orice rezultat diferit de 0 (nul) al unei evaluări, în timp ce despre fals vorbim când o expresie este evaluată la 0 (nul). &lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
  &lt;br /&gt;
În C, condiția  poate avea mai multe reprezentări, după cum urmează &lt;br /&gt;
  &lt;br /&gt;
=== Operandul === &lt;br /&gt;
  &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu:&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
Verificați că un număr citit de la tastatură poate fi numitorul unei fracții.&lt;br /&gt;
&lt;br /&gt;
=== Operația cu operatori relaționali (==, !=, &amp;lt;=, &amp;lt;, &amp;gt;, &amp;gt;=) === &lt;br /&gt;
  &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu:&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
Asociați o valoare variabilei cost în funcție de valoarea variabilei distance după cum urmează: &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align: center;&amp;quot; |distance&lt;br /&gt;
! style=&amp;quot;text-align: center;&amp;quot; |cost&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | Intre 0 si 100&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 5.50&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | Peste 100, dar mai putin de 500&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 8.00&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | Peste 500, dar nu mai mult de 1000&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 10.50&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 1000 sau mai mult&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 13.00&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Operația cu operatori logici (&amp;amp;&amp;amp;, ||, !) === &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu:&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
Folosind operatori logici, aduceți următoarea structură decizională la forma cea mai simplă: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (doesSignificantWork) { &lt;br /&gt;
	if (makesBreakthrough) &lt;br /&gt;
		nobelPrizeCandidate = true; &lt;br /&gt;
	else&lt;br /&gt;
		 nobelPrizeCandidate = false; &lt;br /&gt;
} &lt;br /&gt;
else if (!doesSignificantWork) {&lt;br /&gt;
	nobelPrizeCandidate = false;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; Cuvântul cheie &amp;#039;&amp;#039;&amp;#039;bool&amp;#039;&amp;#039;&amp;#039;, ca și valorile &amp;#039;&amp;#039;&amp;#039;true&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;false&amp;#039;&amp;#039;&amp;#039;, au fost introduse în standardul C99, deci dacă doriți să-l folosiți codul trebuie compilat cu &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;--std=c99&amp;lt;/code&amp;gt; ca argument al compilatorului (gcc).&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a putea lucra cu operatorii logici, este necesar să ne reamintim modul în care aceștia operează. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; | Tabelul operatorilor logici&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | a&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | b&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | !a&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | a &amp;amp;&amp;amp; b&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | a ll b&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 1&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 1&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0 &lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 1 &lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; În tabel remarcăm că operatorul logic &amp;#039;&amp;#039;&amp;#039;SI ( &amp;amp;&amp;amp; )&amp;#039;&amp;#039;&amp;#039; întoarce 1 dacă și numai dacă ambele expresii, &amp;#039;&amp;#039;a&amp;#039;&amp;#039; și &amp;#039;&amp;#039;b&amp;#039;&amp;#039; în cazul nostru, întorc o valoare nenulă. în orice alt caz, operatorul &amp;#039;&amp;#039;&amp;#039;SI&amp;#039;&amp;#039;&amp;#039; întoarce 0. Așadar, pentru a optimiza timpul de execuție a programului, expresia a doua, &amp;#039;&amp;#039;b&amp;#039;&amp;#039; în cazul nostru, va fi evaluată dacă și numai dacă prima expresie, &amp;#039;&amp;#039;a&amp;#039;&amp;#039;, a întors o valoare nenulă. &lt;br /&gt;
În mod asemănător lucrează și operatorul &amp;#039;&amp;#039;&amp;#039;SAU ( || )&amp;#039;&amp;#039;&amp;#039;. &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;: Ce va afișa următorul program? &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
void main(){&lt;br /&gt;
    int a=5,b=10;&lt;br /&gt;
    if(++a||++b) {&lt;br /&gt;
         printf(&amp;quot;%d  %d&amp;quot;,a,b);&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
         printf(&amp;quot;Wayne Rooney&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Alternative la if-else ==&lt;br /&gt;
&lt;br /&gt;
=== Operatorul condițional (  ?  :  ) === &lt;br /&gt;
Singurul operator ternar din C, operatorul condițional funcționează asemenea unui if cu o singură ramură de tip else if. Sintaxa operatorului condițional este următoarea: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
(conditie) ? (expresie1) : (expresie2)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aşadar, blocul decizional&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (a&amp;gt;b)&lt;br /&gt;
	printf (&amp;quot;a este mai mare decat b&amp;quot;);&lt;br /&gt;
else&lt;br /&gt;
	printf (&amp;quot;a este mai mic sau egal cu b&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
poate fi înlocuit astfel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
printf(a &amp;gt; b ? &amp;quot;a este mai mare decat b&amp;quot; : &amp;quot;a este mai mic sau egal cu b&amp;quot;);&lt;br /&gt;
//sau&lt;br /&gt;
(a&amp;gt;b) ? ( printf (&amp;quot;a este mai mare decat b&amp;quot;)) : ( printf (&amp;quot;a este mai mic sau egal cu b&amp;quot;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; Deși prima variantă este cea recunoscută ca fiind corectă, remarcăm că și a două variantă se comportă la fel ca prima. Asta se datorează modului în care funcționează operatorul condițional: el cere ca ambele expresii, &amp;#039;&amp;#039;expresie1&amp;#039;&amp;#039; și &amp;#039;&amp;#039;expresie2&amp;#039;&amp;#039;, să întoarcă &amp;quot;valori&amp;quot;. A doua variantă funcționează deoarece funcția &amp;#039;&amp;#039;printf()&amp;#039;&amp;#039; întoarce întotdeauna o [http://www.tutorialspoint.com/c_standard_library/c_function_printf.htm valoare].&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Structura decizională switch-case === &lt;br /&gt;
Această instrucțiune de decizie este similară unui if cu mai multe ramuri de tip else-if. Sintaxa este următoarea: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
switch (variabilaTestata)	{&lt;br /&gt;
	case valoare1:	 instructiune1;&lt;br /&gt;
				 [break;]&lt;br /&gt;
				&lt;br /&gt;
	case valoare2:	 instructiune2;&lt;br /&gt;
				 [break;]&lt;br /&gt;
				&lt;br /&gt;
	case valoare3:	 instructiune3;&lt;br /&gt;
				 [break;]&lt;br /&gt;
				&lt;br /&gt;
.........................................................................&lt;br /&gt;
	default:		instructiune;&lt;br /&gt;
				&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Valorile &amp;#039;&amp;#039;valoare1&amp;#039;&amp;#039;, &amp;#039;&amp;#039;valoare2&amp;#039;&amp;#039; etc. sunt proprii tipului de dată întreg, la fel ca &amp;#039;&amp;#039;variabilaTestata&amp;#039;&amp;#039;. Ne reamintim însă că întreg nu înseamnă doar variabile de tip &amp;#039;&amp;#039;&amp;#039;int&amp;#039;&amp;#039;&amp;#039;, astfel că &amp;#039;&amp;#039;variabilaTestata&amp;#039;&amp;#039; poate fi de tip &amp;#039;&amp;#039;&amp;#039;char&amp;#039;&amp;#039;&amp;#039;. &lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; instrucțiunea &amp;#039;&amp;#039;break&amp;#039;&amp;#039; este opțională. Modul  care  switch-case funcționează este următorul: &lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;se compară valoarea variabilei &amp;#039;&amp;#039;variabilaTestata&amp;#039;&amp;#039; cu &amp;#039;&amp;#039;valoarea1&amp;#039;&amp;#039;;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;dacă cele două sunt egale, se execută &amp;#039;&amp;#039;instructiune1&amp;#039;&amp;#039;. Apoi există două cazuri:&lt;br /&gt;
&amp;lt;ol type=&amp;quot;i&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;dacă există &amp;#039;&amp;#039;break;&amp;#039;&amp;#039; structura switch-case se încheie și se sare pe linia urmatoare întregului bloc decizional;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;dacă nu există &amp;#039;&amp;#039;break;&amp;#039;&amp;#039; execuția se continuă până se întalnește un &amp;#039;&amp;#039;break;&amp;#039;&amp;#039; sau până când se încheie structura switch-case. Până la acel moment se vor executa toate instrucțiunile întâlnite pe parcurs (&amp;#039;&amp;#039;instructiune2, instructiune3&amp;#039;&amp;#039; etc.);&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;dacă valoarea variabilei &amp;#039;&amp;#039;variabilaTestata&amp;#039;&amp;#039; nu este egală cu niciuna dintre valorile &amp;#039;&amp;#039;valoare1, valoare2&amp;#039;&amp;#039; etc atunci se execută &amp;#039;&amp;#039;instructiune&amp;#039;&amp;#039;, asociată etichetei default.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a verifica echivalența dintre if-else și switch-case, rezolvați folosind ambele structuri decizionale următoarea problemă:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu:&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
Un microbist vrea să afle situația Grupei F de calificare la EURO2016. Astfel, el va introduce o cifră pentru a vedea ce &amp;quot;națională&amp;quot; ocupă acel loc. Folosind următoarea listă, informați-l corect pe suporter.  &lt;br /&gt;
&lt;br /&gt;
1.	Irlanda de Nord&lt;br /&gt;
2.	România&lt;br /&gt;
3.	Ungaria&lt;br /&gt;
4.	Finlanda&lt;br /&gt;
5.	Insulele Feroe&lt;br /&gt;
6.	Grecia&lt;br /&gt;
&lt;br /&gt;
== Exerciții ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ce va afișa următorul program? &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void main(){&lt;br /&gt;
    int a=100;&lt;br /&gt;
    if(a&amp;gt;10) {&lt;br /&gt;
         printf(&amp;quot;Tiberiu Soare &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else if(a&amp;gt;20) {&lt;br /&gt;
         printf(&amp;quot;Horia Andreescu &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else if(a&amp;gt;30) {&lt;br /&gt;
           printf(&amp;quot;Iosif Ion Prunner &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Ştiind că un student primește 350 lei/lună dacă are media cel puțin 8.50, 450 lei/lună pentru o medie mai mare sau egală cu 9.50 și 600 lei/lună dacă are media cel puțin 9.70, scrieți un program prin care studentul să afle ce bursă urmează să primească (media va fi citită de la tastatură). &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Ce va afișa următorul program? &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
void main(){&lt;br /&gt;
    int m=5,n=10,q=20;&lt;br /&gt;
    if(q/n*m)&lt;br /&gt;
         printf(&amp;quot;Bill Gates &amp;quot;);&lt;br /&gt;
    else&lt;br /&gt;
         printf(&amp;quot;Amancio Ortega &amp;quot;);&lt;br /&gt;
         printf(&amp;quot;Carlos Slim Helu &amp;quot;);&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți un program care citește de la tastatură notele unui elev la limba română, matematică și informatică și afișează dacă elevul a promovat sau nu bacalaureatul. &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Fie a și b două numere întregi citite de la tastatură. Scrieți un algoritm care să verifice dacă a si b sunt numere consecutive.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Se citesc de la tastatură 3 numere reprezentând lungimea cele 3 laturi ale unui triunghi. Să se afișeze dacă triunghiul este dreptunghic.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Se citește de la tastatură un număr întreg fără semn de 8 biți. Să se afișeze dacă numărul este sau nu un palindrom (dacă are aceeași valoare citit și de la stânga la dreapta si de la dreapta la stanga; de exemplu 101, sau 242).&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_5&amp;diff=3676</id>
		<title>PC Laborator 5</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_5&amp;diff=3676"/>
		<updated>2015-11-05T17:08:53Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: /* Operația cu operatori logici (&amp;amp;&amp;amp;, ||, !, ^) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Obiective == &lt;br /&gt;
  &lt;br /&gt;
în urma acestui laborator, studentul va fi capabil să: &lt;br /&gt;
* 	 înțeleagă cum funcționează o structură decizională; &lt;br /&gt;
* 	 scrie programe în C folosind construcții decizionale. &lt;br /&gt;
  &lt;br /&gt;
== Structura decizională == &lt;br /&gt;
  &lt;br /&gt;
Se întâmplă adesea ca evoluția unui program să depindă de o anumită condiție. Ea poate lua însă diverse forme, rolul programatorului fiind să conducă execuția programului pe calea corectă, ținând cont de acea condiție logică. Apare astfel structura decizionala if, care ramifică evoluția programului în funcție de valoarea de adevăr  a condiției testate.  &lt;br /&gt;
  &lt;br /&gt;
=== 	 Schema logică === &lt;br /&gt;
Prima etapă din parcurgerea unei structuri decizionale de tipul if-else o reprezintă testarea condiției logice. în cazul în care aceasta este evaluată ca adevărată se execută instructiunea1, cea asociată ramurii if. în cazul în care condiția logică este evaluată ca falsă se execută instructiunea2, cea asociată ramurii else. După executarea instrucțiunii asociate, structura if-else se încheie și programul se continuă cu linia următoare blocului decizional.&lt;br /&gt;
 &lt;br /&gt;
[[Fișier:structura_decizionala.png]]&lt;br /&gt;
&lt;br /&gt;
=== Sintaxă generală ===&lt;br /&gt;
a)	&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (conditie) instructiune;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (conditie) {&lt;br /&gt;
	 instructiune1;&lt;br /&gt;
}&lt;br /&gt;
else {&lt;br /&gt;
	 instructiune2;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
c)	&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (conditie1) {&lt;br /&gt;
	instructiune 1;&lt;br /&gt;
}&lt;br /&gt;
else if (conditie2) {&lt;br /&gt;
	instructiune 2;&lt;br /&gt;
}&lt;br /&gt;
else if (conditie 3) {&lt;br /&gt;
	instructiune3;&lt;br /&gt;
}&lt;br /&gt;
................................&lt;br /&gt;
else {&lt;br /&gt;
	instructiune;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Asocierea ramurilor if-else===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039; Observație: &amp;#039;&amp;#039;&amp;#039; în cazul în care un if are mai multe ramuri, un else se asociază celui mai apropiat if.&amp;lt;/div&amp;gt; &lt;br /&gt;
Această observație ne conduce la următoarele două cazuri: &lt;br /&gt;
  &lt;br /&gt;
* 	 dacă nu există blocuri de instrucțiuni, un else este legat de if-ul imediat anterior; &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (a &amp;gt; 5) &lt;br /&gt;
    if (b &amp;gt; a) &lt;br /&gt;
	printf (&amp;quot;b este mai mare ca a&amp;quot;);&lt;br /&gt;
    else &lt;br /&gt;
	printf (&amp;quot;b este mai mic sau egal cu a&amp;quot;);&lt;br /&gt;
    &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*	dacă există blocuri de instrucțiuni, un else este legat de ultimul if fără pereche.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (a &amp;gt; 5) {&lt;br /&gt;
	if (b &amp;gt; a)&lt;br /&gt;
	      	printf (&amp;quot;b este mai mare ca a&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
else &lt;br /&gt;
    printf (&amp;quot;a nu este mai mare ca 5&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Ce va afișa acest program prost indentat? &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int number = 4; &lt;br /&gt;
double alpha = -1.0; &lt;br /&gt;
if (number &amp;gt; 0) &lt;br /&gt;
	if (alpha &amp;gt; 0)&lt;br /&gt;
		printf( &amp;quot;Here I am!\n&amp;quot;);&lt;br /&gt;
else &lt;br /&gt;
	printf( &amp;quot;No, I’m here!\n&amp;quot;); &lt;br /&gt;
printf(&amp;quot;No, actually, I’m here!\n&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Evaluarea expresiilor logice == &lt;br /&gt;
  &lt;br /&gt;
Am stabilit deja că o condiție logică, prin valoarea ei de adevăr, ramifică evoluția programului. &lt;br /&gt;
  &lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Adevărat în C înseamnă orice rezultat diferit de 0 (nul) al unei evaluări, în timp ce despre fals vorbim când o expresie este evaluată la 0 (nul). &lt;br /&gt;
&amp;lt;/div&amp;gt; &lt;br /&gt;
  &lt;br /&gt;
În C, condiția  poate avea mai multe reprezentări, după cum urmează &lt;br /&gt;
  &lt;br /&gt;
=== Operandul === &lt;br /&gt;
  &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu:&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
Verificați că un număr citit de la tastatură poate fi numitorul unei fracții.&lt;br /&gt;
&lt;br /&gt;
=== Operația cu operatori relaționali (==, !=, &amp;lt;=, &amp;lt;, &amp;gt;, &amp;gt;=) === &lt;br /&gt;
  &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu:&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
Asociați o valoare variabilei cost în funcție de valoarea variabilei distance după cum urmează: &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;text-align: center;&amp;quot; |distance&lt;br /&gt;
! style=&amp;quot;text-align: center;&amp;quot; |cost&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | Intre 0 si 100&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 5.50&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | Peste 100, dar mai putin de 500&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 8.00&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | Peste 500, dar nu mai mult de 1000&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 10.50&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 1000 sau mai mult&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 13.00&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Operația cu operatori logici (&amp;amp;&amp;amp;, ||, !, ^) === &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu:&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
Folosind operatori logici, aduceți următoarea structură decizională la forma cea mai simplă: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (doesSignificantWork) { &lt;br /&gt;
	if (makesBreakthrough) &lt;br /&gt;
		nobelPrizeCandidate = true; &lt;br /&gt;
	else&lt;br /&gt;
		 nobelPrizeCandidate = false; &lt;br /&gt;
} &lt;br /&gt;
else if (!doesSignificantWork) {&lt;br /&gt;
	nobelPrizeCandidate = false;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; Cuvântul cheie &amp;#039;&amp;#039;&amp;#039;bool&amp;#039;&amp;#039;&amp;#039;, ca și valorile &amp;#039;&amp;#039;&amp;#039;true&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;false&amp;#039;&amp;#039;&amp;#039;, au fost introduse în standardul C99, deci dacă doriți să-l folosiți codul trebuie compilat cu &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;--std=c99&amp;lt;/code&amp;gt; ca argument al compilatorului (gcc).&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a putea lucra cu operatorii logici, este necesar să ne reamintim modul în care aceștia operează. &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;5&amp;quot; | Tabelul operatorilor logici&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | a&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | b&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | !a&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | a &amp;amp;&amp;amp; b&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | a ll b&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 1&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 1&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0 &lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 1 &lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
| style=&amp;quot;text-align: center&amp;quot;  | 1&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; În tabel remarcăm că operatorul logic &amp;#039;&amp;#039;&amp;#039;SI ( &amp;amp;&amp;amp; )&amp;#039;&amp;#039;&amp;#039; întoarce 1 dacă și numai dacă ambele expresii, &amp;#039;&amp;#039;a&amp;#039;&amp;#039; și &amp;#039;&amp;#039;b&amp;#039;&amp;#039; în cazul nostru, întorc o valoare nenulă. în orice alt caz, operatorul &amp;#039;&amp;#039;&amp;#039;SI&amp;#039;&amp;#039;&amp;#039; întoarce 0. Așadar, pentru a optimiza timpul de execuție a programului, expresia a doua, &amp;#039;&amp;#039;b&amp;#039;&amp;#039; în cazul nostru, va fi evaluată dacă și numai dacă prima expresie, &amp;#039;&amp;#039;a&amp;#039;&amp;#039;, a întors o valoare nenulă. &lt;br /&gt;
În mod asemănător lucrează și operatorul &amp;#039;&amp;#039;&amp;#039;SAU ( || )&amp;#039;&amp;#039;&amp;#039;. &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;: Ce va afișa următorul program? &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
void main(){&lt;br /&gt;
    int a=5,b=10;&lt;br /&gt;
    if(++a||++b) {&lt;br /&gt;
         printf(&amp;quot;%d  %d&amp;quot;,a,b);&lt;br /&gt;
    }&lt;br /&gt;
    else {&lt;br /&gt;
         printf(&amp;quot;Wayne Rooney&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Alternative la if-else ==&lt;br /&gt;
&lt;br /&gt;
=== Operatorul condițional (  ?  :  ) === &lt;br /&gt;
Singurul operator ternar din C, operatorul condițional funcționează asemenea unui if cu o singură ramură de tip else if. Sintaxa operatorului condițional este următoarea: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
(conditie) ? (expresie1) : (expresie2)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aşadar, blocul decizional&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
if (a&amp;gt;b)&lt;br /&gt;
	printf (&amp;quot;a este mai mare decat b&amp;quot;);&lt;br /&gt;
else&lt;br /&gt;
	printf (&amp;quot;a este mai mic sau egal cu b&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
poate fi înlocuit astfel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
printf(a &amp;gt; b ? &amp;quot;a este mai mare decat b&amp;quot; : &amp;quot;a este mai mic sau egal cu b&amp;quot;);&lt;br /&gt;
//sau&lt;br /&gt;
(a&amp;gt;b) ? ( printf (&amp;quot;a este mai mare decat b&amp;quot;)) : ( printf (&amp;quot;a este mai mic sau egal cu b&amp;quot;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; Deși prima variantă este cea recunoscută ca fiind corectă, remarcăm că și a două variantă se comportă la fel ca prima. Asta se datorează modului în care funcționează operatorul condițional: el cere ca ambele expresii, &amp;#039;&amp;#039;expresie1&amp;#039;&amp;#039; și &amp;#039;&amp;#039;expresie2&amp;#039;&amp;#039;, să întoarcă &amp;quot;valori&amp;quot;. A doua variantă funcționează deoarece funcția &amp;#039;&amp;#039;printf()&amp;#039;&amp;#039; întoarce întotdeauna o [http://www.tutorialspoint.com/c_standard_library/c_function_printf.htm valoare].&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Structura decizională switch-case === &lt;br /&gt;
Această instrucțiune de decizie este similară unui if cu mai multe ramuri de tip else-if. Sintaxa este următoarea: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
switch (variabilaTestata)	{&lt;br /&gt;
	case valoare1:	 instructiune1;&lt;br /&gt;
				 [break;]&lt;br /&gt;
				&lt;br /&gt;
	case valoare2:	 instructiune2;&lt;br /&gt;
				 [break;]&lt;br /&gt;
				&lt;br /&gt;
	case valoare3:	 instructiune3;&lt;br /&gt;
				 [break;]&lt;br /&gt;
				&lt;br /&gt;
.........................................................................&lt;br /&gt;
	default:		instructiune;&lt;br /&gt;
				&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Valorile &amp;#039;&amp;#039;valoare1&amp;#039;&amp;#039;, &amp;#039;&amp;#039;valoare2&amp;#039;&amp;#039; etc. sunt proprii tipului de dată întreg, la fel ca &amp;#039;&amp;#039;variabilaTestata&amp;#039;&amp;#039;. Ne reamintim însă că întreg nu înseamnă doar variabile de tip &amp;#039;&amp;#039;&amp;#039;int&amp;#039;&amp;#039;&amp;#039;, astfel că &amp;#039;&amp;#039;variabilaTestata&amp;#039;&amp;#039; poate fi de tip &amp;#039;&amp;#039;&amp;#039;char&amp;#039;&amp;#039;&amp;#039;. &lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; instrucțiunea &amp;#039;&amp;#039;break&amp;#039;&amp;#039; este opțională. Modul  care  switch-case funcționează este următorul: &lt;br /&gt;
&amp;lt;ol type=&amp;quot;a&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;se compară valoarea variabilei &amp;#039;&amp;#039;variabilaTestata&amp;#039;&amp;#039; cu &amp;#039;&amp;#039;valoarea1&amp;#039;&amp;#039;;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;dacă cele două sunt egale, se execută &amp;#039;&amp;#039;instructiune1&amp;#039;&amp;#039;. Apoi există două cazuri:&lt;br /&gt;
&amp;lt;ol type=&amp;quot;i&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;dacă există &amp;#039;&amp;#039;break;&amp;#039;&amp;#039; structura switch-case se încheie și se sare pe linia urmatoare întregului bloc decizional;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;dacă nu există &amp;#039;&amp;#039;break;&amp;#039;&amp;#039; execuția se continuă până se întalnește un &amp;#039;&amp;#039;break;&amp;#039;&amp;#039; sau până când se încheie structura switch-case. Până la acel moment se vor executa toate instrucțiunile întâlnite pe parcurs (&amp;#039;&amp;#039;instructiune2, instructiune3&amp;#039;&amp;#039; etc.);&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;dacă valoarea variabilei &amp;#039;&amp;#039;variabilaTestata&amp;#039;&amp;#039; nu este egală cu niciuna dintre valorile &amp;#039;&amp;#039;valoare1, valoare2&amp;#039;&amp;#039; etc atunci se execută &amp;#039;&amp;#039;instructiune&amp;#039;&amp;#039;, asociată etichetei default.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a verifica echivalența dintre if-else și switch-case, rezolvați folosind ambele structuri decizionale următoarea problemă:&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu:&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
Un microbist vrea să afle situația Grupei F de calificare la EURO2016. Astfel, el va introduce o cifră pentru a vedea ce &amp;quot;națională&amp;quot; ocupă acel loc. Folosind următoarea listă, informați-l corect pe suporter.  &lt;br /&gt;
&lt;br /&gt;
1.	Irlanda de Nord&lt;br /&gt;
2.	România&lt;br /&gt;
3.	Ungaria&lt;br /&gt;
4.	Finlanda&lt;br /&gt;
5.	Insulele Feroe&lt;br /&gt;
6.	Grecia&lt;br /&gt;
&lt;br /&gt;
== Exerciții ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ce va afișa următorul program? &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void main(){&lt;br /&gt;
    int a=100;&lt;br /&gt;
    if(a&amp;gt;10) {&lt;br /&gt;
         printf(&amp;quot;Tiberiu Soare &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else if(a&amp;gt;20) {&lt;br /&gt;
         printf(&amp;quot;Horia Andreescu &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else if(a&amp;gt;30) {&lt;br /&gt;
           printf(&amp;quot;Iosif Ion Prunner &amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Ştiind că un student primește 350 lei/lună dacă are media cel puțin 8.50, 450 lei/lună pentru o medie mai mare sau egală cu 9.50 și 600 lei/lună dacă are media cel puțin 9.70, scrieți un program prin care studentul să afle ce bursă urmează să primească (media va fi citită de la tastatură). &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Ce va afișa următorul program? &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include&amp;lt;stdio.h&amp;gt;&lt;br /&gt;
void main(){&lt;br /&gt;
    int m=5,n=10,q=20;&lt;br /&gt;
    if(q/n*m)&lt;br /&gt;
         printf(&amp;quot;Bill Gates &amp;quot;);&lt;br /&gt;
    else&lt;br /&gt;
         printf(&amp;quot;Amancio Ortega &amp;quot;);&lt;br /&gt;
         printf(&amp;quot;Carlos Slim Helu &amp;quot;);&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Scrieți un program care citește de la tastatură notele unui elev la limba română, matematică și informatică și afișează dacă elevul a promovat sau nu bacalaureatul. &amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Fie a și b două numere întregi citite de la tastatură. Scrieți un algoritm care să verifice dacă a si b sunt numere consecutive.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Se citesc de la tastatură 3 numere reprezentând lungimea cele 3 laturi ale unui triunghi. Să se afișeze dacă triunghiul este dreptunghic.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Se citește de la tastatură un număr întreg fără semn de 8 biți. Să se afișeze dacă numărul este sau nu un palindrom (dacă are aceeași valoare citit și de la stânga la dreapta si de la dreapta la stanga; de exemplu 101, sau 242).&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_1&amp;diff=3522</id>
		<title>PC Laborator 1</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_1&amp;diff=3522"/>
		<updated>2015-09-30T20:12:32Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: /* Structura de directoare in Linux */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Obiective =&lt;br /&gt;
&lt;br /&gt;
În urma parcurgerii acestui laborator veți fi capabili:&lt;br /&gt;
&lt;br /&gt;
* să folosiți comenzi de bază în sistemul de operare Linux;&lt;br /&gt;
* să scrieți și compilați programe simple în limbajul C;&lt;br /&gt;
* să utilizați programul Make pentru a compila automat programele scrise.&lt;br /&gt;
&lt;br /&gt;
= Sistemul de operare [https://en.wikipedia.org/wiki/Linux Linux] - programe =&lt;br /&gt;
&lt;br /&gt;
Majoritatea utilizatorilor de Windows pornesc de la premisa că Linux este greu de folosit și că nu pot rula programele cu care sunt obișnuiți în Windows. Cu toate că există, într-adevăr unele aplicații care nu sunt portate și nu pot fi rulate în Linux (cum ar fi o mare parte din jocuri precum și unele platforme foarte specifice de simulare și sinteză), majoritatea aplicațiilor sunt disponibile în Linux. Următoarea listă prezintă alternative ale aplicațiilor tradiționale, care pot fi rulate în Linux:&lt;br /&gt;
&lt;br /&gt;
* browser web: Google Chromium Browser (Chrome), Mozilla Firefox&lt;br /&gt;
* player video: VLC Media PLayer&lt;br /&gt;
* editor foto: Inkscape, Gimp&lt;br /&gt;
* suită office: LibreOffice (alternativă la Microsoft Office), Microsoft Office 365 - online, Google Docs - online&lt;br /&gt;
* real time messenger: Pidgin&lt;br /&gt;
* medii de dezvoltare software: Netbeans, Eclipse, Code::Blocks, IntelliJ&lt;br /&gt;
* procesare de semnal: Matlab, Octave (alternativă la Matlab)&lt;br /&gt;
* sinteză și simulare de circuite digitale: Xilinx ISE, Xilinx Vivado&lt;br /&gt;
&lt;br /&gt;
Pentru anumite programe, este de asemenea posibilă rularea acestora într-un emulator de Windows, numit wine.&lt;br /&gt;
&lt;br /&gt;
== Instalare de programe ==&lt;br /&gt;
&lt;br /&gt;
Instalarea unui program in Linux se face foarte ușor, cu o singură comandă (dacă aplicația este în baza de date a distribuției). Spre exemplu, pentru a instala GNU Octave:&lt;br /&gt;
&lt;br /&gt;
 sudo apt-get install -y octave&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; Pentru a putea instala o aplicație, este nevoie de acces de tip administrator de sistem. Acest lucru se poate face în două moduri: &lt;br /&gt;
* execuția unei comenzi de către un utilizator care are drept de administrator, folosind comanda &amp;#039;&amp;#039;&amp;#039;sudo&amp;#039;&amp;#039;&amp;#039;;&lt;br /&gt;
* execuția comenzii de către utilizatorul &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;root&amp;#039;&amp;#039;&amp;#039;&amp;lt;/font&amp;gt;, care este un cont cu acces nelimitat la toate resursele sistemului; &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;ATENȚIE&amp;#039;&amp;#039;&amp;#039;&amp;lt;/font&amp;gt;: Folosiți contul &amp;#039;&amp;#039;&amp;#039;root&amp;#039;&amp;#039;&amp;#039; doar pentru operații de administrare de sistem și deconectați-vă imediat ce ați terminat. Nu dați acces &amp;#039;&amp;#039;&amp;#039;root&amp;#039;&amp;#039;&amp;#039; decât persoanelor în care aveți încredere.   &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Linux [https://en.wikipedia.org/wiki/Bash_(Unix_shell) Bash] =&lt;br /&gt;
&lt;br /&gt;
Noțiunile legate de utilizarea și administrarea sistemului de operare Linux sunt necesare și obligatorii pentru un inginer electronist. În afară de faptul că Linux este un OS open-source stabil și sigur, atractivitatea lui vine în special din posibilitatea de a automatiza procese prin scrierea de scripturi în limbaje de scripting puternice și din faptul că este cel mai răspândit sistem de operare folosit pentru dispozitive embedded. În continuare se vor prezenta noțiuni și comenzi necesare pe parcursul laboratorului de Programarea Calculatoarelor.&lt;br /&gt;
&lt;br /&gt;
Pentru a obține informații legate de utilizarea unei comenzi, în terminalul (consola) Linux se poate da comanda &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;man &amp;lt;comanda&amp;gt;&amp;lt;/code&amp;gt; pentru a deschide manualul la pagina comenzii respective. Odată deschis, se poate naviga cu săgețile sus/ jos și pagina se închide cu tasta &amp;#039;q&amp;#039;. &lt;br /&gt;
&lt;br /&gt;
Odată deschis terminalul, prompt-ul de comandă arată de cele mai multe ori în felul următor: &lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt;&amp;#039;&amp;#039;&amp;#039; &lt;br /&gt;
Acesta este format din următoarele componente:&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;student&amp;#039;&amp;#039;&amp;#039; reprezintă numele utilizatorului curent și este urmat de caracterul &amp;#039;@&amp;#039; (at);&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;pracsis01&amp;#039;&amp;#039;&amp;#039; reprezintă numele calculatorului (host name) și care ar trebui să fie unic în rețea; în lipsa acestuia va apărea &amp;#039;&amp;#039;&amp;#039;localhost&amp;#039;&amp;#039;&amp;#039;;&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;~/Desktop&amp;#039;&amp;#039;&amp;#039; reprezintă directorul curent și este urmat de caracterul &amp;#039;$&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Linux este &amp;#039;&amp;#039;&amp;#039;CASE-SENSITIVE&amp;#039;&amp;#039;&amp;#039;, asta înseamnă că se face diferența între literele mari și mici, și în cadrul comenzilor, și în cadrul numelor de fișiere/ directoare.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru un tutorial mai detaliat, ce descrie un număr mai mare de comenzi, puteți vizita http://linuxcommand.org/learning_the_shell.php&lt;br /&gt;
&lt;br /&gt;
== Structura de directoare in Linux ==&lt;br /&gt;
&lt;br /&gt;
Toate fișierele și directoarele în Linux sunt plasate într-o ierarhie de tip arbore, unde directorul din vârf se numește rădăcină (&amp;#039;&amp;#039;root&amp;#039;&amp;#039;) și este reprezentat prin caracterul &amp;#039;&amp;#039;slash&amp;#039;&amp;#039; (/). &lt;br /&gt;
&lt;br /&gt;
 Structura de directoare și fișiere în Linux este descrisă în detaliu [http://www.tecmint.com/linux-directory-structure-and-important-files-paths-explained/ aici].&lt;br /&gt;
&lt;br /&gt;
În cadrul laboratorului de PC, vom lucra în interiorul directorului personal al utilizatorului &amp;#039;&amp;#039;student&amp;#039;&amp;#039;, care este implicit &amp;lt;code style=&amp;quot;color: blue&amp;quot;&amp;gt;/home/student&amp;lt;/code&amp;gt; (&amp;#039;&amp;#039;slash&amp;#039;&amp;#039; este separatorul de cale în Linux, analog cu &amp;#039;&amp;#039;backslash&amp;#039;&amp;#039; din Windows).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; Calea până la directorul personal este prescurată în Linux prin caracterul ~ . Astfel, &amp;lt;code style=&amp;quot;color: blue&amp;quot;&amp;gt;~&amp;lt;/code&amp;gt; este echivalent cu &amp;lt;code style=&amp;quot;color: blue&amp;quot;&amp;gt;/home/student&amp;lt;/code&amp;gt; iar &amp;lt;code style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop&amp;lt;/code&amp;gt; este echivalent cu &amp;lt;code style=&amp;quot;color: blue&amp;quot;&amp;gt;/home/student/Desktop&amp;lt;/code&amp;gt;. În plus, directorul personal al altor utilizatori poate fi construit folosind caracterul ~ și numele utilizatorului. De exemplu &amp;lt;code style=&amp;quot;color: blue&amp;quot;&amp;gt;~admin&amp;lt;/code&amp;gt; reprezintă calea până la directorul personal al utilizatorului &amp;#039;&amp;#039;admin&amp;#039;&amp;#039;: &amp;lt;code style=&amp;quot;color: blue&amp;quot;&amp;gt;/home/admin&amp;lt;/code&amp;gt;.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Instrucțiuni pentru lucrul cu sistemul de fișiere ==&lt;br /&gt;
&lt;br /&gt;
=== Navigare între directoare (cd) ===&lt;br /&gt;
&lt;br /&gt;
Navigarea către un director anume se face folosind comanda &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;cd&amp;lt;/code&amp;gt; (Change Directory). Comanda &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;cd&amp;lt;/code&amp;gt; poate fi folosită în următoarele moduri:&lt;br /&gt;
* navigarea către o cale absolută, care începe cu &amp;#039;&amp;#039;slash&amp;#039;&amp;#039;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~ $&amp;lt;/span&amp;gt; cd /home/student/Desktop&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* navigarea către o cale relativă, care nu începe cu &amp;#039;&amp;#039;slash&amp;#039;&amp;#039; și care depinde de directorul curent:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~ $&amp;lt;/span&amp;gt; cd Desktop&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* navigarea către directorul personal (home directory), prin apelarea comenzii fără alți parametri:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; cd&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~ $&amp;lt;/span&amp;gt;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* navigarea către calea anterioară (util când e nevoie să alternați între două directoare), folosind parametrul &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;-&amp;lt;/code&amp;gt;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; cd&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~ $&amp;lt;/span&amp;gt; cd -&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; cd -&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~ $&amp;lt;/span&amp;gt;&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Această comandă va eșua dacă directorul specificat nu există, sau nu aveți acces la el sau la unul directoarele părinte.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; Pentru a vă întoarce cu un nivel mai sus în ierarhia de directoare, se poate folosi ”..” în loc de numele directorului. De exemplu:&amp;lt;/div&amp;gt;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; cd ../Desktop/../Desktop/../../student/Desktop&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; &amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Aflarea directorului curent (pwd) ===&lt;br /&gt;
&lt;br /&gt;
Directorul curent se vede în mod normal în prompt, dar în cazul în care acest prompt nu este vizibil sau a fost modificat, sau directorul curent trebuie utilizat în cadrul unui script, comanda care îl afișează pe acesta pe ecran este &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;pwd&amp;lt;/code&amp;gt; (Print Working Directory).&lt;br /&gt;
&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; pwd&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;/home/student/Desktop&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Crearea unui director (mkdir) ===&lt;br /&gt;
&lt;br /&gt;
Pentru a crea un director inexistent, se folosește comanda &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;mkdir&amp;lt;/code&amp;gt; (MaKe DIRectory) specificând numele directorului care se vrea creat:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~ $&amp;lt;/span&amp;gt; mkdir work&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
Această comandă poate eșua dacă nu aveți acces la directorul părinte, dacă directorul părinte nu există, sau dacă directorul care se dorește creat există deja. Pentru a crea un director în situația în care directorul părinte nu există, se poate utiliza fanionul &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;-p&amp;lt;/code&amp;gt;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; mkdir -p ~/work/pc/F/group1/ion/lab1&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Ștergerea unui fisier sau recursiv, a unui director (rm) ===&lt;br /&gt;
&lt;br /&gt;
Pentru a șterge un fișier, un director gol, sau un director care conține alte fișiere sau subdirectoare, se poate folosi comanda &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;rm&amp;lt;/code&amp;gt; (ReMove) cu diferite fanioane: &lt;br /&gt;
&lt;br /&gt;
* pentru a șterge un fișier:&lt;br /&gt;
    &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; rm program.c&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* pentru a șterge un director, se folosește fanionul -r:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; mkdir test&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; rm test&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   rm: cannot remove ‘test’: Is a directory&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; rm -r test&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;Atenție:&amp;#039;&amp;#039;&amp;#039; Flag-ul &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;-r&amp;lt;/code&amp;gt; va șterge tot conținutul directorului, indiferent ce conține acesta, folosiți-l cu mare atenție.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Afișarea conținutului directorului curent (ls) ===&lt;br /&gt;
&lt;br /&gt;
Pentru a vedea conținutul directorului curent se poate utiliza comanda &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;ls&amp;lt;/code&amp;gt; (LiSt):&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; ls&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   chromium-browser.desktop  C-Lion.desktop  netbeans-8.0.2.desktop Xilinx XPS 14.7.desktop&lt;br /&gt;
&lt;br /&gt;
Pentru a vedea detalii despre fiecare fișier sau director, se poate folosi flag-ul &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;-l&amp;lt;/code&amp;gt;. Comanda &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;ls -l&amp;lt;/code&amp;gt; este atât de utilizată încât în anumite distribuții (Debian/ Ubuntu) are un &amp;#039;&amp;#039;alias&amp;#039;&amp;#039;: &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;ll&amp;lt;/code&amp;gt;.&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; ls -l&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   total 44&lt;br /&gt;
   -rwxr-xr-x  1 student student 12591 Jun  2 16:44 chromium-browser.desktop&lt;br /&gt;
   -rwxr-xr-x  1 student student   136 Aug 20 16:59 C-Lion.desktop&lt;br /&gt;
   -rwxr-xr-x  1 student student   261 Jul  9 16:09 netbeans-8.0.2.desktop&lt;br /&gt;
   -rwxr-xr-x  1 student student   162 Aug 25 13:38 Xilinx XPS 14.7.desktop&lt;br /&gt;
&lt;br /&gt;
=== Afișarea unui fișier în consolă (cat) ===&lt;br /&gt;
&lt;br /&gt;
Pentru a vedea conținutul unui fișier text (cum ar fi o sursă C sau un makefile) fără a deschide fișierul pentru editare, se poate utiliza comanda &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;cat&amp;lt;/code&amp;gt; (conCAT):&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; cat /etc/hostname&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;pracsis01&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Copiatul unui fișier sau director (cp) ===&lt;br /&gt;
&lt;br /&gt;
Pentru a copia un fișier sau director, se poate utiliza comanda &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;cp&amp;lt;/code&amp;gt; (CoPy). În cea mai simplă formă, comanda &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;cp&amp;lt;/code&amp;gt; are doi parametri: sursa și apoi destinația, obligatoriu în această ordine. Această comandă se poate folosi în mai multe feluri:&lt;br /&gt;
* copiatul unui fișier dintr-un director în altul:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; cp /etc/hostname ~/Desktop/&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* copiatul unui fișier dintr-un director în directorul curent:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; cp /etc/hostname .&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; În timp ce &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;..&amp;lt;/code&amp;gt; reprezintă directorul părinte, &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;.&amp;lt;/code&amp;gt; reprezintă directorul curent.&amp;lt;/div&amp;gt;&lt;br /&gt;
* copiatul unui fișier dintr-un director în altul, schimbându-i numele:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; cp /etc/hostname ~/Desktop/myhostname&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* copiatul unui director, recursiv, în alt director (se folosește fanionul &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;-r&amp;lt;/code&amp;gt;):&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; cp -r ~/Desktop /tmp/.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;Observație:&amp;#039;&amp;#039;&amp;#039; Această comandă a copiat directorul Desktop al utilizatorului curent în directorul tmp din rădăcină.&amp;lt;/div&amp;gt;&lt;br /&gt;
* copiatul unui director, recursiv, în alt director (se folosește fanionul &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;-r&amp;lt;/code&amp;gt;), schimbându-i numele:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; cp -r ~/Desktop /tmp/MyDesktop&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
=== Mutatul unui fișier sau director (mv) ===&lt;br /&gt;
&lt;br /&gt;
Pentru a muta un fișier sau director, se poate utiliza comanda &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;mv&amp;lt;/code&amp;gt; (MoVe). Analog cu copy, în cea mai simplă formă, comanda &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;mv&amp;lt;/code&amp;gt; are doi parametri: sursa și apoi destinația, obligatoriu în această ordine. Această comandă se poate folosi în mai multe feluri:&lt;br /&gt;
* mutatul unui fișier dintr-un director în altul:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; mv /etc/hostname ~/Desktop/&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* mutatul unui fișier dintr-un director în directorul curent:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; mv /etc/hostname .&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* mutatul unui fișier dintr-un director în altul, schimbându-i numele:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; mv /etc/hostname ~/Desktop/myhostname&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* mutatul unui director, recursiv, în alt director (se folosește fanionul &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;-r&amp;lt;/code&amp;gt;):&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; mv -r ~/Desktop /tmp/.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* mutatul unui director, recursiv, în alt director (se folosește fanionul &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;-r&amp;lt;/code&amp;gt;), schimbându-i numele:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; mv -r ~/Desktop /tmp/MyDesktop&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
= Scrierea, compilarea și executarea unui program în C =&lt;br /&gt;
&lt;br /&gt;
== Editarea fișierului sursă ==&lt;br /&gt;
&lt;br /&gt;
În cadrul laboratorului de PC, vom edita programele C într-un editor simplu de text, pentru a ne obișnui cu procesul de compilare și depanare a programelor. Editoarele de text care pot fi folosite sunt:&lt;br /&gt;
* în mod text (din consolă): nano, mcedit, vim&lt;br /&gt;
* în mod grafic: kate, gedit, notepad++&lt;br /&gt;
&lt;br /&gt;
Fișierele C sunt fișiere text în care se scrie programul.&lt;br /&gt;
&lt;br /&gt;
== Generarea fișierului executabil ==&lt;br /&gt;
&lt;br /&gt;
Din fișierul sursă, se genereaza fișierul executabil în mai multe etape, conform schemei de mai jos:&lt;br /&gt;
&lt;br /&gt;
[[Fișier:c_executable_generation.svg]]&lt;br /&gt;
&lt;br /&gt;
Compilatorul de C pe care îl vom folosi se numește [https://gcc.gnu.org/ GNU Compiler Collection] (sau scurt, gcc). Acesta, de fapt, nu este doar compilator, ci este un toolchain complet pentru generarea de fișiere executabile din fișiere surse C. Acesta poate face doar o parte din, sau toate etapele din schema de mai sus, în funcție de fanioanele utilizate. O parte din fanioanele posibile pentru &amp;#039;&amp;#039;&amp;#039;gcc&amp;#039;&amp;#039;&amp;#039; sunt (pentru lista completă studiaţi pagina de manual pentru GCC - man gcc):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Opțiune !! Efect&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;-o&amp;lt;/code&amp;gt; nume_fișier || Numele fișierului de ieşire va fi nume_fişier. În cazul în care această opțiune nu este setată, se va folosi numele implicit (pentru fișiere executabile: a.out - pentru Linux).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;-I&amp;lt;/code&amp;gt; cale_către_fișiere_antet || Caută fișiere antet și în calea specificată.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;-L&amp;lt;/code&amp;gt; cale_către_biblioteci || Caută fișiere bibliotecă și în calea specificată.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;-l&amp;lt;/code&amp;gt; nume_bibliotecă || Link-editează biblioteca nume_bibliotecă. &amp;#039;&amp;#039;&amp;#039;Atenție!!!&amp;#039;&amp;#039;&amp;#039; nume_bibliotecă nu este întotdeauna același cu numele fișierului antet prin care se include această bibliotecă. Spre exemplu, pentru includerea bibliotecii de funcții matematice, fișierul antet este math.h, iar biblioteca este m.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;-W&amp;lt;/code&amp;gt; tip_warning || Afișează tipurile de avertismente specificate (Pentru mai multe detalii &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;man gcc&amp;lt;/code&amp;gt; sau &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;gcc –help&amp;lt;/code&amp;gt;). Cel mai folosit tip este all. Este indicat ca la compilarea cu &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;-Wall&amp;lt;/code&amp;gt; să nu apară nici un fel de avertismente.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;-c&amp;lt;/code&amp;gt; || Compilează și asamblează, dar nu link-editează. Generează fișiere obiect, cu extensia .o.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;-S&amp;lt;/code&amp;gt; || Se oprește după faza de compilare, fară să asambleze. Rezultă cod assembler în fișiere cu extensia .s.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;-E&amp;lt;/code&amp;gt; || Se oprește după faza de preprocesare, fară să compileze. Rezultă cod C în fișiere cu extensia .c.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;-O&amp;lt;/code&amp;gt; [0-3] || Setează nivelul de optimizare, o valoare numerică între 0 și 3, 0 fiind fără optimizare (viteză de execuție minimă, dimensiune mare a executabilului, timp de compilare mic, cod ușor de depanat), iar 3 fiind optimizare maximă (viteză de execuție maximă, dimensiune mare a codului, mai mare decât la nivelul 2 datorită operațiunii de &amp;#039;&amp;#039;loop unrolling&amp;#039;&amp;#039;, timp de compilare mare, cod greu de depanat).&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;-g&amp;lt;/code&amp;gt; || Adaugă simboluri de debug în executabil, fără de care depanarea nu este posibilă. Mai multe despre instrumentele de debug în laboratoarele următoare.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
În continuare vom prezenta cateva exemple:&lt;br /&gt;
* generarea directă a unui executabil numit &amp;#039;&amp;#039;&amp;#039;hello&amp;#039;&amp;#039;&amp;#039;, dintr-un singur fișier sursă, &amp;#039;&amp;#039;&amp;#039;hello.c&amp;#039;&amp;#039;&amp;#039;, utilizând biblioteca standard:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* generarea directă a unui executabil numit &amp;#039;&amp;#039;&amp;#039;hello&amp;#039;&amp;#039;&amp;#039;, dintr-un singur fișier sursă, &amp;#039;&amp;#039;&amp;#039;hello.c&amp;#039;&amp;#039;&amp;#039;, utilizând biblioteca standard și biblioteca &amp;#039;&amp;#039;&amp;#039;math&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc hello.c -o hello -lm&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* generarea directă a unui executabil numit &amp;#039;&amp;#039;&amp;#039;hello&amp;#039;&amp;#039;&amp;#039;, din două fișiere sursă, &amp;#039;&amp;#039;&amp;#039;hello1.c&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;hello2.c&amp;#039;&amp;#039;&amp;#039;, utilizând biblioteca standard:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc hello1.c hello2.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* generarea unui fișier obiect, numit &amp;#039;&amp;#039;&amp;#039;hello.o&amp;#039;&amp;#039;&amp;#039;, dintr-un fișier sursă numit &amp;#039;&amp;#039;&amp;#039;hello.c&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -c hello.c -o hello.o&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* generarea unui fișier obiect, numit &amp;#039;&amp;#039;&amp;#039;hello.o&amp;#039;&amp;#039;&amp;#039;, din două fișiere sursă, &amp;#039;&amp;#039;&amp;#039;hello1.c&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;hello2.c&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -c hello1.c hello2.c -o hello.o&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* generarea unui executabil numit &amp;#039;&amp;#039;&amp;#039;hello&amp;#039;&amp;#039;&amp;#039;, din două fișiere obiect, &amp;#039;&amp;#039;&amp;#039;hello1.o&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;hello2.o&amp;#039;&amp;#039;&amp;#039;, utilizând biblioteca standard și biblioteca &amp;#039;&amp;#039;&amp;#039;math&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc hello1.o hello2.o -o hello -lm&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* generarea unui fișier cu cod de asamblare, numit &amp;#039;&amp;#039;&amp;#039;hello.s&amp;#039;&amp;#039;&amp;#039;, dintr-un fișier sursă numit &amp;#039;&amp;#039;&amp;#039;hello.c&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -S hello.c -o hello.s&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* generarea unui fișier sursă preprocesat, numit &amp;#039;&amp;#039;&amp;#039;hello_pre.c&amp;#039;&amp;#039;&amp;#039;, dintr-un fișier sursă numit &amp;#039;&amp;#039;&amp;#039;hello.c&amp;#039;&amp;#039;&amp;#039;:&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc -E hello.c -o hello_pre.c&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
== Executarea programului ==&lt;br /&gt;
&lt;br /&gt;
Pentru a executa un program sau script în consola Linux, numele fișierului se precede cu caracterele &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;./&amp;lt;/code&amp;gt; :&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; gcc hello.c -o hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
   &amp;#039;&amp;#039;&amp;#039;&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;student@pracsis01&amp;lt;/span&amp;gt; &amp;lt;span style=&amp;quot;color: blue&amp;quot;&amp;gt;~/Desktop $&amp;lt;/span&amp;gt; ./hello&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
= Compilarea automată a multiple surse - Makefiles =&lt;br /&gt;
&lt;br /&gt;
Dezvoltarea unei aplicații în limbajul C implică multe iterații de tip design - dezvoltare - depanare - integrare. La fiecare modificare a sursei, pentru a putea rula aplicația, codul trebuie recompilat. Odată cu creșterea numărului de linii de cod și a fișierelor sursă, timpul necesar operației de generare a executabilului (build) crește și el, până în punctul în care durează zeci de minute. Aceasta este în special o problemă când dezvoltarea se face pe microcontroler. Se evidențiază următoarele probleme:&lt;br /&gt;
* Dacă o sursă este modificată, ea trebuie recompilată prin rescrierea în consolă a comenzii de compilare. Această comandă poate fi foarte lungă, datorită multiplelor biblioteci și fanioane folosite, prin urmare este incomod de scris de fiecare dată. Este deci nevoie de o soluție pentru a predefini comanda de compilare și a o rula fără efort de fiecare dată.&lt;br /&gt;
* Dacă o aplicație este formată din multe fișiere sursă, compilarea tuturor acestor fișiere durează. În practică, se cere doar compilarea surselor care s-au modificat și apoi rularea operației de link-editare a fișierelor obiect în fișierul executabil (compilarea este operația care consumă cel mai mult timp din tot procesul de build). Este deci nevoie de un sistem care să detecteze care surse s-au modificat, apoi să le compileze strict pe acelea.&lt;br /&gt;
&lt;br /&gt;
Exisă mai multe sisteme de build care rezolvă aceste probleme, dar de departe cel mai folosit în practică este utilizarea aplicației &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;make&amp;lt;/code&amp;gt;, și configurarea acesteia prin Makefiles.&lt;br /&gt;
&lt;br /&gt;
== Anatomia unui Makefile - rețete de fișiere ==&lt;br /&gt;
&lt;br /&gt;
Scrierea unui Makefile este extrem de simplă și se bazează pe ideea de rețetă: pentru a genera un fișier &amp;lt;code style=&amp;quot;color: blue&amp;quot;&amp;gt;destination&amp;lt;/code&amp;gt;, este nevoie de unul sau mai multe fișiere sursă &amp;lt;code style=&amp;quot;color: blue&amp;quot;&amp;gt;sourceA, sourceB, sourceC, ...&amp;lt;/code&amp;gt; și de o comandă &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;command&amp;lt;/code&amp;gt; care să genereze fișierul A din B, C, D, ... Această rețetă se scrie într-un fișier cu numele &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;Makefile&amp;lt;/code&amp;gt; în felul următor:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;make&amp;quot;&amp;gt;&lt;br /&gt;
destination: sourceA sourceB sourceC ...&lt;br /&gt;
  [tab]  command&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Fișierele Makefile sunt sensibile la spații! Nu aveți voie să puneți linii goale decât între rețete, și nu aveți voie să plasați spații la începutul liniei. În plus, comenzile care trebuie rulate pentru generarea fișierului trebuie obligatoriu precedate de un caracter TAB, acesta nu se poate înlocui cu spații.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De exemplu, o rețetă care să genereze un executabil numit &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;hello&amp;lt;/code&amp;gt; dintr-o sursă C numită &amp;lt;code style=&amp;quot;color: blue&amp;quot;&amp;gt;hello.c&amp;lt;/code&amp;gt; se scrie în felul următor:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;make&amp;quot;&amp;gt;&lt;br /&gt;
hello: hello.c&lt;br /&gt;
	gcc hello.c -o hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pentru a face build-ul, se rulează simplu comanda &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;make&amp;lt;/code&amp;gt;, care va rula automat prima rețetă din fișier. Dacă vrem să specificăm care rețetă este rulată, atunci numele ei urmează comenzii &amp;#039;&amp;#039;&amp;#039;make&amp;#039;&amp;#039;&amp;#039;: &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;make hello&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Mai departe, dorim să mai definim o rețetă care să șteargă fișierele generate (să facă curat). Vom numi această rețetă &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;clean&amp;lt;/code&amp;gt;. Această rețetă nu generează un fișier (nu vrem să creăm un fișier numit &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;clean&amp;lt;/code&amp;gt;), astfel această rețetă este una falsă, care se declară PHONY:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;make&amp;quot;&amp;gt;&lt;br /&gt;
hello: hello.c&lt;br /&gt;
	gcc hello.c -o hello&lt;br /&gt;
&lt;br /&gt;
.PHONY: clean&lt;br /&gt;
clean:&lt;br /&gt;
	rm -f hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Putem acum oricând să ștergem fișierul generat rulând comanda &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;make clean&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Regulile după care se execută o rețetă sunt următoarele:&lt;br /&gt;
# Dacă numele rețetei NU este un fișier generat de către comandă, atunci acel target e PHONY, cum este &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;clean&amp;lt;/code&amp;gt;. În cazul acesta, comanda se rulează de fiecare data cand se face rețeta.&lt;br /&gt;
# Dacă numele rețetei ESTE un fișier dar lista de surse lipseste, atunci comanda se ruleaza doar daca fișierul nu există.&lt;br /&gt;
# Dacă numele rețetei ESTE un fișier și lista de surse există, comanda se rulează doar dacă fișierul nu există SAU dacă oricare din surse e mai nouă decat fișierul.&lt;br /&gt;
# Dacă pentru oricare din sursele unei rețete există o altă rețetă care îl generează, atunci se rulează automat întâi acea rețetă, indiferent dacă sursa există sau nu. Dacă fișierul sursă NU există și nu există nici o rețetă care să îl genereze, atunci aplicația &amp;#039;&amp;#039;&amp;#039;make&amp;#039;&amp;#039;&amp;#039; va genera o eroare: &amp;#039;&amp;#039;&amp;#039;No rule to make target&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
== Optimizări ==&lt;br /&gt;
&lt;br /&gt;
Când se scrie o rețetă, numele fișierelor sursă și/ sau a fișierui destinație se poate schimba în timpul dezvoltării aplicației. Dacă numele acestora apare și în comenzile din rețetă, trebuie avut grija ca noile nume să fie modificate peste tot unde apar. De exemplu, dacă Makefile-ul de mai sus, dorim să modificăm numele sursei din &amp;lt;code style=&amp;quot;color: blue&amp;quot;&amp;gt;hello.c&amp;lt;/code&amp;gt; în &amp;lt;code style=&amp;quot;color: blue&amp;quot;&amp;gt;byebye.c&amp;lt;/code&amp;gt;, trebuie modificat în două locuri:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;make&amp;quot;&amp;gt;&lt;br /&gt;
hello: byebye.c&lt;br /&gt;
	gcc byebye.c -o hello&lt;br /&gt;
&lt;br /&gt;
.PHONY: clean&lt;br /&gt;
clean:&lt;br /&gt;
	rm -f hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Astfel, se poate face o optimizare. Există două scurtături care pot fi folosite pentru numele fișierului destinație (&amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;$@&amp;lt;/code&amp;gt;) și pentru lista de fișiere sursă (&amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;$^&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;make&amp;quot;&amp;gt;&lt;br /&gt;
hello: byebye.c&lt;br /&gt;
	gcc $^ -o $@&lt;br /&gt;
&lt;br /&gt;
.PHONY: clean&lt;br /&gt;
clean:&lt;br /&gt;
	rm -f hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Un alt avantaj este acela că dacă executabilul &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;hello&amp;lt;/code&amp;gt; va trebui generat din două fișiere sursă, noul fișier nu trebuie adăugat decât în lista de surse, nu și în comandă, lista propagându-se automat datorită lui &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;$^&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;make&amp;quot;&amp;gt;&lt;br /&gt;
hello: byebye.c hello.c&lt;br /&gt;
	gcc $^ -o $@&lt;br /&gt;
&lt;br /&gt;
.PHONY: clean&lt;br /&gt;
clean:&lt;br /&gt;
	rm -f hello&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Exerciții =&lt;br /&gt;
&lt;br /&gt;
== Bash == &lt;br /&gt;
&lt;br /&gt;
# Navigați până în directorul personal al user-ului &amp;#039;&amp;#039;student&amp;#039;&amp;#039;.&lt;br /&gt;
# Creați un director numit &amp;#039;&amp;#039;&amp;#039;work&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
# În directorul &amp;#039;&amp;#039;&amp;#039;work&amp;#039;&amp;#039;&amp;#039; creați următoarele structuri de directoare:&lt;br /&gt;
#*  PC/seriaF/grupa&amp;#039;&amp;#039;N&amp;#039;&amp;#039;/&amp;#039;&amp;#039;nume&amp;#039;&amp;#039;/lab1&lt;br /&gt;
#*  PC/seriaF/grupa&amp;#039;&amp;#039;N&amp;#039;&amp;#039;/&amp;#039;&amp;#039;nume&amp;#039;&amp;#039;/lab2&lt;br /&gt;
# Schimbați directorul curent în /home/student/work/PC/seriaF/grupa&amp;#039;&amp;#039;N&amp;#039;&amp;#039;/&amp;#039;&amp;#039;nume&amp;#039;&amp;#039;/lab1.&lt;br /&gt;
# Dați comanda &amp;lt;code style=&amp;quot;color: green&amp;quot;&amp;gt;echo Acesta este primul meu fisier text &amp;gt; test.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
# Vizualizați lista de fișiere din directorul curent.&lt;br /&gt;
# Vizualizați conținutul fișierului din directorul curent.&lt;br /&gt;
# Faceți o copie a fișierului &amp;#039;&amp;#039;&amp;#039;text.txt&amp;#039;&amp;#039;&amp;#039; numită &amp;#039;&amp;#039;&amp;#039;test2.txt&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
# Mutați fișierul &amp;#039;&amp;#039;&amp;#039;test2.txt&amp;#039;&amp;#039;&amp;#039; în directorul /home/student/work/PC/seriaF/grupa&amp;#039;&amp;#039;N&amp;#039;&amp;#039;/&amp;#039;&amp;#039;nume&amp;#039;&amp;#039;/lab2&lt;br /&gt;
# Schimbați directorul curent în /home/student/work/PC/seriaF/grupa&amp;#039;&amp;#039;N&amp;#039;&amp;#039;/&amp;#039;&amp;#039;nume&amp;#039;&amp;#039;/lab2.&lt;br /&gt;
# Vizualizați lista de fișiere din directorul curent.&lt;br /&gt;
# Vizualizați conținutul fișierului din directorul curent.&lt;br /&gt;
# Ștergeți directorul /home/student/work&lt;br /&gt;
&lt;br /&gt;
== GCC ==&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Deschideți un editor de text.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Scrieți într-un fișier nou următorul cod C &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(){&lt;br /&gt;
    printf(&amp;quot;Hello PC Lab!\n&amp;quot;);&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Salvați fișierul în directorul /home/student/work/PC/seriaF/grupa&amp;#039;&amp;#039;N&amp;#039;&amp;#039;/&amp;#039;&amp;#039;nume&amp;#039;&amp;#039;/lab1 cu numele &amp;#039;&amp;#039;&amp;#039;source.c&amp;#039;&amp;#039;&amp;#039; (directorul va trebui refăcut)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Navigați în consolă în directorul /home/student/work/PC/seriaF/grupa&amp;#039;&amp;#039;N&amp;#039;&amp;#039;/&amp;#039;&amp;#039;nume&amp;#039;&amp;#039;/lab1&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Compilați fișierul sursă într-un executabil numit &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Executați programul.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Ștergeți fișierul &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Generați un fișier obiect, din fișierul &amp;#039;&amp;#039;&amp;#039;source.c&amp;#039;&amp;#039;&amp;#039;, numit &amp;#039;&amp;#039;&amp;#039;source.o&amp;#039;&amp;#039;&amp;#039;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Generați un executabil numit &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039;, din fișierul obiect.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Executați programul.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Generați un fișier cu cod asamblare, numit &amp;#039;&amp;#039;&amp;#039;source.s&amp;#039;&amp;#039;&amp;#039;, din fișierul sursă.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Afișați pe ecran conținutul fișierului &amp;#039;&amp;#039;&amp;#039;source.s&amp;#039;&amp;#039;&amp;#039;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Generați un fișier cu cod C preprocesat, numit &amp;#039;&amp;#039;&amp;#039;source_pre.c&amp;#039;&amp;#039;&amp;#039;, din fișierul sursă.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Afișați pe ecran conținutul fișierului &amp;#039;&amp;#039;&amp;#039;source_pre.c&amp;#039;&amp;#039;&amp;#039;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Afișați pe ecran conținutul fișierului &amp;#039;&amp;#039;&amp;#039;source.o&amp;#039;&amp;#039;&amp;#039;. Explicați comportamentul.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Makefiles ==&lt;br /&gt;
&lt;br /&gt;
# Scrieți un Makefile cu două rețete:&lt;br /&gt;
#* una care să genereze executabilul &amp;#039;&amp;#039;&amp;#039;main&amp;#039;&amp;#039;&amp;#039; din sursa &amp;#039;&amp;#039;&amp;#039;source.c&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
#* una care să șteargă fișierul generat.&lt;br /&gt;
# Rulați comanda &amp;#039;&amp;#039;&amp;#039;make clean&amp;#039;&amp;#039;&amp;#039; și verificați că executabilul a fost șters.&lt;br /&gt;
# Rulați comanda &amp;#039;&amp;#039;&amp;#039;make&amp;#039;&amp;#039;&amp;#039;, verificați că programul a fost compilat și rulați-l.&lt;br /&gt;
# Rulați comanda &amp;#039;&amp;#039;&amp;#039;make&amp;#039;&amp;#039;&amp;#039; din nou. Ce observați?&lt;br /&gt;
# Modificați fișierul sursă ca în loc de &amp;#039;&amp;#039;&amp;#039;Hello PC Lab!&amp;#039;&amp;#039;&amp;#039; să afișeze pe ecran &amp;#039;&amp;#039;&amp;#039;Makefiles are awesome!&amp;#039;&amp;#039;&amp;#039; (nu uitați să salvați fișierul după modificare).&lt;br /&gt;
# Rulați din nou comanda &amp;#039;&amp;#039;&amp;#039;make&amp;#039;&amp;#039;&amp;#039; și apoi executați programul.&lt;br /&gt;
# Modificați &amp;#039;&amp;#039;&amp;#039;Makefile&amp;#039;&amp;#039;&amp;#039; astfel încât să genereze executabilul dintr-un fișier obiect, iar fișierul obiect să fie generat din fișierul sursă.&lt;br /&gt;
&lt;br /&gt;
= Exerciții pentru acasă =&lt;br /&gt;
&lt;br /&gt;
# Instalați Virtualbox și descărcați mașina virtuală conform instrucțiunilor de pe Moodle (dacă vă simțiti curajoși, puteți instala Linux direct pe calculator, [http://linux.about.com/od/howtos/ss/How-To-Dual-Boot-Windows-81-And-Linux-Mint.htm în paralel cu Windows], sau înlocuindu-l).&lt;br /&gt;
# Refaceți exercițiile din laborator pe propriul calculator.&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_6&amp;diff=3502</id>
		<title>PC Laborator 6</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=PC_Laborator_6&amp;diff=3502"/>
		<updated>2015-09-29T14:48:27Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: Pagină nouă: __TOC__ == Obiective == La sfârșitul acestui laborator studenții vor fi capabili: * să înțeleagă funcționarea blocurilor repetitive; * să conceapă programe care folosesc...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
== Obiective ==&lt;br /&gt;
La sfârșitul acestui laborator studenții vor fi capabili:&lt;br /&gt;
* să înțeleagă funcționarea blocurilor repetitive;&lt;br /&gt;
* să conceapă programe care folosesc blocuri repetitive.&lt;br /&gt;
&lt;br /&gt;
== Structura repetitivă ==&lt;br /&gt;
Structura repetitivă, cunoscută și sub numele de loop sau buclă, reprezintă o bucată de cod care poate fi executată în mod repetat. Structurile repetitive trebuie sa aibă o condiție de continuare. La fiecare iterație a codului această condiție este verificată, iar în momentul în care condiția devine falsă se oprește execuția buclei și se trece mai departe în program.&lt;br /&gt;
Există 2 tipuri de structuri repetitive:&lt;br /&gt;
* structuri repetitive cu număr cunoscut de pași;&lt;br /&gt;
* structuri repetitive cu număr necunoscut de pași.&lt;br /&gt;
&lt;br /&gt;
=== Structuri repetitive cu număr cunoscut de pași ===&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;for&amp;#039;&amp;#039; creează o structură repetitivă cu număr cunoscut de pași. Sintaxa instrucțiunii &amp;#039;&amp;#039;for&amp;#039;&amp;#039; este următoarea:&amp;lt;br/&amp;gt;&lt;br /&gt;
a)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
for (inițializare contor; condiție logică; modificare contor)&lt;br /&gt;
        instrucțiune;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
for (inițializare contor; condiție logică; modificare contor){&lt;br /&gt;
        instrucțiune1;&lt;br /&gt;
        instrucțiune2;&lt;br /&gt;
..............................&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;for&amp;#039;&amp;#039; se parcurge conform schemei următoare:&amp;lt;br/&amp;gt;[[Fișier:For.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce va afisa acest program?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
for (x = 0; x &amp;lt; 10; x++) {&lt;br /&gt;
        printf(&amp;quot;%d\n&amp;quot;, x);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Structuri repetitive cu număr necunoscut de pași ===&lt;br /&gt;
Există două instrucțiuni pentru a crea structuri repetitive cu număr necunoscut de pași:&lt;br /&gt;
* instrucțiunea &amp;#039;&amp;#039;while&amp;#039;&amp;#039;;&lt;br /&gt;
* instrucțiunea &amp;#039;&amp;#039;do..while&amp;#039;&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
==== Instrucțiunea &amp;#039;&amp;#039;while&amp;#039;&amp;#039; ====&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;while&amp;#039;&amp;#039; verifică înainte de fiecare iterație condiția de intrare: dacă această condiție este îndeplinită se execută codul din corpul instrucțiunii, iar dacă nu se îndeplinește condiția se iese din această buclă. Sintaxa instrucțiunii este următoarea:&amp;lt;br/&amp;gt;&lt;br /&gt;
a)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
while (condiție)&lt;br /&gt;
        instrucțiune;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
while (condiție){&lt;br /&gt;
        instrucțiune1;&lt;br /&gt;
        instrucțiune2;&lt;br /&gt;
..............................&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Organigrama instrucțiunii &amp;#039;&amp;#039;while&amp;#039;&amp;#039; se regăsește în imaginea următoare:&amp;lt;br/&amp;gt;[[Fișier:While.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce va afișa următorul cod în urma execuției?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int x = 0;  &lt;br /&gt;
while (x &amp;lt; 10){&lt;br /&gt;
      printf(&amp;quot;%d\n&amp;quot;, x);&lt;br /&gt;
      x++;       &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Instrucțiunea &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; ====&lt;br /&gt;
Instrucțiunea &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; verifică după fiecare iterație condiția de continuare. Sintaxa instrucțiunii &amp;quot;do while&amp;#039;&amp;#039; este următoarea:&amp;lt;br/&amp;gt;&lt;br /&gt;
a)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
do{&lt;br /&gt;
      instrucțiune;&lt;br /&gt;
}while (condiție);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
b)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
do{&lt;br /&gt;
      instrucțiune1;&lt;br /&gt;
      instrucțiune2;&lt;br /&gt;
..............................&lt;br /&gt;
}while (condiție);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Se observă că sintaxa instrucțiunii &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; este puțin diferită:&lt;br /&gt;
* indiferent de numărul de instrucțiuni din cadrul structurii repetitive, se folosesc acoladele;&lt;br /&gt;
* după condiția de continuitate se folosește obligatoriu semnul de punctuație &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;;&amp;#039;&amp;#039;&amp;#039;&amp;lt;/font&amp;gt; .&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Organigrama instrucțiunii &amp;#039;&amp;#039;while&amp;#039;&amp;#039; se regăsește în imaginea următoare:&amp;lt;br/&amp;gt;[[Fișier:Do_while.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;regula&amp;quot;&amp;gt;&amp;#039;&amp;#039;&amp;#039;&amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt; Atenție:&amp;lt;/font&amp;gt;&amp;#039;&amp;#039;&amp;#039; Se observă că datorită faptului că se verifică abia la sfârșitul structurii condiția de continuitate, orice structură iterativă de tip &amp;#039;&amp;#039;do while&amp;#039;&amp;#039; va fi executată întotdeauna cel puțin o dată.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Exemplu&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
Ce se va afișa în urma execuției?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int x;&lt;br /&gt;
x = 0;&lt;br /&gt;
do{&lt;br /&gt;
      printf( &amp;quot;Hello, world!\n&amp;quot; );&lt;br /&gt;
}while (x != 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Cuvintele cheie &amp;#039;&amp;#039;&amp;#039;break&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039; ==&lt;br /&gt;
Pentru structurile repetitive există două cuvinte cheie de mare importanță: &amp;#039;&amp;#039;&amp;#039;break&amp;#039;&amp;#039;&amp;#039; și &amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039;.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;break&amp;#039;&amp;#039;&amp;#039; va ieși din bucla cea mai apropiată indiferent de condițiile de continuare ale acesteia. Utilitatea acestei instrucțiuni apare atunci când trebuie părăsită bucla în anumite circumstanțe.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;continue&amp;#039;&amp;#039;&amp;#039; oprește iterația curentă, face update contorului (în cazul buclei &amp;#039;&amp;#039;for&amp;#039;&amp;#039;) și continuă cu execuția structurii repetitive de la prima instrucțiune. Cu alte cuvinte, &amp;#039;&amp;#039;continue&amp;#039;&amp;#039; ignoră tot ceea ce urmează după el în cadrul buclei și trece la următoarea iterație a buclei.&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Do_while.jpg&amp;diff=3501</id>
		<title>Fișier:Do while.jpg</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:Do_while.jpg&amp;diff=3501"/>
		<updated>2015-09-29T14:28:30Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: Organigrama instrucțiunii do while.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Organigrama instrucțiunii do while.&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
	<entry>
		<id>http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:While.jpg&amp;diff=3500</id>
		<title>Fișier:While.jpg</title>
		<link rel="alternate" type="text/html" href="http://wiki.dcae.pub.ro/index.php?title=Fi%C8%99ier:While.jpg&amp;diff=3500"/>
		<updated>2015-09-29T14:05:49Z</updated>

		<summary type="html">&lt;p&gt;Vpopescu: Organigrama instrucțiunii while&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Organigrama instrucțiunii while&lt;/div&gt;</summary>
		<author><name>Vpopescu</name></author>
	</entry>
</feed>