Curso de C · Módulo 6 de 12

Arrays y cadenas de texto en C

Qué aprenderás en este módulo

manejar colecciones de datos y texto.

Incluye 5 ejercicios con pistas y solución y un quiz de 6 preguntas. Tiempo estimado: 80 minutos.

1. Arrays

Un array es una secuencia contigua de elementos del mismo tipo.

int notas[5];                      // 5 enteros SIN inicializar
int primos[] = {2, 3, 5, 7, 11};   // tamaño deducido: 5
int ceros[10] = {0};               // todo a 0

notas[0] = 8;                      // los índices van de 0 a n-1
printf("%d\n", primos[4]);         // 11

⚠️ C no comprueba límites. notas[5] o notas[-1] compilan y pueden corromper memoria o crashear (comportamiento indefinido). Tú vigilas los índices.

Recorrer:

int n = sizeof primos / sizeof primos[0];   // nº de elementos (solo donde el array es visible como array)
for (int i = 0; i < n; i++) printf("%d ", primos[i]);

Arrays y funciones

Al pasar un array a una función se pasa la dirección del primer elemento; la función no conoce su tamaño, hay que pasarlo aparte y puede modificar el original:

void duplicar(int v[], int n) {        // equivale a int *v
    for (int i = 0; i < n; i++) v[i] *= 2;
}

Arrays 2D

int m[3][4];            // 3 filas, 4 columnas
m[1][2] = 7;

2. Cadenas de texto

En C no existe el tipo cadena: una cadena es un char[] terminado en el carácter nulo '\0'.

char s[] = "hola";     // ocupa 5 bytes: 'h' 'o' 'l' 'a' '\0'
char t[20] = "mundo";  // cabe más texto después

Recorrerla:

for (int i = 0; s[i] != '\0'; i++) putchar(s[i]);

Funciones de <string.h>

Función Hace
strlen(s) longitud (sin contar '\0')
strcpy(dst, src) copia (¡dst debe tener sitio!)
strncpy / snprintf copias con límite (más seguras)
strcat(dst, src) concatena al final
strcmp(a, b) 0 si son iguales, <0 / >0 según orden
strchr(s, c) / strstr(s, sub) busca un carácter / subcadena

a == b con cadenas compara direcciones, no contenido. Usa strcmp(a, b) == 0. No puedes asignar cadenas con =: usa strcpy.

De <ctype.h>

isdigit isalpha isspace toupper tolower, siempre sobre un carácter.

3. Leer texto de forma segura

char nombre[32];
scanf("%31s", nombre);            // una palabra; %31s limita para no desbordar (31 + '\0')
fgets(linea, sizeof linea, stdin);// una línea completa (incluye el '\n' si cabe)
  • Nunca uses gets ni scanf("%s") sin límite: desbordamiento de buffer.
  • fgets deja el '\n'. Quitarlo: linea[strcspn(linea, "\n")] = '\0';
  • Mezclar scanf y fgets causa sorpresas (el \n pendiente): lee todo con fgets y convierte con sscanf/atoi/strtol cuando puedas.

4. Ordenar (burbuja)

Idea: recorre comparando vecinos e intercambia los que estén mal; repite hasta que no haya cambios. Es lenta (O(n²)) pero fácil de entender. En la vida real usarás qsort (módulo 9).

Prueba esto

  1. Rellena un array con los 20 primeros cuadrados e imprímelo.
  2. Cuenta cuántas veces aparece cada letra de una palabra (array de 26 contadores; c - 'a' da el índice).
  3. Implementa mayusculas(char s[]) que convierta la cadena a mayúsculas en su sitio.

Ejercicios prácticos del módulo 6

Programar se aprende programando: intenta cada ejercicio antes de mirar las pistas, y usa la solución solo para comparar. Marca los que resuelvas y tu progreso se guarda en este navegador.

6.1 Estadisticas de un array
Lee n (1 <= n <= 100) y despues n enteros. Imprime el maximo, el minimo y la media (2 decimales): max=9 min=-2 media=3.40

Entrada de ejemplo

5
3 9 -2 4 3

Salida esperada

max=9 min=-2 media=3.40

Tu punto de partida

#include <stdio.h>

int main(void) {
    int v[100], n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) scanf("%d", &v[i]);
    // TODO

    return 0;
}

Cópialo en tu editor, complétalo, compílalo (gcc -Wall -Wextra programa.c -o programa) y prueba la entrada de ejemplo. Para que se corrija solo con varios casos de prueba, descarga el curso.

Pista 1

Inicializa max y min con v[0], no con 0 (y si todos son negativos?).

Pista 2

La media es suma / n, pero con cast a double.

Ver solución (inténtalo antes)
#include <stdio.h>

int main(void) {
    int v[100], n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) scanf("%d", &v[i]);
    int max = v[0], min = v[0];
    long long suma = 0;
    for (int i = 0; i < n; i++) {
        if (v[i] > max) max = v[i];
        if (v[i] < min) min = v[i];
        suma += v[i];
    }
    printf("max=%d min=%d media=%.2f\n", max, min, (double)suma / n);
    return 0;
}
6.2 Invertir un array
Lee n y n enteros. Imprime los numeros en orden inverso, separados por espacio, INVIRTIENDO el array en su sitio (intercambiando v[i] con v[n-1-i]) y luego recorriendolo.

Entrada de ejemplo

5
1 2 3 4 5

Salida esperada

5 4 3 2 1

Tu punto de partida

#include <stdio.h>

int main(void) {
    int v[100], n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) scanf("%d", &v[i]);
    // TODO: invierte v en su sitio y luego imprimelo

    return 0;
}

Cópialo en tu editor, complétalo, compílalo (gcc -Wall -Wextra programa.c -o programa) y prueba la entrada de ejemplo. Para que se corrija solo con varios casos de prueba, descarga el curso.

Pista 1

Solo hay que recorrer la MITAD del array: i < n / 2.

Pista 2

Necesitas una variable temporal para intercambiar.

Ver solución (inténtalo antes)
#include <stdio.h>

int main(void) {
    int v[100], n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) scanf("%d", &v[i]);
    for (int i = 0; i < n / 2; i++) {
        int t = v[i];
        v[i] = v[n - 1 - i];
        v[n - 1 - i] = t;
    }
    for (int i = 0; i < n; i++) printf("%d ", v[i]);
    printf("\n");
    return 0;
}
6.3 Ordenar (burbuja)
Lee n y n enteros y muestralos ordenados de menor a mayor, separados por espacio. Implementa tu propia ordenacion de burbuja (no uses qsort todavia).

Entrada de ejemplo

6
5 2 9 1 5 6

Salida esperada

1 2 5 5 6 9

Tu punto de partida

#include <stdio.h>

void ordenar(int v[], int n) {
    // TODO: burbuja
}

int main(void) {
    int v[100], n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) scanf("%d", &v[i]);
    ordenar(v, n);
    for (int i = 0; i < n; i++) printf("%d ", v[i]);
    printf("\n");
    return 0;
}

Cópialo en tu editor, complétalo, compílalo (gcc -Wall -Wextra programa.c -o programa) y prueba la entrada de ejemplo. Para que se corrija solo con varios casos de prueba, descarga el curso.

Pista 1

Dos bucles: en cada pasada comparas vecinos v[j] y v[j+1] y los intercambias si estan al reves.

Pista 2

Los arrays se pasan a funciones sin copiarse: lo que modifiques dentro, queda modificado fuera.

Ver solución (inténtalo antes)
#include <stdio.h>

void ordenar(int v[], int n) {
    for (int i = 0; i < n - 1; i++)
        for (int j = 0; j < n - 1 - i; j++)
            if (v[j] > v[j + 1]) {
                int t = v[j];
                v[j] = v[j + 1];
                v[j + 1] = t;
            }
}

int main(void) {
    int v[100], n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) scanf("%d", &v[i]);
    ordenar(v, n);
    for (int i = 0; i < n; i++) printf("%d ", v[i]);
    printf("\n");
    return 0;
}
6.4 Contar vocales
Lee una linea de texto (con fgets, puede tener espacios) e imprime cuantas vocales (a, e, i, o, u, mayusculas o minusculas, sin acentos) contiene: vocales=5

Entrada de ejemplo

Hola Mundo

Salida esperada

vocales=4

Tu punto de partida

#include <stdio.h>
#include <ctype.h>

int main(void) {
    char s[256];
    fgets(s, sizeof s, stdin);
    // TODO: recorre hasta '\0'

    return 0;
}

Cópialo en tu editor, complétalo, compílalo (gcc -Wall -Wextra programa.c -o programa) y prueba la entrada de ejemplo. Para que se corrija solo con varios casos de prueba, descarga el curso.

Pista 1

Una cadena es un array de char terminado en '\0': recorre hasta encontrarlo.

Pista 2

tolower (de <ctype.h>) te evita comprobar mayusculas y minusculas por separado.

Ver solución (inténtalo antes)
#include <stdio.h>
#include <ctype.h>

int main(void) {
    char s[256];
    fgets(s, sizeof s, stdin);
    int n = 0;
    for (int i = 0; s[i] != '\0'; i++) {
        switch (tolower((unsigned char)s[i])) {
            case 'a': case 'e': case 'i': case 'o': case 'u': n++;
        }
    }
    printf("vocales=%d\n", n);
    return 0;
}
6.5 Palindromo
Lee una palabra (sin espacios, con scanf("%s")) e imprime "si" si es un palindromo (se lee igual al reves, p.ej. "anilina") o "no". Distingue mayusculas de minusculas. Usa <string.h> (strlen).

Entrada de ejemplo

anilina

Salida esperada

si

Tu punto de partida

#include <stdio.h>
#include <string.h>

int main(void) {
    char s[100];
    scanf("%99s", s);
    // TODO

    return 0;
}

Cópialo en tu editor, complétalo, compílalo (gcc -Wall -Wextra programa.c -o programa) y prueba la entrada de ejemplo. Para que se corrija solo con varios casos de prueba, descarga el curso.

Pista 1

Compara s[i] con s[n-1-i] solo hasta la mitad.

Pista 2

Si encuentras una pareja distinta, ya sabes que no lo es: sal del bucle.

Ver solución (inténtalo antes)
#include <stdio.h>
#include <string.h>

int main(void) {
    char s[100];
    scanf("%99s", s);
    int n = (int)strlen(s), ok = 1;
    for (int i = 0; i < n / 2; i++)
        if (s[i] != s[n - 1 - i]) { ok = 0; break; }
    printf("%s\n", ok ? "si" : "no");
    return 0;
}

Quiz del módulo 6

6 preguntas para comprobar que has fijado los conceptos. Las opciones se barajan cada vez.