Salta al contingut
Llegat fiber

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

  • #include i using namespace std;
  • Llegir amb cin >>, while (cin >> x), getline i stringstream
  • Funcions: retornen un valor o res (void)
  • Paràmetres per valor, per referència (&) i const&
  • Escriure amb cout <<
  • struct per crear un tipus nou

L’esquelet

Gairebé tots els programes de PRO2 tenen aquestes parts, en aquest ordre:

#include <…>Includes<tipus> <nom>(…)Funcionsint main()Maincin >> …1. Llegir dades<nom>(…)2. Crides a funcionscout << …3. Imprimir dades
Les parts d'un programa, de dalt a baix. El 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 cin o escrius amb cout, 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.
mainfx5y6a6b
Després de 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;
    }
}