Fundamentos de Arrays y Funciones en C: Memoria, Parámetros y Algoritmos Matriciales

Gestión de Memoria y Semántica de Parámetros

Los vectores en C se alojan de forma contigua en el segmento de datos. Esta propiedad garantiza que los elementos adyacentes ocupan direcciones inmediatas. La discrepancia de 16 bytes mencionada en los ejercicios de práctica corresponde al desplazamiento genreado por cuatro enteros de 32 bits o a la separación entre referencias en entornos de 64 bits, manteniendo siempre la misma dirección base inicial.

Al transmitir un bloque de datos como argumento, el identificador original se degrada automáticamente a un puntero hacia su primer componente. El parámetro formal y el real apuntan al mismo segmento de memoria, aunque utilicen nombres distintos. La rutina de ingestión recopila los valores ingresados, mientras que el procedimiento de cómputo estadístico filtra los extremos (máximo y mínimo) antes de dividir la suma acumulada por la cantidad de registros válidos.

En estructuras bidimensionales, la firma de la función debe declarar explícitamente la segunda dimensión (tipo matriz[][COL]). Esta restricción es estricta porque el compilador requiere conocer el ancho de cada fila para resolver las aritméticas de punteros mediante el cálculo base + (fila * COL + columna) * sizeof(tipo). Las rutinas de inicialización y visualización recorren sistemáticamente las coordenadas para poblar o imprimir los datos en formato tabular.

Implementaciones de Referencia

Cálculo de la Mediana Estadística

#include <stdio.h>
#define MAX_SIZE 100

void leer_datos(int *buffer, int cantidad);
double calcular_mediana(int *buffer, int cantidad);

int main() {
    int datos[MAX_SIZE];
    int n;
    double resultado;

    while (printf("Ingrese cantidad de elementos: ") && scanf("%d", &n) != EOF) {
        leer_datos(datos, n);
        resultado = calcular_mediana(datos, n);
        printf("La mediana es: %g\n\n", resultado);
    }
    return 0;
}

void leer_datos(int *buffer, int cantidad) {
    for (int idx = 0; idx < cantidad; idx++) {
        scanf("%d", &buffer[idx]);
    }
}

double calcular_mediana(int *buffer, int cantidad) {
    for (int i = 0; i < cantidad - 1; i++) {
        for (int j = 0; j < cantidad - i - 1; j++) {
            if (buffer[j] > buffer[j + 1]) {
                int tmp = buffer[j];
                buffer[j] = buffer[j + 1];
                buffer[j + 1] = tmp;
            }
        }
    }

    if (cantidad % 2 == 0) {
        return (buffer[cantidad / 2] + buffer[cantidad / 2 - 1]) / 2.0;
    } else {
        return buffer[cantidad / 2];
    }
}

Desplazamiento Circular de Filas

#include <stdio.h>
#define MAX_DIM 100

void ingresar_matriz(int mat[][MAX_DIM], int dim);
void mostrar_matriz(int mat[][MAX_DIM], int dim);
void desplazar_derecha(int mat[][MAX_DIM], int dim);

int main() {
    int cuadrado[MAX_DIM][MAX_DIM];
    int n;

    printf("Ingrese la dimension (n): ");
    scanf("%d", &n);

    ingresar_matriz(cuadrado, n);
    printf("Matriz original:\n");
    mostrar_matriz(cuadrado, n);

    desplazar_derecha(cuadrado, n);

    printf("Matriz tras desplazamiento circular a la derecha:\n");
    mostrar_matriz(cuadrado, n);

    return 0;
}

void ingresar_matriz(int mat[][MAX_DIM], int dim) {
    for (int f = 0; f < dim; f++) {
        for (int c = 0; c < dim; c++) {
            scanf("%d", &mat[f][c]);
        }
    }
}

void mostrar_matriz(int mat[][MAX_DIM], int dim) {
    for (int f = 0; f < dim; f++) {
        for (int c = 0; c < dim; c++) {
            printf("%4d", mat[f][c]);
        }
        printf("\n");
    }
}

void desplazar_derecha(int mat[][MAX_DIM], int dim) {
    for (int f = 0; f < dim; f++) {
        int ultimo = mat[f][dim - 1];
        for (int c = dim - 1; c > 0; c--) {
            mat[f][c] = mat[f][c - 1];
        }
        mat[f][0] = ultimo;
    }
}

Conversión de Bases Numéricas

#include <stdio.h>

void convertir_base(int valor_decimal, int base_objetivo);

int main() {
    int entrada;
    while (printf("Introduzca un entero en base 10: ") && scanf("%d", &entrada) != EOF) {
        convertir_base(entrada, 2);
        convertir_base(entrada, 8);
        convertir_base(entrada, 16);
        printf("\n");
    }
    return 0;
}

void convertir_base(int valor_decimal, int base_objetivo) {
    if (valor_decimal == 0) {
        printf("0 ");
        return;
    }

    int restos[32];
    int indice = 0;
    int num_temp = valor_decimal;

    while (num_temp > 0) {
        restos[indice++] = num_temp % base_objetivo;
        num_temp /= base_objetivo;
    }

    const char caracteres_hex[] = "0123456789ABCDEF";
    printf("(");
    for (int i = indice - 1; i >= 0; i--) {
        printf("%c", caracteres_hex[restos[i]]);
    }
    printf(") base %d ", base_objetivo);
}

Validación de Cuadrados Mágicos

#include <stdio.h>
#define MAX_N 100

void cargar_cuadrado(int grid[][MAX_N], int n);
void imprimir_cuadrado(int grid[][MAX_N], int n);
int validar_cuadrado_magico(int grid[][MAX_N], int n);

int main() {
    int tabla[MAX_N][MAX_N];
    int orden;

    while (printf("Especifique el orden del cuadrado (n): ") && scanf("%d", &orden) != EOF) {
        printf("Rellene la matriz %dx%d:\n", orden, orden);
        cargar_cuadrado(tabla, orden);

        printf("Matriz proporcionada:\n");
        imprimir_cuadrado(tabla, orden);

        if (validar_cuadrado_magico(tabla, orden)) {
            printf("El conjunto cumple con las propiedades de un cuadrado mágico.\n\n");
        } else {
            printf("El conjunto NO es un cuadrado mágico.\n\n");
        }
    }
    return 0;
}

void cargar_cuadrado(int grid[][MAX_N], int n) {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            scanf("%d", &grid[i][j]);
        }
    }
}

void imprimir_cuadrado(int grid[][MAX_N], int n) {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf("%4d", grid[i][j]);
        }
        printf("\n");
    }
}

int validar_cuadrado_magico(int grid[][MAX_N], int n) {
    if (n % 2 == 0) return 0;

    int presente[MAX_N * MAX_N] = {0};
    int suma_ref = 0;

    for (int i = 0; i < n; i++) {
        int suma_fila = 0;
        int suma_col = 0;
        for (int j = 0; j < n; j++) {
            int val = grid[i][j];
            if (val < 1 || val > n * n) return 0;
            if (presente[val]) return 0;
            presente[val] = 1;

            suma_fila += val;
            suma_col += grid[j][i];
        }
        if (i == 0) suma_ref = suma_fila;
        else if (suma_fila != suma_ref) return 0;
        if (suma_col != suma_ref) return 0;
    }

    int sum_diag1 = 0, sum_diag2 = 0;
    for (int k = 0; k < n; k++) {
        sum_diag1 += grid[k][k];
        sum_diag2 += grid[k][n - 1 - k];
    }

    return (sum_diag1 == suma_ref && sum_diag2 == suma_ref);
}

Etiquetas: C Lenguaje C arreglos Matrices algoritmos

Publicado el 9-3 08:06