Documente Academic
Documente Profesional
Documente Cultură
LIMBAJUL C/C++
REGULI PRACTICE DE
PROGRAMARE EFICIENTĂ
Curs 14
CUPRINS
1. Noţiuni introductive
2. Funcții pentru intrări-ieșiri
3. Funcții pentru șiruri de caractere și afișări pe
ecran
4. Funcții bazate pe caracter
5. Funcții pentru alocarea dinamică a memoriei
6. Funcții pentru modul video
7. Funcții matematice
8. Funcții pentru timp și dată
9. Alte funcții de bibliotecă
2
1. NOŢIUNI INTRODUCTIVE
C++0x(1y) e un limbaj ce dorește dezvoltarea limbajului C++
există variante 2003, 2007(8), 2011(2), 2014, 2017
C++20 revision standardului ISO/IEC care urmeaza dupa C++17.
Standardul a fost finalizat din punct de vedere tehnic de catre
WG21 la Praga in februarie 2020, aprobat in septembrie 2020, si
publicat de ISO in decembrie 2020, (C++20).
O noua variantă este anuntata pentru anul 2020 (C++20)
6
2. FUNCŢII PENTRU INTRĂRI-IEŞIRI
<cstdio>/ <stdio.h>, <conio.h>
Generale
char name[20]="";
scanf ("%[^\n]%*c", name);
[^\n] precizează că se va citi orice caracter, dacă nu e ‘\n’
%*c – caracterul * indică faptul că se va extrage din flux
caracterul newline, dar nu va fi stocat
Obs : Dacă se va citi un alt tip de dată (numerică), șirurile
următoare nu se mai citesc corect
scanf("%[^\n]s", name);
[^\n] setează delimitatorul pentru șirul citit
8
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <conio.h>
#define DIM 50
int main() {
char name[DIM] = "";
printf("\nEnter a string with space: ");
scanf("%[^\n]%*c", name);
printf(name);
printf("\nEnter a new string with space: ");
scanf("%[^\n]s", name);
printf(name);
_getch();
return 0; 9
}
Exemplu cu gets_s()
#include <iostream>
using namespace std;
#include <regex>
const int max_dim = 30;
int main() {
// versiune C
printf("\nGets: ");
char buf[max_dim];
char *adr = gets_s(buf, sizeof(buf));
printf(buf);
printf("\nAdr. init %p Adr. ret: %p", buf, adr);
double d_var;
printf("\nValoare double: ");
scanf_s("%lf", &d_var);
10
printf("\Valoarea double: %lf \n", d_var);
//versiune C++
cout << "\n C++ - Introduceti numele si prenumele studentului: ";
cin.ignore();
cin.getline(buf, sizeof(buf));
regex pattern(" ");
while (!regex_search(buf, pattern)) //verifica separare nume prenume cu spatiu
{
cout << "\nNu ati introdus corect, reintroduceti Nume Prenume !!";
cin.getline(buf, sizeof(buf));
}
cout << "\nIntrodu o valoare double: ";
cin >> d_var;
cout << "\n Studentul este: " << buf << "\t Valoarea double e: " <<
d_var << endl;
11
cout << "\nIntroduceti inca o data numele si prenumele
studentului (nu se valideaza spatiu intre nume si prenume): " <<
endl;
cin.ignore();
cin.getline(buf, sizeof(buf));
cout << "\nIntrodu inca o valoare double: ";
cin >> d_var;
cout << "\n Studentul este: " << buf << "\t Valoarea double e: " <<
d_var << endl;
cin.ignore();
cin.get();
}
12
3. FUNCŢII PENTRU ŞIRURI DE CARACTERE ŞI
AFIŞĂRI PE ECRAN
Din biblioteca <string.h>/<cstring>
strlen()
strcat()
strcmp()
strdup()
...
Pentru afișări pe ecran în mod text din <stdio.h>/<cstdio> ,
<conio.h>
textcolor() (Turbo C compiler)
textbackgroundcolor()
cprintf() (similar cu printf(), afiseaza doar la consola)
13
cputs() (similar cu puts(), fara trecere la rand nou)
4. FUNCŢII BAZATE PE CARACTER
Caracteristici (ctype.h>/cctype)
utilizate pentru
testarea caracterelor
conversia caracterelor
int main(void){
int loop;
char string[]="THIS IS A TEST";
//converteste caracter cu caracter la minuscula
for(loop=0;loop<strlen(string);loop++)
string[loop]=tolower(string[loop]);
printf("%s\n",string);
_getch();
return 0; 16
}
// Conversie caractere mici <-> mari fara biblioteci
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <conio.h>
unsigned to_upper(unsigned, unsigned);
int main(){
unsigned int mask_to_lower=0x20;
unsigned int mask_to_upper=0xDF;
char c;
printf("\nEnter a lower character: ");
fflush(stdin);
scanf("%c",&c);
printf("\nThe equivalent upper character is = %c ", 17
19
Initializare biblioteca grafica in vechile versiuni,
nefunctional in noile versiuni
#include<graphics.h>
#include<conio.h>
int main()
{
int gd = DETECT, gm;
21
22
23
FUNCŢII EXPONENŢIALE, LOGARITMICE ŞI
PUTERE
double exp(double x);
Returnează valoarea lui e ridicată la puterea x.
double frexp(double x, int* exponent);
Numărul real x este împărţit în mantisă şi exponent.
Valoarea de retur este mantisa şi la pointerul întreg exponent vom
avea exponentul.
Valoarea lui x =mantisa * 2^exponent.
Domeniu: mantisa în domeniul [0.5, 1), (dependent de standardul
folosit).
double modf(double x, double *integer);
Imparte numărul flotant x în componentele: întreg şi parte
fracţionară. Valoarea de retur este partea fracţionară (partea după
punct), şi pointerul integer va indica partea întreagă. 24
double log(double x);
Returnează logaritmul natural (logaritm în baza e) a lui x.
double log10(double x);
Returnează logaritm în baza 10 a lui x.
double pow(double x, double y);
Returnează x ridicat la puterea lui y. Domeniu:
x nu poate fi negativ dacă y e o valoare fracţionară.
x nu poate fi zero dacă y e mai mic sau egal cu zero.
double sqrt(double x);
Returnează radical din x.
Domeniu: Argumentul nu poate fi negativ. Valoarea de retur e
totdeauna pozitivă. Exista supraîncărcări pentru argumente float şi
la unele variante şi int.
25
ALTE FUNCŢII MATEMATICE
double ceil(double x);
Returnează valoarea primului întreg mai mic sau egal cu x.
double fabs(double x);
Returnează valoarea absolută a lui x (o valoare negativă
devine pozitivă, o valoare pozitivă e nemodificată).
double floor(double x);
Returnează valoarea primului întreg mai mare sau egal cu x.
double fmod(double x, double y);
Returnează restul împărţirii lui x la y.
Nu există un domeniu pentru valoarea de retur. Dacă y e
zero, atunci o eroare de domeniu va fi semnalizată, sau
funcţia va returna zero (depinde de implementare). 26
8. FUNCŢII PENTRU TIMP ŞI DATĂ
<time.h>/<ctime>
Header-ul de timp oferă mai multe funcţii utile pentru
citirea şi conversia timpului şi datei curente. Unele funcţii
sunt definite pentru un comportament local, dat de
setarea LC_TIME.
Variabile specifice:
• CLOCKS_PER_SEC e numărul de clock-uri pe
secundă ale procesor-ului (constantă macro)
• clock_t e un tip utilizat la memorarea timpului
procesor
• time_t e un tip utilizat la memorarea timpului de tip
calendar.
27
struct tm e o structură folosită pt a reţine datele de tip time şi date
cu următorii membrii:
int tm_sec; /*secunde (0 to 61) */
int tm_min; /*minute (0 to 59) */
int tm_hour; /*ore dupa miezul noptii (0 to 23) */
int tm_mday; /*ziua din luna(1 to 31) */
int tm_mon; /* luna incepand cu ianuarie (0 to 11) */
int tm_year; /* anul raportat la1900 */
int tm_wday; /* zi din saptamana (0 to 6 Sunday=0)*/
int tm_yday; /* zile incepand cu 1 Ianuarie 1 (0 to 365) */
int tm_isdst; /* Daylight Savings Time */
Dacă tm_isdst e zero, atunci Daylight Savings Time nu are efect. Dacă e o
valoare pozitivă, atunci Daylight Savings Time are efect. Dacă e negativ,
informaţia nu este disponibilă
tm_sec poate avea o valoare până la 61 pentru ajustarea orei în vederea
28
sincronizării cu mişcarea de rotaţie a Pământului
ALTE FUNCŢII:
char *asctime(const struct tm *timeptr);
Returnează un pointer la un şir de caractere care reprezintă ziua şi
timpul din structura tm indicată de timeptr. Şirul e în următorul format:
DDD MMM dd hh:mm:ss YYYY
DDD ziua din saptamană (Sun, Mon, Tue, Wed, Thu, Fri, Sat)
MMM Luna din an (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct,
Nov, Dec)
dd Ziua din luna (1,...,31)
hh Ora (0,...,23) mm Minutul (0,...,59) ss Secunda
(0,...,59) YYYY Anul
32
clock_t clock(void);
Returnează timpul procesorului folosit de la începutul implementării
(în mod normal de la începutul programului). Valoarea de return
împărţită la CLOCKS_PER_SEC ne va da numărul de secunde.
Dacă valoarea nu e disponibilă va returna -1.
33
EXEMPLU
#include<time.h>
#include<stdio.h>
#include <conio.h>
int main(void){
clock_t ticks1, ticks2;
ticks1=clock();
ticks2=ticks1;
while((ticks2/CLOCKS_PER_SEC-ticks1/CLOCKS_PER_SEC)<1)
ticks2=clock();
printf("Took %ld ticks to wait one second.\n",ticks2- ticks1);
printf("This value should be the same as CLOCKS_PER_SEC
which is %ld.\n",CLOCKS_PER_SEC);
_getch();
return 0; 34
}
9. ALTE FUNCŢII DE BIBLIOTECĂ
Sunt multe alte funcţii de bibliotecă şi compilatoarele noi
C++ consideră multe din funcţiile vechi de tip deprecated,
oferind alte funcţii cu semnătura diferită.
Funcţii prezentate în cursurile precedente şi la laboratoare:
qsort(), rand(), srand(), atoi(), strtod(), va_start(),…etc.
Alte funcţii:- pentru stabilirea domeniului valorilor
numerice, detecţie de erori, testare şi depanare, timp local,
interacţiuni cu SO, etc.
35
Reguli practice de
programare
36
37
1. PROIECTAREA PROGRAMELOR
d) Întreţinerea programului.
40
ÎNTOCMIREA DOCUMENTAŢIEI
Documentaţia va conţine următoarele piese:
- enunţul problemei;
- prezentarea în limbaj natural a metodei de rezolvare;
- lista variabilelor de intrare şi ieşire, a altor structuri de date
folosite
- prezentarea caracteristicilor metodelor folosite
- o organigramă dacă e posibil, care să descrie elementele
de bază ale aplicaţiei
- listingul programului sursă;
- rezultatele testării experimentale;
- instrucţiuni de operare
41
2. NUME DE FIŞIERE/PROIECTE
Numele proiectelor trebuie să sugereze scopul aplicaţiei
Fiecare fişier trebuie să aibă un nume sugestiv, care să
reprezinte conţinutul fişierului
Extensii ale fişierelor:
3. DIRECTIVE PREPROCESOR
Fişierele antet se includ începând cu cele mai specifice
(fişiere antet proprii, din directorul curent apoi din alte
directoare) şi terminând cu cele mai generale (fişiere antet
din biblioteca standard)
4. FUNCŢII
Funcţiile sunt elementele de bază ale programării C/C++
5. DOCUMENTAŢIE INTRODUCTIVĂ
//*********************************************************
// Program: Sortare
// Autor: Icsulescu
// Descriere: sortare prin selectie
// Data: 14.01.2019
// Nume fisier: sort.cpp
//*********************************************************
51
DOCUMENTAŢIE INTRODUCTIVĂ
Fiecare funcţie trebuie precedată de un bloc comentariu
ce descrie funcţia:
scop,
semnificația parametrilor,
de unde este apelată aceasta
//****************************************************
// Functie: CalcMediaAritm
// Scop: calculeaza media aritmetica
// Parametri: p – adresa elementelor
// n – numarul de elemente
// Apel: din main()
//****************************************************
52
6. DECLARAŢII
Pentru identificatori se vor utiliza nume ce au semnificaţie
în problema rezolvată prin program şi care sugerează
utilizarea identificatorului în program
excepţie: variabilele de ciclare
7. POINTERI
Se iniţializează cu NULL la declarare (dacă nu se face
alocare dinamică în momentul declarării)
Se atribuie valoarea NULL după eliberare (excepţie: la
încheierea blocului)
C++1y recomanda utilizarea nullptr
Se verifică existenţa unui pointer înainte de utilizare
Se vor evita expresiile complicate cu pointeri
Eliberaţi explicit zonele de memorie alocate atunci
când nu mai sunt necesare
56
8. OPERATORI
Folosiţi paranteze pentru a clarifica ordinea de
evaluare a operatorilor
Operatorii binari vor fi separaţi de operanzi prin spaţii
Operatorii unari se vor scrie direct lângă operanzi
Operatorii de adresare (&) şi indirectare (*) se vor scrie
în faţa variabilelor fără spaţii
Nu se vor folosi spaţii în jurul operatorilor de acces . şi
->
57
9. COMENTARII
Utilizarea judicioasă a comentariilor uşurează
depanarea, revizuirea şi intreţinerea programelor:
nu se utilizează comentarii pentru a repeta ceea ce
reiese clar din cod
se folosesc comentarii pentru a preciza scopul unei
secvenţe de cod ce urmează
în cele mai multe cazuri se folosesc comentarii pe
linii separate
se vor comenta obligatoriu soluţiile deosebite sau
facilităţi nedocumentate ale unui mediu de
programare
blocurile de comentarii se vor separa de cod prin cel
puţin o linie goală, pentru a se vedea mai uşor unde
începe şi unde se termină o zonă de cod
58
10. INSTRUCŢIUNI
Fiecare instrucţiune se va scrie pe o singură linie
Astfel în loc de:
left = nextLeft; right = nextRight;
se va utiliza:
left = nextLeft;
right = nextRight;
instructiune
{
corp
}
61
INSTRUCŢIUNI
if (expresie)
{
instrucţiuni
} // end if (expresie)
62
INSTRUCŢIUNI
Instrucţiuni if…else
cazul normal se va asocia cu ramura if și nu cu
ramura else
se vor evita instrucţiuni if-NULL: if(expresie);
Instrucţiuni switch
etichetele case se vor trece în ordinea cea mai
probabilă
acţiunile asociate vor fi simple
11. INTRĂRI/IEŞIRI
Pentru toate datele de intrare se vor folosi I/E cu ecou
(a.î. utilizatorul să vadă ce introduce)
- pentru in/out
- pentru lucrul cu caractere/ siruri de caractere
- pentru alocare dinamica
- functii matematice
- pentru timp si data
- etc.
Reguli de programare eficienta
65
66