Estructura d'un programa
Les parts d'un programa en C++: els includes, el main, com llegeix les dades, les funcions i com escriu el resultat.
Conceptes clau
#includeiusing namespace std;- Llegir amb
cin >>,while (cin >> x),getlineistringstream - Funcions: retornen un valor o res (
void) - Paràmetres per valor, per referència (
&) iconst& - Escriure amb
cout << structper crear un tipus nou
L’esquelet
Gairebé tots els programes de PRO2 tenen aquestes parts, en aquest ordre:
main llegeix les dades, crida les funcions i escriu el resultat.Cada part s’explica a sota.
Includes
#include <biblioteca>
using namespace std;
Una biblioteca és codi que ja ve fet: llegir i escriure, vectors, textos, ordenar…
Quan el teu programa fa servir alguna cosa d’una biblioteca, n’has de posar l’#include a dalt de tot.
Si no, el compilador no la coneix i dona error.
- Si llegeixes amb
cino escrius ambcout, cal#include <iostream>. - Si fas servir un
vector, cal#include <vector>.
using namespace std; t’estalvia escriure std:: davant de tot el que ve de les biblioteques: cout en lloc de std::cout.
| Biblioteca | Quan la poses |
|---|---|
<iostream> |
Sempre que llegeixes o escrius. |
<vector> |
Quan fas servir vectors. |
<string> |
Quan fas servir textos (string) o getline. |
<sstream> |
Quan trenques una línia amb stringstream. |
<cmath> |
Quan calcules arrels, potències… (sqrt, pow). |
<algorithm> |
Quan ordenes (sort) o busques màxims i mínims (max, min). |
<stack> |
Quan fas servir piles (stack). |
<queue> |
Quan fas servir cues (queue). |
<list> |
Quan fas servir llistes (list). |
<map> |
Quan fas servir diccionaris (map). |
<set> |
Quan fas servir conjunts (set). |
Les piles, les cues, les llistes, els diccionaris i els conjunts els veuràs a fons al tema 2.
Alerta: si el compilador diu 'cout' was not declared in this scope, t’has oblidat l’#include o el using namespace std;.
Llegir dades
El programa comença al main, i normalment el primer que fa és llegir les dades.
Es llegeixen amb cin:
cin >> <variable>;
cin >> llegeix un valor del tipus de la variable i salta els espais i els salts de línia que hi hagi abans.
Amb un string, llegeix una paraula.
Si no saps quantes dades hi ha, llegeix fins que s’acabin:
while (cin >> <variable>) {
<instruccions>
}
Per llegir una línia sencera, amb els espais, fes servir getline.
Després, amb un stringstream, pots llegir aquesta línia com si fos un cin:
string linia;
while (getline(cin, linia)) { // llegeix una línia sencera
stringstream ss(linia); // la llegeix com si fos un cin
int x;
while (ss >> x) { // cada nombre de la línia
<instruccions>
}
}
Alerta: després d’un cin >>, el salt de línia encara hi és. Si just després fas un getline, llegeix una línia buida. Posa cin.ignore(1000, '\n'); entre els dos.
Funcions
<tipus> <nom>(<paràmetres>) {
<instruccions>
return <valor>;
}
Una funció pot retornar un valor, del <tipus> que diu la capçalera, o no retornar res.
Si no retorna res, el tipus és void i no porta return <valor>.
Una funció s’ha de declarar abans de cridar-la.
Per això les funcions s’escriuen a sobre del main.
Els paràmetres
| Forma | Què passa |
|---|---|
<tipus> <nom> |
Per valor: la funció rep una còpia. Si la canvia, l’original no canvia. |
<tipus>& <nom> |
Per referència: no es copia res. La funció treballa amb l’original, i si el canvia, el canvi es veu fora. |
const <tipus>& <nom> |
No es copia res, però la funció no el pot canviar. |
f(x, y): a és una còpia de x, i canviar-la no toca x. b no té caixa pròpia: és un altre nom per a y.Copiar un vector o un string gran és lent.
Si la funció només els ha de llegir, passa’ls per const&.
Imprimir dades
cout << <valor> << <valor> << endl;
Encadenes els valors amb <<.
endl fa un salt de línia.
Structs
Un struct crea un tipus nou que agrupa diverses dades:
struct <Nom> {
<tipus> <camp>;
<tipus> <camp>;
};
A cada camp hi accedeixes amb el punt: <variable>.<camp>.
- Un alumne amb el nom i la nota:
struct Alumne {
string nom;
double nota;
};
Alumne a;
a.nom = "anna"; // canvia el camp nom de a
a.nota = 7.5; // canvia el camp nota de a
cout << a.nom << ": " << a.nota << endl; // escriu «anna: 7.5»
Al tema 1 veuràs les classes, que són com un struct amb operacions.
Un programa sencer
Llegeix noms i notes fins al final, i escriu la mitjana i qui la iguala o la supera:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
struct Alumne {
string nom;
double nota;
};
// Retorna la nota mitjana dels alumnes de v (v no pot ser buit)
double mitjana(const vector<Alumne>& v) {
double suma = 0;
for (int i = 0; i < v.size(); ++i) suma += v[i].nota;
return suma / v.size();
}
int main() {
// Llegir dades
vector<Alumne> classe;
Alumne a;
while (cin >> a.nom >> a.nota) classe.push_back(a);
// Crida a la funció
double m = mitjana(classe);
// Imprimir dades
cout << "Mitjana: " << m << endl;
for (int i = 0; i < classe.size(); ++i) {
if (classe[i].nota >= m) cout << classe[i].nom << endl;
}
}