Fiche de révision : Fundamentos y Técnicas en Programación en C

📋 Esquema del Curso

  1. Estructura de un programa en C
  2. Comentarios en C y compilación
  3. Tipos numéricos y precisión en C
  4. Condicionales if y condiciones compuestas
  5. Lectura y escritura con printf y scanf
  6. Bucles anidados y control de iteraciones
  7. Sentencia switch y casos múltiples
  8. Arrays y funciones auxiliares en C
  9. Cadenas de caracteres y librería string.h
  10. Funciones recursivas y determinantes
  11. Escritura y lectura a ficheros
  12. Convergencia de series y eficiencia

📖 1. Estructura de un programa en C

🔑 Conceptos clave y definiciones

  • Código fuente : El código fuente es la forma legible del programa que escribes en un fichero de texto con extensión .c.
  • Código máquina : El código máquina es el conjunto de instrucciones que el ordenador puede ejecutar directamente.
  • Compilador : El compilador es la herramienta que traduce el código fuente a código máquina.
  • Cabecera de programa : La cabecera es la parte inicial del programa donde se incluyen librerías y se fijan constantes con directivas.
  • Función main : La función main es el punto de arranque del programa y debe tener tipo int.

📝 Puntos esenciales

  • Un programa C se escribe en ficheros .c y, para programas complejos, puede repartirse en varios .c y .h.
  • La estructura básica del programa es cabecera seguida de un conjunto de funciones, incluyendo main al final o en el cuerpo del fichero.
  • Las directivas #include cargan librerías y #define fija valores constantes en la cabecera del programa.
  • Cada función se declara con un tipo de retorno (void, int, double, etc.), un nombre y parámetros entre paréntesis, y su cuerpo va entre llaves { }.
  • El compilador GNU C se invoca con cc, y para ejecutar un binario en el directorio actual se usa ./nombre.

💡 Truco mnemotécnico

main arranca: piensa “main = inicio” y todo lo demás son funciones llamadas después.

📖 2. Comentarios en C y compilación

🔑 Conceptos clave y definiciones

  • Error de sintaxis : Error de compilación que aparece cuando el código no respeta la gramática del lenguaje y el compilador no puede formar una estructura válida.
  • Error de ejecución : Error de run-time que ocurre durante la ejecución del programa y puede hacer que el sistema operativo detenga el proceso.
  • Segmentation fault : Fallo de ejecución que ocurre al intentar acceder a una zona de memoria no permitida.
  • División por cero : Situación de run-time en la que el denominador vale 0 y el resultado puede interrumpir el programa o producir inf o nan.
  • Error de lógica : Fallo en el resultado final debido a un comportamiento incorrecto del programa aunque compile y ejecute.

📝 Puntos esenciales

  • Los errores de sintaxis suelen indicar paréntesis, llaves o tokens esperados, como falta de ')' o de '{'/'}' o un ';' en lugar incorrecto.
  • Los warnings se muestran con la opción -Wall y no impiden compilar, pero señalan aspectos técnicos potencialmente problemáticos.
  • Un segmentation fault suele aparecer al exceder los límites de un array o al omitir el uso de & en los argumentos de scanf.
  • En división por cero, el programa puede parar con una excepción de coma flotante o continuar con resultado inf o nan según el caso.
  • Los bucles infinitos se ejecutan indefinidamente hasta que se corta el proceso (p. ej., Ctrl-C) y pueden ser peligrosos si escriben en archivos externos.
  • Las llaves desemparejadas dificultan localizar la línea exacta del fallo porque el compilador no identifica con precisión dónde falta o sobra una llave.

💡 Truco mnemotécnico

Sintaxis: falla antes de correr; run-time: falla al correr; lógica: compila y corre pero falla el resultado.

📖 3. Tipos numéricos y precisión en C

🔑 Conceptos clave y definiciones

  • Tipos de precisión arbitraria : Tipos de precisión arbitraria permiten representar enteros o reales con tamaño/cifras que no están limitados por los tipos estándar.
  • GMP mpz_t : mpz_t es el tipo de GMP para enteros de tamaño arbitrario, con funciones para inicializar, operar y liberar memoria.
  • GMP mpf_t : mpf_t es el tipo de GMP para reales de precisión arbitraria, donde la precisión se fija con una configuración global.
  • quadmath : quadmath es una extensión para usar precisión cuádruple en C, que requiere instalar el paquete correspondiente y enlazar con flags extra.
  • Librería complex.h : complex.h proporciona tipos y operaciones para números complejos en C, junto con constantes y funciones matemáticas específicas.

📝 Puntos esenciales

  • GMP permite trabajar con enteros sin límite de tamaño mediante mpz_t y con reales con un número arbitrario de cifras significativas mediante mpf_t.
  • Para mpf_t, la precisión se fija con mpf_set_default_prec(n) antes de inicializar y operar con variables mpf_t.
  • Las operaciones con GMP (por ejemplo sqrt, multiplicaciones y factoriales) se realizan con funciones de la librería y no con operadores aritméticos estándar.
  • El cálculo con precisión arbitraria es mucho más lento que con tipos estándar como int y double, por lo que suele reservarse para casos que lo exijan.
  • Para compilar GMP se requieren flags de enlace como -lgmp y -lquadmath (según el caso) y paquetes extra como libgmp10 y libgmp-dev.
  • Para usar quadmath en Ubuntu hay que instalar el paquete libquadmath0 y enlazar con el flag correspondiente al compilar.

💡 Truco mnemotécnico

Precisión arbitraria = más “cifras” pero menos “velocidad”: GMP (mpz_t/mpf_t) y quadmath requieren instalación y enlace extra.

📖 4. Condicionales if y condiciones compuestas

🔑 Conceptos clave y definiciones

  • Operador lógico AND : Operador lógico que une dos condiciones y exige que ambas sean verdaderas para que el resultado sea verdadero.
  • Operador lógico OR : Operador lógico que une dos condiciones y hace que el resultado sea verdadero si al menos una es verdadera.
  • Negación lógica : Operador lógico que invierte el valor de una condición, haciendo verdadero lo que antes era falso y viceversa.
  • Condición compuesta : Condición formada por varias subcondiciones conectadas con operadores lógicos para decidir el flujo del programa en if.
  • Bloque de llaves en if : Estructura que agrupa varias sentencias para que se ejecuten juntas cuando la condición del if resulta verdadera.

📝 Puntos esenciales

  • En C, una condición compuesta con AND se cumple solo si todas las subcondiciones conectadas con && son verdaderas a la vez.
  • En C, una condición compuesta con OR se cumple si al menos una de las subcondiciones conectadas con || es verdadera.
  • La negación lógica se escribe con ! y hace que una condición se cumpla cuando la condición original es falsa.
  • Los paréntesis ayudan a controlar el orden de evaluación en expresiones como (x>=-1)&&(x<=1).
  • Si el if ejecuta una sola sentencia, se pueden omitir las llaves { }, pero si hay varias sentencias deben usarse para agruparlas.
  • Ejemplo de AND: (n>0)&&(m==0) exige n>0 y m==0 simultáneamente para que el if se active.

💡 Truco mnemotécnico

AND = “todo a la vez” (&&), OR = “alguna vale” (||), NOT = “lo contrario” (!).

📖 5. Lectura y escritura con printf y scanf

🔑 Conceptos clave y definiciones

  • printf : Función de salida que muestra texto y valores formateados en pantalla usando especificadores de formato.
  • scanf : Función de entrada que lee datos desde teclado según un formato y los guarda en variables mediante direcciones.
  • Especificador de formato %d : Marcador de printf/scanf para tratar un entero con signo, asociado a una variable del tipo entero correspondiente.
  • Especificador de formato %lf : Marcador de printf/scanf para tratar un número de punto flotante double, usado para lectura y escritura de double.
  • Operador & : Operador que proporciona la dirección de una variable para que scanf pueda escribir el valor leído en memoria.

📝 Puntos esenciales

  • printf y scanf usan cadenas de formato con especificadores como %d y %lf para controlar cómo se interpreta cada dato.
  • En scanf se pasan direcciones de variables con & (por ejemplo, &a) para que la función pueda modificar su contenido.
  • En printf el valor se pasa por valor y debe coincidir con el especificador (por ejemplo, %d con un int).
  • Para leer dos enteros seguidos se puede usar un formato con dos %d y pasar dos direcciones, como en scanf(" %d %d", &a, &b).
  • Para imprimir un double con precisión se usa el especificador %lf y, si se requiere, se ajusta con formato de decimales (p. ej., 15 decimales en los ejercicios).
  • En scanf es habitual incluir un espacio inicial en el formato (" %d" o " %lf") para consumir espacios en blanco antes del número.

💡 Truco mnemotécnico

Piensa en printf como “formatea y muestra” y scanf como “lee y escribe en la dirección” (por eso lleva &).

📖 6. Bucles anidados y control de iteraciones

🔑 Conceptos clave y definiciones

  • Bucle for : Estructura de control que repite un bloque mientras una variable de control recorre un rango definido por inicialización, condición y actualización.
  • Bucle anidado : Estructura formada por un bucle dentro de otro, usada para recorrer sistemáticamente estructuras con varias dimensiones como matrices.
  • Variable de control del bucle : Entero que gobierna las iteraciones del bucle y permite indexar elementos de arrays sin salirse de sus límites.
  • Índices de arrays desde 0 : Convención en C por la que el primer elemento de un array se accede como a[0] y el último como a[N-1].
  • Control de iteraciones con return 0 : Salida temprana del programa mediante return 0 para detener la ejecución cuando se cumple una condición previa.

📝 Puntos esenciales

  • En los ejercicios de primos y perfectos se recorre con for todos los enteros entre 2 y N para evaluar una propiedad por cada candidato.
  • Para invertir cifras se mantiene un bucle mientras n sea no nulo, actualizando n con el cociente entero de n/10 y acumulando el resto en inv.
  • En arrays multidimensionales, el último índice es el que cambia más deprisa en la memoria lineal al recorrer el array.
  • Para inicializar matrices con bucles anidados, se usan dos índices (i y j) y se asigna A[i][j] según una condición como i==j para la identidad.
  • En el cálculo de máximos y mínimos se inicia max (o min) con el primer elemento y luego se compara secuencialmente el resto para actualizarlo.
  • En arrays grandes, el fallo típico puede ser por stack limitado, y se puede ampliar con ulimit -s unlimited antes de ejecutar el programa.

💡 Truco mnemotécnico

Anidado = “tablero”: dos índices (fila,columna) y el último índice “corre” más rápido; return 0 corta la ejecución antes de iterar.

📖 7. Sentencia switch y casos múltiples

🔑 Conceptos clave y definiciones

  • Sentencia switch : Estructura de control que compara una expresión con varias constantes y ejecuta el bloque del caso que coincida.
  • Caso case : Etiqueta dentro de un switch que marca el valor con el que se compara la expresión y el bloque a ejecutar si coincide.
  • Caso default : Etiqueta opcional de un switch que se ejecuta cuando ningún case coincide con el valor evaluado.
  • Sentencia break : Instrucción que termina la ejecución del switch evitando que el flujo continúe en casos posteriores.

📝 Puntos esenciales

  • En un switch, la expresión se evalúa una sola vez y se compara contra los valores indicados en cada case.
  • Si un case coincide y no hay break, la ejecución continúa “cayendo” al siguiente case (fall-through).
  • El default no se ejecuta si existe al menos un case coincidente; se usa como ruta por defecto.
  • Los valores de case deben ser constantes (no expresiones variables) y del tipo compatible con la expresión del switch.
  • La presencia de break dentro de cada case típico evita ejecutar varios bloques por accidente.
  • El orden de los case importa solo cuando hay fall-through por ausencia de break.

💡 Truco mnemotécnico

Piensa en switch como “llave” que abre un único caso; el break es el “candado” que impide seguir a los siguientes casos.

📖 8. Arrays y funciones auxiliares en C

🔑 Conceptos clave y definiciones

  • Array unidimensional : Estructura de datos en C que guarda una secuencia indexada de elementos del mismo tipo en memoria contigua.
  • Array bidimensional : Estructura de datos en C que organiza elementos en filas y columnas, accedidos con dos índices.
  • Función auxiliar : Subprograma en C que realiza una tarea concreta y puede devolver un valor al programa que la llama.
  • Tipo de retorno : Especificación del tipo de dato que una función devuelve mediante return.
  • Prototipo de función : Declaración previa de una función antes de su definición para que el compilador conozca su firma.

📝 Puntos esenciales

  • Para declarar una función que devuelve un valor se usa return(variable) y se debe indicar el tipo de retorno en la cabecera.
  • Los argumentos de una función reciben copias de los valores del programa principal, por lo que sin punteros no se modifican variables externas.
  • La llamada a una función usa su nombre seguido de paréntesis con el número y orden correctos de parámetros.
  • Si la función está definida antes de main no se necesita prototipo; si está después o en otro fichero, se requiere prototipo.
  • En C, el compilador procesa de arriba abajo, así que main no puede llamar a una función no declarada previamente sin prototipo.
  • Para declarar argumentos existen dos sintaxis equivalentes: tipos dentro de la lista o tipos declarados antes de la llave de apertura.

💡 Truco mnemotécnico

Array: piensa en “índice → elemento”; función: “firma (tipo+parámetros) → return”.

📖 9. Cadenas de caracteres y librería string.h

🔑 Conceptos clave y definiciones

  • Puntero : Un puntero es una variable que almacena una dirección de memoria para acceder a otra variable.
  • Operador & : El operador & obtiene la dirección de memoria asociada a una variable.
  • Paso por valor : El paso por valor hace que la función reciba copias de los argumentos, sin modificar las variables originales.
  • Paso por referencia : El paso por referencia permite que una función modifique variables del programa principal usando punteros.
  • Librería string.h : La librería string.h agrupa funciones estándar para trabajar con cadenas de caracteres en C.

📝 Puntos esenciales

  • Un puntero debe apuntar a un tipo compatible con la variable objetivo para evitar errores de compilación o comportamiento incorrecto.
  • El contenido al que apunta un puntero se accede con * y puede cambiarse asignando un nuevo valor a *puntero.
  • La dirección de una variable se puede imprimir con el formato %x usando &variable o el puntero correspondiente.
  • En scanf los argumentos deben pasarse por referencia porque la función modifica los valores recibidos.
  • En printf los argumentos se pasan por valor, por lo que no se modifican las variables originales desde la función.

💡 Truco mnemotécnico

& es “dirección”: con & pasas la ubicación; con * lees o escribes el contenido de esa ubicación.

📖 10. Funciones recursivas y determinantes

🔑 Conceptos clave y definiciones

  • Recursión en C : La recursión en C es una técnica en la que una función se llama a sí misma para resolver un problema mediante subproblemas más pequeños.
  • Función fact : La función fact es un ejemplo recursivo que calcula el factorial usando una condición base y llamadas con n-1.
  • Sucesión de Fibonacci : La sucesión de Fibonacci es una serie definida por recurrencia que puede implementarse con una función recursiva que suma dos términos anteriores.
  • Regla de Laplace : La regla de Laplace es un método para calcular el determinante desarrollándolo en una fila o columna mediante menores complementarios.
  • Menor complementario : El menor complementario MijM_{ij} es la matriz que se obtiene al eliminar la fila i y la columna j de una matriz cuadrada A.

📝 Puntos esenciales

  • En una función recursiva debe existir una condición base que detenga las llamadas para evitar recursión infinita.
  • Para fact(n)fact(n), si n>1n>1 se devuelve nfact(n1)n\,fact(n-1) y si no, se devuelve 1.
  • Para fibonacci(n)fibonacci(n), si n==0n==0 devuelve 0, si n==1n==1 devuelve 1, y en otro caso devuelve fibonacci(n1)+fibonacci(n2)fibonacci(n-1)+fibonacci(n-2).
  • Para una matriz AA de rango n, el determinante se desarrolla como A=j=1n(1)i+jaijMij|A|=\sum_{j=1}^{n}(-1)^{i+j}a_{ij}\,|M_{ij}| al fijar una fila i (por ejemplo i=0).
  • Al desarrollar por la primera fila, el bucle suma términos a[0][p](1)pdeterm(n1,m)a[0][p]\,(-1)^p\,determ(n-1,m) donde m contiene el menor asociado al elemento (0,p)(0,p).
  • Para construir el menor m del elemento (0,p)(0,p) se copian las filas 1..n-1 y todas las columnas excepto p, usando un índice auxiliar (como j2) para reindexar m.

💡 Truco mnemotécnico

Recursión: “divide y multiplica” hasta la condición base; Laplace: “fila fija + menores” con signos (1)i+j(-1)^{i+j}.

📖 11. Escritura y lectura a ficheros

🔑 Conceptos clave y definiciones

  • Fichero de texto : Recurso en disco que guarda información en caracteres para que pueda leerse y escribirse con facilidad desde el programa.
  • factorial.dat : Nombre del fichero auxiliar de salida donde se escribe el valor decimal del factorial calculado por el programa.
  • Lectura desde fichero : Proceso de obtener datos (por ejemplo una matriz) desde un archivo de texto para usarlos como entrada del cálculo.
  • Escritura en fichero : Proceso de volcar resultados calculados (por ejemplo una matriz) a un archivo de texto con un formato definido.

📝 Puntos esenciales

  • El ejercicio del factorial exige escribir N! en factorial.dat con 80 números por línea.
  • Para evitar ceros a la izquierda al imprimir el factorial, se debe buscar el primer dígito no nulo y empezar a escribir desde ahí.
  • Para insertar saltos de línea cada 80 caracteres, se usa un contador y se escribe '\n' cuando el contador alcance múltiplos de 80.
  • El ejercicio de la exponencial de matrices pide leer la matriz fila a fila desde un fichero de texto auxiliar y escribir e^A en otro fichero auxiliar.
  • En la exponencial de matrices, el criterio de parada es que el error en cada elemento de e^A sea menor que 10−12.

💡 Truco mnemotécnico

Piensa en dos “tuberías”: factorial.dat para salida formateada (80 por línea) y otro fichero para e^A, con lectura fila a fila y parada por error < 10−12.

📖 12. Convergencia de series y eficiencia

🔑 Conceptos clave y definiciones

  • Matriz identidad : La matriz identidad es una matriz cuadrada con unos en la diagonal y ceros fuera de ella, usada como valor inicial neutro para acumulaciones.
  • Suma de serie matricial : La suma de una serie matricial es el acumulado de términos sucesivos en una matriz S, actualizada iteración a iteración.
  • Factorial en el sumatorio : El factorial en el sumatorio es el denominador i! que escala cada término de la serie y controla su rapidez de convergencia.
  • Criterio de precisión ε : El criterio de precisión ε fija un umbral numérico para decidir cuándo el siguiente término ya no cambia de forma apreciable la suma.
  • Eficiencia algorítmica : La eficiencia algorítmica mide el tiempo de ejecución y busca que el programa termine en un tiempo razonable para el tamaño del problema.

📝 Puntos esenciales

  • Se inicializa B con la matriz identidad y S con la identidad antes de comenzar las iteraciones del bucle principal.
  • En cada iteración se calcula C = A^i·S (multiplicando B y A) y luego se actualiza S sumando C dividido por i! elemento a elemento.
  • Para la siguiente iteración se copia B ← C, de modo que B va acumulando potencias de A según avanza el bucle.
  • La convergencia se decide comprobando que al sumar el siguiente sumando (A^i/i!) cada elemento cambia menos que ε = 10^{-12}.
  • La condición práctica se verifica calculando el máximo valor absoluto de los elementos de A^i/i! y deteniendo si ese máximo es menor que ε.
  • En problemas tipo projecteuler se exige que el programa ejecute en menos de un minuto, y si tarda mucho indica un algoritmo ineficiente.

💡 Truco mnemotécnico

Convergencia: mira el mayor cambio (máximo |A^i/i!|) y para cuando sea < ε; Eficiencia: si no termina en ~1 min, el algoritmo es “demasiado lento”.

📊 Tablas de síntesis

Tipos de errores en C

TipoCuándo ocurreEjemplo
Error de sintaxisAl compilar (no respeta la gramática)Falta un ';' o un ')' o llaves mal emparejadas
Error de ejecución (run-time)Durante la ejecuciónSegmentation fault o división por cero
Error de lógicaCompila y ejecuta, pero el resultado es incorrectoUsar '=' en un if en vez de '=='

⚠️ Errores y confusiones frecuentes

  1. Confundir error de sintaxis con run-time: el primero impide compilar y el segundo aparece al ejecutar (p. ej., segmentation fault).
  2. Olvidar que en C las sentencias terminan en ';' salvo if/for/while/do while/switch y #include/#define; un ';' mal puesto rompe el programa.
  3. Usar scanf sin '&' en los argumentos: scanf modifica memoria y necesita direcciones; si falta '&' suele acabar en segmentation fault.
  4. Creer que printf y scanf tratan los argumentos igual: printf pasa por valor y debe coincidir el especificador (%d con int, %lf con double).
  5. Hacer divisiones enteras sin casting: si ambos operandos son enteros, C devuelve cociente entero (p. ej., 5/3=1) y luego se asigna a float/double.
  6. No inicializar variables: si declaras int i; y luego haces i=i+1, el valor inicial es basura y el resultado será incorrecto.
  7. En arrays, confundir tamaño con índice: int a[3] tiene índices 0..2; acceder a a[3] o a límites incorrectos provoca errores run-time.

✅ Lista de verificación para examen

  1. Explica qué es código fuente, código máquina y compilador, y describe la estructura básica de un programa C (cabecera con #include/#define y funciones, con main de tipo int).
  2. Compila y ejecuta correctamente en Linux usando cc y ./nombre, y distingue el caso de un solo fichero vs varios .c/.o con enlazado (incluyendo -lm cuando proceda).
  3. Identifica y diagnostica errores de sintaxis típicos (expected ';', undeclared, expected ')'...) y relaciona llaves desemparejadas con dificultad para localizar la línea.
  4. Distingue error de ejecución vs error de lógica, y reconoce causas típicas: segmentation fault por límites de array o scanf sin '&', y división por cero con inf/nan o excepción.
  5. Usa correctamente tipos numéricos y precisión: entiende float/double/long double, por qué hay errores de redondeo y cuándo conviene double (y qué implica quadmath/GMP a nivel de instalación/enlace).
  6. Construye condiciones compuestas con &&, || y !, usando paréntesis para controlar evaluación, y decide correctamente cuándo se ejecuta un if con una o varias sentencias (llaves obligatorias si hay varias).
  7. Escribe programas con printf/scanf haciendo coincidir especificadores de formato (%d, %lf, etc.) y usando & en scanf; incluye lectura de varios valores con el formato adecuado.
  8. Implementa bucles for/while/do while correctamente: inicialización/condición/actualización en for, diferencia entre while (condición al inicio) y do-while (mínimo una vez), y evita errores como ';' tras el for o bucles “

Testez vos connaissances

Testez vos connaissances sur Fundamentos y Técnicas en Programación en C avec 24 questions à choix multiples avec corrections détaillées.

1. ¿Qué describe mejor la función main en un programa en C?

2. ¿Qué hacen las directivas #include y #define en la cabecera de un programa en C?

Faire le QCM →

Révisez avec les flashcards

Mémorisez les concepts clés de Fundamentos y Técnicas en Programación en C avec 24 flashcards interactives.

Estructura programa en C — componentes clave?

Cabecera, funciones, main, #include, #define.

Código fuente — qué es?

Archivo legible en .c que escribe el programador.

Código máquina — qué representa?

Instrucciones ejecutables por el procesador.

Voir les flashcards →

Cours similaires

Crée tes propres fiches de révision

Importe ton cours et l'IA génère fiches, QCM et flashcards en 30 secondes.

Générateur de fiches