Documentos de Académico
Documentos de Profesional
Documentos de Cultura
UAX Programaci N Presentaci N
UAX Programaci N Presentaci N
Septiembre 2022
1 Introducción
2 Programación Estructurada
1 Introducción
Palabras reservadas
Tipos primitivos en C
Imprimir en la consola
2 Programación Estructurada
Codificación
Compilador / Enlazador
IDE
Comentarios
Comentarios de bloque:
Comentarios de bloque
Empieza por /*
Termina por */
Comentarios de lı́nea:
Comentarios de lı́nea
Empieza por //
Termina en el final de la lı́nea
Comentarios de documentación (JAVA):
Comentarios de documentación
Empieza por /**
Termina por */
Fernando Rodrı́guez Sela (UAX) UAX - Programación 1º Septiembre 2022 8 / 106
Introducción
Convenio identificadores
Introducción
Palabras reservadas
Palabras reservadas
Introducción
Tipos primitivos en C
Modificadores
Modificador Descripción
signed Con signo (por defecto)
unsigned Sin signo
long Largo
short Corto
const Valor constante
volatile Variable cuyo valor se modifica externamente
IEEE-754:
https://en.wikipedia.org/wiki/Double-precision_
floating-point_format
Tipo booleano
En C99, usa la librerı́a stdboolean.h
Introducción
Imprimir en la consola
#include <stdio.h>
void main() {
printf("Hola Mundo !\n");
}
Hola Mundo !
y cambiará de lı́nea.
Fernando Rodrı́guez Sela (UAX) UAX - Programación 1º Septiembre 2022 20 / 106
Introducción Imprimir en la consola
printf - Formatos
La función anterior también puede servirnos para formatear cadenas más
complejas, ya que la función acepta un número indeterminado de opciones:
#include <stdio.h>
#include <limits.h>
int main() {
printf("El tipo long ocupa %d bytes y tiene un rango de valores
,→ entre %ld y %ld\n", sizeof(long), LONG_MIN, LONG_MAX);
}
printf - Formatos
Formato Salida
%d o %i Entero en base 10 con signo
%u Entero en base 10 sin signo
%o Entero en base 8 (octal) sin signo
%x Entero en base 16 (hexadecimal) en minúsculas
%X Entero en base 16 (hexadecimal) en MAYÚSCULAS
%ld Entero de 32 bits (long)
%lu Entero de 32 bits sin signo (unsigned long)
%f Real de precisión simple (float)
%lf Real de precisión doble (double)
%e Real con notación cientı́fica1 en minúsculas
%E Real con notación cientı́fica en MAYÚSCULAS
%c Caracter ASCII (char)
%s Cadena de caracteres (char*)
1
mantisa / exponente
Fernando Rodrı́guez Sela (UAX) UAX - Programación 1º Septiembre 2022 22 / 106
Introducción Imprimir en la consola
Caracteres especiales
Carácter Significado
\t Tabulador
\n Salto de lı́nea
\r Inicio de lı́nea
\” Comillas dobles
\’ Comillas simples
\\ Carácter barra hacia atrás (\)
1 Introducción
2 Programación Estructurada
Estructura de un programa
Identificadores, variables, Operaciones y expresiones
Punteros
Lectura de datos por teclado
Funciones
Separando el código en múltiples ficheros
Estructuras de control
Recursividad
Arrays
Estructuras de datos
TAD - Tipo Abstracto de Datos
Programación Estructurada
Estructura de un programa
Estructura de un programa en C
Programación Estructurada
Tipos de datos
2
Ir a las transparencias de lso tipos primitivos: 2
Fernando Rodrı́guez Sela (UAX) UAX - Programación 1º Septiembre 2022 29 / 106
Programación Estructurada Identificadores, variables, Operaciones y expresiones
Números enteros
#include <stdio.h>
int main() {
int entero = 625;
long enteroLargo = 387482;
}
3
La operación módulo nos devuelve el resto de la división entera
Fernando Rodrı́guez Sela (UAX) UAX - Programación 1º Septiembre 2022 31 / 106
Programación Estructurada Identificadores, variables, Operaciones y expresiones
Números reales
#include <stdio.h>
int main() {
float real = 625.43;
double realDoblePrecision = 3.1e21;
}
Nota
En la entrada de números reales podemos usar notación cientı́fica
4
Fijarse que en números reales no hay operación módulo
Fernando Rodrı́guez Sela (UAX) UAX - Programación 1º Septiembre 2022 33 / 106
Programación Estructurada Identificadores, variables, Operaciones y expresiones
Caracteres
#include <stdio.h>
int main() {
char caracter1 = 'F';
char caracter2 = 70;
}
Textos
#include <stdio.h>
int main() {
char *cadena = "Mi cadena de texto";
}
5
Estudiaremos los punteros en breve
6
El * representa ’puntero a . . . ’
Fernando Rodrı́guez Sela (UAX) UAX - Programación 1º Septiembre 2022 35 / 106
Programación Estructurada Identificadores, variables, Operaciones y expresiones
Operadores booleanos
Precedencia de operaciones
El orden es el siguiente:
1 Operadores unarios
2 Operadores multiplicativos (izquierda a derecha)
3 Operadores aditivos (izquierda a derecha)
4 Operadores de relación
5 Operadores de asignación
Conversión de tipos
int a = 3;
int b = 5;
printf("División entera %d\n", a/b); // Da 0
printf("División real %f\n", a/(float)b); // Da 0.6
Ejercicio
Ejercicio
Implementar un programa que dadas dos variables enteras y otras dos
reales:
Imprima los cuatro números
Mostrar los resultados de operaciones aditivas, multiplicativas, ...
Programación Estructurada
Punteros
Punteros
ATENCIÓN
Aviso a navegantes: lo que vamos a ver a continuación son conceptos
avanzados de cómo usar la memoria de un ordenador.
Si bien no es difı́cil, si tienes que prestar mucha atención.
Al final, entender bien esta parte es lo que diferencia a los buenos y malos
programadores.
Sea el lenguaje que sea (que no te engañen), hay punteros (algunos lo
ocultan, pero están allı́) pues es como funciona el procesador y el lenguaje
máquina que, al fin y al cabo, es lo que generamos en última instancia.
Punteros
Qué es un puntero
Un puntero es una variable que almacena la dirección de memoria de otra
variable.
Uso de punteros en C
En C, los punteros los declaramos con el uso del sı́mbolo * delante del
nombre de la variable.
Usando el * Nos referimos a “La dirección referida en ...”
Si necesitamos saber la dirección en memoria de una variable cualquiera,
usamos el sı́mbolo & delante del nombre de la variable.
Esto nos permitirá tener acceso a variables de otras funciones o disponer
de estructuras de datos más “complejas” como iremos viendo en los
próximos cursos.
#include <stdio.h>
int main() {
int numero = 3;
int *refANumero = №
Aritmética de punteros
Los punteros no dejan de ser una variable más, por lo que podremos usar
operaciones aritméticas con ellos (suma, resta, ...) permitiéndonos
movernos por la memoria a nuestro antojo (y ası́ recorrer secuencias de
datos).
Atención
Hay que tener mucho cuidado cuando jugamos con la aritmética de
punteros pues es muy fácil salirse de las zonas de memoria que nos asignó
el sistema operativo, provocando un error tipo “Buffer Overflow”.
También, programas que controlan poco estas situaciones son propensos a
ser vı́ctimas de ataques.
#include <stdio.h>
int main() {
char *cadena = "Hola Mundo cruel";
char *caracter = cadena;
printf("%c\n", *caracter); // H
caracter += 5;
printf("%c\n", *caracter); // M
}
Punteros void
7
Si recuerdas, indicar entre paréntesis el tipo de dato: (float)miVariableEntera
Fernando Rodrı́guez Sela (UAX) UAX - Programación 1º Septiembre 2022 48 / 106
Programación Estructurada Punteros
Punteros
Programación Estructurada
Será muy habitual que necesites solicitar información al usuario, para ello
deberás esperar a que introduzca la información por el teclado y pulse
ENTER.
En C, haremos uso de la función scanf, cuyo funcionamiento es muy
similar a la que ya conocemos, printf.
Importante
Fı́jate que tenemos que darle una variable para que nos escriba la
información que el usuario ha tecleado; para que esto funcionea , scanf
espera recibir un puntero a una variable dónde escribir, por eso le pasamos
&miVariable (La dirección de memoria dónde se aloja miVariable.
a
Responderemos al ¿por qué? cuando hablemos de las funciones.
Uso de scanf
#include <stdio.h>
#define MAX_NOMBRE 40
int main() {
int entero;
printf("Dime un numero: ");
scanf("%d", &entero);
float decimal;
printf("Dime un numero real: ");
scanf("%f", &decimal);
Uso de scanf
char nombre[MAX_NOMBRE];
printf("Dime tu nombre: ");
scanf("%s", nombre);
int entero2;
printf("Ahora dime 2 numeros enteros separados por un espacio: ");
scanf("%d %d", &entero, &entero2);
printf("Me has dicho %d y %d%n", entero, entero2);
}
Ejercicio
Ejercicio
Implementar un programa calcule la ecuación de segundo grado usando 3
variables.
Solicitar los datos al usuario
√
−b ± b 2 − 4ac
x= (1)
2a
Cuidado
Cuidado con resultados complejos; Evita meter valores que hagan que la
raı́z sea negativa, es decir, debe cumplirse que: 4ac <= b 2
Programación Estructurada
Funciones
Funciones y Procedimientos
Hasta ahora hemos estado escribiendo nuestros programas bajo una única
función, la principal (main).
Si bien esto funciona, no es un método viable para implementar programas
de gran envergadura8 , además que nos obliga a repetir código cuando
requerimos hacer una misma tarea una y otra vez a lo largo de nuestro
programa.
Todo lenguaje de programación dispone de mecanismos para organizar
nuestro código y poder agrupar funcionalidades de manera lógica.
Vamos a estudiar como se utilizan las funciones en C.
8
Por ejemplo, el Kernel 5.12 de Linux tiene 28.8 millones de lı́neas de código
Fernando Rodrı́guez Sela (UAX) UAX - Programación 1º Septiembre 2022 56 / 106
Programación Estructurada Funciones
Función o Procedimiento
Esta distinción es más teórica que otra cosa, básicamente una función
debe devolver un valor mientras que un procedimiento simplemente
ejecuta comandos pero no devuelve nada.
Con el tipo void podemos indicar que NO devolvemos absolutamente
nada (vacı́o) y por tanto estaremos definiendo un procedimiento.
¿Qué tamaño deberı́a tener una función? ¿cuándo debo crear una nueva?
Si bien no hay una respuesta “oficial” a estas preguntas, el sentido común
nos dice que una función no deberı́a superar el tamaño de una pantalla, es
decir, que podamos verla entera sin tener que hacer scroll.
Por otro lado, a la segunda pregunta, debemos crear una nueva función
cuando lo implementado en ella sea un “concepto” propio o tenga entidad
propia y podamos darle un nombre.
La experiencia y los años programando te irán diciendo dónde hacer
nuevas funciones.
// Definimos un procedimiento
void nombreProcedimiento(int parametro1, float parametro2) {
// Código del procedimiento
// No se devuelve NADA
}
int main() {
int a = nombreFuncion(3, 2.8);
nombreProcedimiento(3, 2.8);
return 0;
}
Ejemplos
Veamos éste código, podemos observar que repetimos una y otra vez lo
mismo, es un ejemplo claro de que nos hace falta una función:
void main() {
// ...
double areaCirculo1 = 2 * M_PI * pow(radioCirculo1, 2);
// ...
double areaCirculo2 = 2 * M_PI * pow(radioCirculo2, 2);
// ...
}
Ejemplos
Separada en funciones:
void main() {
// ...
double areaCirculo1 = areaCirculo(radioCirculo1);
// ...
double areaCirculo2 = areaCirculo(radioCirculo2);
// ...
}
El paso de parámetros
Como hemos visto, podemos definir un número variable de parámetros que
se pueden pasar a una función en C, pero ¿qué pasa realmente entre
“bambalinas”?
Lo que sucede es que se copian los datos a la pila y al entrar en la
función, se asigna el valor a la variable local.
El paso de parámetros
IMPORTANTE
Grábatelo a fuego: todo dato que se pasa a una función es una COPIA
Devolución de resultados
sumaDos(&miNumero);
Función main
Ya hemos hablado de la función main como punto de entrada de nuestra
aplicación. Todo programa en C empieza en main.
También vimos que main devolvı́a int o nada void.
Esto nos permitı́a informar al Sistema Operativo acerca de posibles fallos
de nuestra aplicación (0 =¿ Todo Ok).
Y parámetros, ¿puede main recibir parámetros?
La respuesta es SÍ, más aún, si algún dı́a usaste algún programa desde una
consola, seguramente habrás llamado al ejecutable y le habrás pasado
algún parámetro.
Pues bien, para poder acceder a esos parámetros desde nuestro programa
en C, lo haremos de la siguiente forma:
Nota
Los arrays los veremos más adelante
Ejercicio
Ejercicio
Implementa una función que devuelva si un número es par o no.
Implementa un procedimiento, que reciba un número, llame a la función
anterior y escriba en pantalla el resultado.
Desde main, simplemente llamaremos al procedimiento.
Observa con el depurador cómo se van copiando los valores a las distintas
variables locales pero están en distintos sitios de la memoria
Ejercicio
Modifica el programa de la ecuación de segundo grado y usa funciones o
procedimientos (según consideres).
Recuerda, que devolverás dos resultados ... ¿cómo se te ocurre que puedes
hacerlo?
Programación Estructurada
main.c
Dónde vayamos a usar las nuevas funciones, debemos incluir su cabecera.
#include "circulo.h"
void main() {
// ...
double areaCirculo1 = areaCirculo(radioCirculo1);
// ...
double areaCirculo2 = areaCirculo(radioCirculo2);
// ...
}
Fı́jate que ahora lo hacemos con las comillas y no con los sı́mbolos ¡ y ¿.
Esto es porque con ¡ ¿ va a buscar la cabecera en las carpetas
predefinidas, y con comillas, en la carpeta del proyecto.
Fernando Rodrı́guez Sela (UAX) UAX - Programación 1º Septiembre 2022 76 / 106
Programación Estructurada Separando el código en múltiples ficheros
circulo.c
circulo.h
#ifndef _CIRCULO_H_
#define _CIRCULO_H_
#endif
Construcción
Finalmente queda indicar al compilador que compile nuestro nuevo fichero
y los enlace.
En el caso de CLion, trabaja con CMake, una herramienta para facilitar
las labores de construcción.
Únicamente nos queda indicarle que considere nuestro nuevo fichero
modificando el fichero ‘CMakeLists.txt’ y añadiéndolo a la lista de
add executable(...):
cmake_minimum_required(VERSION 3.23)
project(programaCirculos C)
set(CMAKE_C_STANDARD 99)
Programación Estructurada
Estructuras de control
Estructuras de control
if (/* Condición */ ) {
// Código a ejecutar si Condición es verdadera (!= 0)
}
if (/* Condición */ )
// Una única lı́nea (instrucción) a ejecutar si Condición es
,→ verdadera
if (/* Condición */ ) {
// Código a ejecutar si Condición es verdadera (!= 0)
} else {
// Código a ejecutar si Condición es falsa (== 0)
}
if (/* Condición */ )
// Una única lı́nea (instrucción) a ejecutar si Condición es
,→ verdadera
else
// Una única lı́nea (instrucción) a ejcutar si Condición es falsa
if (/* Condición 1 */ ) {
// Código a ejecutar si Condición 1 es verdadera (!= 0)
} else if (/* Condición 2 */ ) {
// Código a ejecutar si Condición 1 es falsa (== 0) y Condición 2
,→ es verdadera (!= 0)
} else if (/* Condición 3 */ ) {
// Código a ejecutar si Condición 1 y 2 son falsas (== 0) y
,→ Condición 3 es verdadera (!= 0)
} else {
// Código a ejecutar si todas las condiciones son falsas
}
switch(/* Variable */ ) {
case /* Valor 1*/ :
// Código a ejecutar si Variable == Valor 1
break;
case /* Valor 2*/ :
// Código a ejecutar si Variable == Valor 2
break;
default:
// Código a ejecutar si Variable no se cubre en ningún case
}
switch(/* Variable */ ) {
case /* Valor 1*/ :
// Código a ejecutar si Variable == Valor 1
case /* Valor 2*/ :
// Código a ejecutar si Variable == Valor 2 o == Valor1
break;
default:
// Código a ejecutar si Variable no se cubre en ningún case
}
NOTA
Hay lenguajes que OBLIGAN a poner los break en todos los case, como
C#
Ejercicio
Ejercicio
Implementar un programa que dada una variable entera nos indique:
Si es par
Si es impar
Si es múltiplo de 3
Si es múltiplo de 5
Si es múltiplo de 3 y 5
Ejercicio
Ejercicio
Implementar un programa que pregunte al usuario su edad y a
continuación escriba en pantalla el precio de la cuota del club de Golf:
10€ menores de 18
20€ menores de 25
30€ menores de 65
15€ mayores de 65
Ejercicio
Ejercicio
Preguntar al usuario la fecha (dı́a, mes y año).
A continuación escribirla como:
Hoy es 25 del Septiembre del 2022
Ejercicio
Ejercicio
Preguntar al usuario la fecha (dı́a, mes y año).
A continuación indicar cuántos dı́as quedan del mes:
Hoy es 25/9/2022. Quedan 5 dı́as para terminar el mes.
Bisiestos
Un año es bisiesto si es múltiplo de 4, salvo que sea a su vez múltiplo de
100.
Si es múltiplo de 100, entonces también deberá ser múltiplo de 400.
Implementa una función boolean esBisiesto(int anio); que haga esta
comprobación.
Los bucles nos permiten ejecutar una parte de nuestro código múltiples
veces.
En C disponemos de tres:
for
while
do ... while
void main() {
printf("Antes del goto\n");
goto salir;
// ... código que no se ejecutará
salir: printf("Última lı́nea\n");
}
Programación Estructurada
Recursividad
Programación Estructurada
Arrays
Programación Estructurada
Estructuras de datos
Programación Estructurada
1 Introducción
2 Programación Estructurada
Fernando Rodrı́guez Sela (UAX) UAX - Programación 1º Septiembre 2022 100 / 106
Programación Orientada a Objetos - OOPS Del TAD a la Clase
Fernando Rodrı́guez Sela (UAX) UAX - Programación 1º Septiembre 2022 101 / 106
Programación Orientada a Objetos - OOPS Introducción a JAVA
Introducción a JAVA
Fernando Rodrı́guez Sela (UAX) UAX - Programación 1º Septiembre 2022 102 / 106
Programación Orientada a Objetos - OOPS Lectura de teclado. Clases de Utilidad
Fernando Rodrı́guez Sela (UAX) UAX - Programación 1º Septiembre 2022 103 / 106
Programación Orientada a Objetos - OOPS Clases y Objetos
Clases y Objetos
Fernando Rodrı́guez Sela (UAX) UAX - Programación 1º Septiembre 2022 104 / 106
Programación Orientada a Objetos - OOPS Control de Errores. Excepciones
Fernando Rodrı́guez Sela (UAX) UAX - Programación 1º Septiembre 2022 105 / 106
Programación Orientada a Objetos - OOPS Entrada/Salida. Ficheros
Entrada/Salida. Ficheros
Fernando Rodrı́guez Sela (UAX) UAX - Programación 1º Septiembre 2022 106 / 106