Fundamentos de Programación
En un mundo que ha sufrido un importante proceso de transformación digital cada vez hay más aplicativos desarrollados con el fin de interactuar con los seres humanos, si estos aplicativos no están correctamente programados un atacante puede hacer uso mal intencionado del software y controlar el flujo de ejecución, pudiendo alterar la información y/o robarla.
Antes de nada, haremos una distinción fundamental entre hardware y software
- Hardware: Todos los componentes físicos de un ordenador.
- Software: Programas e instrucciones para ejecutar tareas en un ordenador.
Una vez tenemos claro la diferencia, en esta entrada de este blog nos centraremos en el software, y en una de sus unidades fundamentales: Los Programas.
Definiríamos programa como:
- Secuencia de instrucciones.
- Entendible por el ordenador.
- Tienen un objetivo o tarea concreta.
Los ordenadores son máquinas eléctricas que sólo entienden de 0 y 1, siendo:
- 0 no hay corriente.
- 1 hay corriente.
Este es el único lenguaje que entiende el ordenador, llamado lenguaje binario.
Un programa es un conjunto de instrucciones que se crea para realizar una tarea específica en una computadora. Estas instrucciones son escritas en un lenguaje de programación y se traducen a un lenguaje que la computadora puede entender y ejecutar. Los programas pueden ser simples, como una calculadora, o muy complejos, como un sistema operativo. En esencia, un programa es como una receta que le dice a la computadora qué hacer y cómo hacerlo. Los programadores crean programas para automatizar tareas, procesar datos, resolver problemas y realizar una amplia variedad de funciones en la computadora.
Como ya hemos dicho para crear un programa y que la computadora lo interprete y ejecute, las instrucciones deben escribirse en un lenguaje de programación. En los primeros tiempos de la computación se programaba directamente en código máquina. Escribir programas así resultaba demasiado complicado, también era difícil entenderlos y mantenerlos una vez escritos. Con el tiempo, se fueron desarrollando herramientas para facilitar el trabajo y aparecieron los lenguajes de programación, que podemos dividir en dos grupos:
- Lenguajes de bajo nivel: son los más cercanos al binario, pero son difíciles de programar.
- Lenguajes de alto nivel: necesitan ser traducidos antes de llegar al ordenador, pero son fáciles de programar ya que son más cercanos al lenguaje natural de las personas
Algunos ejemplos:
- Lenguajes bajo nivel: lenguaje máquina y Ensamblador.
- Lenguajes alto nivel: C, C++, Java, PHP, Python, Go, Rust, Ruby...
En el desarrollo de software hay muchas condicionantes que marcan que elección de lenguaje se usará en el proyecto:
- Requisitos técnicos marcados por otras piezas de software/hardware.
- Tiempo de entrega del software.
- Necesidad de rendimiento.
Programar viene a ser el proceso de crear un software fiable mediante la escritura en un lenguaje (code en inglés), prueba (test), depuración (debug), compilación o interpretación, y mantenimiento (maintenance) del código fuente de dicho programa informático.
CODIFICAR ⇒ PROBAR ⇒ DEPURAR ⇒ COMPILAR/INTERPRETAR ⇒ MANTENER (y vuelta a empezar)
El funcionamiento de un equipo informático es relativamente sencillo. En un área de la memoria principal se tiene un conjunto de bits agrupados en unidades denominadas instrucciones, que son potencias de 2 y cuyo tamaño depende de la arquitectura del equipo: 8 bits, 16 bits, 32 bits, 64 bits, 128 bits. El procesador obtiene la siguiente instrucción a ejecutar, la interpreta y manda "órdenes" a los diferentes elementos del equipo como registros, memoria principal, ALU o periféricos, una vez finalizada la instrucción pasa a la siguiente instrucción de la memoria principal.
- If-else: Se indica una condición que al evaluarse devuelve cierto o falso y en función del resultado ejecuta uno u otro bloque.
- Switch: Permite evaluar una expresión y ejecutar más de dos posibles opciones en función de la expresión. Dependiendo del lenguaje, la expresión se puede limitar a comparar números enteros o caracteres como en C o en lenguajes más recientes como C. con enteros, caracteres, cadenas, booleanos o enumerados.
- While: Se ejecuta el bloque contenido en la estructura mientras se cumpla la condición lógica. Se puede dar el caso de no ejecutarse ninguna vez.
- Do-While: Se ejecuta el bloque contenido en la estructura mientras se cumpla la condición lógica. La evaluación de la condición se ejecuta al final del bloque de instrucciones.
- For: En este caso, además de la condición, posee un bloque de instrucciones que se ejecutan al inicio, el bloque en el que se encuentra la condición a evaluar en cada iteración y por último un bloque de instrucciones que se ejecuta en cada iteración del bucle. Si bien es posible indicar varias instrucciones separadas por comas en cada elemento del bucle for, no suele ser usual utilizarlo ya que no es intuitivo...
- Por valor: Se realiza una copia de la variable y esta copia es la que recibe la función, por tanto los cambios realizados en función no tienen consecuencias en la variable original.
- Por referencia: Ya sea con los mecanismos que provee de C (dirección de memoria del inicio de la variable que se pasa como argumento, conocida como puntero), Java (en las variable original se almacenan la dirección del objeto y se realiza una copia de la variable a pasar corno argumento, referenciando la copia también al objeto) o de otros lenguajes, las consecuencia principal es que las modificaciones realizadas dentro de la función afectan a la variable pasada como argumento.
- Lenguaje compilado
- Nuestro código fuente se transforma en un binario mediante compilación.
- El ordenador ejecuta el binario.
- No necesitamos por tanto ningún programa adicional.
- Lenguaje interpretado
- Nuestro código fuente es leído en tiempo real por un programa (intérprete) que lo traduce a código máquina (objeto binario).
- El ordenador ejecuta ese binario.
- Necesita por tanto un programa adicional, llamado intérprete, que hace de traductor entre las instrucciones y el código máquina.
- Lenguaje intermedio
- El código fuente se compila a un lenguaje intermedio.
- Este lenguaje intermedio se ejecuta en una máquina virtual.
- Un intérprete traduce el código fuente linea a línea como se describe a continuación: primero traduce la primera línea, detiene la traducción y, seguidamente la ejecuta; lee la siguiente línea, detiene la traducción y la ejecuta, y así sucesivamente. El intérprete tiene que estar cargado en memoria ejecutándose para poder ejecutar el programa. Al igual que el intérprete, el código fuente tiene que estar también en la memoria. En caso de detectar un error durante el proceso de traducción el intérprete detiene la ejecución del programa.
- PHP.
- Perl.
- Python.
- Ruby.
- Un compilador traduce un programa entero de un lenguaje de programación (llamado código fuente) a otro denominado lenguaje objetivo. Usualmente, el lenguaje objetivo es código máquina, aunque también puede ser traducido a un código intermedio (bytecode) o a texto. El compilador únicamente estará instalado en la máquina de desarrollo. El código generado para un sistema sólo funcionará para una arquitectura hardware y software determinadas. Si se desea ejecutar en un sistema con un hardware o software diferente habrá que volver a recompilarlo. Ejemplos de lenguajes compilados típicos son:
- C/C++.
- Pascal.
- Entre otros.
- Se compila una vez; se ejecuta muchas veces.
- La ejecución del programa objeto es mucho más rápida que si se interpreta el programa fuente.
- El compilador tiene una visión global del programa, por lo que la información de los mensajes de error es más detallada.
- Un intérprete necesita menos memoria que un compilador.
- Permite una mayor interactividad con el código en tiempo de desarrollo (e incluso, en algunos casos, mientras se ejecuta el código).
- Editor de Código: Los IDEs incluyen editores de código que ofrecen resaltado de sintaxis, sugerencias de autocompletado y otras características para mejorar la eficiencia de escritura.
- Depuración: Los entornos de desarrollo proporcionan herramientas de depuración que permiten a los programadores detectar y corregir errores en su código de manera eficiente.
- Gestión de Proyectos: Los IDEs suelen ofrecer funciones para organizar proyectos, gestionar bibliotecas y dependencias, y facilitar la colaboración en equipo.
- Integración con Herramientas: Pueden integrar herramientas de control de versiones, compiladores, analizadores estáticos y otros recursos que hacen que el desarrollo sea más efectivo.
- Personalización: Los entornos de desarrollo suelen ser altamente personalizables para adaptarse a las preferencias del programador.
- Soporte Multiplataforma: Muchos IDEs se pueden utilizar en sistemas operativos como Windows, macOS y Linux.