136 lines
9.4 KiB
Markdown
136 lines
9.4 KiB
Markdown
# <mark style="background: #FFF3A3A6;">TEMA 1: Introducción</mark>
|
|
Aunque la sintaxis de Java derive de C, NO son tan similares. Hay que entender el ámbito del lenguaje: por ejemplo C (Software de Sistemas, sustitución de assembly, etc) o Java (aplicaciones, etc). Existen palabras reservadas con más de un uso (`static` o `const`).
|
|
|
|
> **C++ amplia el ámbito de C**
|
|
|
|
## <mark style="background: #ADCCFFA6;">1. Introducción y características</mark>
|
|
### <mark style="background: #FFB86CA6;">Estandarización</mark>
|
|
Los estándares más usados para C y C++ son el 99 y 98 respectivamente.
|
|
```C
|
|
#include "archivo.h"
|
|
// "pega" archivo.h y sigue compilando
|
|
void main() {
|
|
|
|
}
|
|
```
|
|
Dependiendo del compilador se pueden especificar directivas como `#pragma once` para solo incluir el archivo una vez.
|
|
|
|
### ⚠ Incongruencia
|
|
C/C++ es portable para **aplicaciones** pero para Software de Sistemas **NO** $\rightarrow$ siempre habrá problemas de portabilidad. **SÍ** que es portable desde el punto de vista de los 80:
|
|
- Hay compilador C para cualquier arquitectura.
|
|
- Si sé C, puedo programar en cualquier arquitectura.
|
|
- El código fuente es compatible.
|
|
|
|
### <mark style="background: #FFB86CA6;">Nivel de abstracción</mark>
|
|
Varía de un lenguaje a otro (C tiene menor nivel de abstracción que los lenguajes modernos). Las estructuras del lenguaje y funcionamiento general son lo más parecido al código máquina. C++ tiene mayor nivel de abstracción pero aumenta la sobrecarga.
|
|
|
|
### <mark style="background: #FFB86CA6;">Runtime, librerías, frameworks</mark>
|
|
**Runtime** es el código que añade el compilador, que no está asociado al código de usuario sino al lenguaje. En C es mínimo, por eso se prefiere para sistemas empotrados.
|
|
|
|
### <mark style="background: #FFB86CA6;">Relación C/C++</mark>
|
|
Compatible C -> C++. Las extensiones mas importantes de C++ son POO, tipado, librerías...
|
|
La mayor parte de compiladores son duales. La extensión del archivo determina si hay que compilar C (.c, .h) o C++ (.cpp, .hpp ó .hh).
|
|
|
|
### <mark style="background: #FFB86CA6;">Java VS C/C++</mark>
|
|
|
|
| **Java** | **C** | **C++** |
|
|
| ----------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
|
| El programa se compone de clases (propiedades y métodos). | El programa es un conjunto de datos y funciones, **no existen clases**. | |
|
|
| Para ejecutar un programa, se empieza por el punto de entrada (main) y se van instanciando, modificando, destruyendo objetos. | Para ejecutar un programa, se empieza por el punto de entrada (main), se inicializan las variables globales y se van creando, modificando variables y ejecutando funciones. | |
|
|
| Base de programación: Objetos | No hay base de programación | |
|
|
| La unidad de compilación es el fichero (o clase pública). | La unidad de compilación es el fichero. | |
|
|
| <span style="color:red">Básicamente, típico lenguaje orientado a objetos</span> | <span style="color:red">Básicamente, típico lenguaje imperativo (procedural)</span> | |
|
|
## <mark style="background: #ADCCFFA6;">2. Programar en C/C++</mark>
|
|
A diferencia de Java, que declarar y definir se realiza a la vez:
|
|
```java
|
|
public class Persona {
|
|
private String name;
|
|
|
|
...
|
|
|
|
public String getName() {
|
|
return this.name;
|
|
}
|
|
}
|
|
```
|
|
En C/C++ se debe declarar primero la función para que al compilar, la primera pasada la "registre", y luego a la hora de ejecutar, se pueda ejecutar dicha función.
|
|
```C
|
|
void funcion(); // declaración
|
|
|
|
int main()
|
|
{
|
|
funcion();
|
|
return 0;
|
|
}
|
|
|
|
void funcion()
|
|
{
|
|
// definición
|
|
}
|
|
```
|
|
En C/C++ se pueden usar sentencias `#include` para "importar" archivos que contienen declaraciones (de variables, funciones, etc)
|
|
### <mark style="background: #FFB86CA6;">Tipos de datos</mark>
|
|
**Variables:**
|
|
- `char` = 8 bits (-128, 127)
|
|
- `unsigned char` = 8 bits (0, 255)
|
|
- `short int` = 16 bits
|
|
- `int` = 32 bits
|
|
- `long int` = 32 bits
|
|
- `long long int` = 64 bits
|
|
**En cuanto a punteros:**
|
|
- `<tipo>*` 32 bits (x86) 64 bits (x64)
|
|
# <mark style="background: #FFF3A3A6;">TEMA 2: Depuración</mark>
|
|
|
|
## <mark style="background: #ADCCFFA6;">1. Introducción</mark>
|
|
El depurador es una herramienta para diseccionar el código y poder analizarlo para arreglar los errores. En ingeniería se sigue la regla "Para matar moscas mejor usar un matamoscas que un cañón. "
|
|
## <mark style="background: #ADCCFFA6;">2. Tipos de error</mark>
|
|
Los errores son comportamientos no deseados del código causados por la inexperiencia (al principio) o falta de atención del programador.
|
|
### <mark style="background: #FFB86CA6;">Errores sintácticos</mark>
|
|
Son los errores más fáciles de detectar y corregir. El compilador suele detectar todos y decirte dónde están y qué los causa (pero no siempre). Suelen provocar más errores en cadena.
|
|
### <mark style="background: #FFB86CA6;">Errores lógicos/semánticos</mark>
|
|
Más difíciles de detectar (ninguna herramienta los detecta del todo bien) pero relativamente fáciles de corregir.
|
|
### <mark style="background: #FFB86CA6;">Errores de diseño</mark>
|
|
Todos los componentes del sistema funcionan pero el sistema no hace lo esperado. Problemas asociados a la Ing. del Software. Muy difíciles de detectar y costosos de arreglar.
|
|
## <mark style="background: #ADCCFFA6;">3. Fases del tratamiento de errores</mark>
|
|
Hay una serie de pasos comunes (pero no infalibles):
|
|
- Detectar el problema
|
|
- Recolectar datos
|
|
- Diagnóstico
|
|
- Reparación
|
|
- Verificación
|
|
### <mark style="background: #FFB86CA6;">Detección del problema</mark>
|
|
Hay varias herramientas:
|
|
- **Warnings:** muchas veces son la posible causa de errores futuros. Se deberían arreglar siempre que se pueda, pero OJO: algunas veces son <span style="color:rgb(255, 0, 0)">falsos positivos</span>.
|
|
### <mark style="background: #FFB86CA6;">Controlar la ejecución</mark>
|
|
Los computadores actuales no son capaces de determinar la información importante para dar con un error. Para eso se usa el **depurador**, que aunque no te da la causa del error como tal, si que se puede descubrir "pidiéndole" la información adecuada.
|
|
### <mark style="background: #FFB86CA6;">Inspección de estado</mark>
|
|
**Contexto:** datos accesibles en medio de la ejecución (variables locales o globales, parámetros...).
|
|
### <mark style="background: #FFB86CA6;">Pila de llamadas y marco de pila</mark>
|
|
La pila de llamadas es un bloque de memoria que el S.O. asigna al programa para llamadas y retornos de funciones. Si este se llena, se produce un "stack overflow". El marco de pila es básicamente la región de la pila marcada por los punteros ESP (límite superior de la pila) y EBP (inicio de marco de pila), que pertenece a una función.
|
|
|
|
![[Pasted image 20241003113528.png|500]]
|
|
# <mark style="background: #FFF3A3A6;">TEMA 3: Generación de programas</mark>
|
|
## <mark style="background: #ADCCFFA6;">1. Introducción</mark>
|
|
Es conveniente conocer como se genera el código:
|
|
- qué es un programa ejecutable
|
|
- cómo se trata desde el punto de vista del SO y del IDE
|
|
y qué elementos intervienen en la generación del ejecutable:
|
|
- compiladores y linkers
|
|
- archivos objeto, runtime, bibliotecas estáticas y dinámicas
|
|
## <mark style="background: #ADCCFFA6;">2. Archivos ejecutables</mark>
|
|
|
|
![[Pasted image 20241010091834.png|600]]
|
|
El ejecutable se genera a partir de:
|
|
- el código fuente
|
|
- el proceso de compilación
|
|
La gran parte del ejecutable la añade el IDE y **no** es generada del código fuente.
|
|
## <mark style="background: #ADCCFFA6;">3. Transformación de formatos</mark>
|
|
![[Pasted image 20241010092102.png|600]]
|
|
Hay al menos tres formatos:
|
|
- Código fuente de alto nivel: creado por el programador y compilado por el compilador del lenguaje X.
|
|
- Código **objeto**: creado por el compilador, procesado por el linker.
|
|
- Ejecutable: creado por el linker, procesado por el cargador del SO.
|
|
## <mark style="background: #ADCCFFA6;">4. Tipos de archivo ejecutable</mark>
|
|
Hay tantos tipos de ejecutable como mecanismos de carga distintos. Los detalles del mecanismo de carga dependen del SO.
|
|
### <mark style="background: #FFB86CA6;">Imágenes binarias</mark>
|
|
El ejecutable es un **mapa de memoria**. Es el formato más simple, sin información de carga/reubicación. En el archivo están las zonas de memoria que usa el programa (el SO lo carga y se ejecuta). Se usan en computadores donde el SO o es muy simple o no existe (embedded). |