Tema 3 · Condicionals, bucles, funcions
Introducció
Els programes han de prendre decisions i repetir accions. Amb condicionals (if, else, switch) controlem el flux segons condicions.
Els bucles (for, while) ens permeten repetir instruccions.
Les funcions agrupen codi reutilitzable, fent el programa més llegible i modular.
Objectius
- Utilitzar
if/elseiswitchper prendre decisions - Repetir tasques amb
for,whileido-while - Crear funcions amb paràmetres i valor de retorn
- Comprendre l'àmbit de les variables (local, global, static)
- Calcular la composició nucleotídica d'una seqüència d'ADN
1. Condicionals
Permeten executar diferents blocs de codi en funció d'una condició.
1.1 if / else if / else
Classificació d'una base nitrogenada:
#include <stdio.h>
int main() {
char base;
printf("Base (A, C, G, T): ");
scanf(" %c", &base);
if (base == 'A' || base == 'a')
printf("Adenina\n");
else if (base == 'C' || base == 'c')
printf("Citosina\n");
else if (base == 'G' || base == 'g')
printf("Guanina\n");
else if (base == 'T' || base == 't')
printf("Timina\n");
else
printf("Base no reconeguda\n");
return 0;
}
|| (OR) permet acceptar majúscules i minúscules
1.2 switch
Alternativa a múltiples if-else quan comparem una variable amb valors discrets:
#include <stdio.h>
int main() {
char base;
printf("Base (A, C, G, T): ");
scanf(" %c", &base);
switch (base) {
case 'A': case 'a': printf("Adenina\n"); break;
case 'C': case 'c': printf("Citosina\n"); break;
case 'G': case 'g': printf("Guanina\n"); break;
case 'T': case 't': printf("Timina\n"); break;
default: printf("Base no reconeguda\n");
}
return 0;
}
break evita que s'executin els casos següents
1.3 Operador ternari ? :
Forma compacta d'un if-else per assignar un valor:
int edat = 18;
char *tipus = (edat >= 18) ? "major d'edat" : "menor d'edat";
printf("%s\n", tipus);
2. Bucles
Permeten repetir un bloc de codi mentre es compleixi una condició.
2.1 for (iteració controlada per comptador)
Comptar bases en una seqüència d'ADN:
#include <stdio.h>
#include <string.h>
int main() {
char adn[] = "AGCTTAGGCTA";
int i, a = 0, c = 0, g = 0, t = 0;
for (i = 0; i < strlen(adn); i++) {
switch (adn[i]) {
case 'A': a++; break;
case 'C': c++; break;
case 'G': g++; break;
case 'T': t++; break;
}
}
printf("A: %d, C: %d, G: %d, T: %d\n", a, c, g, t);
return 0;
}
2.2 while (iteració condicional)
Llegir bases fins que l'usuari introdueixi '0':
#include <stdio.h>
int main() {
char base;
printf("Introdueix bases (0 per acabar):\n");
while (1) {
scanf(" %c", &base);
if (base == '0') break;
printf("Base rebuda: %c\n", base);
}
return 0;
}
break per sortir del bucle
2.3 do-while (s'executa almenys una vegada)
Menú interactiu que es mostra fins que l'usuari triï sortir:
#include <stdio.h>
int main() {
int opcio;
do {
printf("\n--- MENÚ ---\n");
printf("1. Opció A\n");
printf("2. Opció B\n");
printf("0. Sortir\n");
printf("Tria: ");
scanf("%d", &opcio);
switch (opcio) {
case 1: printf("Has triat A\n"); break;
case 2: printf("Has triat B\n"); break;
case 0: printf("Adeu!\n"); break;
default: printf("Opció no vàlida\n");
}
} while (opcio != 0);
return 0;
}
2.4 break i continue
// break: surt del bucle
// continue: salta la resta d'iteracions i va a la següent
for (int i = 0; i < 10; i++) {
if (i == 5) break; // s'atura a i=5
if (i % 2 == 0) continue; // salta els parells
printf("%d ", i); // només imparells (1,3)
}
3. Funcions
Les funcions encapsulen codi reutilitzable. Poden rebre paràmetres i retornar un valor.
3.1 Funció que retorna un valor
Percentatge d'una base en una seqüència:
#include <stdio.h>
#include <string.h>
float percentatge_base(const char adn[], char base) {
int i, compt = 0;
int len = strlen(adn);
for (i = 0; i < len; i++) {
if (adn[i] == base) compt++;
}
return (100.0 * compt) / len;
}
int main() {
char seq[] = "AGCTAGCT";
printf("%%A = %.2f\n", percentatge_base(seq, 'A'));
printf("%%G = %.2f\n", percentatge_base(seq, 'G'));
return 0;
}
3.2 Funció void (no retorna res)
Imprimeix un resum de la composició:
void mostrar_composicio(const char adn[]) {
int a=0, c=0, g=0, t=0, len = strlen(adn);
for (int i=0; i
3.3 Pas per referència (amb punters)
Modificar una variable externa des de la funció:
void incrementar(int *p) {
(*p)++; // incrementa el valor apuntat
}
int main() {
int x = 5;
incrementar(&x);
printf("%d\n", x); // 6
return 0;
}
& passa l'adreça; * accedeix al valor
4. Àmbit de variables
On és visible una variable?
#include <stdio.h>
int global = 10; // variable global (visible a tot el fitxer)
void funcio() {
static int estatica = 0; // conserva el valor entre crides
estatica++;
int local = 5; // només dins de la funció
printf("estatica: %d, local: %d\n", estatica, local);
}
int main() {
int local_main = 3; // local al main
printf("global: %d\n", global);
funcio();
funcio();
return 0;
}
- Local: declarada dins d'una funció; només accessible dins d'ella.
- Global: declarada fora de qualsevol funció; accessible des de qualsevol part.
- Estàtica (
static): local però manté el valor entre crides; útil per comptadors.
Exercicis
- Vocal o consonant: Programa que demani una lletra i digui si és vocal (incloent accents) o consonant, amb
if. - Suma fins a 0: Amb un bucle
while, llegeix enters fins que l'usuari introdueixi 0 i mostra la suma total. - Complementària: Crea una funció
char complementaria(char base)que retorni la base complementària (A↔T, C↔G). - Inversa complementària: Escriu una funció que, donada una cadena d'ADN, retorni la seva inversa complementària (ex: "ATGC" → "GCAT").
- Comptador de codons: Compta quants codons (triplets) hi ha en una seqüència d'ADN, ignorant els caràcters que no són A,C,G,T.
Mini Projecte – Calculadora de Composició Nucleotídica
Crea un programa que ofereixi un menú amb les següents opcions:
- 1. Introduir una seqüència d'ADN (màxim 100 caràcters).
- 2. Calcular el nombre i percentatge de cada base (A, C, G, T).
- 3. Calcular el contingut GC ((G+C)/total * 100).
- 4. Mostrar la seqüència complementària inversa.
- 0. Sortir.
Utilitza funcions per a cada càlcul i manté la seqüència en una variable global o estàtica.
Exemple de sortida:
Seqüència: AGCTAGCT A: 2 (25.0%) C: 2 (25.0%) G: 2 (25.0%) T: 2 (25.0%) Contingut GC: 50.0% Complementària inversa: AGCTAGCT → GCTAGCTA