Enrere Mòdul 3
Fonaments de Programació. Llenguatge C/C++---
Pràctica  Exercicis
Pràctica d'ampliació

 

Resum Teòric

Les bifurcacions

En principi, les sentències d'un programa C/C++ s'executen seqüencialment, és a dir, una a continuació de l'altra. Un programa amb estructura seqüencial se sol representar gràficament de la següent forma:

En els programes seqüencials les accions:

  • s'executen totes
  • s'executa cada una només una vegada
  • s'executen en el mateix ordre en què han estat escrites

En la majoria de programes necessitarem que els programes executin o no una o més accions, depenent que es compleixi o no una condició. Això s'aconsegueix amb les sentències condicionals o bifurcacions.

 

La sentència if...else

Les sentències condicionals més simples de C/C++ són: la sentència if i la sentència if...else que tenen la següent sintaxi:

 if (<condició>) <sentència>

if (<condició>) <sentència1> else <sentència2>

En el primer cas, la condició, que és una expressió lògica (recordeu que en C/C++, les expressions lògiques són de fet expressions numèriques) és avaluada. Si aquesta té el valor de veritat (valor diferent de 0) s'executa la sentència, en cas contrari, és a dir, si el valor de la condició és fals (igual a 0), se salta l'execució de la sentència (o bloc) que hi ha a continuació i passa a la sentència immediatament posterior.

En el segon cas, una vegada avaluada la condició, si aquesta és veritat s'executa la sentència1, i a continuació se salta la sentència2 per executar la sentència immediatament posterior a la sentència2. Si la condició és falsa se salta la sentència 1 i passa directament a la sentència 2.

La representació gràfica d'aquestes dues sentències és:

Les sentències poden ser, evidentment, sentències simples (acabades en punt i coma) o blocs de sentències (tancades entre claus).

Les seqüències condicionals es poden encaixar donant lloc a estructures condicionals complexes com:

 

En el cas de tenir més d'una seqüència if, una "dintre" de l'altra, cada else es refereix al if més proper.

La sentència if...else permet una ramificació múltiple, executant una entre diferents parts del programa segons una entre diferents condicions. La forma general d'aquesta estructura és:

if (<expressió1>)

     sentència1;

else if (<expressió2>)

     sentència2;

else if (<expressió3>)

     sentència3;

...

else

     sentència_n;

 

L'operador ternari ?

Moltes vegades es pot substituir una sentència condicional if...else per l'operador ternari ?...:. La seva sintaxi és:

<expr1> ? <expr2>: <expr3>

El valor d'aquesta expressió és <expr2> en el cas que <expr1> sigui veritat (diferent de 0) o bé <expr3> si <expr1>=0.

Es diu operador ternari precisament perquè té tres operants. La diferència principal entre l'ús de l'operador ternari ? i la sentència if...else, és que els operants d'aquest operador han de ser expressions i no sentències. 

Exemple:

y=x ? 100 : 200;

En aquest exemple, s'assignarà el valor de l'expressió (x ? 100 : 200) a la variable y. L'operador ? té prioritat respecte l'operador d'assignació =:

 

La sentència switch

C/C++ incorpora una sentència de bifurcació múltiple que és més elegant i fàcil de llegir que moltes sentències if juntes, es tracta de la sentència switch i té la següent sintaxi:

switch (<variable>){

case <constante1>):

<sentència1>

break;

case <constante2>):

<sentència2>

break;

...

default:

<sentència>

}

Quan es troba aquesta sentència, és avaluada la variable que acompanya a la paraula switch. Aquesta variable ha de ser de caràcter, entera, o bé altre tipus que pugui ser convertida a entera sense ambigüitat. Aquesta variable és comparada amb les expressions constants que acompanyen a les etiquetes case, si coincideix amb alguna d'aquestes constants, se segueix executant a partir de la sentència que es troba a continuació d'aquesta constant. En cas de no coincidir cap de les constants, s'executa a partir de la sentència que es troba a continuació de l'etiqueta default, si és que aquesta existeix, si no és així, segueix l'execució en la sentència que es trobi a continuació del bloc de sentència switch.

Quan s'ha trobat una coincidència, el codi se segueix executant fins a trobar una sentència de salt break. Aquesta sentència fa que l'execució salti incondicionalment fins al final del bloc de sentència switch. La sentència break és tècnicament opcional, si s'omet, l'execució continuarà ignorant altres etiquetes i executant les sentències associades a aquestes altres etiquetes. Això pot ser una tècnica de programació correcta en C/C++. 

Freqüentment, la sentència switch es fa servir per processar ordres del teclat com els menús

Igual que passa amb la sentència if...else, les sentències swicht també es poden encaixar creant estructures condicionals complicades. El diagrama d'una sentència swicht és: 

 

Les estructures repetitives o bucles

Les estructures repetitives o iteratives, també anomenades bucles, són també un element essencial de gairebé tots els llenguatges informàtics. Les sentències de repetició que suporta C/C++ són:  while,  do...while i for.

La sentència while

Aquesta sentència permet executar repetidament una sentència simple o grup de sentències mentre es compleix una determinada condició. La seva sintaxi és:

while (<expressió_condició>)
     sentència_bucle;

El funcionament d'aquesta sentència és el següent: en primer lloc s'avalua l'expressió que acompanya la paraula while i que es troba entre parèntesi. Si aquesta expressió dóna un resultat fals surt del bucle, és a dir, s'executa la sentència que hi ha a continuació de sentència_bucle. Si el valor de l'expressió és vertader, s'executa sentència_bucle i es torna a avaluar expressió_condició. El resultat és, per tant, que la sentència_bucle s'executa repetidament fins que expressió_condició sigui falsa. 

S'ha de tenir en compte que la condició s'avalua abans d'entrar en el bucle, per tant, si la primera vegada que s'avalua l'expressió de condició, aquesta és falsa, no s'arriba a entrar en el bucle mai.

En el següent exemple, el bucle consisteix en l'assignació a la variable car d'un caràcter llegit del teclat. El bucle s'executa sempre que aquest caràcter no sigui el caràcter amb codi ASCII=27, que correspon a la tecla ESC.

char car;
car='\0';
while (car!= 27) car = getch();

 

La sentència do...while

Aquesta sentència és similar a l'anterior amb la diferència que la condició es comprova després d'entrar en el bucle, per tant, el cos del bucle s'executa almenys una vegada. La seva sintaxi és:

do{
      sentència;
}while (<expressió_condició>);

Les claus no són necessàries si la sentència del bucle és una sentència simple, no obstant, és pot posar per claredat del codi.

En el següent exemple es llegeix números fins que es premi un 0.

int n;
do{
     scanf("%d",&n);
}while(n!=0);

 

El bucle for

La sentència for és la forma més versàtil de generar una seqüència iterativa. La seva sintaxi és:

for (<inicialització>;<condició>;<increment>) sentència;

Aquesta sentència és equivalent a la següent construcció:

<inicialització>;
while (<condició>){
      sentència;
      <actualització>
;
}

Abans d'iniciar-se el bucle s'executa inicialització, que normalment s'utilitza per assignar valors inicials a variables de control o comptadors.  La condició és una expressió que normalment comprova la variable de control per determinar si ha de sortir o no del bucle. L'increment defineix la forma de canviar la variable de control en cada execució del bucle. Aquestes tres parts s'han de separar amb punt i coma (;). El bucle continuarà fins que la condició sigui falsa.

L'ús més comú d'aquesta sentència és l'execució d'un bucle un nombre determinat de vegades, per exemple:

for (int x=1;x<=100;x++) printf("%d ",x);

En aquest exemple s'ha fet servir la part d'inicialització per declarar una variable entera que servirà de comptador (declarar variables dintre d'aquesta part de la sentència for és una característica pròpia de C++ i no és compatible amb C, on totes les variables s'han de declarar al començament).

Aquesta variable comptador és inicialitzada a 1. Cada vegada que s'executi el bucle, que en         aquest cas consisteix només en la crida a la funció printf(), el valor de la variable és incrementat en una unitat (x++) i es comprova si es compleix la condició. El bucle deixarà d'executar-se quan x sigui  101, per tant, la sortida d'aquest programa serà la impressió dels números de l'1 al 100.

L'operador coma

L'operador coma (,) avalua dues expressions en llocs on la sintaxi només ens en permet una. El valor de l'operador és el valor de l'expressió que apareix a la dreta de l'operador. El format de l'expressió es:

expressió_esquerra , expressió_dreta

Normalment aquest operador es fa servir en alguna de les parts dels bucles for, quan es fa servir més d'una variable de control. Per exemple:

for (i=0,j=0;i<maxi, j<maxj;i++, j++){

 

Les sentències break i continue

La sentència break, a més utilitzar-se amb la sentència switch  com acabament d'un cas (case) es pot fer servir dintre d'un bucle per forçar el fi immediat d'aquest, saltant la prova condicional. Quan es troba una sentència break el control d'execució torna a la sentència següent al bucle.

Exemple:

ct=0;
while (ct<100){
   if (a[ct]==1253) {
             printf("trobat");
       break;
   }
   ct++;
}

En aquest exemple es comprova en un vector de 100 components si conté la dada 1253. Una vegada trobat surt del bucle.

 

La sentència continue fa que se salti qualsevol codi i força una nova iteració del bucle.

Exemple:

for(ct=0;ct<100;ct++){
    if(ct%3) continue;
    printf("el número %d és múltiple de 3\n",ct);

}

En aquest exemple, si la variable ct és múltiple de 3, ct%3 és 0 (fals) i per tant es visualitzarà el missatge: "el número ... és múltiple de 3". En cas que ct%3 no sigui 0 (veritat) no es visualitzarà el missatge i es tornarà a entrar en el bucle. 

 

La sentència goto

La sentència goto fa un salt incondicional a una part del programa determinada. La seva sintaxi és la següent:

goto etiqueta;

En algun lloc de la mateixa funció ha d'existir una etiqueta amb el mateix nom. Una etiqueta és un identificador vàlid de C que acaba en dos punts. Per exemple:

    if (codi==0) goto error;
    printf("No ha hagut error\n");

    .........

error:
    printf("Ha hagut un error\n");

La sentència goto és una sentència que s'ha d'evitar sempre que es pugui. Normalment fa que el codi sigui més difícil de llegir. Només és recomanable usar-la per sortir d'una estructura complicada de bucles i condicionals en una situació especial.

 

--- ---