C/C++

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/else i switch per prendre decisions
  • Repetir tasques amb for, while i do-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;
}
L'operador || (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;
}
El 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;
}
Utilitzem 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;
}
El & 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

  1. Vocal o consonant: Programa que demani una lletra i digui si és vocal (incloent accents) o consonant, amb if.
  2. Suma fins a 0: Amb un bucle while, llegeix enters fins que l'usuari introdueixi 0 i mostra la suma total.
  3. Complementària: Crea una funció char complementaria(char base) que retorni la base complementària (A↔T, C↔G).
  4. Inversa complementària: Escriu una funció que, donada una cadena d'ADN, retorni la seva inversa complementària (ex: "ATGC" → "GCAT").
  5. 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
Programació Aplicada a les Ciències Biomèdiques · Tema 3