Differences

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

Link to this comparison view

so:laboratoare:resurse:c_tips [2015/03/02 20:39]
adrian.stanciu [Structura unui fișier header]
so:laboratoare:resurse:c_tips [2016/06/05 17:51] (current)
adrian.stanciu [Folosirea specificatorului static pentru variabile globale și funcții]
Line 26: Line 26:
  
   * începe cu un include guard (pentru a evita includerea sa într-un modul de mai multe ori)   * începe cu un include guard (pentru a evita includerea sa într-un modul de mai multe ori)
-  * include un set minim de alte fișiere header necesare pentru a putea compila ​sursele ​în care header-ul curent va fi inclus+  * include un set minim de alte fișiere header necesare pentru a putea compila ​fișierele sursă (.c) în care header-ul curent va fi inclus
   * poate conține directive pentru compilare condiționată   * poate conține directive pentru compilare condiționată
-  * conține declarații incomplete (forward declarations) pentru structurile și uniunile ce apar doar ca pointeri în cadrul header-ului și pentru care nu se încearcă accesarea vreunui membru din interiorul header-ului;​ această tehnică poate reduce numărul de fișiere header ce trebuiesc incluse în header-ul curent+  ​* conține macrodefiniții și definiții de tipuri ce trebuiesc partajate 
 +  ​* conține declarații incomplete (forward declarations) pentru structurile și uniunile ce apar doar ca pointeri în cadrul header-ului și pentru care nu se încearcă accesarea vreunui membru din interiorul header-ului;​ această tehnică poate reduce numărul de fișiere header ce trebuiesc incluse în header-ul curent
 +<code c> 
 +struct x_t; 
 + 
 +struct y_t { 
 +    struct x_t *x; 
 +    ... 
 +}; 
 +/* 
 + * nu este necesar să includem header-ul în care este declarat tipul struct x_t 
 + * acel header va fi inclus în fișierele sursă care folosesc obiecte de tipul struct x_t 
 + */ 
 +</​code>​
   * conține declarații de structuri, uniuni și enumerații ce trebuiesc partajate   * conține declarații de structuri, uniuni și enumerații ce trebuiesc partajate
-  * **NU** conține structurile,​ uniunile și enumerațiile interne modulului; dacă un alt modul trebuie să lucreze cu un obiect de un tip declarat în modulul curent (o structură sau o uniune), dar nu vrem să facem publică implementarea acelui tip, putem să ne folosim de o declarație incompletă și de definirea unui nume care să fie utilizat de acel modul:+  * **NU** conține structurile,​ uniunile și enumerațiile interne modulului; dacă un alt modul trebuie să lucreze cu un obiect de un tip declarat în modulul curent (o structură sau o uniune), dar nu vrem să facem publică implementarea acelui tip, putem să ne folosim de o declarație incompletă și de definirea unui nou nume, ce va fi utilizat de acel modul:
 <code c> <code c>
 struct vector; struct vector;
 typedef struct vector vector_t; typedef struct vector vector_t;
 +/* 
 + * alte module vor folosi tipul vector_t
 + * variabilele de acest tip vor fi manipulate prin funcții exportate de modulul curent
 + */
 </​code>​ </​code>​
-  * conține macrodefiniții și definiții de tipuri ce trebuiesc partajate 
   * declară variabilele globale exportate de modul (declarate cu keyword-ul **extern**)   * declară variabilele globale exportate de modul (declarate cu keyword-ul **extern**)
-  * conține prototipurile funcțiilor exportate; **NU** se exportă funcțiile ce sunt folosite doar intern de către modul (funcțiile folosite intern trebuie definite în surse folosind keyword-ul **static**)+  * conține prototipurile funcțiilor exportate; **NU** se exportă funcțiile ce sunt folosite doar intern de către modul (funcțiile folosite intern trebuie definite în fișierele sursă (.c) folosind keyword-ul **static**)
   * poate conține definiții de funcții inline ce trebuiesc partajate   * poate conține definiții de funcții inline ce trebuiesc partajate
   * **NU** conține cod executabil cu excepția funcțiilor inline și a macro-urilor   * **NU** conține cod executabil cu excepția funcțiilor inline și a macro-urilor
Line 44: Line 60:
  
 O practică bună este ca atunci când scriem o instrucțiune ce alocă o resursă (alocare dinamică de memorie, deschidere a unui fișier) să scriem și instrucțiunea asociată care eliberează acea resursă atunci când nu mai este necesară. În acest fel ne asigurăm că nu ținem ocupate resursele sistemului mai mult decât este cazul. O practică bună este ca atunci când scriem o instrucțiune ce alocă o resursă (alocare dinamică de memorie, deschidere a unui fișier) să scriem și instrucțiunea asociată care eliberează acea resursă atunci când nu mai este necesară. În acest fel ne asigurăm că nu ținem ocupate resursele sistemului mai mult decât este cazul.
 +
 +==== Folosirea de tool-uri pentru verificarea coding style-ului ====
 +
 +Un coding style bun, folosit consecvent, face mai ușoară și mai rapidă înțelegerea unui cod. Marile proiecte software îsi stabilesc un coding style și realizează utilitare pentru verificarea automată a acestuia. ​
 +[[https://​github.com/​torvalds/​linux/​blob/​master/​scripts/​checkpatch.pl | Checkpatch.pl]] este un script Perl folosit în kernelul Linux pentru a verifica coding style-ului patch-urilor ce urmează a fi submise.
  
 ===== Limbaj ===== ===== Limbaj =====
Line 408: Line 429:
   * declarația unui array extern:   * declarația unui array extern:
 <code c> <code c>
-extern int a[];+extern int a[]; // definit în alt modul ca: int a[N];
 </​code>​ </​code>​
   * definiția unui array; definiția este un caz special de declarație care alocă spațiu pentru array-ul definit și eventual îl inițializează cu diverse valori:   * definiția unui array; definiția este un caz special de declarație care alocă spațiu pentru array-ul definit și eventual îl inițializează cu diverse valori:
Line 428: Line 449:
 int m = *(a + i); int m = *(a + i);
 </​code>​ </​code>​
 +
 +==== Folosirea specificatorului "​static"​ pentru variabile globale și funcții ====
 +
 +O variabilă globală sau o funcție declarată cu specificatorul "​static"​ are internal [[http://​en.cppreference.com/​w/​c/​language/​storage_duration | linkage]], adică poate fi referită doar din translation unit-ul respectiv (un translation unit reprezintă un fișier sursă .c împreună cu toate fișierele header pe care acesta le include).
 +
 +Avantajele acestei practici sunt:
 +  * simbolurile sunt vizibile doar în translation unit-ul respectiv; astfel, se evită poluarea namespace-ului global și se reduc șansele conflictelor de nume
 +  * încapsulare:​ exte expusă doar interfața publică a modulului (nu și obiectele și funcțiile interne ce contribuie la implementarea interfeței)
  
 ===== Utilizare API ===== ===== Utilizare API =====
Line 466: Line 495:
   *[[http://​www.gnu.org/​software/​libc/​manual/​ | Documentația GNU C Library]]   *[[http://​www.gnu.org/​software/​libc/​manual/​ | Documentația GNU C Library]]
   *[[http://​linux.die.net/​man/​1/​indent | Tool pentru indentare]]   *[[http://​linux.die.net/​man/​1/​indent | Tool pentru indentare]]
- 
-~~DISCUSSION:​off~~ 
so/laboratoare/resurse/c_tips.1425321545.txt.gz · Last modified: 2015/03/02 20:39 by adrian.stanciu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0