Taller de creación de juegos retro
Make Classic Games
C es un lenguaje de programación de proposito general que fue desarrollado entre los años 1969 y 1972.
Es un lenguaje estructurado, compilado, debilmente tipado y que puede usarse tanto como alto nivel como bajo nivel (Se considera nivel medio).
C NO es un lenguaje orientado a Objetos.
Windows:
Instalar el IDE Visual Studio
Instalar MinGW32/64
Linux:
Instalar las Herramientas de Desarrollo "build-essentials" (o equivalente en la distribución):
sudo apt install build-essentials
Este paquete incluye entre otros el compilador gcc
MacOs:
En Macos Existen diferentes opciones para utiliar un compilador de C como puede ser la utilización de Clang o incluso gcc.
user@~% clang --version
Docker
Otra opción es utilizar un contenedor docker para realizar la compilación:
FROM gcc:4.9
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
RUN gcc -o myapp main.c
CMD ["./myapp"]
docker build -t compiler .
gcc main.c -o a.out
docker run compiler
hello world
#include <stdio.h>
int main(){
printf("Hello World");
return 0;
}
Una variable en C, es un elemento donde se puede almacenar un valor.
La sintaxis para crear una es:
<tipo> <nombre>;
int num;
char letra;
Tipos Básicos de C
Tipo | Descripción | rango |
---|---|---|
int | Entero simple | -32 768 a 32 767 |
float | Decimal simple | 3.4E-38 a 3.4E+38 |
double | Decimal doble | 1.7E-308 a 1.7E+308 |
long | Entero largo | -2 147 483 648 a 2147 483 647 |
char | caracter | 0 a 255 |
bool | booleano | true o false |
Operadores Matemáticos
Operadores Lógicos
Tipo | Descripción |
---|---|
+ | Suma |
- | Resta |
* | Producto |
/ | División |
% | Resto |
>> | Desplazamiento bits derecha |
<< | Desplazamiento bits izquierda |
Tipo | Descripción |
---|---|
== | Igual que |
>= | Mayor o igual que |
<= | Menor o igual Que |
!= | Distinto De |
! | NO |
Operadores Asignación
Operadores Lógicos II
Tipo | Descripción |
---|---|
= | Asignación |
+= | Asignación con suma |
-= | Asignación con resta |
++ | Suma 1 valor |
-- | Resta 1 valor |
Tipo | Descripción |
---|---|
> | Menor que |
< | Mayor que |
&& | and |
|| | Or |
& | And Lógico |
| | Or Lógico |
Comentarios
Tipo | Descripción |
---|---|
// | Comentario de línea. |
/* */ | Comentario de Bloque |
Condicionales
if(edad<18){
printf("Es menor de edad");
}
Condicionales
if(edad<18){
printf("Es menor de edad");
}else{
printf("Es mayor de edad");
}
Condicionales
switch(a){
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
printf("Es una vocal");
break;
default:
printf("Consonante");
}
Repetitivas
while (a==1){
a++;
}
Repetitivas
do{
a++;
}while(a==1);
Repetitivas
for(int i=0;i<10;i++){
a=i+1;
}
En C, existe una serie de instrucciones especiales llamadas de preprocesado que nos van a ayudar a mantener nuestro código más ordenado.
#include
Permite añadir un fichero externo para tener acceso a sus contenido desde nuestro código
#include <stdio.h>
Nota: si el fichero va entre <> se considera de sistema y si va entre "" es local.
#define
Permite crear una constante.
#define CONSTANTE 1
Si la constante a definir es una función, esta se llama MACRO.
#define
Definir una macro
#define DOUBLE(n) (2*n)
DOUBLE(2); //4
#ifndef
Permite que se pueda acceder a bloques de código en función de si esta definida una variable o no.
#ifndef _H_MIFICHERO_
#define _H_MIFICHERO_
//codigo a incluir una sola vez.
//de esta forma aunque se incluya el fichero varias veces,
//solo se referenciará una.
#endif
En C, podemos dividir nuestros programas en pequeños subprogramas para organizarlo y poder reutilizarlo. Esto se realiza a través de las funciones.
Una función, se compone de su cabecera y de su implementación.
La cabecera de la función se compone de la siguiente información:
<tipodevuelto> <nombre>(<lista de parametros>);
int calcularDoble(int);
El cuerpo de la función, es donde estará definido su contenido. Normalmente esta en un fichero a parte.
Normalmente, los ficheros que contienen las cabaceras de las funciones son los que tienen extensión .h.
Mientras que los ficheros que contienen las implementaciones, tienen extensión .c.
int calcularDoble(int n){
return 2*n;
}
misfunciones.c
int calcularDoble(int n);
//otras funciones y variables necesarias
misfunciones.h
#include "misfunciones.h"
int calcularDoble(int n){
return 2*n;
}
Hasta ahora, hemos estado trabajando en usar variables simples; pero ¿Qué ocurre cuando queremos usar muchas variables del mismo tipo?
int datos[4]; //array de 1 dimension
int datos2[4][4] //array de 2 dimensiones
Los Arrays, permitem almacenar de forma contigua información homogénea.
Se definen:
<tipo> <nombre>[<longitud>];
Para utilizar un Array, se utiliza uno o más índices; suele ser muy útil, el uso de bucles for para recorrer o escribir las distintas posiciones de un Array.
int datos[4]; //array de 1 dimension
//inicializar un array
for(int i=0;i<4;i++){
datos[i]=i;
}
//leer un array
for(int j=0;j<4;j++){
printf("posicion %d: %d", j, datos[j]);
}
En C, no existe el tipo de dato "String" como en otros lenguajes. en C, las cadenas de caracteres, son arrays de tipo char.
char micadena[10]="Hola Mundo";
Las cadenas son arrays de char que siempre acaban con el carácter '\0'.
Un puntero, es una variable que almacena una posición de memoria.
Para manejar punteros, existen dos operadores especiales.
Operador *
Operador &
Define un puntero y su contenido.
int* mipuntero;
Establece la dirección de memoria de una variable o puntero.
int variable=1;
int* mipuntero= &variable;
int valor2 = *mipuntero;
El nombre de un array, es un puntero; y por lo tanto cada puntero, puede ser usado como un array.
int miarray[5];
int* mipuntero = miarray;
for(int i=0;i<5;i++){
printf("%d",mipuntero[i]);
}
Hasta ahora, las funciones las hemos utilizado pasando parametros básicos o como se conoce "por valor". Esto quiere decir, que en cada llamada se hace una copia de los parámetros.
int calculaDoble(int n);//Paso por valor
void calculaDoble(int* n);//Paso por referencia o por puntero.
En el paso por referencia, si se modifica el parámetro se modifica el original.
También podemos utilizar punteros a "funciones", es decir, utilizar una función como parámetro que se pueda ejecutar cuando llegue el momento.
int foo (int,int, int); //prototipo
int (*foo)(int,int,int);//puntero a función
Un puntero a función puede ser llamado en cualquier momento.
pointer(1,2,3);
En ocasiones, se necesitan tipos de datos complejos que nos permitirán definir objetos del mundo.
Para definir un struct, se utiliza la palabra reservada "struct"; seguida de la siguiente definición:
struct <nombre>{
<definicion de elementos>
}<variables>;
struct ejemplo{
int edad;
char nombre[50];
}a1;
Inicializar Structs
Acceder a Elementos
ejemplo e1={34, "victor"}
printf("%d",e1.edad);//Como variable
ejemplo* e2=&e1;//creación de un puntero.
printf("%d",e2->edad);//Como puntero
NOTA: las definiciones de structs, normalmente se definen en los ficheros .h.
typedef
Typedef, es una palabra reservada que se utiliza para crear sinonimos de tipos o structs.
typedef struct{
int edad;
char* nombre[50];
}Persona;
...
Persona mipersona;
Un enum, o tipo enumerado, permite guardar un tipo que tiene una serie de valores fijos.
typedef enum COLOR{
ROJO, VERDE, AZUL
}Color;
...
Color color= ROJO;
En proyectos ya complejos, es necesaria una herramienta que nos ayude con la configuración y compilación de todos los ficheros de nuestro proyecto.
Por ello, se utiliza la herramienta "make"; que gracias a los conocidos Makefiles, nos va a permitir configurar y construir nuestro proyecto.
main: hello.c
gcc -o hello hello.c
Para crear un Makefile se utiliza el siguiente esquema:
<objetivo>: <dependencias>
<acciones>
Donde:
Gcc (gnu C compiler), es un compilador o grupo de compiladores que nos permitirá generar un ejecutables o los diferentes ficheros necesarios para crear nuestra aplicación.
gcc [opciones] fichero.c
Las opciones pueden ser:
Crear una aplicación de consola usando el lenguaje C que permita a un usuario realizar operaciones matemáticas a través de un menú de texto; las operaciones son:
En cada operación se debe pedir los diferentes operando y mostrar por pantalla el resultado.
Utilizar un fichero MakeFile para realizar la compilación y generación del ejecutable.