Funciones en C — ejercicios resueltos con la guagua: segundo peor retraso, paradas que se cierran y abren y horarios que se fusionan (más el chuletario para el examen)

En el simulacro de IC2 que hicimos en clase, mi función para quitar una parada de la línea funcionaba perfecta… dentro de la función. En main la línea seguía teniendo cinco paradas, porque el tamaño n lo había pasado por valor. Dos caracteres, un * en el parámetro y un & en la llamada, separaban el programa bueno del malo. Estos ejercicios están pensados para que esos dos caracteres te salgan solos.

Son los ejercicios de la teoría y la práctica de funciones en C, con la línea 201 de la guagua. Cómo sacarles partido: lee el enunciado y la salida esperada, escribe las funciones con sus prototipos arriba, compila con -Wall (o pruébalo en el entorno de C de la web), abre la pista solo si llevas un rato atascado y compara con la solución comentada. Antes de las soluciones tienes tres fragmentos de «¿Qué falla aquí?» y al final, el chuletario completo de funciones. Todas las salidas son de una ejecución real con gcc 14.

Nivel básico

Ejercicio 1: el segundo peor retraso

Queremos saber el peor retraso del día y también el segundo peor, que tiene que ser un valor distinto del máximo (si el 85 aparece dos veces, el segundo no es 85). Escribe un programa con estas funciones:

  • int maximo(int v[], int n): devuelve el valor máximo.
  • int segundo_maximo(int v[], int n): devuelve el mayor valor estrictamente menor que el máximo, o -1 si no hay (todos iguales).
  • void mostrar(int v[], int n) y void informe(int v[], int n), que imprime el vector, el máximo y el segundo.

Pruébalo con los retrasos del lunes {42, 7, 19, 85, 26, 85, 54, 13}, del martes {10, 10, 10, 10} y del miércoles {9, 31}.

Salida esperada:

Retrasos: 42 7 19 85 26 85 54 13 
Máximo:         85
Segundo máximo: 54

Retrasos: 10 10 10 10 
Máximo:         10
Segundo máximo: no hay (todos iguales)

Retrasos: 9 31 
Máximo:         31
Segundo máximo: 9

No hace falta ordenar. Primero calcula el máximo llamando a maximo (reutiliza la función). Después recorre el vector buscando el mayor valor que cumpla v[i] < max. Empieza ese segundo máximo en -1: como los retrasos nunca son negativos, si al final sigue en -1 es que no había ninguno distinto.

Nivel intermedio

Ejercicio 2: cerrar y abrir paradas

La línea 201 guarda los códigos de sus paradas en un vector de hasta 10 casillas, de las que se usan n. Por obras cierran una parada y abren otra. Escribe:

  • int eliminar_posicion(int v[], int *n, int pos): quita la parada de la posición pos, corre las demás a la izquierda, actualiza *n y devuelve el código quitado. Si la posición no es válida, devuelve -1 sin tocar nada.
  • int insertar_posicion(int v[], int *n, int pos, int valor, int max): mete valor en pos, corre las demás a la derecha y actualiza *n. Devuelve 1 si ha podido y 0 si la posición no es válida o no queda sitio.
  • void mostrar(int v[], int n).

Con {101, 104, 112, 118, 125}: cierra la posición 2, abre la 120 en la posición 3, prueba a quitar la posición 9 e intenta meter la 99 con un máximo de 5.

Salida esperada:

Línea (5 paradas): 101 104 112 118 125 
Eliminada la 112 de la posición 2
Línea (4 paradas): 101 104 118 125 
Insertada la 120 en la posición 3
Línea (5 paradas): 101 104 118 120 125 
Posición 9 no válida: no cambio nada
Sin sitio para la 99
Línea (5 paradas): 101 104 118 120 125 

El tamaño cambia, así que n va por referencia: int *n en el parámetro y &n en la llamada; dentro, *n para leerlo y (*n)-- o (*n)++ para cambiarlo. Para quitar, recorre de la posición hacia la derecha copiando v[i + 1] en v[i]. Para insertar, de *n hacia la posición copiando v[i - 1] en v[i]. Insertar en pos == *n es válido: es añadir al final.

Desafío final

Ejercicio 3: fusionar dos horarios ordenados

Las líneas 201 y 202 comparten parada en San Telmo. Cada una tiene su horario de salidas ordenado (números hhmm) y queremos el horario conjunto, también ordenado. Escribe:

  • void fusionar(int a[], int na, int b[], int nb, int res[], int *nr): mezcla a y b, los dos ordenados, en res, que queda ordenado; deja en *nr el número de salidas.
  • void ordenar(int v[], int n): ordena un vector (el de la burbuja vale).
  • void mostrar(const char *titulo, int v[], int n).

Fusiona la 201 {610, 710, 810, 910, 1010} con la 202 {640, 700, 820, 950, 1100, 1210, 1300}. Después ordena la 303, que llega desordenada {1500, 730, 1215, 905}, y fusiónala con la 201. Por último, fusiona la 201 con un horario vacío.

Salida esperada:

Línea 201: 610 710 810 910 1010 
Línea 202: 640 700 820 950 1100 1210 1300 
Juntas:    610 640 700 710 810 820 910 950 1010 1100 1210 1300 
Salidas: 12

Línea 303 ordenada: 730 905 1215 1500 
201 + 303: 610 710 730 810 905 910 1010 1215 1500 
201 + nada: 610 710 810 910 1010 

No juntes los dos vectores para ordenar después: aprovecha que ya están ordenados. Usa tres índices, i para a, j para b y k para res. Mientras queden salidas en los dos, copia la menor de las dos «cabezas» (a[i] o b[j]) y avanza su índice. Cuando uno se acabe, copia lo que quede del otro. Prueba siempre el caso de un vector vacío (nb = 0).

¿Qué falla aquí?

Tres fragmentos con un error típico de funciones cada uno. Lee el código, predice qué imprimirá y después mira la explicación.

Fragmento 1: el saldo que no bajaba

#include <stdio.h>

void cobrar(int saldo, int precio) {
    saldo = saldo - precio;
}

int main(void) {
    int saldo = 1000;
    cobrar(saldo, 155);
    cobrar(saldo, 155);
    printf("Saldo tras dos viajes: %d\n", saldo);
    return 0;
}

Dos viajes de 1,55 euros sobre un bono de 10. ¿Qué saldo imprime?

Saldo tras dos viajes: 1000

Sigue en 1000. cobrar recibe una copia del saldo, le resta el viaje y la copia muere al salir de la función. gcc no avisa: el programa es correcto en C, solo que no hace lo que querías. Arreglo: la función recibe la dirección y escribe a través de ella.

#include <stdio.h>

void cobrar(int *saldo, int precio) {
    *saldo = *saldo - precio;            /* escribe en la variable de main */
}

int main(void) {
    int saldo = 1000;
    cobrar(&saldo, 155);
    cobrar(&saldo, 155);
    printf("Saldo tras dos viajes: %d\n", saldo);
    return 0;
}
Saldo tras dos viajes: 690

1000 − 155 − 155 = 690, dos viajes cobrados de verdad.

Fragmento 2: contar las casillas dentro de la función

#include <stdio.h>

int paradas_llenas(int v[]) {
    int n = sizeof(v) / sizeof(v[0]);    /* ¿cuántas casillas tiene? */
    int c = 0;
    for (int i = 0; i < n; i++)
        if (v[i] > 40) c++;
    return c;
}

int main(void) {
    int viajeros[6] = {15, 48, 42, 3, 51, 19};
    printf("Paradas con más de 40: %d\n", paradas_llenas(viajeros));
    return 0;
}

Hay tres paradas con más de 40 viajeros (48, 42 y 51). ¿Cuántas cuenta la función?

contar.c: In function 'paradas_llenas':
contar.c:4: warning: 'sizeof' on array function parameter 'v' will return size of 'int *' [-Wsizeof-array-argument]
contar.c:3: note: declared here
Paradas con más de 40: 1

Solo una. Dentro de la función, v es un puntero, así que sizeof(v) da 8 y 8 / 4 son 2 casillas: la función solo mira 15 y 48. gcc lo avisa con -Wsizeof-array-argument. Arreglo: el tamaño se calcula en main, donde viajeros sí es el vector, y se pasa como parámetro.

#include <stdio.h>

int paradas_llenas(int v[], int n) {     /* el tamaño viaja aparte */
    int c = 0;
    for (int i = 0; i < n; i++)
        if (v[i] > 40) c++;
    return c;
}

int main(void) {
    int viajeros[6] = {15, 48, 42, 3, 51, 19};
    int n = sizeof viajeros / sizeof viajeros[0];   /* aquí sí: en main es el vector */
    printf("Paradas con más de 40: %d\n", paradas_llenas(viajeros, n));
    return 0;
}
Paradas con más de 40: 3

Fragmento 3: el billete de 3 zonas

#include <stdio.h>

int precio(int zonas) {
    if (zonas == 1)
        return 155;
    else if (zonas == 2)
        return 175;
}

int main(void) {
    for (int z = 1; z <= 3; z++)
        printf("%d zonas: %d céntimos\n", z, precio(z));
    return 0;
}

¿Cuánto cuesta el billete de 3 zonas?

precio.c: In function 'precio':
precio.c:8: warning: control reaches end of non-void function [-Wreturn-type]
1 zonas: 155 céntimos
2 zonas: 175 céntimos
3 zonas: 3 céntimos

3 céntimos. Con 3 zonas ninguno de los dos if se cumple, la función llega a su llave de cierre sin return y devuelve lo que hubiera en el registro de retorno; en esta ejecución, un 3 (probablemente el valor de zonas, que se había quedado en ese registro). En otro ordenador saldrá otra cosa. gcc lo avisa con control reaches end of non-void function: ese aviso nunca se ignora. Arreglo: que todos los caminos acaben en un return.

#include <stdio.h>

int precio(int zonas) {
    if (zonas == 1)
        return 155;
    else if (zonas == 2)
        return 175;
    return 195;                          /* 3 zonas o más: todos los caminos devuelven */
}

int main(void) {
    for (int z = 1; z <= 3; z++)
        printf("%d zonas: %d céntimos\n", z, precio(z));
    return 0;
}
1 zonas: 155 céntimos
2 zonas: 175 céntimos
3 zonas: 195 céntimos

Soluciones comentadas

Solución del ejercicio 1

#include <stdio.h>

int maximo(int v[], int n);
int segundo_maximo(int v[], int n);
void mostrar(int v[], int n);
void informe(int v[], int n);

int main(void) {
    int lunes[8] = {42, 7, 19, 85, 26, 85, 54, 13};   /* retrasos en minutos */
    int martes[4] = {10, 10, 10, 10};
    int miercoles[2] = {9, 31};
    informe(lunes, 8);
    informe(martes, 4);
    informe(miercoles, 2);
    return 0;
}

int maximo(int v[], int n) {
    int m = v[0];
    for (int i = 1; i < n; i++)
        if (v[i] > m) m = v[i];
    return m;
}

/* El mayor valor ESTRICTAMENTE menor que el máximo, o -1 si no hay */
int segundo_maximo(int v[], int n) {
    int max = maximo(v, n);               /* primera pasada, reutilizando */
    int segundo = -1;                     /* -1: todavía no he visto ninguno */
    for (int i = 0; i < n; i++)
        if (v[i] < max && v[i] > segundo) /* distinto del máximo y mejor que el actual */
            segundo = v[i];
    return segundo;
}

void mostrar(int v[], int n) {
    for (int i = 0; i < n; i++)
        printf("%d ", v[i]);
    printf("\n");
}

void informe(int v[], int n) {
    printf("Retrasos: ");
    mostrar(v, n);
    printf("Máximo:         %d\n", maximo(v, n));
    int s = segundo_maximo(v, n);
    if (s == -1)
        printf("Segundo máximo: no hay (todos iguales)\n\n");
    else
        printf("Segundo máximo: %d\n\n", s);
}

Las decisiones que importan:

  • segundo_maximo llama a maximo en lugar de repetir el bucle: dos pasadas sencillas valen más que una enrevesada.
  • La condición es doble: v[i] < max descarta el máximo (aunque esté repetido) y v[i] > segundo se queda con el mejor de los que quedan.
  • -1 como «no hay»: funciona porque los retrasos son minutos no negativos. Si los datos pudieran ser negativos, habría que devolver el resultado por puntero y un 1/0 con return, como buscar_pos en la práctica.
  • informe evita repetir las cuatro líneas de impresión tres veces: cada día es una llamada.

Traza del lunes ({42, 7, 19, 85, 26, 85, 54, 13}, máximo 85):

v[i]¿< 85?¿> segundo?segundo
42SíSí (42 > -1)42
7, 19SíNo42
85No—42
26SíNo42
85No—42
54SíSí54
13SíNo54

Solución del ejercicio 2

#include <stdio.h>
#define MAX 10

int eliminar_posicion(int v[], int *n, int pos);
int insertar_posicion(int v[], int *n, int pos, int valor, int max);
void mostrar(int v[], int n);

int main(void) {
    int paradas[MAX] = {101, 104, 112, 118, 125};   /* códigos de la línea */
    int n = 5;

    mostrar(paradas, n);
    int quitada = eliminar_posicion(paradas, &n, 2);  /* cierran la parada 112 */
    printf("Eliminada la %d de la posición 2\n", quitada);
    mostrar(paradas, n);

    if (insertar_posicion(paradas, &n, 3, 120, MAX))  /* abren la 120 */
        printf("Insertada la 120 en la posición 3\n");
    mostrar(paradas, n);

    if (eliminar_posicion(paradas, &n, 9) == -1)      /* posición que no existe */
        printf("Posición 9 no válida: no cambio nada\n");
    if (!insertar_posicion(paradas, &n, 0, 99, 5))    /* ya hay 5 y el máximo es 5 */
        printf("Sin sitio para la 99\n");
    mostrar(paradas, n);
    return 0;
}

/* Quita v[pos], corre el resto a la izquierda y actualiza *n */
int eliminar_posicion(int v[], int *n, int pos) {
    if (pos < 0 || pos >= *n)
        return -1;                        /* no válida: no toco nada */
    int quitado = v[pos];
    for (int i = pos; i < *n - 1; i++)    /* de izquierda a derecha */
        v[i] = v[i + 1];
    (*n)--;
    return quitado;
}

/* Mete valor en pos, corre el resto a la derecha; 1 si pudo, 0 si no */
int insertar_posicion(int v[], int *n, int pos, int valor, int max) {
    if (pos < 0 || pos > *n || *n >= max) /* pos == *n vale: añadir al final */
        return 0;
    for (int i = *n; i > pos; i--)        /* de derecha a izquierda */
        v[i] = v[i - 1];
    v[pos] = valor;
    (*n)++;
    return 1;
}

void mostrar(int v[], int n) {
    printf("Línea (%d paradas): ", n);
    for (int i = 0; i < n; i++)
        printf("%d ", v[i]);
    printf("\n");
}
  • int *n en las dos funciones: el tamaño de la línea vive en main y las funciones lo cambian. Dentro se escribe *n (y (*n)--, con paréntesis); en la llamada, &n.
  • La validación va primero: pos >= *n en eliminar (no hay casilla *n) y pos > *n en insertar (sí se puede insertar justo al final), más *n >= max para no escribir fuera del vector.
  • Las direcciones de recorrido son opuestas: al quitar la 112 se copia de izquierda a derecha (118 a la casilla 2, 125 a la 3); al meter la 120 se copia de derecha a izquierda (125 de la casilla 3 a la 4) y luego se escribe la 120.
  • Los valores de retorno informan: el código quitado (o -1) y 1/0 al insertar. main decide qué mensaje dar.
Eliminar e insertar desplazandoCinco filas: la línea con la 112, la 118 y la 125 corriéndose a la izquierda al quitarla, n pasa a 4, la 125 se corre a la derecha para meter la 120 y n vuelve a 5.inicio, n = 5101104112118125eliminar pos 2101104118125·n = 4101104118125insertar 120 en 3101104118120125n = 5101104118120125←→
Para quitar se recorre de izquierda a derecha; para meter, de derecha a izquierda.

Solución del ejercicio 3

#include <stdio.h>
#define MAX 20

void fusionar(int a[], int na, int b[], int nb, int res[], int *nr);
void ordenar(int v[], int n);
void mostrar(const char *titulo, int v[], int n);

int main(void) {
    int l201[5] = {610, 710, 810, 910, 1010};                 /* ya ordenadas (hhmm) */
    int l202[7] = {640, 700, 820, 950, 1100, 1210, 1300};
    int todas[MAX], n;

    mostrar("Línea 201: ", l201, 5);
    mostrar("Línea 202: ", l202, 7);
    fusionar(l201, 5, l202, 7, todas, &n);
    mostrar("Juntas:    ", todas, n);
    printf("Salidas: %d\n\n", n);

    int l303[4] = {1500, 730, 1215, 905};                     /* desordenadas */
    ordenar(l303, 4);
    mostrar("Línea 303 ordenada: ", l303, 4);
    fusionar(l201, 5, l303, 4, todas, &n);
    mostrar("201 + 303: ", todas, n);

    int vacia[1];
    fusionar(l201, 5, vacia, 0, todas, &n);                   /* nb = 0 */
    mostrar("201 + nada: ", todas, n);
    return 0;
}

/* Mezcla dos vectores ordenados en res, también ordenado */
void fusionar(int a[], int na, int b[], int nb, int res[], int *nr) {
    int i = 0, j = 0, k = 0;
    while (i < na && j < nb) {          /* mientras queden en los dos */
        if (a[i] <= b[j])
            res[k++] = a[i++];          /* el menor de las dos cabezas */
        else
            res[k++] = b[j++];
    }
    while (i < na) res[k++] = a[i++];   /* lo que sobre de a */
    while (j < nb) res[k++] = b[j++];   /* o lo que sobre de b */
    *nr = k;                            /* el tamaño sale por puntero */
}

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;
            }
}

void mostrar(const char *titulo, int v[], int n) {
    printf("%s", titulo);
    for (int i = 0; i < n; i++)
        printf("%d ", v[i]);
    printf("\n");
}
  • Tres índices que solo avanzan: cada salida se mira una vez, así que fusionar 5 + 7 salidas cuesta 12 pasos. Ordenar al final costaría muchos más.
  • <= en la comparación: si las dos líneas salieran a la misma hora, primero se copia la de a. Con < también funcionaría; <= mantiene el orden de origen, que en otros problemas importa.
  • Los dos while finales: solo uno de ellos llega a ejecutarse, el del vector que no se ha acabado. Con la 202, las tres últimas salidas (1100, 1210 y 1300) entran ahí.
  • *nr = k al final: k ha contado cada salida copiada; el tamaño llega a main por el puntero. Con el horario vacío (nb = 0) el primer while ni empieza y se copia la 201 entera.
Fusionar dos horarios ordenadosLas cinco salidas de la línea 201 en violeta y las siete de la 202 en coral se mezclan en un vector de doce, ordenado, conservando el color de su origen.Línea 2016107108109101010Línea 202640700820950110012101300Juntas6106407007108108209109501010110012101300en cada paso entra la menor de las dos cabezas (a[i] o b[j])cuando la 201 se acaba, se copia lo que queda de la 202
El color dice de qué línea viene cada salida: nunca hace falta ordenar al final.

Para seguir practicando

Si los tres ejercicios te han salido, estas variantes repasan lo mismo desde otro ángulo. Están pensadas para el tipo de pregunta que cae en el práctico, donde te piden una función concreta y la llamada desde main:

  • Segundo máximo en una sola pasada. Reescribe segundo_maximo sin llamar a maximo, manteniendo dos variables (primero y segundo) que se actualizan en el mismo bucle. Cuidado con el caso en que aparece un valor nuevo mayor que primero: el viejo primero pasa a ser el segundo.
  • Eliminar por valor. Escribe int eliminar_valor(int v[], int *n, int codigo), que busque la parada por su código (reutilizando una búsqueda) y llame a eliminar_posicion. Devuelve 1 si la quitó y 0 si no existía.
  • Eliminar todas las apariciones. Con la lista de líneas repetidas de la práctica, quita todas las veces que aparece la 201 y comprueba que *n acaba en el número correcto.
  • Fusionar sin repetidos. Modifica fusionar para que, si las dos líneas salen a la misma hora, esa hora aparezca una sola vez en el horario conjunto. Pista: cuando a[i] == b[j], copia uno y avanza los dos índices.

En todas ellas, antes de compilar, escribe primero los prototipos y marca con una flecha qué parámetros son de salida: si una función cambia algo de main, ese parámetro lleva * y la llamada lleva &.

Míralo paso a paso en Python Tutor

En Python Tutor, eligiendo C, puedes ver cómo eliminar_posicion cambia a la vez el vector y el tamaño de main. Pega esta versión corta:

#include <stdio.h>

int eliminar_posicion(int v[], int *n, int pos) {
    if (pos < 0 || pos >= *n) {
        return -1;
    }
    int quitado = v[pos];
    for (int i = pos; i < *n - 1; i++) {
        v[i] = v[i + 1];
    }
    (*n)--;
    return quitado;
}

int main(void) {
    int paradas[5] = {101, 104, 112, 118, 125};
    int n = 5;
    int q = eliminar_posicion(paradas, &n, 2);
    printf("quitada %d, quedan %d\n", q, n);
    return 0;
}

Qué observar paso a paso:

  1. Al entrar en la función, v apunta al vector paradas y n apunta a la variable n de main: dos flechas.
  2. quitado guarda el 112 antes de que nadie lo pise.
  3. En el for, las casillas 2 y 3 de paradas reciben 118 y 125: el cambio se ve directamente en el marco de main.
  4. En (*n)-- la caja n de main pasa de 5 a 4. Si hubieras escrito *n--, verías moverse la flecha y el 5 quedaría intacto.
  5. Al volver, q recibe 112 y el programa imprime quitada 112, quedan 4.

Chuletario: funciones en C

Lo esencial en 30 segundos

Una función tiene tipo de retorno, nombre, parámetros con tipo y cuerpo. El prototipo (la firma con ;) va arriba para poder llamarla antes de definirla. void significa «no devuelve nada» o «no recibe nada». C pasa los argumentos por valor (copias); para modificar una variable de quien llama, se pasa su dirección. Un vector se pasa como dirección y su tamaño, aparte.

Declarar, definir y llamar

Quiero…CódigoResultado
Un prototipoint precio_billete(int zonas);se puede llamar antes de definirla
Una función que devuelveint f(int x) { return x * 2; }f(3) vale 6
Una función sin retornovoid separador(int largo)hace algo y no devuelve nada
Sin parámetrosint primera_salida(void)se llama primera_salida()
Salir antes de una voidreturn;termina sin valor
El main correctoint main(void) { …; return 0; }código de salida 0

Valor, referencia y vectores

Quiero…CódigoResultado
Que solo lea un datovoid f(int x) y f(saldo)trabaja con una copia
Que modifique un datovoid f(int *x) y f(&saldo)dentro, *x = …
Incrementar lo apuntado(*n)++;con paréntesis
Devolver dos resultadosint f(…, int *pos)uno por return, otro por *pos
Pasar un vectorvoid f(int v[], int n) y f(v, n)puede modificarlo
Un vector de solo lecturavoid f(const int v[], int n)gcc impide escribir
Tamaño de un vectorsizeof v / sizeof v[0] en mainnunca dentro de la función
Cambiar un elemento por punterointercambiar(&v[j], &v[j + 1])& de cada casilla

Plantillas de los ejercicios

/* Segundo máximo distinto del máximo (ejercicio 1) */
int max = maximo(v, n), segundo = -1;
for (int i = 0; i < n; i++)
    if (v[i] < max && v[i] > segundo) segundo = v[i];

/* Eliminar en una posición con el tamaño por referencia (ejercicio 2) */
if (pos < 0 || pos >= *n) return -1;
for (int i = pos; i < *n - 1; i++) v[i] = v[i + 1];
(*n)--;

/* Insertar en una posición (ejercicio 2) */
for (int i = *n; i > pos; i--) v[i] = v[i - 1];
v[pos] = valor;
(*n)++;

/* Fusionar dos vectores ordenados (ejercicio 3) */
while (i < na && j < nb)
    res[k++] = (a[i] <= b[j]) ? a[i++] : b[j++];
while (i < na) res[k++] = a[i++];
while (j < nb) res[k++] = b[j++];
*nr = k;

Resultados con los datos de los ejercicios: segundo peor retraso del lunes 54 (máximo 85); la línea queda 101 104 118 120 125; el horario conjunto de la 201 y la 202 tiene 12 salidas, de 610 a 1300.

Síntoma y causa probable

SíntomaCausa probable
implicit declaration of functionfalta el prototipo o el #include
conflicting types forel prototipo y la definición no coinciden
La variable de main no cambiase pasó por valor: falta * en el parámetro y & en la llamada
Un tamaño que no se actualizan pasado por valor, o *n-- en vez de (*n)--
sizeof on array function parametersizeof de un vector dentro de la función
control reaches end of non-void functionun camino sin return
Un número absurdo como resultadola función devolvió basura por un camino sin return
return type of 'main' is not 'int'void main en lugar de int main(void)

Antes de entregar, pregúntate

  1. ¿Están todos los prototipos arriba y coinciden con sus definiciones?
  2. ¿Las variables que una función tiene que modificar llegan como punteros, con & en la llamada?
  3. ¿Cada función que recibe un vector recibe también su tamaño?
  4. ¿Todos los caminos de las funciones que devuelven algo terminan en un return?

Con las funciones dominadas, el siguiente tema es Memoria dinámica en C: malloc devuelve una dirección, y las funciones que acabas de escribir te servirán para trabajar con vectores que crecen mientras el programa corre.

Sigue aprendiendoTodos los artículos de C

¿Te ha servido este artículo? Así puedes apoyar SergioLearns →

Sigue aprendiendo

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *