This is an old revision of the document!
Responsabili:
Această pagină are o importanță deosebită pentru modul vostru de formare ca programatori. Vă rugăm să o citiți integral!
Este foarte important să putem scrie cod corect, eficient, dar, în aceeași măsură, codul nostru trebuie să poată fi înțeles și de alte persoane.
Imaginați-vă următoarele scenarii: 1. 2 colegi scriu cod în maniere cu totul diferite, iar la un moment dat trebuie să îl combine pentru a face produsul final. Deoarece nici unul nu înțelege ce a făcut celălalt pentru că au scris cod cum au vrut, acum sunt nevoiți să stea și să facă modificări astfel încât să ajungă la un numitor comun și să poată colabora. Nu era mai bine ca fiecare să fi urmat aceleași convenții de la bun început?
2. Un alt scenariu, mai aproape de voi, este chiar acum când voi scrieți primele programe în C. Se întămplă (și este normal) să uităm anumite lucruri o dată cu trecerea timpului, prin urmare voi veți simți nevoia să vă uitați pe programele scrise de voi (ex. cum aloc dinamic un tablou 3D în C, cum am rezolvat tema X care avea o idee asemănătoare cu ce îmi trebuie mie acum). Ce se va întâmpla dacă nu aveți un coding style adecvat? Răspunsul este simplu: nu veți înțelege propriu cod! Pentru lucrurile simple evident că trebuie să treaca un timp destul de lung, dar pentru cele grele și foarte grele puteți ajunge în situația în care să “uitați” cum se codează o chestie de pe o zi pe alta.
Toate scenariile de mai sus reprezintă exemple care v-ar putea afecta în sens negativ, de aceea la materia PC (și multe altele în facultate) vi se va impune să urmăriți anumite aspecte care să vă obisnuiască încă de la început, când lucrurile sunt foarte simple, astfel încât aceste deprinderi să intre în modul vostru normal de a coda.
Cum rezolvăm problemele de mai sus? Scenariul 2 se poate rezolva prin a scrie într-un mod ordonat, propriu, codul. Este de ajuns? Răspunsul este nu, întrucât e foarte puțin probabil să scrii cod de unul singur tot timpul. Colaborarea este un lucru care va veni la un moment dat în ajutorul vostru.
Pentru a rezolva toate problemele care pot apărea, vom folosi o convenție de coding style. Convențiile sunt seturi de reguli acceptate de comunități largi. Există mici diferențe între ele, fapt care face ca atunci când se trece de la o convenție la alta (ex. alta firmă) să nu reprezinte o problemă.
La Programarea Calculatoarelor seria CA vom folosi o convenție de coding style extrasă din documentația oficială de C++ de la Google (Google C++ ). Motivele pentru care am ales-o este că este larg folosită de comunitatea open-source, oferă un script automat de testare care afisează toate problemele pentru a le corecta, iar acest script poate fi ușor adaptat de la C++ la C.
Vom încerca să enumerăm lucrurile pe care trebuie să le aveți in vedere, apoi vom trece prin toate instrucțiunile limbajului C și vom da exemple.
* Codul trebuie să fie:
Cititi exemplele cu if-else de mai jos si analizati:
if (condition) { printf("Gigel!\n"); } ... if (n % 2 == 0 && n > 10 && (n % 3 == 1 || n % 7 == 2)) { ... } ... if (condition) { ... } else { ... } ... if (condition1) { ... } else if (condition2) { ... } else if (condition3) { ... } else { ... }
Citiți exemplele cu for de mai jos și analizați
for (int i = 0; i <= n; ++i) { printf("%d", i); } ... for (int i = n; i >= 0; --i) { printf("%d", i); } ... int found = 0; for (int i = n; i >= 0 && !found; i -= 2) { ... if (...) { printf("%d", i); found = 1; } } ... for (int i = 3; i * i <= n; i += 2) { // i * i <= n simuleaza conditia i <= sqrt(n) fara a lucra cu numere reale if (n % i == 0) { printf("%d", i); // afiseaza pe ecran toate numerele impare de la 3 la sqrt(n) // care sunt divizori ai lui n } } ... for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { printf("%d ", j); } printf("\n"); }
Observațiile de mai sus sunt valabile și pentru celelalte cicluri repetitive.
Analizați exemplele de funcții de mai jos și observați că.
void clean_display() { ... } ... void print_array(int n, int v[NMAX]) { ... } int print_gigel(int gigel) { ... return result; } int count_duplicates(int n, int v[NMAX]) { int x = n; // niciodata nu lasam prima linie dintr-un block {} goala, nu are sens ... // daca avem mai multe declaratii/alocari etc putem lasa o linie goala sa aratam ca ca s-a terminat initializarea int cnt = 0; for (int i = 0; i <= n; ++i) { ... } // mai las o linie goala (optional) sa arat ca s-a terminat algoritmul print_gigel(cnt); return cnt; }
Fie următorul șablon de program. Analizați: * cum scriem în fișier mai multe funcții * care e structura generală a unui program
#include <stdio.h> ... // alte biblioteci incluse sau macro-uri #include <math.h> #define NMAX 100 // nu vom declara tablouri cu int v[100]; ci vom folosi un macro pentru dimensiune // linie goala void dummy() { } // lasam o linie goala intre functii int print_array(int n, int v[NMAX]) { ... } // lasam o linie goala intre functii int main() { ... return 0; }
Evident ca atunci cand fișirul main devine prea mare, este nevoie să grupăm componentele după logică și să le mutăm în alte fișiere sursă C/headere.
Toate aspectele menționate mai sus sunt foarte importante și trebuie să vi le însușiți. Evident că la început este greu să rețineți toate regulile, de aceea va punem la dispoție o modalitate de testare, folosind scriptul Google C++, adaptat pentru nevoile noastre.
Varianta de script pe care o vom folosi la PC este aici.
Să presupunem că cineva a scris din greșeală următorul cod (sigur nu voi).
#include <stdio.h> int main() { int x = 0; printf("%d\n" , x); return 0;}
În caz că nu observ problemele pe care trebuie să le corectez, rulez următoarea comandă:
darius@pc ~ $ python cs.py cs_negative_example.c cs_negative_example.c:0: No copyright message found. You should have a line: "Copyright [year] <Copyright Owner>" [legal/copyright] [5] cs_negative_example.c:6: { should almost always be at the end of the previous line [whitespace/braces] [4] cs_negative_example.c:7: Redundant blank line at the start of a code block should be deleted. [whitespace/blank_line] [2] cs_negative_example.c:12: Tab found; better to use spaces [whitespace/tab] [1] Done processing cs_negative_example.c Total errors found: 4
Dacă vom corecta cele reclamate de script, vom obține un nou fișier cu următorul conținut:
// Copyright 2018 Darius Neatu (neatudarius@gmail.com) #include <stdio.h> int main() { int x = 0; printf("%d\n", x); return 0; }
Rulăm din nou scriptul și observăm că problemele au dispărut.
darius@pc ~ $ python cs.py cs_positive_example.c Done processing cs_positive_example.c Total errors found: 0
Este foarte important să avem un coding style OK. Această pagină vine în ajutorul vostru.