A la lliçó anterior vas aprendre que el teu programa prengui decisions amb if/else, però aquestes decisions s'avaluaven una sola vegada. A BiblioTechConsola, però, gairebé cap tasca real consisteix a mirar una única dada: cal recórrer tot el catàleg de llibres per mostrar-lo, comptar quants exemplars estan disponibles, o buscar-ne un pel títol fins a trobar-lo (o comprovar que no existeix). Repetir una acció un nombre determinat o indeterminat de vegades és la feina dels bucles. En aquesta lliçó coneixeràs les quatre formes de bucle que ofereix C# —for, while, do-while i foreach— i aprendràs a controlar-los amb break i continue.

Contingut

  1. El bucle for
  2. El bucle while
  3. El bucle do-while
  4. El bucle foreach
  5. Comparativa: quan usar cada un
  6. break i continue
  7. Bucles imbricats
  8. Aplicació completa: llistar, comptar i buscar al catàleg

  1. El bucle for

El bucle for és ideal quan saps per endavant (o pots calcular) quantes vegades s'ha de repetir una acció, típicament perquè recorres una col·lecció per índex.

string[] titolsLlibres = { "Cent anys de solitud", "Rayuela", "Ficcions", "El Aleph" };

for (int i = 0; i < titolsLlibres.Length; i++)
{
    Console.WriteLine($"{i + 1}) {titolsLlibres[i]}");
}

La capçalera del for té tres parts separades per ;:

Part Exemple Quan s'executa
Inicialització int i = 0 Una sola vegada, abans de començar
Condició i < titolsLlibres.Length Abans de cada iteració; si és false, el bucle acaba
Increment (o actualització) i++ Després de cada iteració

Fer servir titolsLlibres.Length a la condició, en lloc d'un número fix com 4, evita que el bucle deixi de funcionar (o falli) si l'array canvia de mida més endavant.

També es pot recórrer en sentit invers, cosa útil quan es van a eliminar elements d'una col·lecció mentre es recorre (tema que s'ampliarà amb List<T> al Mòdul 4):

for (int i = titolsLlibres.Length - 1; i >= 0; i--)
{
    Console.WriteLine(titolsLlibres[i]);
}

  1. El bucle while

while repeteix un bloc mentre una condició sigui true, avaluant-la abans de cada iteració. És l'opció natural quan no se sap per endavant quantes vegades caldrà repetir l'acció.

int index = 0;
int llibresDisponibles = 0;
bool[] disponibilitat = { true, false, true, true };

while (index < disponibilitat.Length)
{
    if (disponibilitat[index])
    {
        llibresDisponibles++;
    }

    index++;
}

Console.WriteLine($"Llibres disponibles: {llibresDisponibles}");

Un cas típic de while és esperar una entrada vàlida de l'usuari, on no se sap quants intents caldran:

string? entrada = null;
int paginesLlibre = 0;
bool entradaValida = false;

while (!entradaValida)
{
    Console.Write("Introdueix el nombre de pagines del llibre: ");
    entrada = Console.ReadLine();
    entradaValida = int.TryParse(entrada, out paginesLlibre);

    if (!entradaValida)
    {
        Console.WriteLine("Entrada no valida, torna-ho a intentar.");
    }
}

Console.WriteLine($"Nombre de pagines registrat: {paginesLlibre}");

Compte: si la condició d'un while mai no arriba a ser false, el bucle s'executa per sempre (un bucle infinit). Sempre ha d'existir, dins del bloc, alguna instrucció que apropi la condició al seu final (en el primer exemple, index++).

  1. El bucle do-while

do-while és gairebé idèntic a while, amb una diferència clau: la condició s'avalua després d'executar el bloc, així que el bloc s'executa sempre almenys una vegada, fins i tot si la condició ja era false des del principi.

int intents = 0;
bool prestecRegistrat = false;

do
{
    intents++;
    Console.WriteLine($"Intent numero {intents} de registrar el prestec...");

    // Simulem que el registre te exit al segon intent
    prestecRegistrat = intents >= 2;

} while (!prestecRegistrat);

Console.WriteLine("Prestec registrat correctament.");

Fixa't en la sintaxi: la paraula while i la seva condició van després de la clau de tancament, i la línia acaba amb ;. Aquest patró encaixa bé amb menús interactius, on el menú s'ha de mostrar almenys una vegada abans de comprovar si l'usuari vol sortir.

  1. El bucle foreach

foreach recorre tots els elements d'una col·lecció (un array, o qualsevol tipus que sigui "iterable", com veuràs amb més detall al Mòdul 4 amb les col·leccions), sense necessitat de gestionar manualment un índex ni una condició d'aturada.

string[] titolsLlibres = { "Cent anys de solitud", "Rayuela", "Ficcions", "El Aleph" };

foreach (string titol in titolsLlibres)
{
    Console.WriteLine(titol);
}

foreach és més llegible que for quan no necessites l'índex, però té una limitació important: la variable d'iteració (titol en l'exemple) és de només lectura dins del bucle; no pots fer servir foreach per modificar els elements de l'array directament a través d'ella.

int[] copiesDisponibles = { 2, 0, 1, 3 };

// foreach (int copies in copiesDisponibles)
// {
//     copies++; // Error de compilacio: no es pot assignar a la variable de iteracio
// }

// Si necessites modificar aquest array, fes servir for amb index:
for (int i = 0; i < copiesDisponibles.Length; i++)
{
    copiesDisponibles[i]++;
}

  1. Comparativa: quan usar cada un

Bucle S'utilitza quan... Avalua la condició...
for Saps (o pots calcular) el nombre d'iteracions, o necessites l'índex Abans de cada iteració
while No saps quantes iteracions faran falta, i podria ser zero Abans de cada iteració
do-while Com while, però el bloc s'ha d'executar almenys una vegada Després de cada iteració
foreach Només necessites recórrer tots els elements, sense índex ni modificar-los Abans de cada iteració (de forma interna)

A la pràctica, for i foreach cobreixen la immensa majoria dels recorreguts sobre arrays i col·leccions a BiblioTechConsola; while i do-while es reserven per a situacions on la condició d'aturada depèn d'alguna cosa diferent de "recórrer una col·lecció completa", com validar una entrada d'usuari o esperar que es compleixi una condició externa.

  1. break i continue

Dins de qualsevol bucle, dues paraules clau permeten alterar el flux normal d'iteració:

  • break: acaba el bucle immediatament, sense avaluar més iteracions.
  • continue: salta la resta del cos del bucle en la iteració actual i passa directament a la següent.
string[] titolsLlibres = { "Cent anys de solitud", "Rayuela", "Ficcions", "El Aleph" };
string titolBuscat = "Ficcions";

for (int i = 0; i < titolsLlibres.Length; i++)
{
    if (titolsLlibres[i] == titolBuscat)
    {
        Console.WriteLine($"Trobat a la posicio {i}.");
        break; // ja no cal seguir recorrent aquest array
    }
}
bool[] disponibilitat = { true, false, true, true, false };

for (int i = 0; i < disponibilitat.Length; i++)
{
    if (!disponibilitat[i])
    {
        continue; // saltem els llibres no disponibles
    }

    Console.WriteLine($"Llibre a la posicio {i}: disponible");
}

break també funciona dins de while, do-while i foreach; continue, igualment.

  1. Bucles imbricats

Un bucle pot contenir un altre bucle al seu interior. Això és habitual quan es treballa amb arrays de dues dimensions (que ja vas veure a la lliçó d'arrays), per exemple, per representar un mapa de prestatgeries i lleixes a BiblioTech:

string[,] mapaPrestatgeries = new string[2, 3]
{
    { "Narrativa", "Narrativa", "Assaig" },
    { "Poesia", "Infantil", "Infantil" }
};

for (int prestatgeria = 0; prestatgeria < 2; prestatgeria++)
{
    for (int lleixa = 0; lleixa < 3; lleixa++)
    {
        Console.WriteLine($"Prestatgeria {prestatgeria}, lleixa {lleixa}: {mapaPrestatgeries[prestatgeria, lleixa]}");
    }
}

El bucle exterior recorre les prestatgeries; per cada prestatgeria, el bucle interior recorre les seves lleixes. En total s'executen 2 × 3 = 6 iteracions. Tingues en compte que break i continue només afecten el bucle més intern en què es troben; si necessites sortir d'ambdós bucles alhora, una tècnica senzilla és fer servir una variable booleana com a bandera:

bool trobat = false;

for (int prestatgeria = 0; prestatgeria < 2 && !trobat; prestatgeria++)
{
    for (int lleixa = 0; lleixa < 3; lleixa++)
    {
        if (mapaPrestatgeries[prestatgeria, lleixa] == "Assaig")
        {
            Console.WriteLine($"Genere trobat a prestatgeria {prestatgeria}, lleixa {lleixa}");
            trobat = true;
            break;
        }
    }
}

  1. Aplicació completa: llistar, comptar i buscar al catàleg

Combinem tot l'anterior en tres operacions típiques sobre el catàleg de BiblioTechConsola: llistar els títols, comptar quants n'hi ha de disponibles i buscar-ne un pel títol.

string[] titolsLlibres = { "Cent anys de solitud", "Rayuela", "Ficcions", "El Aleph", "Pedro Paramo" };
bool[] disponibilitat = { true, false, true, true, false };

// 1) Llistar tots els titols amb el seu estat (foreach no serveix aqui perque cal saber la posicio)
Console.WriteLine("=== Cataleg BiblioTech ===");
for (int i = 0; i < titolsLlibres.Length; i++)
{
    string estat = disponibilitat[i] ? "Disponible" : "Prestat";
    Console.WriteLine($"{i + 1}) {titolsLlibres[i]} - {estat}");
}

// 2) Comptar quants llibres estan disponibles (foreach: no cal la posicio)
int totalDisponibles = 0;
foreach (bool estaDisponible in disponibilitat)
{
    if (estaDisponible)
    {
        totalDisponibles++;
    }
}
Console.WriteLine($"Total de llibres disponibles: {totalDisponibles}");

// 3) Buscar un titol concret i aturar-se en trobar-lo
string titolBuscat = "Ficcions";
bool trobat = false;

for (int i = 0; i < titolsLlibres.Length; i++)
{
    if (titolsLlibres[i] == titolBuscat)
    {
        Console.WriteLine($"'{titolBuscat}' trobat a la posicio {i + 1}, disponible: {disponibilitat[i]}");
        trobat = true;
        break;
    }
}

if (!trobat)
{
    Console.WriteLine($"'{titolBuscat}' no es troba al cataleg.");
}

Aquest fragment ja combina un for (quan l'índex importa), un foreach (quan només importa el valor), i break (per aturar una cerca en trobar el resultat): tres decisions deliberades, no arbitràries.

Errors Comuns i Consells

  • Bucles infinits: oblidar actualitzar la variable de control en un while (per exemple, no incrementar l'índex) deixa el programa penjat per sempre. Revisa sempre que la condició pugui arribar a ser false.
  • Desbordar l'índex d'un array: en un for, fer servir <= en lloc de < contra array.Length provoca accedir a una posició que no existeix i llança una excepció en temps d'execució (ho veuràs en detall a l'última lliçó del mòdul).
  • Intentar modificar la variable de foreach: com s'ha vist, no compila. Si necessites modificar els elements, fes servir for amb índex.
  • Fer servir for quan foreach és més clar (i viceversa): si no necessites l'índex, prefereix foreach; millora la llegibilitat i redueix el risc d'errors d'índex.
  • Confondre break amb continue: break surt del bucle sencer; continue només salta a la iteració següent. Un ús equivocat sol produir resultats incomplets o bucles que acaben abans d'hora.
  • Imbricar bucles sense necessitat: abans d'imbricar dos bucles, comprova si el problema es pot resoldre amb un únic recorregut; la imbricació multiplica el nombre d'iteracions (i el temps d'execució) i afegeix complexitat.

Exercicis

  1. Donat l'array int[] copiesDisponibles = { 3, 0, 5, 2, 0 };, fes servir un bucle for per recórrer-lo i mostrar per consola quantes posicions tenen 0 còpies disponibles (llibres exhaurits).

  2. Fes servir un bucle while per simular la validació d'una contrasenya d'administrador: parteix de string intent = ""; i d'una llista simulada d'intents vàlids string[] intentsSimulats = { "1234", "abcd", "bibliotech" }; (recorre aquest array amb un índex creixent a cada volta del while, com si fossin intents successius de l'usuari). El bucle ha d'acabar en el moment que intent sigui igual a "bibliotech", mostrant quants intents han fet falta.

  3. Donat l'array de títols string[] titolsLlibres = { "Cent anys de solitud", "Rayuela", "Ficcions", "El Aleph" };, recorre l'array amb foreach i, fent servir continue, mostra per consola únicament els títols que tinguin més de 8 caràcters.

Solucions

int[] copiesDisponibles = { 3, 0, 5, 2, 0 };
int llibresExhaurits = 0;

for (int i = 0; i < copiesDisponibles.Length; i++)
{
    if (copiesDisponibles[i] == 0)
    {
        llibresExhaurits++;
    }
}

Console.WriteLine($"Llibres exhaurits: {llibresExhaurits}");

El resultat és 2, corresponent a les posicions 1 i 4 (índexs començant en 0).

string[] intentsSimulats = { "1234", "abcd", "bibliotech" };
string intent = "";
int index = 0;
int nombreIntents = 0;

while (intent != "bibliotech")
{
    intent = intentsSimulats[index];
    nombreIntents++;
    index++;
}

Console.WriteLine($"Contrasenya correcta trobada despres de {nombreIntents} intent(s).");

El resultat mostra 3 intents, perquè "bibliotech" ocupa la tercera posició de l'array simulat (índex 2). Fixa't que la condició del while s'avalua abans de cada volta, així que l'última comprovació (intent != "bibliotech", ja false) és la que atura el bucle sense executar una volta de més.

string[] titolsLlibres = { "Cent anys de solitud", "Rayuela", "Ficcions", "El Aleph" };

foreach (string titol in titolsLlibres)
{
    if (titol.Length <= 8)
    {
        continue;
    }

    Console.WriteLine(titol);
}

Es mostra únicament "Cent anys de solitud" (20 caràcters). La resta de títols — "Rayuela" (7 caràcters), "Ficcions" (8 caràcters) i "El Aleph" (8 caràcters)— tenen una longitud igual o menor que 8, així que el continue salta les seves iteracions sense mostrar res. És un bon exercici per comprovar amb Console.WriteLine(titol.Length) com canvia el resultat si fas servir < en lloc de <=: amb <, tant "Ficcions" com "El Aleph" (exactament 8 caràcters) deixarien de saltar-se i es mostrarien, ja que 8 < 8 és false.

Conclusió

En aquesta lliçó has après a repetir accions amb for, while i do-while, a recórrer col·leccions de manera senzilla amb foreach, a controlar el flux d'un bucle amb break i continue, i a combinar bucles imbricats quan les dades tenen més d'una dimensió. Amb aquestes eines, BiblioTechConsola ja pot llistar el seu catàleg complet, comptar llibres disponibles i buscar títols concrets sense repetir codi a mà.

Fins ara, per classificar alguna cosa (com l'estat d'un préstec) has fet servir cadenes de if/else if/else. A la lliçó següent, Sentències Switch, coneixeràs una alternativa més clara quan cal comparar una mateixa variable contra molts valors possibles, per exemple, per classificar un llibre segons la seva categoria o gènere dins de BiblioTech.

Curs de Programació en C#

Mòdul 1: Introducció al C#

Mòdul 2: Estructures de Control

Mòdul 3: Programació Orientada a Objectes

Mòdul 4: Conceptes Avançats de C#

Mòdul 5: Treballant amb Dades

Mòdul 6: Temes Avançats

Mòdul 7: Construcció d'Aplicacions

Mòdul 8: Bones Pràctiques i Patrons de Disseny

Mòdul 9: Projecte Final

© Copyright 2026. Tots els drets reservats