<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="es">
		<id>https://1984.lsi.us.es/wiki-c/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Carfalgar</id>
		<title>Wiki del curso de C - Contribuciones del usuario [es]</title>
		<link rel="self" type="application/atom+xml" href="https://1984.lsi.us.es/wiki-c/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Carfalgar"/>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php/Especial:Contribuciones/Carfalgar"/>
		<updated>2026-05-14T17:34:00Z</updated>
		<subtitle>Contribuciones del usuario</subtitle>
		<generator>MediaWiki 1.29.0</generator>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=319</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=319"/>
				<updated>2019-06-26T18:15:15Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Tareas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:Slides_prin.pdf|Transparencias para imprimir]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
* [https://github.com/profedotc/solucion Repositorio con la solución del trabajo de clase] (se irá actualizando)&lt;br /&gt;
* [https://en.cppreference.com/w/c Documentación de C]&lt;br /&gt;
* [[:Archivo:Autotools.zip | Plantilla autotools]]&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
# https://youtu.be/IDfllYxE7I4&lt;br /&gt;
# https://youtu.be/57-zWEnGxHU&lt;br /&gt;
# https://youtu.be/1SJ_fEXD7OA&lt;br /&gt;
# https://youtu.be/EhX3E8lLcUM&lt;br /&gt;
# No hay&lt;br /&gt;
# https://youtu.be/dk-0xF5pJpQ (incompleto)&lt;br /&gt;
# https://youtu.be/sq14oKSodPM&lt;br /&gt;
# https://youtu.be/JHUozE_4HPs&lt;br /&gt;
# https://youtu.be/cVDUGO0_saE&lt;br /&gt;
# https://youtu.be/Qq9u5Odq0jU&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
|&lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Crear makefile y dividir el programa&lt;br /&gt;
* Se crean &amp;quot;gol.h&amp;quot; y &amp;quot;gol.c&amp;quot;&lt;br /&gt;
* Se crea un makefile para compilar y limpiar el repositorio&lt;br /&gt;
* Se añade un .gitignore para ignorar los productos de la compilación&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 7&lt;br /&gt;
| 7.1&lt;br /&gt;
| Objetos: Reserva dinámica de memoria para la estructura `gol`&lt;br /&gt;
* Se cambia ligeramente la interfaz de la función `gol_alloc` para que devuelva un puntero a `struct gol` en lugar de recibirlo.&lt;br /&gt;
* Ahora se reservan dinámicamente dos bloques de memoria: uno para la estructura `struct gol` y otro para los arrays del mundo.&lt;br /&gt;
* La función `gol_free` debe liberar los dos bloques de memoria.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 7.2&lt;br /&gt;
| Objetos: Ocultar la estructura `gol`&lt;br /&gt;
Mediante una declaración adelantada de `struct gol` en `gol.h` conseguimos&lt;br /&gt;
ocultar los campos de nuestro objeto (privatizar) a los usuarios de la librería.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 8&lt;br /&gt;
| 8.1&lt;br /&gt;
| Utilizar getopt para recibir argumentos de línea de comandos&lt;br /&gt;
* El programa ahora recibe como argumentos el ancho y el alto del mundo, además de el argumento `-u, --usage` que imprime el siguiente mensaje de ayuda:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt;&lt;br /&gt;
      -u, --usage: Prints this help message&lt;br /&gt;
      -w, --width: Width of the world&lt;br /&gt;
      -h, --height: Height of the world&lt;br /&gt;
* Es obligatorio especificar el tamaño del mundo, si no se especifica se imprime un mensaje de error y se termina el programa.&lt;br /&gt;
* Se define el tipo `struct gol_options` para guardar los parámetros de entrada: `int width`, `int height` y `bool usage`&lt;br /&gt;
* Se crean dos funciones estáticas que encapsulan la lógica de tratar los argumentos y de imprimir el mensaje de ayuda:&lt;br /&gt;
* `static bool parse_args(struct gol_options *gol_opt, int argc, char *argv[]);`&lt;br /&gt;
* `static void print_usage(const char *argv0);`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 8.2&lt;br /&gt;
| Implementar la opción de inicializar el mundo aleatoriamente&lt;br /&gt;
* Se añade un argumento opcional con un parámetro obligatorio. Indica el patrón de inicialización del mundo: &amp;quot;glider&amp;quot; o &amp;quot;random&amp;quot;&lt;br /&gt;
* Se añade otro argumento opcional con parámetro obligatorio. Proporcionará la semilla para `srand()`. Si no se pasa este parámetro, se toma como semilla el tiempo actual. Esta es ahora la salida de `./gol -u`:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt; [-s &amp;lt;seed&amp;gt;] [-p &amp;lt;pattern&amp;gt;]&lt;br /&gt;
      -u, --usage:             Prints this help message&lt;br /&gt;
      -w, --width:             Width of the world&lt;br /&gt;
      -h, --height:            Height of the world&lt;br /&gt;
      -s, --Seed [seed]:       Seed for random world.&lt;br /&gt;
      -p, --pattern [pattern]: Initialization pattern:&lt;br /&gt;
 				 - glider&lt;br /&gt;
 				 - random&lt;br /&gt;
* Se modifica el método `gol_init()` para recibir un enumerado, `enum gol_init_pattern`, que esta definido en `gol.h`. El método `gol_init()` llama a los métodos privados `gol_init_rand()` o `gol_init_glider()`, según el patrón de inicialización seleccionado.&lt;br /&gt;
* Se crea una función auxiliar en `main.c` que transforma del string recibido como argumento a el enumerado que acepta `gol_init()`&lt;br /&gt;
* Se modifica `mem_test.c` para adaptarlo al nuevo `gol_init()`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 9&lt;br /&gt;
| 9.1&lt;br /&gt;
| Cargar y guardar el mundo desde un archivo binario&lt;br /&gt;
* Implementar los métodos `gol_save()` y `gol_load()` para guardar y cargar el mundo desde un archivo binario. Estas funciones simplemente guardan el array tal cual en el archivo especificado y leen el archivo guardándolo en el array.&lt;br /&gt;
 bool gol_load(struct gol *gol, const char *file);&lt;br /&gt;
 bool gol_save(const struct gol *gol, const char *file);&lt;br /&gt;
* Modificar el main para que acepte los siguientes comandos, además de 'q' para cerrar:&lt;br /&gt;
* 'l': Si se pulsa este caracter, llamar a una función estática `load_world()` que pida al usuario que inserte el nombre de un archivo.  Luego carga este archivo con la función `gol_load()`&lt;br /&gt;
* 's': Si se pulsa este caracter, llamar a una función estática `save_world()` que pida al usuario que inserte el nombre de un archivo.  Luego guarda este archivo con la función `gol_save()`&lt;br /&gt;
* Si cualquiera de los nuevos comandos falla, se informa al usuario del error y se continua la ejecución. Para que el usuario pueda leer el mensaje de error se llama a `getchar()`, así se pausa la ejecución hasta que se pulse un caracter.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 9.2&lt;br /&gt;
| Guardar y cargar el mundo desde un archivo de texto&lt;br /&gt;
Modificar `gol_save()` y `gol_load()` para guardar y cargar el estado del&lt;br /&gt;
mundo en un formato de texto parecido al que se usa en `gol_print()`.&lt;br /&gt;
&lt;br /&gt;
Ejemplo de archivo para mundo de 10x20:&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . # . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . # # # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 10&lt;br /&gt;
|&lt;br /&gt;
| Configura compilación con autotools&lt;br /&gt;
* Se mueve todo el código a una nueva carpeta `src/`&lt;br /&gt;
* Se crean los archivos necesarios para configurar autotools:&lt;br /&gt;
** `autogen.sh`&lt;br /&gt;
** `configure.ac`&lt;br /&gt;
** `makefile.am`&lt;br /&gt;
* Se elimina el `makefile` ya que este será generado por autotools&lt;br /&gt;
* Se añaden al `.gitignore` todos los archivos autogenerados de autotools&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; | 11&lt;br /&gt;
| 11.1&lt;br /&gt;
| Objetos II: Implementar el objeto `gol_toroid` hijo de `gol`&lt;br /&gt;
En esta primera versión, se implementa una herencia usando punteros a funciones.&lt;br /&gt;
&lt;br /&gt;
* El objeto `gol` contiene dos atributos nuevos, punteros a las funciones que implementarán la funcionalidad de `get_cell()` y `set_cell()`&lt;br /&gt;
* Los métodos estáticos `get_cell()` y `set_cell()` de `gol.c` simplemente llaman a los punteros a funciones del objeto.&lt;br /&gt;
* Se crea el objeto nuevo en dos archivos: `gol_toroid.c` y `gol_toroid.h`&lt;br /&gt;
* La interfaz de este objeto (funciones en `gol_toroid.h`) sólo añade dos métodos: un constructor y un destructor, `gol_toroid_alloc()` y `gol_toroid_free()`)&lt;br /&gt;
* En `gol_toroid.c` se implementan este constructor y este destructor, además de las funciones estáticas `get_cell()` y `set_cell()` cuyas direcciones se asignan a los punteros a funcion.&lt;br /&gt;
* Las funciones estáticas `get_cell()` y `set_cell()` de `gol_toroid.c` implementan un acceso toroidal al mundo&lt;br /&gt;
* Como en `gol_toroid.c` se necesita acceso a la estructura y a los métodos `gol_alloc()` y `gol_free()`, se vuelven a pasar a `gol.h`.&lt;br /&gt;
* Se modifica `mem_test` para que haga uso de este nuevo objeto&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 11.2&lt;br /&gt;
| Objetos II: Implementar un nuevo objeto `gol_finite`&lt;br /&gt;
* Se implementa el objeto `gol_finite` igual que se implementó `gol_toroid`&lt;br /&gt;
* Este objeto implementa un mundo con límites, a partir de los cuales todas las células se consideran muertas&lt;br /&gt;
* Se modifica el main para que `getopt` interprete un nuevo argumento que seleccionará el tipo de mundo a instanciar.&lt;br /&gt;
* Se modifica `mem_test` para que compruebe los dos mundos&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 11.3&lt;br /&gt;
| Objetos II: Privatizar la estructura gol y algunos métodos&lt;br /&gt;
* Se crea una paraja de archivos `gol_priv.h` y `gol_priv.c` que albergan las definiciones de `struct gol` y de los métodos `gol_alloc()` y `gol_free()`&lt;br /&gt;
* El resto de objetos incluyen este `gol_priv.h` para tener acceso a la estrucutra, constructor y destructor. Pero no se incluye en el `main.c`.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 11.4&lt;br /&gt;
| Objetos II: ...&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Slides_prin.pdf&amp;diff=318</id>
		<title>Archivo:Slides prin.pdf</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Slides_prin.pdf&amp;diff=318"/>
				<updated>2019-06-12T14:59:55Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: Carfalgar subió una nueva versión de Archivo:Slides prin.pdf&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Transparencias.pdf&amp;diff=317</id>
		<title>Archivo:Transparencias.pdf</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Transparencias.pdf&amp;diff=317"/>
				<updated>2019-06-12T14:59:37Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: Carfalgar subió una nueva versión de Archivo:Transparencias.pdf&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=316</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=316"/>
				<updated>2019-06-12T14:47:41Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Vídeos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:Slides_prin.pdf|Transparencias para imprimir]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
* [https://github.com/profedotc/solucion Repositorio con la solución del trabajo de clase] (se irá actualizando)&lt;br /&gt;
* [https://en.cppreference.com/w/c Documentación de C]&lt;br /&gt;
* [[:Archivo:Autotools.zip | Plantilla autotools]]&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
# https://youtu.be/IDfllYxE7I4&lt;br /&gt;
# https://youtu.be/57-zWEnGxHU&lt;br /&gt;
# https://youtu.be/1SJ_fEXD7OA&lt;br /&gt;
# https://youtu.be/EhX3E8lLcUM&lt;br /&gt;
# No hay&lt;br /&gt;
# https://youtu.be/dk-0xF5pJpQ (incompleto)&lt;br /&gt;
# https://youtu.be/sq14oKSodPM&lt;br /&gt;
# https://youtu.be/JHUozE_4HPs&lt;br /&gt;
# https://youtu.be/cVDUGO0_saE&lt;br /&gt;
# https://youtu.be/Qq9u5Odq0jU&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
|&lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Crear makefile y dividir el programa&lt;br /&gt;
* Se crean &amp;quot;gol.h&amp;quot; y &amp;quot;gol.c&amp;quot;&lt;br /&gt;
* Se crea un makefile para compilar y limpiar el repositorio&lt;br /&gt;
* Se añade un .gitignore para ignorar los productos de la compilación&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 7&lt;br /&gt;
| 7.1&lt;br /&gt;
| Objetos: Reserva dinámica de memoria para la estructura `gol`&lt;br /&gt;
* Se cambia ligeramente la interfaz de la función `gol_alloc` para que devuelva un puntero a `struct gol` en lugar de recibirlo.&lt;br /&gt;
* Ahora se reservan dinámicamente dos bloques de memoria: uno para la estructura `struct gol` y otro para los arrays del mundo.&lt;br /&gt;
* La función `gol_free` debe liberar los dos bloques de memoria.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 7.2&lt;br /&gt;
| Objetos: Ocultar la estructura `gol`&lt;br /&gt;
Mediante una declaración adelantada de `struct gol` en `gol.h` conseguimos&lt;br /&gt;
ocultar los campos de nuestro objeto (privatizar) a los usuarios de la librería.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 8&lt;br /&gt;
| 8.1&lt;br /&gt;
| Utilizar getopt para recibir argumentos de línea de comandos&lt;br /&gt;
* El programa ahora recibe como argumentos el ancho y el alto del mundo, además de el argumento `-u, --usage` que imprime el siguiente mensaje de ayuda:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt;&lt;br /&gt;
      -u, --usage: Prints this help message&lt;br /&gt;
      -w, --width: Width of the world&lt;br /&gt;
      -h, --height: Height of the world&lt;br /&gt;
* Es obligatorio especificar el tamaño del mundo, si no se especifica se imprime un mensaje de error y se termina el programa.&lt;br /&gt;
* Se define el tipo `struct gol_options` para guardar los parámetros de entrada: `int width`, `int height` y `bool usage`&lt;br /&gt;
* Se crean dos funciones estáticas que encapsulan la lógica de tratar los argumentos y de imprimir el mensaje de ayuda:&lt;br /&gt;
* `static bool parse_args(struct gol_options *gol_opt, int argc, char *argv[]);`&lt;br /&gt;
* `static void print_usage(const char *argv0);`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 8.2&lt;br /&gt;
| Implementar la opción de inicializar el mundo aleatoriamente&lt;br /&gt;
* Se añade un argumento opcional con un parámetro obligatorio. Indica el patrón de inicialización del mundo: &amp;quot;glider&amp;quot; o &amp;quot;random&amp;quot;&lt;br /&gt;
* Se añade otro argumento opcional con parámetro obligatorio. Proporcionará la semilla para `srand()`. Si no se pasa este parámetro, se toma como semilla el tiempo actual. Esta es ahora la salida de `./gol -u`:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt; [-r[&amp;lt;seed&amp;gt;]]&lt;br /&gt;
      -u, --usage:             Prints this help message&lt;br /&gt;
      -w, --width:             Width of the world&lt;br /&gt;
      -h, --height:            Height of the world&lt;br /&gt;
      -s, --Seed [seed]:       Seed for random world.&lt;br /&gt;
      -p, --pattern [pattern]: Initialization pattern:&lt;br /&gt;
 				 - glider&lt;br /&gt;
 				 - random&lt;br /&gt;
* Se modifica el método `gol_init()` para recibir un enumerado, `enum gol_init_pattern`, que esta definido en `gol.h`. El método `gol_init()` llama a los métodos privados `gol_init_rand()` o `gol_init_glider()`, según el patrón de inicialización seleccionado.&lt;br /&gt;
* Se crea una función auxiliar en `main.c` que transforma del string recibido como argumento a el enumerado que acepta `gol_init()`&lt;br /&gt;
* Se modifica `mem_test.c` para adaptarlo al nuevo `gol_init()`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 9&lt;br /&gt;
| 9.1&lt;br /&gt;
| Cargar y guardar el mundo desde un archivo binario&lt;br /&gt;
* Implementar los métodos `gol_save()` y `gol_load()` para guardar y cargar el mundo desde un archivo binario. Estas funciones simplemente guardan el array tal cual en el archivo especificado y leen el archivo guardándolo en el array.&lt;br /&gt;
 bool gol_load(struct gol *gol, const char *file);&lt;br /&gt;
 bool gol_save(const struct gol *gol, const char *file);&lt;br /&gt;
* Modificar el main para que acepte los siguientes comandos, además de 'q' para cerrar:&lt;br /&gt;
* 'l': Si se pulsa este caracter, llamar a una función estática `load_world()` que pida al usuario que inserte el nombre de un archivo.  Luego carga este archivo con la función `gol_load()`&lt;br /&gt;
* 's': Si se pulsa este caracter, llamar a una función estática `save_world()` que pida al usuario que inserte el nombre de un archivo.  Luego guarda este archivo con la función `gol_save()`&lt;br /&gt;
* Si cualquiera de los nuevos comandos falla, se informa al usuario del error y se continua la ejecución. Para que el usuario pueda leer el mensaje de error se llama a `getchar()`, así se pausa la ejecución hasta que se pulse un caracter.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 9.2&lt;br /&gt;
| Guardar y cargar el mundo desde un archivo de texto&lt;br /&gt;
Modificar `gol_save()` y `gol_load()` para guardar y cargar el estado del&lt;br /&gt;
mundo en un formato de texto parecido al que se usa en `gol_print()`.&lt;br /&gt;
&lt;br /&gt;
Ejemplo de archivo para mundo de 10x20:&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . # . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . # # # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 10&lt;br /&gt;
|&lt;br /&gt;
| Configura compilación con autotools&lt;br /&gt;
* Se mueve todo el código a una nueva carpeta `src/`&lt;br /&gt;
* Se crean los archivos necesarios para configurar autotools:&lt;br /&gt;
** `autogen.sh`&lt;br /&gt;
** `configure.ac`&lt;br /&gt;
** `makefile.am`&lt;br /&gt;
* Se elimina el `makefile` ya que este será generado por autotools&lt;br /&gt;
* Se añaden al `.gitignore` todos los archivos autogenerados de autotools&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; | 11&lt;br /&gt;
| 11.1&lt;br /&gt;
| Objetos II: Implementar el objeto `gol_toroid` hijo de `gol`&lt;br /&gt;
En esta primera versión, se implementa una herencia usando punteros a funciones.&lt;br /&gt;
&lt;br /&gt;
* El objeto `gol` contiene dos atributos nuevos, punteros a las funciones que implementarán la funcionalidad de `get_cell()` y `set_cell()`&lt;br /&gt;
* Los métodos estáticos `get_cell()` y `set_cell()` de `gol.c` simplemente llaman a los punteros a funciones del objeto.&lt;br /&gt;
* Se crea el objeto nuevo en dos archivos: `gol_toroid.c` y `gol_toroid.h`&lt;br /&gt;
* La interfaz de este objeto (funciones en `gol_toroid.h`) sólo añade dos métodos: un constructor y un destructor, `gol_toroid_alloc()` y `gol_toroid_free()`)&lt;br /&gt;
* En `gol_toroid.c` se implementan este constructor y este destructor, además de las funciones estáticas `get_cell()` y `set_cell()` cuyas direcciones se asignan a los punteros a funcion.&lt;br /&gt;
* Las funciones estáticas `get_cell()` y `set_cell()` de `gol_toroid.c` implementan un acceso toroidal al mundo&lt;br /&gt;
* Como en `gol_toroid.c` se necesita acceso a la estructura y a los métodos `gol_alloc()` y `gol_free()`, se vuelven a pasar a `gol.h`.&lt;br /&gt;
* Se modifica `mem_test` para que haga uso de este nuevo objeto&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 11.2&lt;br /&gt;
| Objetos II: Implementar un nuevo objeto `gol_finite`&lt;br /&gt;
* Se implementa el objeto `gol_finite` igual que se implementó `gol_toroid`&lt;br /&gt;
* Este objeto implementa un mundo con límites, a partir de los cuales todas las células se consideran muertas&lt;br /&gt;
* Se modifica el main para que `getopt` interprete un nuevo argumento que seleccionará el tipo de mundo a instanciar.&lt;br /&gt;
* Se modifica `mem_test` para que compruebe los dos mundos&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 11.3&lt;br /&gt;
| Objetos II: Privatizar la estructura gol y algunos métodos&lt;br /&gt;
* Se crea una paraja de archivos `gol_priv.h` y `gol_priv.c` que albergan las definiciones de `struct gol` y de los métodos `gol_alloc()` y `gol_free()`&lt;br /&gt;
* El resto de objetos incluyen este `gol_priv.h` para tener acceso a la estrucutra, constructor y destructor. Pero no se incluye en el `main.c`.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 11.4&lt;br /&gt;
| Objetos II: ...&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=315</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=315"/>
				<updated>2019-06-10T14:59:38Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Vídeos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:Slides_prin.pdf|Transparencias para imprimir]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
* [https://github.com/profedotc/solucion Repositorio con la solución del trabajo de clase] (se irá actualizando)&lt;br /&gt;
* [https://en.cppreference.com/w/c Documentación de C]&lt;br /&gt;
* [[:Archivo:Autotools.zip | Plantilla autotools]]&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
# https://youtu.be/IDfllYxE7I4&lt;br /&gt;
# https://youtu.be/57-zWEnGxHU&lt;br /&gt;
# https://youtu.be/1SJ_fEXD7OA&lt;br /&gt;
# https://youtu.be/EhX3E8lLcUM&lt;br /&gt;
# No hay&lt;br /&gt;
# https://youtu.be/dk-0xF5pJpQ (incompleto)&lt;br /&gt;
# https://youtu.be/sq14oKSodPM&lt;br /&gt;
# https://youtu.be/JHUozE_4HPs&lt;br /&gt;
# https://youtu.be/cVDUGO0_saE&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
|&lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Crear makefile y dividir el programa&lt;br /&gt;
* Se crean &amp;quot;gol.h&amp;quot; y &amp;quot;gol.c&amp;quot;&lt;br /&gt;
* Se crea un makefile para compilar y limpiar el repositorio&lt;br /&gt;
* Se añade un .gitignore para ignorar los productos de la compilación&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 7&lt;br /&gt;
| 7.1&lt;br /&gt;
| Objetos: Reserva dinámica de memoria para la estructura `gol`&lt;br /&gt;
* Se cambia ligeramente la interfaz de la función `gol_alloc` para que devuelva un puntero a `struct gol` en lugar de recibirlo.&lt;br /&gt;
* Ahora se reservan dinámicamente dos bloques de memoria: uno para la estructura `struct gol` y otro para los arrays del mundo.&lt;br /&gt;
* La función `gol_free` debe liberar los dos bloques de memoria.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 7.2&lt;br /&gt;
| Objetos: Ocultar la estructura `gol`&lt;br /&gt;
Mediante una declaración adelantada de `struct gol` en `gol.h` conseguimos&lt;br /&gt;
ocultar los campos de nuestro objeto (privatizar) a los usuarios de la librería.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 8&lt;br /&gt;
| 8.1&lt;br /&gt;
| Utilizar getopt para recibir argumentos de línea de comandos&lt;br /&gt;
* El programa ahora recibe como argumentos el ancho y el alto del mundo, además de el argumento `-u, --usage` que imprime el siguiente mensaje de ayuda:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt;&lt;br /&gt;
      -u, --usage: Prints this help message&lt;br /&gt;
      -w, --width: Width of the world&lt;br /&gt;
      -h, --height: Height of the world&lt;br /&gt;
* Es obligatorio especificar el tamaño del mundo, si no se especifica se imprime un mensaje de error y se termina el programa.&lt;br /&gt;
* Se define el tipo `struct gol_options` para guardar los parámetros de entrada: `int width`, `int height` y `bool usage`&lt;br /&gt;
* Se crean dos funciones estáticas que encapsulan la lógica de tratar los argumentos y de imprimir el mensaje de ayuda:&lt;br /&gt;
* `static bool parse_args(struct gol_options *gol_opt, int argc, char *argv[]);`&lt;br /&gt;
* `static void print_usage(const char *argv0);`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 8.2&lt;br /&gt;
| Implementar la opción de inicializar el mundo aleatoriamente&lt;br /&gt;
* Se añade un argumento opcional con un parámetro obligatorio. Indica el patrón de inicialización del mundo: &amp;quot;glider&amp;quot; o &amp;quot;random&amp;quot;&lt;br /&gt;
* Se añade otro argumento opcional con parámetro obligatorio. Proporcionará la semilla para `srand()`. Si no se pasa este parámetro, se toma como semilla el tiempo actual. Esta es ahora la salida de `./gol -u`:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt; [-r[&amp;lt;seed&amp;gt;]]&lt;br /&gt;
      -u, --usage:             Prints this help message&lt;br /&gt;
      -w, --width:             Width of the world&lt;br /&gt;
      -h, --height:            Height of the world&lt;br /&gt;
      -s, --Seed [seed]:       Seed for random world.&lt;br /&gt;
      -p, --pattern [pattern]: Initialization pattern:&lt;br /&gt;
 				 - glider&lt;br /&gt;
 				 - random&lt;br /&gt;
* Se modifica el método `gol_init()` para recibir un enumerado, `enum gol_init_pattern`, que esta definido en `gol.h`. El método `gol_init()` llama a los métodos privados `gol_init_rand()` o `gol_init_glider()`, según el patrón de inicialización seleccionado.&lt;br /&gt;
* Se crea una función auxiliar en `main.c` que transforma del string recibido como argumento a el enumerado que acepta `gol_init()`&lt;br /&gt;
* Se modifica `mem_test.c` para adaptarlo al nuevo `gol_init()`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 9&lt;br /&gt;
| 9.1&lt;br /&gt;
| Cargar y guardar el mundo desde un archivo binario&lt;br /&gt;
* Implementar los métodos `gol_save()` y `gol_load()` para guardar y cargar el mundo desde un archivo binario. Estas funciones simplemente guardan el array tal cual en el archivo especificado y leen el archivo guardándolo en el array.&lt;br /&gt;
 bool gol_load(struct gol *gol, const char *file);&lt;br /&gt;
 bool gol_save(const struct gol *gol, const char *file);&lt;br /&gt;
* Modificar el main para que acepte los siguientes comandos, además de 'q' para cerrar:&lt;br /&gt;
* 'l': Si se pulsa este caracter, llamar a una función estática `load_world()` que pida al usuario que inserte el nombre de un archivo.  Luego carga este archivo con la función `gol_load()`&lt;br /&gt;
* 's': Si se pulsa este caracter, llamar a una función estática `save_world()` que pida al usuario que inserte el nombre de un archivo.  Luego guarda este archivo con la función `gol_save()`&lt;br /&gt;
* Si cualquiera de los nuevos comandos falla, se informa al usuario del error y se continua la ejecución. Para que el usuario pueda leer el mensaje de error se llama a `getchar()`, así se pausa la ejecución hasta que se pulse un caracter.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 9.2&lt;br /&gt;
| Guardar y cargar el mundo desde un archivo de texto&lt;br /&gt;
Modificar `gol_save()` y `gol_load()` para guardar y cargar el estado del&lt;br /&gt;
mundo en un formato de texto parecido al que se usa en `gol_print()`.&lt;br /&gt;
&lt;br /&gt;
Ejemplo de archivo para mundo de 10x20:&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . # . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . # # # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 10&lt;br /&gt;
|&lt;br /&gt;
| Configura compilación con autotools&lt;br /&gt;
* Se mueve todo el código a una nueva carpeta `src/`&lt;br /&gt;
* Se crean los archivos necesarios para configurar autotools:&lt;br /&gt;
** `autogen.sh`&lt;br /&gt;
** `configure.ac`&lt;br /&gt;
** `makefile.am`&lt;br /&gt;
* Se elimina el `makefile` ya que este será generado por autotools&lt;br /&gt;
* Se añaden al `.gitignore` todos los archivos autogenerados de autotools&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; | 11&lt;br /&gt;
| 11.1&lt;br /&gt;
| Objetos II: Implementar el objeto `gol_toroid` hijo de `gol`&lt;br /&gt;
En esta primera versión, se implementa una herencia usando punteros a funciones.&lt;br /&gt;
&lt;br /&gt;
* El objeto `gol` contiene dos atributos nuevos, punteros a las funciones que implementarán la funcionalidad de `get_cell()` y `set_cell()`&lt;br /&gt;
* Los métodos estáticos `get_cell()` y `set_cell()` de `gol.c` simplemente llaman a los punteros a funciones del objeto.&lt;br /&gt;
* Se crea el objeto nuevo en dos archivos: `gol_toroid.c` y `gol_toroid.h`&lt;br /&gt;
* La interfaz de este objeto (funciones en `gol_toroid.h`) sólo añade dos métodos: un constructor y un destructor, `gol_toroid_alloc()` y `gol_toroid_free()`)&lt;br /&gt;
* En `gol_toroid.c` se implementan este constructor y este destructor, además de las funciones estáticas `get_cell()` y `set_cell()` cuyas direcciones se asignan a los punteros a funcion.&lt;br /&gt;
* Las funciones estáticas `get_cell()` y `set_cell()` de `gol_toroid.c` implementan un acceso toroidal al mundo&lt;br /&gt;
* Como en `gol_toroid.c` se necesita acceso a la estructura y a los métodos `gol_alloc()` y `gol_free()`, se vuelven a pasar a `gol.h`.&lt;br /&gt;
* Se modifica `mem_test` para que haga uso de este nuevo objeto&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 11.2&lt;br /&gt;
| Objetos II: Implementar un nuevo objeto `gol_finite`&lt;br /&gt;
* Se implementa el objeto `gol_finite` igual que se implementó `gol_toroid`&lt;br /&gt;
* Este objeto implementa un mundo con límites, a partir de los cuales todas las células se consideran muertas&lt;br /&gt;
* Se modifica el main para que `getopt` interprete un nuevo argumento que seleccionará el tipo de mundo a instanciar.&lt;br /&gt;
* Se modifica `mem_test` para que compruebe los dos mundos&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 11.3&lt;br /&gt;
| Objetos II: Privatizar la estructura gol y algunos métodos&lt;br /&gt;
* Se crea una paraja de archivos `gol_priv.h` y `gol_priv.c` que albergan las definiciones de `struct gol` y de los métodos `gol_alloc()` y `gol_free()`&lt;br /&gt;
* El resto de objetos incluyen este `gol_priv.h` para tener acceso a la estrucutra, constructor y destructor. Pero no se incluye en el `main.c`.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 11.4&lt;br /&gt;
| Objetos II: ...&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=314</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=314"/>
				<updated>2019-06-10T14:52:14Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Material de clase */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:Slides_prin.pdf|Transparencias para imprimir]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
* [https://github.com/profedotc/solucion Repositorio con la solución del trabajo de clase] (se irá actualizando)&lt;br /&gt;
* [https://en.cppreference.com/w/c Documentación de C]&lt;br /&gt;
* [[:Archivo:Autotools.zip | Plantilla autotools]]&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
# https://youtu.be/IDfllYxE7I4&lt;br /&gt;
# https://youtu.be/57-zWEnGxHU&lt;br /&gt;
# https://youtu.be/1SJ_fEXD7OA&lt;br /&gt;
# https://youtu.be/EhX3E8lLcUM&lt;br /&gt;
# No hay&lt;br /&gt;
# https://youtu.be/dk-0xF5pJpQ (incompleto)&lt;br /&gt;
# https://youtu.be/sq14oKSodPM&lt;br /&gt;
# https://youtu.be/JHUozE_4HPs&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
|&lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Crear makefile y dividir el programa&lt;br /&gt;
* Se crean &amp;quot;gol.h&amp;quot; y &amp;quot;gol.c&amp;quot;&lt;br /&gt;
* Se crea un makefile para compilar y limpiar el repositorio&lt;br /&gt;
* Se añade un .gitignore para ignorar los productos de la compilación&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 7&lt;br /&gt;
| 7.1&lt;br /&gt;
| Objetos: Reserva dinámica de memoria para la estructura `gol`&lt;br /&gt;
* Se cambia ligeramente la interfaz de la función `gol_alloc` para que devuelva un puntero a `struct gol` en lugar de recibirlo.&lt;br /&gt;
* Ahora se reservan dinámicamente dos bloques de memoria: uno para la estructura `struct gol` y otro para los arrays del mundo.&lt;br /&gt;
* La función `gol_free` debe liberar los dos bloques de memoria.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 7.2&lt;br /&gt;
| Objetos: Ocultar la estructura `gol`&lt;br /&gt;
Mediante una declaración adelantada de `struct gol` en `gol.h` conseguimos&lt;br /&gt;
ocultar los campos de nuestro objeto (privatizar) a los usuarios de la librería.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 8&lt;br /&gt;
| 8.1&lt;br /&gt;
| Utilizar getopt para recibir argumentos de línea de comandos&lt;br /&gt;
* El programa ahora recibe como argumentos el ancho y el alto del mundo, además de el argumento `-u, --usage` que imprime el siguiente mensaje de ayuda:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt;&lt;br /&gt;
      -u, --usage: Prints this help message&lt;br /&gt;
      -w, --width: Width of the world&lt;br /&gt;
      -h, --height: Height of the world&lt;br /&gt;
* Es obligatorio especificar el tamaño del mundo, si no se especifica se imprime un mensaje de error y se termina el programa.&lt;br /&gt;
* Se define el tipo `struct gol_options` para guardar los parámetros de entrada: `int width`, `int height` y `bool usage`&lt;br /&gt;
* Se crean dos funciones estáticas que encapsulan la lógica de tratar los argumentos y de imprimir el mensaje de ayuda:&lt;br /&gt;
* `static bool parse_args(struct gol_options *gol_opt, int argc, char *argv[]);`&lt;br /&gt;
* `static void print_usage(const char *argv0);`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 8.2&lt;br /&gt;
| Implementar la opción de inicializar el mundo aleatoriamente&lt;br /&gt;
* Se añade un argumento opcional con un parámetro obligatorio. Indica el patrón de inicialización del mundo: &amp;quot;glider&amp;quot; o &amp;quot;random&amp;quot;&lt;br /&gt;
* Se añade otro argumento opcional con parámetro obligatorio. Proporcionará la semilla para `srand()`. Si no se pasa este parámetro, se toma como semilla el tiempo actual. Esta es ahora la salida de `./gol -u`:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt; [-r[&amp;lt;seed&amp;gt;]]&lt;br /&gt;
      -u, --usage:             Prints this help message&lt;br /&gt;
      -w, --width:             Width of the world&lt;br /&gt;
      -h, --height:            Height of the world&lt;br /&gt;
      -s, --Seed [seed]:       Seed for random world.&lt;br /&gt;
      -p, --pattern [pattern]: Initialization pattern:&lt;br /&gt;
 				 - glider&lt;br /&gt;
 				 - random&lt;br /&gt;
* Se modifica el método `gol_init()` para recibir un enumerado, `enum gol_init_pattern`, que esta definido en `gol.h`. El método `gol_init()` llama a los métodos privados `gol_init_rand()` o `gol_init_glider()`, según el patrón de inicialización seleccionado.&lt;br /&gt;
* Se crea una función auxiliar en `main.c` que transforma del string recibido como argumento a el enumerado que acepta `gol_init()`&lt;br /&gt;
* Se modifica `mem_test.c` para adaptarlo al nuevo `gol_init()`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 9&lt;br /&gt;
| 9.1&lt;br /&gt;
| Cargar y guardar el mundo desde un archivo binario&lt;br /&gt;
* Implementar los métodos `gol_save()` y `gol_load()` para guardar y cargar el mundo desde un archivo binario. Estas funciones simplemente guardan el array tal cual en el archivo especificado y leen el archivo guardándolo en el array.&lt;br /&gt;
 bool gol_load(struct gol *gol, const char *file);&lt;br /&gt;
 bool gol_save(const struct gol *gol, const char *file);&lt;br /&gt;
* Modificar el main para que acepte los siguientes comandos, además de 'q' para cerrar:&lt;br /&gt;
* 'l': Si se pulsa este caracter, llamar a una función estática `load_world()` que pida al usuario que inserte el nombre de un archivo.  Luego carga este archivo con la función `gol_load()`&lt;br /&gt;
* 's': Si se pulsa este caracter, llamar a una función estática `save_world()` que pida al usuario que inserte el nombre de un archivo.  Luego guarda este archivo con la función `gol_save()`&lt;br /&gt;
* Si cualquiera de los nuevos comandos falla, se informa al usuario del error y se continua la ejecución. Para que el usuario pueda leer el mensaje de error se llama a `getchar()`, así se pausa la ejecución hasta que se pulse un caracter.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 9.2&lt;br /&gt;
| Guardar y cargar el mundo desde un archivo de texto&lt;br /&gt;
Modificar `gol_save()` y `gol_load()` para guardar y cargar el estado del&lt;br /&gt;
mundo en un formato de texto parecido al que se usa en `gol_print()`.&lt;br /&gt;
&lt;br /&gt;
Ejemplo de archivo para mundo de 10x20:&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . # . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . # # # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 10&lt;br /&gt;
|&lt;br /&gt;
| Configura compilación con autotools&lt;br /&gt;
* Se mueve todo el código a una nueva carpeta `src/`&lt;br /&gt;
* Se crean los archivos necesarios para configurar autotools:&lt;br /&gt;
** `autogen.sh`&lt;br /&gt;
** `configure.ac`&lt;br /&gt;
** `makefile.am`&lt;br /&gt;
* Se elimina el `makefile` ya que este será generado por autotools&lt;br /&gt;
* Se añaden al `.gitignore` todos los archivos autogenerados de autotools&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; | 11&lt;br /&gt;
| 11.1&lt;br /&gt;
| Objetos II: Implementar el objeto `gol_toroid` hijo de `gol`&lt;br /&gt;
En esta primera versión, se implementa una herencia usando punteros a funciones.&lt;br /&gt;
&lt;br /&gt;
* El objeto `gol` contiene dos atributos nuevos, punteros a las funciones que implementarán la funcionalidad de `get_cell()` y `set_cell()`&lt;br /&gt;
* Los métodos estáticos `get_cell()` y `set_cell()` de `gol.c` simplemente llaman a los punteros a funciones del objeto.&lt;br /&gt;
* Se crea el objeto nuevo en dos archivos: `gol_toroid.c` y `gol_toroid.h`&lt;br /&gt;
* La interfaz de este objeto (funciones en `gol_toroid.h`) sólo añade dos métodos: un constructor y un destructor, `gol_toroid_alloc()` y `gol_toroid_free()`)&lt;br /&gt;
* En `gol_toroid.c` se implementan este constructor y este destructor, además de las funciones estáticas `get_cell()` y `set_cell()` cuyas direcciones se asignan a los punteros a funcion.&lt;br /&gt;
* Las funciones estáticas `get_cell()` y `set_cell()` de `gol_toroid.c` implementan un acceso toroidal al mundo&lt;br /&gt;
* Como en `gol_toroid.c` se necesita acceso a la estructura y a los métodos `gol_alloc()` y `gol_free()`, se vuelven a pasar a `gol.h`.&lt;br /&gt;
* Se modifica `mem_test` para que haga uso de este nuevo objeto&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 11.2&lt;br /&gt;
| Objetos II: Implementar un nuevo objeto `gol_finite`&lt;br /&gt;
* Se implementa el objeto `gol_finite` igual que se implementó `gol_toroid`&lt;br /&gt;
* Este objeto implementa un mundo con límites, a partir de los cuales todas las células se consideran muertas&lt;br /&gt;
* Se modifica el main para que `getopt` interprete un nuevo argumento que seleccionará el tipo de mundo a instanciar.&lt;br /&gt;
* Se modifica `mem_test` para que compruebe los dos mundos&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 11.3&lt;br /&gt;
| Objetos II: Privatizar la estructura gol y algunos métodos&lt;br /&gt;
* Se crea una paraja de archivos `gol_priv.h` y `gol_priv.c` que albergan las definiciones de `struct gol` y de los métodos `gol_alloc()` y `gol_free()`&lt;br /&gt;
* El resto de objetos incluyen este `gol_priv.h` para tener acceso a la estrucutra, constructor y destructor. Pero no se incluye en el `main.c`.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 11.4&lt;br /&gt;
| Objetos II: ...&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Autotools.zip&amp;diff=313</id>
		<title>Archivo:Autotools.zip</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Autotools.zip&amp;diff=313"/>
				<updated>2019-06-10T14:52:00Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=312</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=312"/>
				<updated>2019-06-10T14:49:28Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Tareas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:Slides_prin.pdf|Transparencias para imprimir]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
* [https://github.com/profedotc/solucion Repositorio con la solución del trabajo de clase] (se irá actualizando)&lt;br /&gt;
* [https://en.cppreference.com/w/c Documentación de C]&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
# https://youtu.be/IDfllYxE7I4&lt;br /&gt;
# https://youtu.be/57-zWEnGxHU&lt;br /&gt;
# https://youtu.be/1SJ_fEXD7OA&lt;br /&gt;
# https://youtu.be/EhX3E8lLcUM&lt;br /&gt;
# No hay&lt;br /&gt;
# https://youtu.be/dk-0xF5pJpQ (incompleto)&lt;br /&gt;
# https://youtu.be/sq14oKSodPM&lt;br /&gt;
# https://youtu.be/JHUozE_4HPs&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
|&lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Crear makefile y dividir el programa&lt;br /&gt;
* Se crean &amp;quot;gol.h&amp;quot; y &amp;quot;gol.c&amp;quot;&lt;br /&gt;
* Se crea un makefile para compilar y limpiar el repositorio&lt;br /&gt;
* Se añade un .gitignore para ignorar los productos de la compilación&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 7&lt;br /&gt;
| 7.1&lt;br /&gt;
| Objetos: Reserva dinámica de memoria para la estructura `gol`&lt;br /&gt;
* Se cambia ligeramente la interfaz de la función `gol_alloc` para que devuelva un puntero a `struct gol` en lugar de recibirlo.&lt;br /&gt;
* Ahora se reservan dinámicamente dos bloques de memoria: uno para la estructura `struct gol` y otro para los arrays del mundo.&lt;br /&gt;
* La función `gol_free` debe liberar los dos bloques de memoria.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 7.2&lt;br /&gt;
| Objetos: Ocultar la estructura `gol`&lt;br /&gt;
Mediante una declaración adelantada de `struct gol` en `gol.h` conseguimos&lt;br /&gt;
ocultar los campos de nuestro objeto (privatizar) a los usuarios de la librería.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 8&lt;br /&gt;
| 8.1&lt;br /&gt;
| Utilizar getopt para recibir argumentos de línea de comandos&lt;br /&gt;
* El programa ahora recibe como argumentos el ancho y el alto del mundo, además de el argumento `-u, --usage` que imprime el siguiente mensaje de ayuda:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt;&lt;br /&gt;
      -u, --usage: Prints this help message&lt;br /&gt;
      -w, --width: Width of the world&lt;br /&gt;
      -h, --height: Height of the world&lt;br /&gt;
* Es obligatorio especificar el tamaño del mundo, si no se especifica se imprime un mensaje de error y se termina el programa.&lt;br /&gt;
* Se define el tipo `struct gol_options` para guardar los parámetros de entrada: `int width`, `int height` y `bool usage`&lt;br /&gt;
* Se crean dos funciones estáticas que encapsulan la lógica de tratar los argumentos y de imprimir el mensaje de ayuda:&lt;br /&gt;
* `static bool parse_args(struct gol_options *gol_opt, int argc, char *argv[]);`&lt;br /&gt;
* `static void print_usage(const char *argv0);`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 8.2&lt;br /&gt;
| Implementar la opción de inicializar el mundo aleatoriamente&lt;br /&gt;
* Se añade un argumento opcional con un parámetro obligatorio. Indica el patrón de inicialización del mundo: &amp;quot;glider&amp;quot; o &amp;quot;random&amp;quot;&lt;br /&gt;
* Se añade otro argumento opcional con parámetro obligatorio. Proporcionará la semilla para `srand()`. Si no se pasa este parámetro, se toma como semilla el tiempo actual. Esta es ahora la salida de `./gol -u`:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt; [-r[&amp;lt;seed&amp;gt;]]&lt;br /&gt;
      -u, --usage:             Prints this help message&lt;br /&gt;
      -w, --width:             Width of the world&lt;br /&gt;
      -h, --height:            Height of the world&lt;br /&gt;
      -s, --Seed [seed]:       Seed for random world.&lt;br /&gt;
      -p, --pattern [pattern]: Initialization pattern:&lt;br /&gt;
 				 - glider&lt;br /&gt;
 				 - random&lt;br /&gt;
* Se modifica el método `gol_init()` para recibir un enumerado, `enum gol_init_pattern`, que esta definido en `gol.h`. El método `gol_init()` llama a los métodos privados `gol_init_rand()` o `gol_init_glider()`, según el patrón de inicialización seleccionado.&lt;br /&gt;
* Se crea una función auxiliar en `main.c` que transforma del string recibido como argumento a el enumerado que acepta `gol_init()`&lt;br /&gt;
* Se modifica `mem_test.c` para adaptarlo al nuevo `gol_init()`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 9&lt;br /&gt;
| 9.1&lt;br /&gt;
| Cargar y guardar el mundo desde un archivo binario&lt;br /&gt;
* Implementar los métodos `gol_save()` y `gol_load()` para guardar y cargar el mundo desde un archivo binario. Estas funciones simplemente guardan el array tal cual en el archivo especificado y leen el archivo guardándolo en el array.&lt;br /&gt;
 bool gol_load(struct gol *gol, const char *file);&lt;br /&gt;
 bool gol_save(const struct gol *gol, const char *file);&lt;br /&gt;
* Modificar el main para que acepte los siguientes comandos, además de 'q' para cerrar:&lt;br /&gt;
* 'l': Si se pulsa este caracter, llamar a una función estática `load_world()` que pida al usuario que inserte el nombre de un archivo.  Luego carga este archivo con la función `gol_load()`&lt;br /&gt;
* 's': Si se pulsa este caracter, llamar a una función estática `save_world()` que pida al usuario que inserte el nombre de un archivo.  Luego guarda este archivo con la función `gol_save()`&lt;br /&gt;
* Si cualquiera de los nuevos comandos falla, se informa al usuario del error y se continua la ejecución. Para que el usuario pueda leer el mensaje de error se llama a `getchar()`, así se pausa la ejecución hasta que se pulse un caracter.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 9.2&lt;br /&gt;
| Guardar y cargar el mundo desde un archivo de texto&lt;br /&gt;
Modificar `gol_save()` y `gol_load()` para guardar y cargar el estado del&lt;br /&gt;
mundo en un formato de texto parecido al que se usa en `gol_print()`.&lt;br /&gt;
&lt;br /&gt;
Ejemplo de archivo para mundo de 10x20:&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . # . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . # # # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 10&lt;br /&gt;
|&lt;br /&gt;
| Configura compilación con autotools&lt;br /&gt;
* Se mueve todo el código a una nueva carpeta `src/`&lt;br /&gt;
* Se crean los archivos necesarios para configurar autotools:&lt;br /&gt;
** `autogen.sh`&lt;br /&gt;
** `configure.ac`&lt;br /&gt;
** `makefile.am`&lt;br /&gt;
* Se elimina el `makefile` ya que este será generado por autotools&lt;br /&gt;
* Se añaden al `.gitignore` todos los archivos autogenerados de autotools&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; | 11&lt;br /&gt;
| 11.1&lt;br /&gt;
| Objetos II: Implementar el objeto `gol_toroid` hijo de `gol`&lt;br /&gt;
En esta primera versión, se implementa una herencia usando punteros a funciones.&lt;br /&gt;
&lt;br /&gt;
* El objeto `gol` contiene dos atributos nuevos, punteros a las funciones que implementarán la funcionalidad de `get_cell()` y `set_cell()`&lt;br /&gt;
* Los métodos estáticos `get_cell()` y `set_cell()` de `gol.c` simplemente llaman a los punteros a funciones del objeto.&lt;br /&gt;
* Se crea el objeto nuevo en dos archivos: `gol_toroid.c` y `gol_toroid.h`&lt;br /&gt;
* La interfaz de este objeto (funciones en `gol_toroid.h`) sólo añade dos métodos: un constructor y un destructor, `gol_toroid_alloc()` y `gol_toroid_free()`)&lt;br /&gt;
* En `gol_toroid.c` se implementan este constructor y este destructor, además de las funciones estáticas `get_cell()` y `set_cell()` cuyas direcciones se asignan a los punteros a funcion.&lt;br /&gt;
* Las funciones estáticas `get_cell()` y `set_cell()` de `gol_toroid.c` implementan un acceso toroidal al mundo&lt;br /&gt;
* Como en `gol_toroid.c` se necesita acceso a la estructura y a los métodos `gol_alloc()` y `gol_free()`, se vuelven a pasar a `gol.h`.&lt;br /&gt;
* Se modifica `mem_test` para que haga uso de este nuevo objeto&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 11.2&lt;br /&gt;
| Objetos II: Implementar un nuevo objeto `gol_finite`&lt;br /&gt;
* Se implementa el objeto `gol_finite` igual que se implementó `gol_toroid`&lt;br /&gt;
* Este objeto implementa un mundo con límites, a partir de los cuales todas las células se consideran muertas&lt;br /&gt;
* Se modifica el main para que `getopt` interprete un nuevo argumento que seleccionará el tipo de mundo a instanciar.&lt;br /&gt;
* Se modifica `mem_test` para que compruebe los dos mundos&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 11.3&lt;br /&gt;
| Objetos II: Privatizar la estructura gol y algunos métodos&lt;br /&gt;
* Se crea una paraja de archivos `gol_priv.h` y `gol_priv.c` que albergan las definiciones de `struct gol` y de los métodos `gol_alloc()` y `gol_free()`&lt;br /&gt;
* El resto de objetos incluyen este `gol_priv.h` para tener acceso a la estrucutra, constructor y destructor. Pero no se incluye en el `main.c`.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 11.4&lt;br /&gt;
| Objetos II: ...&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=311</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=311"/>
				<updated>2019-06-05T15:04:30Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Vídeos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:Slides_prin.pdf|Transparencias para imprimir]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
* [https://github.com/profedotc/solucion Repositorio con la solución del trabajo de clase] (se irá actualizando)&lt;br /&gt;
* [https://en.cppreference.com/w/c Documentación de C]&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
# https://youtu.be/IDfllYxE7I4&lt;br /&gt;
# https://youtu.be/57-zWEnGxHU&lt;br /&gt;
# https://youtu.be/1SJ_fEXD7OA&lt;br /&gt;
# https://youtu.be/EhX3E8lLcUM&lt;br /&gt;
# No hay&lt;br /&gt;
# https://youtu.be/dk-0xF5pJpQ (incompleto)&lt;br /&gt;
# https://youtu.be/sq14oKSodPM&lt;br /&gt;
# https://youtu.be/JHUozE_4HPs&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
|&lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Crear makefile y dividir el programa&lt;br /&gt;
* Se crean &amp;quot;gol.h&amp;quot; y &amp;quot;gol.c&amp;quot;&lt;br /&gt;
* Se crea un makefile para compilar y limpiar el repositorio&lt;br /&gt;
* Se añade un .gitignore para ignorar los productos de la compilación&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 7&lt;br /&gt;
| 7.1&lt;br /&gt;
| Objetos: Reserva dinámica de memoria para la estructura `gol`&lt;br /&gt;
* Se cambia ligeramente la interfaz de la función `gol_alloc` para que devuelva un puntero a `struct gol` en lugar de recibirlo.&lt;br /&gt;
* Ahora se reservan dinámicamente dos bloques de memoria: uno para la estructura `struct gol` y otro para los arrays del mundo.&lt;br /&gt;
* La función `gol_free` debe liberar los dos bloques de memoria.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 7.2&lt;br /&gt;
| Objetos: Ocultar la estructura `gol`&lt;br /&gt;
Mediante una declaración adelantada de `struct gol` en `gol.h` conseguimos&lt;br /&gt;
ocultar los campos de nuestro objeto (privatizar) a los usuarios de la librería.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 8&lt;br /&gt;
| 8.1&lt;br /&gt;
| Utilizar getopt para recibir argumentos de línea de comandos&lt;br /&gt;
* El programa ahora recibe como argumentos el ancho y el alto del mundo, además de el argumento `-u, --usage` que imprime el siguiente mensaje de ayuda:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt;&lt;br /&gt;
      -u, --usage: Prints this help message&lt;br /&gt;
      -w, --width: Width of the world&lt;br /&gt;
      -h, --height: Height of the world&lt;br /&gt;
* Es obligatorio especificar el tamaño del mundo, si no se especifica se imprime un mensaje de error y se termina el programa.&lt;br /&gt;
* Se define el tipo `struct gol_options` para guardar los parámetros de entrada: `int width`, `int height` y `bool usage`&lt;br /&gt;
* Se crean dos funciones estáticas que encapsulan la lógica de tratar los argumentos y de imprimir el mensaje de ayuda:&lt;br /&gt;
* `static bool parse_args(struct gol_options *gol_opt, int argc, char *argv[]);`&lt;br /&gt;
* `static void print_usage(const char *argv0);`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 8.2&lt;br /&gt;
| Implementar la opción de inicializar el mundo aleatoriamente&lt;br /&gt;
* Se añade un argumento opcional con un parámetro obligatorio. Indica el patrón de inicialización del mundo: &amp;quot;glider&amp;quot; o &amp;quot;random&amp;quot;&lt;br /&gt;
* Se añade otro argumento opcional con parámetro obligatorio. Proporcionará la semilla para `srand()`. Si no se pasa este parámetro, se toma como semilla el tiempo actual. Esta es ahora la salida de `./gol -u`:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt; [-r[&amp;lt;seed&amp;gt;]]&lt;br /&gt;
      -u, --usage:             Prints this help message&lt;br /&gt;
      -w, --width:             Width of the world&lt;br /&gt;
      -h, --height:            Height of the world&lt;br /&gt;
      -s, --Seed [seed]:       Seed for random world.&lt;br /&gt;
      -p, --pattern [pattern]: Initialization pattern:&lt;br /&gt;
 				 - glider&lt;br /&gt;
 				 - random&lt;br /&gt;
* Se modifica el método `gol_init()` para recibir un enumerado, `enum gol_init_pattern`, que esta definido en `gol.h`. El método `gol_init()` llama a los métodos privados `gol_init_rand()` o `gol_init_glider()`, según el patrón de inicialización seleccionado.&lt;br /&gt;
* Se crea una función auxiliar en `main.c` que transforma del string recibido como argumento a el enumerado que acepta `gol_init()`&lt;br /&gt;
* Se modifica `mem_test.c` para adaptarlo al nuevo `gol_init()`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 9&lt;br /&gt;
| 9.1&lt;br /&gt;
| Cargar y guardar el mundo desde un archivo binario&lt;br /&gt;
* Implementar los métodos `gol_save()` y `gol_load()` para guardar y cargar el mundo desde un archivo binario. Estas funciones simplemente guardan el array tal cual en el archivo especificado y leen el archivo guardándolo en el array.&lt;br /&gt;
 bool gol_load(struct gol *gol, const char *file);&lt;br /&gt;
 bool gol_save(const struct gol *gol, const char *file);&lt;br /&gt;
* Modificar el main para que acepte los siguientes comandos, además de 'q' para cerrar:&lt;br /&gt;
* 'l': Si se pulsa este caracter, llamar a una función estática `load_world()` que pida al usuario que inserte el nombre de un archivo.  Luego carga este archivo con la función `gol_load()`&lt;br /&gt;
* 's': Si se pulsa este caracter, llamar a una función estática `save_world()` que pida al usuario que inserte el nombre de un archivo.  Luego guarda este archivo con la función `gol_save()`&lt;br /&gt;
* Si cualquiera de los nuevos comandos falla, se informa al usuario del error y se continua la ejecución. Para que el usuario pueda leer el mensaje de error se llama a `getchar()`, así se pausa la ejecución hasta que se pulse un caracter.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 9.1&lt;br /&gt;
(opcional)&lt;br /&gt;
| Guardar y cargar el mundo desde un archivo de texto&lt;br /&gt;
Modificar `gol_save()` y `gol_load()` para guardar y cargar el estado del&lt;br /&gt;
mundo en un formato de texto parecido al que se usa en `gol_print()`.&lt;br /&gt;
&lt;br /&gt;
Ejemplo de archivo para mundo de 10x20:&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . # . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . # # # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=310</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=310"/>
				<updated>2019-06-03T15:12:59Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Tareas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:Slides_prin.pdf|Transparencias para imprimir]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
* [https://github.com/profedotc/solucion Repositorio con la solución del trabajo de clase] (se irá actualizando)&lt;br /&gt;
* [https://en.cppreference.com/w/c Documentación de C]&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
# https://youtu.be/IDfllYxE7I4&lt;br /&gt;
# https://youtu.be/57-zWEnGxHU&lt;br /&gt;
# https://youtu.be/1SJ_fEXD7OA&lt;br /&gt;
# https://youtu.be/EhX3E8lLcUM&lt;br /&gt;
# No hay&lt;br /&gt;
# https://youtu.be/dk-0xF5pJpQ (incompleto)&lt;br /&gt;
# https://youtu.be/sq14oKSodPM&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
|&lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Crear makefile y dividir el programa&lt;br /&gt;
* Se crean &amp;quot;gol.h&amp;quot; y &amp;quot;gol.c&amp;quot;&lt;br /&gt;
* Se crea un makefile para compilar y limpiar el repositorio&lt;br /&gt;
* Se añade un .gitignore para ignorar los productos de la compilación&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 7&lt;br /&gt;
| 7.1&lt;br /&gt;
| Objetos: Reserva dinámica de memoria para la estructura `gol`&lt;br /&gt;
* Se cambia ligeramente la interfaz de la función `gol_alloc` para que devuelva un puntero a `struct gol` en lugar de recibirlo.&lt;br /&gt;
* Ahora se reservan dinámicamente dos bloques de memoria: uno para la estructura `struct gol` y otro para los arrays del mundo.&lt;br /&gt;
* La función `gol_free` debe liberar los dos bloques de memoria.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 7.2&lt;br /&gt;
| Objetos: Ocultar la estructura `gol`&lt;br /&gt;
Mediante una declaración adelantada de `struct gol` en `gol.h` conseguimos&lt;br /&gt;
ocultar los campos de nuestro objeto (privatizar) a los usuarios de la librería.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 8&lt;br /&gt;
| 8.1&lt;br /&gt;
| Utilizar getopt para recibir argumentos de línea de comandos&lt;br /&gt;
* El programa ahora recibe como argumentos el ancho y el alto del mundo, además de el argumento `-u, --usage` que imprime el siguiente mensaje de ayuda:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt;&lt;br /&gt;
      -u, --usage: Prints this help message&lt;br /&gt;
      -w, --width: Width of the world&lt;br /&gt;
      -h, --height: Height of the world&lt;br /&gt;
* Es obligatorio especificar el tamaño del mundo, si no se especifica se imprime un mensaje de error y se termina el programa.&lt;br /&gt;
* Se define el tipo `struct gol_options` para guardar los parámetros de entrada: `int width`, `int height` y `bool usage`&lt;br /&gt;
* Se crean dos funciones estáticas que encapsulan la lógica de tratar los argumentos y de imprimir el mensaje de ayuda:&lt;br /&gt;
* `static bool parse_args(struct gol_options *gol_opt, int argc, char *argv[]);`&lt;br /&gt;
* `static void print_usage(const char *argv0);`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 8.2&lt;br /&gt;
| Implementar la opción de inicializar el mundo aleatoriamente&lt;br /&gt;
* Se añade un argumento opcional con un parámetro obligatorio. Indica el patrón de inicialización del mundo: &amp;quot;glider&amp;quot; o &amp;quot;random&amp;quot;&lt;br /&gt;
* Se añade otro argumento opcional con parámetro obligatorio. Proporcionará la semilla para `srand()`. Si no se pasa este parámetro, se toma como semilla el tiempo actual. Esta es ahora la salida de `./gol -u`:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt; [-r[&amp;lt;seed&amp;gt;]]&lt;br /&gt;
      -u, --usage:             Prints this help message&lt;br /&gt;
      -w, --width:             Width of the world&lt;br /&gt;
      -h, --height:            Height of the world&lt;br /&gt;
      -s, --Seed [seed]:       Seed for random world.&lt;br /&gt;
      -p, --pattern [pattern]: Initialization pattern:&lt;br /&gt;
 				 - glider&lt;br /&gt;
 				 - random&lt;br /&gt;
* Se modifica el método `gol_init()` para recibir un enumerado, `enum gol_init_pattern`, que esta definido en `gol.h`. El método `gol_init()` llama a los métodos privados `gol_init_rand()` o `gol_init_glider()`, según el patrón de inicialización seleccionado.&lt;br /&gt;
* Se crea una función auxiliar en `main.c` que transforma del string recibido como argumento a el enumerado que acepta `gol_init()`&lt;br /&gt;
* Se modifica `mem_test.c` para adaptarlo al nuevo `gol_init()`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 9&lt;br /&gt;
| 9.1&lt;br /&gt;
| Cargar y guardar el mundo desde un archivo binario&lt;br /&gt;
* Implementar los métodos `gol_save()` y `gol_load()` para guardar y cargar el mundo desde un archivo binario. Estas funciones simplemente guardan el array tal cual en el archivo especificado y leen el archivo guardándolo en el array.&lt;br /&gt;
 bool gol_load(struct gol *gol, const char *file);&lt;br /&gt;
 bool gol_save(const struct gol *gol, const char *file);&lt;br /&gt;
* Modificar el main para que acepte los siguientes comandos, además de 'q' para cerrar:&lt;br /&gt;
* 'l': Si se pulsa este caracter, llamar a una función estática `load_world()` que pida al usuario que inserte el nombre de un archivo.  Luego carga este archivo con la función `gol_load()`&lt;br /&gt;
* 's': Si se pulsa este caracter, llamar a una función estática `save_world()` que pida al usuario que inserte el nombre de un archivo.  Luego guarda este archivo con la función `gol_save()`&lt;br /&gt;
* Si cualquiera de los nuevos comandos falla, se informa al usuario del error y se continua la ejecución. Para que el usuario pueda leer el mensaje de error se llama a `getchar()`, así se pausa la ejecución hasta que se pulse un caracter.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 9.1&lt;br /&gt;
(opcional)&lt;br /&gt;
| Guardar y cargar el mundo desde un archivo de texto&lt;br /&gt;
Modificar `gol_save()` y `gol_load()` para guardar y cargar el estado del&lt;br /&gt;
mundo en un formato de texto parecido al que se usa en `gol_print()`.&lt;br /&gt;
&lt;br /&gt;
Ejemplo de archivo para mundo de 10x20:&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . # . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . # # # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=309</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=309"/>
				<updated>2019-06-03T15:01:16Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Vídeos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:Slides_prin.pdf|Transparencias para imprimir]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
* [https://github.com/profedotc/solucion Repositorio con la solución del trabajo de clase] (se irá actualizando)&lt;br /&gt;
* [https://en.cppreference.com/w/c Documentación de C]&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
# https://youtu.be/IDfllYxE7I4&lt;br /&gt;
# https://youtu.be/57-zWEnGxHU&lt;br /&gt;
# https://youtu.be/1SJ_fEXD7OA&lt;br /&gt;
# https://youtu.be/EhX3E8lLcUM&lt;br /&gt;
# No hay&lt;br /&gt;
# https://youtu.be/dk-0xF5pJpQ (incompleto)&lt;br /&gt;
# https://youtu.be/sq14oKSodPM&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
|&lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Crear makefile y dividir el programa&lt;br /&gt;
* Se crean &amp;quot;gol.h&amp;quot; y &amp;quot;gol.c&amp;quot;&lt;br /&gt;
* Se crea un makefile para compilar y limpiar el repositorio&lt;br /&gt;
* Se añade un .gitignore para ignorar los productos de la compilación&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 7&lt;br /&gt;
| 7.1&lt;br /&gt;
| Objetos: Reserva dinámica de memoria para la estructura `gol`&lt;br /&gt;
* Se cambia ligeramente la interfaz de la función `gol_alloc` para que devuelva un puntero a `struct gol` en lugar de recibirlo.&lt;br /&gt;
* Ahora se reservan dinámicamente dos bloques de memoria: uno para la estructura `struct gol` y otro para los arrays del mundo.&lt;br /&gt;
* La función `gol_free` debe liberar los dos bloques de memoria.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 7.2&lt;br /&gt;
| Objetos: Ocultar la estructura `gol`&lt;br /&gt;
Mediante una declaración adelantada de `struct gol` en `gol.h` conseguimos&lt;br /&gt;
ocultar los campos de nuestro objeto (privatizar) a los usuarios de la librería.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 8&lt;br /&gt;
| 8.1&lt;br /&gt;
| Utilizar getopt para recibir argumentos de línea de comandos&lt;br /&gt;
* El programa ahora recibe como argumentos el ancho y el alto del mundo, además de el argumento `-u, --usage` que imprime el siguiente mensaje de ayuda:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt;&lt;br /&gt;
      -u, --usage: Prints this help message&lt;br /&gt;
      -w, --width: Width of the world&lt;br /&gt;
      -h, --height: Height of the world&lt;br /&gt;
* Es obligatorio especificar el tamaño del mundo, si no se especifica se imprime un mensaje de error y se termina el programa.&lt;br /&gt;
* Se define el tipo `struct gol_options` para guardar los parámetros de entrada: `int width`, `int height` y `bool usage`&lt;br /&gt;
* Se crean dos funciones estáticas que encapsulan la lógica de tratar los argumentos y de imprimir el mensaje de ayuda:&lt;br /&gt;
* `static bool parse_args(struct gol_options *gol_opt, int argc, char *argv[]);`&lt;br /&gt;
* `static void print_usage(const char *argv0);`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 8.2&lt;br /&gt;
| Implementar la opción de inicializar el mundo aleatoriamente&lt;br /&gt;
* Se añade un argumento opcional con un parámetro obligatorio. Indica el patrón de inicialización del mundo: &amp;quot;glider&amp;quot; o &amp;quot;random&amp;quot;&lt;br /&gt;
* Se añade otro argumento opcional con parámetro obligatorio. Proporcionará la semilla para `srand()`. Si no se pasa este parámetro, se toma como semilla el tiempo actual. Esta es ahora la salida de `./gol -u`:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt; [-r[&amp;lt;seed&amp;gt;]]&lt;br /&gt;
      -u, --usage:             Prints this help message&lt;br /&gt;
      -w, --width:             Width of the world&lt;br /&gt;
      -h, --height:            Height of the world&lt;br /&gt;
      -s, --Seed [seed]:       Seed for random world.&lt;br /&gt;
      -p, --pattern [pattern]: Initialization pattern:&lt;br /&gt;
 				 - glider&lt;br /&gt;
 				 - random&lt;br /&gt;
* Se modifica el método `gol_init()` para recibir un enumerado, `enum gol_init_pattern`, que esta definido en `gol.h`. El método `gol_init()` llama a los métodos privados `gol_init_rand()` o `gol_init_glider()`, según el patrón de inicialización seleccionado.&lt;br /&gt;
* Se crea una función auxiliar en `main.c` que transforma del string recibido como argumento a el enumerado que acepta `gol_init()`&lt;br /&gt;
* Se modifica `mem_test.c` para adaptarlo al nuevo `gol_init()`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 8&lt;br /&gt;
| 9.1&lt;br /&gt;
| Cargar y guardar el mundo desde un archivo binario&lt;br /&gt;
* Implementar los métodos `gol_save()` y `gol_load()` para guardar y cargar el mundo desde un archivo binario. Estas funciones simplemente guardan el array tal cual en el archivo especificado y leen el archivo guardándolo en el array.&lt;br /&gt;
 bool gol_load(struct gol *gol, const char *file);&lt;br /&gt;
 bool gol_save(const struct gol *gol, const char *file);&lt;br /&gt;
* Modificar el main para que acepte los siguientes comandos, además de 'q' para cerrar:&lt;br /&gt;
* 'l': Si se pulsa este caracter, llamar a una función estática `load_world()` que pida al usuario que inserte el nombre de un archivo.  Luego carga este archivo con la función `gol_load()`&lt;br /&gt;
* 's': Si se pulsa este caracter, llamar a una función estática `save_world()` que pida al usuario que inserte el nombre de un archivo.  Luego guarda este archivo con la función `gol_save()`&lt;br /&gt;
* Si cualquiera de los nuevos comandos falla, se informa al usuario del error y se continua la ejecución. Para que el usuario pueda leer el mensaje de error se llama a `getchar()`, así se pausa la ejecución hasta que se pulse un caracter.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 9.1&lt;br /&gt;
(opcional)&lt;br /&gt;
| Guardar y cargar el mundo desde un archivo de texto&lt;br /&gt;
Modificar `gol_save()` y `gol_load()` para guardar y cargar el estado del&lt;br /&gt;
mundo en un formato de texto parecido al que se usa en `gol_print()`.&lt;br /&gt;
&lt;br /&gt;
Ejemplo de archivo para mundo de 10x20:&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . # . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . # # # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=308</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=308"/>
				<updated>2019-06-03T14:38:21Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Material de clase */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:Slides_prin.pdf|Transparencias para imprimir]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
* [https://github.com/profedotc/solucion Repositorio con la solución del trabajo de clase] (se irá actualizando)&lt;br /&gt;
* [https://en.cppreference.com/w/c Documentación de C]&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
# https://youtu.be/IDfllYxE7I4&lt;br /&gt;
# https://youtu.be/57-zWEnGxHU&lt;br /&gt;
# https://youtu.be/1SJ_fEXD7OA&lt;br /&gt;
# https://youtu.be/EhX3E8lLcUM&lt;br /&gt;
# No hay&lt;br /&gt;
# https://youtu.be/dk-0xF5pJpQ (incompleto)&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
|&lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Crear makefile y dividir el programa&lt;br /&gt;
* Se crean &amp;quot;gol.h&amp;quot; y &amp;quot;gol.c&amp;quot;&lt;br /&gt;
* Se crea un makefile para compilar y limpiar el repositorio&lt;br /&gt;
* Se añade un .gitignore para ignorar los productos de la compilación&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 7&lt;br /&gt;
| 7.1&lt;br /&gt;
| Objetos: Reserva dinámica de memoria para la estructura `gol`&lt;br /&gt;
* Se cambia ligeramente la interfaz de la función `gol_alloc` para que devuelva un puntero a `struct gol` en lugar de recibirlo.&lt;br /&gt;
* Ahora se reservan dinámicamente dos bloques de memoria: uno para la estructura `struct gol` y otro para los arrays del mundo.&lt;br /&gt;
* La función `gol_free` debe liberar los dos bloques de memoria.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 7.2&lt;br /&gt;
| Objetos: Ocultar la estructura `gol`&lt;br /&gt;
Mediante una declaración adelantada de `struct gol` en `gol.h` conseguimos&lt;br /&gt;
ocultar los campos de nuestro objeto (privatizar) a los usuarios de la librería.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 8&lt;br /&gt;
| 8.1&lt;br /&gt;
| Utilizar getopt para recibir argumentos de línea de comandos&lt;br /&gt;
* El programa ahora recibe como argumentos el ancho y el alto del mundo, además de el argumento `-u, --usage` que imprime el siguiente mensaje de ayuda:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt;&lt;br /&gt;
      -u, --usage: Prints this help message&lt;br /&gt;
      -w, --width: Width of the world&lt;br /&gt;
      -h, --height: Height of the world&lt;br /&gt;
* Es obligatorio especificar el tamaño del mundo, si no se especifica se imprime un mensaje de error y se termina el programa.&lt;br /&gt;
* Se define el tipo `struct gol_options` para guardar los parámetros de entrada: `int width`, `int height` y `bool usage`&lt;br /&gt;
* Se crean dos funciones estáticas que encapsulan la lógica de tratar los argumentos y de imprimir el mensaje de ayuda:&lt;br /&gt;
* `static bool parse_args(struct gol_options *gol_opt, int argc, char *argv[]);`&lt;br /&gt;
* `static void print_usage(const char *argv0);`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 8.2&lt;br /&gt;
| Implementar la opción de inicializar el mundo aleatoriamente&lt;br /&gt;
* Se añade un argumento opcional con un parámetro obligatorio. Indica el patrón de inicialización del mundo: &amp;quot;glider&amp;quot; o &amp;quot;random&amp;quot;&lt;br /&gt;
* Se añade otro argumento opcional con parámetro obligatorio. Proporcionará la semilla para `srand()`. Si no se pasa este parámetro, se toma como semilla el tiempo actual. Esta es ahora la salida de `./gol -u`:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt; [-r[&amp;lt;seed&amp;gt;]]&lt;br /&gt;
      -u, --usage:             Prints this help message&lt;br /&gt;
      -w, --width:             Width of the world&lt;br /&gt;
      -h, --height:            Height of the world&lt;br /&gt;
      -s, --Seed [seed]:       Seed for random world.&lt;br /&gt;
      -p, --pattern [pattern]: Initialization pattern:&lt;br /&gt;
 				 - glider&lt;br /&gt;
 				 - random&lt;br /&gt;
* Se modifica el método `gol_init()` para recibir un enumerado, `enum gol_init_pattern`, que esta definido en `gol.h`. El método `gol_init()` llama a los métodos privados `gol_init_rand()` o `gol_init_glider()`, según el patrón de inicialización seleccionado.&lt;br /&gt;
* Se crea una función auxiliar en `main.c` que transforma del string recibido como argumento a el enumerado que acepta `gol_init()`&lt;br /&gt;
* Se modifica `mem_test.c` para adaptarlo al nuevo `gol_init()`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 8&lt;br /&gt;
| 9.1&lt;br /&gt;
| Cargar y guardar el mundo desde un archivo binario&lt;br /&gt;
* Implementar los métodos `gol_save()` y `gol_load()` para guardar y cargar el mundo desde un archivo binario. Estas funciones simplemente guardan el array tal cual en el archivo especificado y leen el archivo guardándolo en el array.&lt;br /&gt;
 bool gol_load(struct gol *gol, const char *file);&lt;br /&gt;
 bool gol_save(const struct gol *gol, const char *file);&lt;br /&gt;
* Modificar el main para que acepte los siguientes comandos, además de 'q' para cerrar:&lt;br /&gt;
* 'l': Si se pulsa este caracter, llamar a una función estática `load_world()` que pida al usuario que inserte el nombre de un archivo.  Luego carga este archivo con la función `gol_load()`&lt;br /&gt;
* 's': Si se pulsa este caracter, llamar a una función estática `save_world()` que pida al usuario que inserte el nombre de un archivo.  Luego guarda este archivo con la función `gol_save()`&lt;br /&gt;
* Si cualquiera de los nuevos comandos falla, se informa al usuario del error y se continua la ejecución. Para que el usuario pueda leer el mensaje de error se llama a `getchar()`, así se pausa la ejecución hasta que se pulse un caracter.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 9.1&lt;br /&gt;
(opcional)&lt;br /&gt;
| Guardar y cargar el mundo desde un archivo de texto&lt;br /&gt;
Modificar `gol_save()` y `gol_load()` para guardar y cargar el estado del&lt;br /&gt;
mundo en un formato de texto parecido al que se usa en `gol_print()`.&lt;br /&gt;
&lt;br /&gt;
Ejemplo de archivo para mundo de 10x20:&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . # . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . # # # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Slides_prin.pdf&amp;diff=307</id>
		<title>Archivo:Slides prin.pdf</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Slides_prin.pdf&amp;diff=307"/>
				<updated>2019-06-03T01:39:27Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: Carfalgar subió una nueva versión de Archivo:Slides prin.pdf&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Transparencias.pdf&amp;diff=306</id>
		<title>Archivo:Transparencias.pdf</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Transparencias.pdf&amp;diff=306"/>
				<updated>2019-06-03T01:39:10Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: Carfalgar subió una nueva versión de Archivo:Transparencias.pdf&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=305</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=305"/>
				<updated>2019-06-03T01:29:34Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Tareas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:Slides_prin.pdf|Transparencias para imprimir]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
* [https://github.com/profedotc/solucion Repositorio con la solución del trabajo de clase] (se irá actualizando)&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
# https://youtu.be/IDfllYxE7I4&lt;br /&gt;
# https://youtu.be/57-zWEnGxHU&lt;br /&gt;
# https://youtu.be/1SJ_fEXD7OA&lt;br /&gt;
# https://youtu.be/EhX3E8lLcUM&lt;br /&gt;
# No hay&lt;br /&gt;
# https://youtu.be/dk-0xF5pJpQ (incompleto)&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
|&lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Crear makefile y dividir el programa&lt;br /&gt;
* Se crean &amp;quot;gol.h&amp;quot; y &amp;quot;gol.c&amp;quot;&lt;br /&gt;
* Se crea un makefile para compilar y limpiar el repositorio&lt;br /&gt;
* Se añade un .gitignore para ignorar los productos de la compilación&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 7&lt;br /&gt;
| 7.1&lt;br /&gt;
| Objetos: Reserva dinámica de memoria para la estructura `gol`&lt;br /&gt;
* Se cambia ligeramente la interfaz de la función `gol_alloc` para que devuelva un puntero a `struct gol` en lugar de recibirlo.&lt;br /&gt;
* Ahora se reservan dinámicamente dos bloques de memoria: uno para la estructura `struct gol` y otro para los arrays del mundo.&lt;br /&gt;
* La función `gol_free` debe liberar los dos bloques de memoria.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 7.2&lt;br /&gt;
| Objetos: Ocultar la estructura `gol`&lt;br /&gt;
Mediante una declaración adelantada de `struct gol` en `gol.h` conseguimos&lt;br /&gt;
ocultar los campos de nuestro objeto (privatizar) a los usuarios de la librería.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 8&lt;br /&gt;
| 8.1&lt;br /&gt;
| Utilizar getopt para recibir argumentos de línea de comandos&lt;br /&gt;
* El programa ahora recibe como argumentos el ancho y el alto del mundo, además de el argumento `-u, --usage` que imprime el siguiente mensaje de ayuda:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt;&lt;br /&gt;
      -u, --usage: Prints this help message&lt;br /&gt;
      -w, --width: Width of the world&lt;br /&gt;
      -h, --height: Height of the world&lt;br /&gt;
* Es obligatorio especificar el tamaño del mundo, si no se especifica se imprime un mensaje de error y se termina el programa.&lt;br /&gt;
* Se define el tipo `struct gol_options` para guardar los parámetros de entrada: `int width`, `int height` y `bool usage`&lt;br /&gt;
* Se crean dos funciones estáticas que encapsulan la lógica de tratar los argumentos y de imprimir el mensaje de ayuda:&lt;br /&gt;
* `static bool parse_args(struct gol_options *gol_opt, int argc, char *argv[]);`&lt;br /&gt;
* `static void print_usage(const char *argv0);`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 8.2&lt;br /&gt;
| Implementar la opción de inicializar el mundo aleatoriamente&lt;br /&gt;
* Se añade un argumento opcional con un parámetro obligatorio. Indica el patrón de inicialización del mundo: &amp;quot;glider&amp;quot; o &amp;quot;random&amp;quot;&lt;br /&gt;
* Se añade otro argumento opcional con parámetro obligatorio. Proporcionará la semilla para `srand()`. Si no se pasa este parámetro, se toma como semilla el tiempo actual. Esta es ahora la salida de `./gol -u`:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt; [-r[&amp;lt;seed&amp;gt;]]&lt;br /&gt;
      -u, --usage:             Prints this help message&lt;br /&gt;
      -w, --width:             Width of the world&lt;br /&gt;
      -h, --height:            Height of the world&lt;br /&gt;
      -s, --Seed [seed]:       Seed for random world.&lt;br /&gt;
      -p, --pattern [pattern]: Initialization pattern:&lt;br /&gt;
 				 - glider&lt;br /&gt;
 				 - random&lt;br /&gt;
* Se modifica el método `gol_init()` para recibir un enumerado, `enum gol_init_pattern`, que esta definido en `gol.h`. El método `gol_init()` llama a los métodos privados `gol_init_rand()` o `gol_init_glider()`, según el patrón de inicialización seleccionado.&lt;br /&gt;
* Se crea una función auxiliar en `main.c` que transforma del string recibido como argumento a el enumerado que acepta `gol_init()`&lt;br /&gt;
* Se modifica `mem_test.c` para adaptarlo al nuevo `gol_init()`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 8&lt;br /&gt;
| 9.1&lt;br /&gt;
| Cargar y guardar el mundo desde un archivo binario&lt;br /&gt;
* Implementar los métodos `gol_save()` y `gol_load()` para guardar y cargar el mundo desde un archivo binario. Estas funciones simplemente guardan el array tal cual en el archivo especificado y leen el archivo guardándolo en el array.&lt;br /&gt;
 bool gol_load(struct gol *gol, const char *file);&lt;br /&gt;
 bool gol_save(const struct gol *gol, const char *file);&lt;br /&gt;
* Modificar el main para que acepte los siguientes comandos, además de 'q' para cerrar:&lt;br /&gt;
* 'l': Si se pulsa este caracter, llamar a una función estática `load_world()` que pida al usuario que inserte el nombre de un archivo.  Luego carga este archivo con la función `gol_load()`&lt;br /&gt;
* 's': Si se pulsa este caracter, llamar a una función estática `save_world()` que pida al usuario que inserte el nombre de un archivo.  Luego guarda este archivo con la función `gol_save()`&lt;br /&gt;
* Si cualquiera de los nuevos comandos falla, se informa al usuario del error y se continua la ejecución. Para que el usuario pueda leer el mensaje de error se llama a `getchar()`, así se pausa la ejecución hasta que se pulse un caracter.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 9.1&lt;br /&gt;
(opcional)&lt;br /&gt;
| Guardar y cargar el mundo desde un archivo de texto&lt;br /&gt;
Modificar `gol_save()` y `gol_load()` para guardar y cargar el estado del&lt;br /&gt;
mundo en un formato de texto parecido al que se usa en `gol_print()`.&lt;br /&gt;
&lt;br /&gt;
Ejemplo de archivo para mundo de 10x20:&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . # . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . # # # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=304</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=304"/>
				<updated>2019-06-03T01:27:41Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Tareas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:Slides_prin.pdf|Transparencias para imprimir]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
* [https://github.com/profedotc/solucion Repositorio con la solución del trabajo de clase] (se irá actualizando)&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
# https://youtu.be/IDfllYxE7I4&lt;br /&gt;
# https://youtu.be/57-zWEnGxHU&lt;br /&gt;
# https://youtu.be/1SJ_fEXD7OA&lt;br /&gt;
# https://youtu.be/EhX3E8lLcUM&lt;br /&gt;
# No hay&lt;br /&gt;
# https://youtu.be/dk-0xF5pJpQ (incompleto)&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
|&lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Crear makefile y dividir el programa&lt;br /&gt;
* Se crean &amp;quot;gol.h&amp;quot; y &amp;quot;gol.c&amp;quot;&lt;br /&gt;
* Se crea un makefile para compilar y limpiar el repositorio&lt;br /&gt;
* Se añade un .gitignore para ignorar los productos de la compilación&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 7&lt;br /&gt;
| 7.1&lt;br /&gt;
| Objetos: Reserva dinámica de memoria para la estructura `gol`&lt;br /&gt;
* Se cambia ligeramente la interfaz de la función `gol_alloc` para que devuelva un puntero a `struct gol` en lugar de recibirlo.&lt;br /&gt;
* Ahora se reservan dinámicamente dos bloques de memoria: uno para la estructura `struct gol` y otro para los arrays del mundo.&lt;br /&gt;
* La función `gol_free` debe liberar los dos bloques de memoria.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 7.2&lt;br /&gt;
| Objetos: Ocultar la estructura `gol`&lt;br /&gt;
Mediante una declaración adelantada de `struct gol` en `gol.h` conseguimos&lt;br /&gt;
ocultar los campos de nuestro objeto (privatizar) a los usuarios de la librería.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 8&lt;br /&gt;
| 8.1&lt;br /&gt;
| Utilizar getopt para recibir argumentos de línea de comandos&lt;br /&gt;
* El programa ahora recibe como argumentos el ancho y el alto del mundo, además de el argumento `-u, --usage` que imprime el siguiente mensaje de ayuda:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt;&lt;br /&gt;
      -u, --usage: Prints this help message&lt;br /&gt;
      -w, --width: Width of the world&lt;br /&gt;
      -h, --height: Height of the world&lt;br /&gt;
* Es obligatorio especificar el tamaño del mundo, si no se especifica se imprime un mensaje de error y se termina el programa.&lt;br /&gt;
* Se define el tipo `struct gol_options` para guardar los parámetros de entrada: `int width`, `int height` y `bool usage`&lt;br /&gt;
* Se crean dos funciones estáticas que encapsulan la lógica de tratar los argumentos y de imprimir el mensaje de ayuda:&lt;br /&gt;
* `static bool parse_args(struct gol_options *gol_opt, int argc, char *argv[]);`&lt;br /&gt;
* `static void print_usage(const char *argv0);`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 8.2&lt;br /&gt;
| Implementar la opción de inicializar el mundo aleatoriamente&lt;br /&gt;
* Se añade un argumento opcional con un parámetro obligatorio. Indica el patrón de inicialización del mundo: &amp;quot;glider&amp;quot; o &amp;quot;random&amp;quot;&lt;br /&gt;
* Se añade otro argumento opcional con parámetro obligatorio. Proporcionará la semilla para `srand()`. Si no se pasa este parámetro, se toma como semilla el tiempo actual. Esta es ahora la salida de `./gol -u`:&lt;br /&gt;
 Usage: ./gol -w &amp;lt;width&amp;gt; -h &amp;lt;height&amp;gt; [-r[&amp;lt;seed&amp;gt;]]&lt;br /&gt;
      -u, --usage:             Prints this help message&lt;br /&gt;
      -w, --width:             Width of the world&lt;br /&gt;
      -h, --height:            Height of the world&lt;br /&gt;
      -s, --Seed [seed]:       Seed for random world.&lt;br /&gt;
      -p, --pattern [pattern]: Initialization pattern:&lt;br /&gt;
 				 - glider&lt;br /&gt;
 				 - random&lt;br /&gt;
* Se modifica el método `gol_init()` para recibir un enumerado, `enum gol_init_pattern`, que esta definido en `gol.h`. El método `gol_init()` llama a los métodos privados `gol_init_rand()` o `gol_init_glider()`, según el patrón de inicialización seleccionado.&lt;br /&gt;
* Se crea una función auxiliar en `main.c` que transforma del string recibido como argumento a el enumerado que acepta `gol_init()`&lt;br /&gt;
* Se modifica `mem_test.c` para adaptarlo al nuevo `gol_init()`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 8&lt;br /&gt;
| 9.1&lt;br /&gt;
| Cargar y guardar el mundo desde un archivo binario&lt;br /&gt;
* Implementar los métodos `gol_save()` y `gol_load()` para guardar y cargar el mundo desde un archivo binario. Estas funciones simplemente guardan el array tal cual en el archivo especificado y leen el archivo guardándolo en el array.&lt;br /&gt;
 bool gol_load(struct gol *gol, const char *file);&lt;br /&gt;
 bool gol_save(const struct gol *gol, const char *file);&lt;br /&gt;
* Modificar el main para que acepte los siguientes comandos, además de 'q' para cerrar:&lt;br /&gt;
* 'l': Si se pulsa este caracter, llamar a una función estática `load_world()` que pida al usuario que inserte el nombre de un archivo.  Luego carga este archivo con la función `gol_load()`&lt;br /&gt;
* 's': Si se pulsa este caracter, llamar a una función estática `save_world()` que pida al usuario que inserte el nombre de un archivo.  Luego guarda este archivo con la función `gol_save()`&lt;br /&gt;
* Si cualquiera de los nuevos comandos falla, se informa al usuario del error y se continua la ejecución. Para que el usuario pueda leer el mensaje de error se llama a `getchar()`, así se pausa la ejecución hasta que se pulse un caracter.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 9.1&lt;br /&gt;
| Guardar y cargar el mundo desde un archivo de texto&lt;br /&gt;
Modificar `gol_save()` y `gol_load()` para guardar y cargar el estado del&lt;br /&gt;
mundo en un formato de texto parecido al que se usa en `gol_print()`.&lt;br /&gt;
&lt;br /&gt;
Ejemplo de archivo para mundo de 10x20:&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . # . . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . # # # . . . . . . . . . . . .&lt;br /&gt;
 . . . . . . . . . . . . . . . . . . . .&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=303</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=303"/>
				<updated>2019-06-03T01:17:47Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Material de clase */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:Slides_prin.pdf|Transparencias para imprimir]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
* [https://github.com/profedotc/solucion Repositorio con la solución del trabajo de clase] (se irá actualizando)&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
# https://youtu.be/IDfllYxE7I4&lt;br /&gt;
# https://youtu.be/57-zWEnGxHU&lt;br /&gt;
# https://youtu.be/1SJ_fEXD7OA&lt;br /&gt;
# https://youtu.be/EhX3E8lLcUM&lt;br /&gt;
# No hay&lt;br /&gt;
# https://youtu.be/dk-0xF5pJpQ (incompleto)&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| &lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Crear makefile y dividir el programa&lt;br /&gt;
* Se crean &amp;quot;gol.h&amp;quot; y &amp;quot;gol.c&amp;quot;&lt;br /&gt;
* Se crea un makefile para compilar y limpiar el repositorio&lt;br /&gt;
* Se añade un .gitignore para ignorar los productos de la compilación&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=302</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=302"/>
				<updated>2019-05-31T16:44:51Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Vídeos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:Slides_prin.pdf|Transparencias para imprimir]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
# https://youtu.be/IDfllYxE7I4&lt;br /&gt;
# https://youtu.be/57-zWEnGxHU&lt;br /&gt;
# https://youtu.be/1SJ_fEXD7OA&lt;br /&gt;
# https://youtu.be/EhX3E8lLcUM&lt;br /&gt;
# No hay&lt;br /&gt;
# https://youtu.be/dk-0xF5pJpQ (incompleto)&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| &lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Crear makefile y dividir el programa&lt;br /&gt;
* Se crean &amp;quot;gol.h&amp;quot; y &amp;quot;gol.c&amp;quot;&lt;br /&gt;
* Se crea un makefile para compilar y limpiar el repositorio&lt;br /&gt;
* Se añade un .gitignore para ignorar los productos de la compilación&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=301</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=301"/>
				<updated>2019-05-31T14:56:26Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Vídeos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:Slides_prin.pdf|Transparencias para imprimir]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
# https://youtu.be/IDfllYxE7I4&lt;br /&gt;
# https://youtu.be/57-zWEnGxHU&lt;br /&gt;
# https://youtu.be/1SJ_fEXD7OA&lt;br /&gt;
# https://youtu.be/EhX3E8lLcUM&lt;br /&gt;
# No hay&lt;br /&gt;
# https://youtu.be/dk-0xF5pJpQ&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| &lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Crear makefile y dividir el programa&lt;br /&gt;
* Se crean &amp;quot;gol.h&amp;quot; y &amp;quot;gol.c&amp;quot;&lt;br /&gt;
* Se crea un makefile para compilar y limpiar el repositorio&lt;br /&gt;
* Se añade un .gitignore para ignorar los productos de la compilación&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Transparencias.pdf&amp;diff=300</id>
		<title>Archivo:Transparencias.pdf</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Transparencias.pdf&amp;diff=300"/>
				<updated>2019-05-28T20:24:27Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: Carfalgar subió una nueva versión de Archivo:Transparencias.pdf&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Slides_prin.pdf&amp;diff=299</id>
		<title>Archivo:Slides prin.pdf</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Slides_prin.pdf&amp;diff=299"/>
				<updated>2019-05-28T20:24:20Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: Carfalgar subió una nueva versión de Archivo:Slides prin.pdf&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=298</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=298"/>
				<updated>2019-05-27T14:43:09Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Vídeos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:Slides_prin.pdf|Transparencias para imprimir]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
# https://youtu.be/IDfllYxE7I4&lt;br /&gt;
# https://youtu.be/57-zWEnGxHU&lt;br /&gt;
# https://youtu.be/1SJ_fEXD7OA&lt;br /&gt;
# https://youtu.be/EhX3E8lLcUM&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| &lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Crear makefile y dividir el programa&lt;br /&gt;
* Se crean &amp;quot;gol.h&amp;quot; y &amp;quot;gol.c&amp;quot;&lt;br /&gt;
* Se crea un makefile para compilar y limpiar el repositorio&lt;br /&gt;
* Se añade un .gitignore para ignorar los productos de la compilación&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=297</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=297"/>
				<updated>2019-05-24T14:56:42Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Vídeos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:Slides_prin.pdf|Transparencias para imprimir]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
# https://youtu.be/IDfllYxE7I4&lt;br /&gt;
# https://youtu.be/57-zWEnGxHU&lt;br /&gt;
# https://youtu.be/1SJ_fEXD7OA&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| &lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Crear makefile y dividir el programa&lt;br /&gt;
* Se crean &amp;quot;gol.h&amp;quot; y &amp;quot;gol.c&amp;quot;&lt;br /&gt;
* Se crea un makefile para compilar y limpiar el repositorio&lt;br /&gt;
* Se añade un .gitignore para ignorar los productos de la compilación&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=296</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=296"/>
				<updated>2019-05-22T14:58:49Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Vídeos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:Slides_prin.pdf|Transparencias para imprimir]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
# https://youtu.be/IDfllYxE7I4&lt;br /&gt;
# https://youtu.be/57-zWEnGxHU&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| &lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Crear makefile y dividir el programa&lt;br /&gt;
* Se crean &amp;quot;gol.h&amp;quot; y &amp;quot;gol.c&amp;quot;&lt;br /&gt;
* Se crea un makefile para compilar y limpiar el repositorio&lt;br /&gt;
* Se añade un .gitignore para ignorar los productos de la compilación&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=295</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=295"/>
				<updated>2019-05-20T15:02:34Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Tareas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:Slides_prin.pdf|Transparencias para imprimir]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
# https://youtu.be/IDfllYxE7I4&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| &lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Crear makefile y dividir el programa&lt;br /&gt;
* Se crean &amp;quot;gol.h&amp;quot; y &amp;quot;gol.c&amp;quot;&lt;br /&gt;
* Se crea un makefile para compilar y limpiar el repositorio&lt;br /&gt;
* Se añade un .gitignore para ignorar los productos de la compilación&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=294</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=294"/>
				<updated>2019-05-20T14:52:34Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Vídeos */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:Slides_prin.pdf|Transparencias para imprimir]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
# https://youtu.be/IDfllYxE7I4&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| &lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=293</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=293"/>
				<updated>2019-05-20T14:49:54Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:Slides_prin.pdf|Transparencias para imprimir]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| &lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=292</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=292"/>
				<updated>2019-05-20T14:49:05Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:Transparencias_print.pdf|Transparencias para imprimir]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| &lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Slides_prin.pdf&amp;diff=291</id>
		<title>Archivo:Slides prin.pdf</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Slides_prin.pdf&amp;diff=291"/>
				<updated>2019-05-20T14:48:54Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Transparencias.pdf&amp;diff=290</id>
		<title>Archivo:Transparencias.pdf</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Transparencias.pdf&amp;diff=290"/>
				<updated>2019-05-20T14:46:38Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: Carfalgar subió una nueva versión de Archivo:Transparencias.pdf&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=P%C3%A1gina_principal&amp;diff=289</id>
		<title>Página principal</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=P%C3%A1gina_principal&amp;diff=289"/>
				<updated>2019-05-20T14:45:55Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Bienvenid@ al wiki del IV Curso de programación en C.&lt;br /&gt;
&lt;br /&gt;
Este curso ofrecerá una visión moderna de la programación en C, partiendo de los estándares de C99 y C11. Se realizará siempre un enfoque práctico. Es por ello que el curso introducirá al estudiante en el uso de las bibliotecas nativas en C de referencia para el desarrollo de software en entornos gráficos, red, importación/exportación de datos de ficheros. Consulta el [https://1984.lsi.us.es/curso-programacion-c/ contenido del curso].&lt;br /&gt;
&lt;br /&gt;
= Matrícula y preinscripción =&lt;br /&gt;
&lt;br /&gt;
* '''Preinscripción''': Si estás interesado debes realizar la preinscripción gratuita cuanto antes para reservar tu plaza.&lt;br /&gt;
* '''Matrícula''': El periodo de matrícula está comprendido entre los días '''1 y 7 de Abril''' (&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;si quieres matricularte fuera de plazo contacta con nosotros&amp;lt;/span&amp;gt;) y tiene un coste total de '''180€'''&lt;br /&gt;
&lt;br /&gt;
Puedes realizar tanto la matrícula como la preinscripción a través de esta web: https://cfp.us.es/cursos/fc/programacion-en-c/3831/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:20px;color:red&amp;quot;&amp;gt; ¡¡ATENCIÓN: Los créditos ECTS de este curso NO son convalidables!!&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Los créditos de los cursos de formación continua tienen una validez meramente curricular y no pueden ser reconocidos para los planes de grado.&lt;br /&gt;
&lt;br /&gt;
= Lugar =&lt;br /&gt;
&lt;br /&gt;
El curso se impartirá en el edificio '''CRAI Antonio de Ulloa''', Avenida Reina Mercedes, s/n 41012 Sevilla. ([http://www.openstreetmap.org/way/27486919#map=19/37.35971/-5.98621 ver en mapa]). Se utilizará el aula TIC1, situada en la 2ª planta del edificio.&lt;br /&gt;
&lt;br /&gt;
Todas las aulas disponen de ordenadores para los alumnos. Si desea llevar su portátil, puede hacerlo siempre que disponga de alguna distribución GNU/Linux (preferiblemente Ubuntu nativo o en máquina virtual).&lt;br /&gt;
&lt;br /&gt;
= Fechas y horario =&lt;br /&gt;
&lt;br /&gt;
El curso comprenderá entre los días '''2 de Mayo''' y '''14 de Junio'''. Las clases serán los '''Lunes''', '''Miércoles''' y '''Viernes''' de '''17:00 a 19:30''' (salvo excepción). &lt;br /&gt;
Para más información consultar: http://1984.lsi.us.es/curso-programacion-c/&lt;br /&gt;
&lt;br /&gt;
[[File:horario.png|thumb|700px]]&lt;br /&gt;
&lt;br /&gt;
= Lista de correo =&lt;br /&gt;
El curso se apoya en una [https://listas.us.es/mailman/listinfo/programacion-c lista de correo] que puedes emplear para plantear dudas y discusiones relacionadas con la programación en C.&lt;br /&gt;
&lt;br /&gt;
= Criterios de evaluación = &lt;br /&gt;
El curso tendrá un enfoque muy práctico, por lo que la evaluación se basará en diversos ejercicios y trabajos realizados individualmente y repartidos a lo largo del curso.&lt;br /&gt;
&lt;br /&gt;
= Profesores =&lt;br /&gt;
* '''Pablo Neira Ayuso''': pneira &amp;lt;AT&amp;gt; us &amp;lt;DOT&amp;gt; es&lt;br /&gt;
* '''Carlos Falgueras García''': carfalgar &amp;lt;AT&amp;gt; alum &amp;lt;DOT&amp;gt; us &amp;lt;DOT&amp;gt; es&lt;br /&gt;
&lt;br /&gt;
= Contacto y más información =&lt;br /&gt;
Para más información puedes consultar la [https://cfp.us.es/cursos/fc/programacion-en-c/3831/ web del Centro de Formación Permanente] o contactar por email: '''carfalgar &amp;lt;AT&amp;gt; alum &amp;lt;DOT&amp;gt; us &amp;lt;DOT&amp;gt; es'''&lt;br /&gt;
&lt;br /&gt;
= Material y tareas =&lt;br /&gt;
[[Material]]&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=288</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=288"/>
				<updated>2019-05-19T19:26:46Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;br /&gt;
&lt;br /&gt;
== Tareas ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Tarea&lt;br /&gt;
! Subtarea&lt;br /&gt;
! Descripción&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| &lt;br /&gt;
|  Versión inicial&lt;br /&gt;
* Completada la plantilla del juego de la vida&lt;br /&gt;
* Completado README.md&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 2&lt;br /&gt;
| 2.1&lt;br /&gt;
|  Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 2.2&lt;br /&gt;
| Intercambiar mundos en lugar de copiarlos&lt;br /&gt;
* Se utiliza un array de 3 dimensiones para guardar los 2 mundos&lt;br /&gt;
* Se van intercambiando los mundos &amp;quot;actual&amp;quot; y &amp;quot;siguiente&amp;quot; en cada iteración&lt;br /&gt;
* Se elimina la función `gol_copy`, ahora innecesaria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 3&lt;br /&gt;
| 3.1&lt;br /&gt;
| Encapsular el juego de la vida en una estructura&lt;br /&gt;
* Se encapsulan las variables `worlds` y `current_world` en la estructura `gol`&lt;br /&gt;
* La función `gol_step` se encarga ahora de gestionar la variable `curren_world`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 3.2&lt;br /&gt;
| Ocultar todas las funciones que el usuario no necesite&lt;br /&gt;
* Se ocultan `gol_get_cell` y `gol_count_neighbours`&lt;br /&gt;
* Se declaran como `static` y se elimina el prefijo `gol_`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 4&lt;br /&gt;
| 4.1&lt;br /&gt;
| Memoria dinámica I: Añadir objetivos `debug` y `release`&lt;br /&gt;
Se añaden dos nuevos objetivos al makefile que modifican los flags de gcc para&lt;br /&gt;
crear dos ejecutables distintos según convenga.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 4.2&lt;br /&gt;
| Memoria dinámica I: Reserva dinámica de memoria para el mundo&lt;br /&gt;
* Ahora los mundos se reservan dinámicamente con `malloc`&lt;br /&gt;
* La nueva función `gol_alloc` se encarga de la esta reserva y `gol_free` de la liberación&lt;br /&gt;
* Cada mundo es un puntero a un puntero a un boleano, ie un vector de vectores. Se realiza una llamada a malloc para guardar un vector de punteros a filas y luego se realiza otra llamada por cada fila para reservarla.&lt;br /&gt;
* Para guardar la referencia a los dos mundos se utiliza un array de dos punteros. El mundo actual y el próximo siempre están en la misma posición de este array, y en cada iteración se intercambian las direcciones de los dos punteros.&lt;br /&gt;
* Se usa un enumerado para identificar los índices del mundo actual y el siguiente&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 5&lt;br /&gt;
| 5.1&lt;br /&gt;
| Memoria dinámica II: Implementar test de memoria&lt;br /&gt;
* Se crea un nuevo archivo `mem_test.c` con otro `main()` que realiza un número finito de iteraciones del juego sin requerir la interacción del usuario, ni imprimir nada por pantalla&lt;br /&gt;
* Se añade un nuevo objetivo (`test`) al makefile que primero compilar el ejecutable `mem_test` con opciones de depuración y con todas las optimizaciones. Después lanzará este ejecutable con valgrind para comprobar fugas de memoria&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 5.2&lt;br /&gt;
| Memoria dinámica II: Una sola reserva de memoria por mundo&lt;br /&gt;
* Los mundos son un único puntero a un bloque de memoria dónde está la matriz entera. Se realiza una llama a malloc por mundo.&lt;br /&gt;
* Ahora hay que calcular el offset de cada célula a mano, por lo que los accesos al mundo siempre se hacen a través de `get_cell` y la nueva función `set_cell`&lt;br /&gt;
* Las funciones `set_cell` y `get_cell` reciben el mundo sobre el que actuar (actual o siguiente)&lt;br /&gt;
* Se saca la lógica para comprobar los límites del mundo a la función `fix_coords` para poder utilizarla en `set_cell` y `get_cell` sin repetir código&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | 6&lt;br /&gt;
| 6.1&lt;br /&gt;
| Memoria dinámica III: Macro funcional para acceder a las células&lt;br /&gt;
Utilizar una macro para reutilizar y evitar repetir el mismo código en&lt;br /&gt;
`get_cell` y `set_cell`&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| 6.2&lt;br /&gt;
| Memoria dinámica III: Una reserva de memoria para los dos mundos&lt;br /&gt;
* La memoria para los dos mundos se reserva de una vez. La referencia a este bloque de memoria se guarda en la estructura del objeto&lt;br /&gt;
* Se utiliza la misma lógica que antes para acceder a las células, con dos punteros a los mundos que vamos intercarbiando.&lt;br /&gt;
|-&lt;br /&gt;
&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
| ...&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=P%C3%A1gina_principal&amp;diff=287</id>
		<title>Página principal</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=P%C3%A1gina_principal&amp;diff=287"/>
				<updated>2019-05-06T04:48:00Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Bienvenid@ al wiki del IV Curso de programación en C.&lt;br /&gt;
&lt;br /&gt;
Este curso ofrecerá una visión moderna de la programación en C, partiendo de los estándares de C99 y C11. Se realizará siempre un enfoque práctico. Es por ello que el curso introducirá al estudiante en el uso de las bibliotecas nativas en C de referencia para el desarrollo de software en entornos gráficos, red, importación/exportación de datos de ficheros. Consulta el [https://1984.lsi.us.es/curso-programacion-c/ contenido del curso].&lt;br /&gt;
&lt;br /&gt;
= Matrícula y preinscripción =&lt;br /&gt;
&lt;br /&gt;
* '''Preinscripción''': Si estás interesado debes realizar la preinscripción gratuita cuanto antes para reservar tu plaza.&lt;br /&gt;
* '''Matrícula''': El periodo de matrícula está comprendido entre los días '''1 y 7 de Abril''' (&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;si quieres matricularte fuera de plazo contacta con nosotros&amp;lt;/span&amp;gt;) y tiene un coste total de '''180€'''&lt;br /&gt;
&lt;br /&gt;
Puedes realizar tanto la matrícula como la preinscripción a través de esta web: https://cfp.us.es/cursos/fc/programacion-en-c/3831/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:20px;color:red&amp;quot;&amp;gt; ¡¡ATENCIÓN: Los créditos ECTS de este curso NO son convalidables!!&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Los créditos de los cursos de formación continua tienen una validez meramente curricular y no pueden ser reconocidos para los planes de grado.&lt;br /&gt;
&lt;br /&gt;
= Lugar =&lt;br /&gt;
&lt;br /&gt;
El curso se impartirá en el edificio '''CRAI Antonio de Ulloa''', Avenida Reina Mercedes, s/n 41012 Sevilla. ([http://www.openstreetmap.org/way/27486919#map=19/37.35971/-5.98621 ver en mapa]). Se utilizará el aula TIC1, situada en la 2ª planta del edificio.&lt;br /&gt;
&lt;br /&gt;
Todas las aulas disponen de ordenadores para los alumnos. Si desea llevar su portátil, puede hacerlo siempre que disponga de alguna distribución GNU/Linux (preferiblemente Ubuntu nativo o en máquina virtual).&lt;br /&gt;
&lt;br /&gt;
= Fechas y horario =&lt;br /&gt;
&lt;br /&gt;
El curso comprenderá entre los días '''2 de Mayo''' y '''14 de Junio'''. Las clases serán los '''Lunes''', '''Miércoles''' y '''Viernes''' de '''17:00 a 19:30''' (salvo excepción). &lt;br /&gt;
Para más información consultar: http://1984.lsi.us.es/curso-programacion-c/&lt;br /&gt;
&lt;br /&gt;
[[File:horario.png|thumb|700px]]&lt;br /&gt;
&lt;br /&gt;
= Lista de correo =&lt;br /&gt;
El curso se apoya en una [https://listas.us.es/mailman/listinfo/programacion-c lista de correo] que puedes emplear para plantear dudas y discusiones relacionadas con la programación en C.&lt;br /&gt;
&lt;br /&gt;
= Criterios de evaluación = &lt;br /&gt;
El curso tendrá un enfoque muy práctico, por lo que la evaluación se basará en diversos ejercicios y trabajos realizados individualmente y repartidos a lo largo del curso.&lt;br /&gt;
&lt;br /&gt;
= Profesores =&lt;br /&gt;
* '''Pablo Neira Ayuso''': pneira &amp;lt;AT&amp;gt; us &amp;lt;DOT&amp;gt; es&lt;br /&gt;
* '''Carlos Falgueras García''': carfalgar &amp;lt;AT&amp;gt; alum &amp;lt;DOT&amp;gt; us &amp;lt;DOT&amp;gt; es&lt;br /&gt;
&lt;br /&gt;
= Contacto y más información =&lt;br /&gt;
Para más información puedes consultar la [https://cfp.us.es/cursos/fc/programacion-en-c/3831/ web del Centro de Formación Permanente] o contactar por email: '''carfalgar &amp;lt;AT&amp;gt; alum &amp;lt;DOT&amp;gt; us &amp;lt;DOT&amp;gt; es'''&lt;br /&gt;
&lt;br /&gt;
= Material =&lt;br /&gt;
[[Material]]&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=286</id>
		<title>Material</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Material&amp;diff=286"/>
				<updated>2019-05-06T04:46:35Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: Página creada con « == Material de clase ==  * Transparencias  (Se irá actualizando) * Plantilla Juego de la vida  == Vídeos ==...»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Material de clase ==&lt;br /&gt;
&lt;br /&gt;
* [[:Archivo:Transparencias.pdf|Transparencias]]  (Se irá actualizando)&lt;br /&gt;
* [[:Archivo:plantilla_gol.c|Plantilla Juego de la vida]]&lt;br /&gt;
&lt;br /&gt;
== Vídeos ==&lt;br /&gt;
&lt;br /&gt;
# https://youtu.be/C0UiG1uYgYQ&lt;br /&gt;
# https://youtu.be/gqzYwGdPfYM&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Plantilla_gol.c&amp;diff=285</id>
		<title>Archivo:Plantilla gol.c</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Plantilla_gol.c&amp;diff=285"/>
				<updated>2019-05-06T04:45:52Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Transparencias.pdf&amp;diff=284</id>
		<title>Archivo:Transparencias.pdf</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Transparencias.pdf&amp;diff=284"/>
				<updated>2019-05-06T04:43:08Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=P%C3%A1gina_principal&amp;diff=283</id>
		<title>Página principal</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=P%C3%A1gina_principal&amp;diff=283"/>
				<updated>2019-03-27T17:28:29Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Fechas y horario */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Bienvenid@ al wiki del IV Curso de programación en C.&lt;br /&gt;
&lt;br /&gt;
Este curso ofrecerá una visión moderna de la programación en C, partiendo de los estándares de C99 y C11. Se realizará siempre un enfoque práctico. Es por ello que el curso introducirá al estudiante en el uso de las bibliotecas nativas en C de referencia para el desarrollo de software en entornos gráficos, red, importación/exportación de datos de ficheros. Consulta el [https://1984.lsi.us.es/curso-programacion-c/ contenido del curso].&lt;br /&gt;
&lt;br /&gt;
= Matrícula y preinscripción =&lt;br /&gt;
&lt;br /&gt;
* '''Preinscripción''': Si estás interesado debes realizar la preinscripción gratuita cuanto antes para reservar tu plaza.&lt;br /&gt;
* '''Matrícula''': El periodo de matrícula está comprendido entre los días '''1 y 7 de Abril''' (&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;si quieres matricularte fuera de plazo contacta con nosotros&amp;lt;/span&amp;gt;) y tiene un coste total de '''180€'''&lt;br /&gt;
&lt;br /&gt;
Puedes realizar tanto la matrícula como la preinscripción a través de esta web: https://cfp.us.es/cursos/fc/programacion-en-c/3831/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:20px;color:red&amp;quot;&amp;gt; ¡¡ATENCIÓN: Los créditos ECTS de este curso NO son convalidables!!&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Los créditos de los cursos de formación continua tienen una validez meramente curricular y no pueden ser reconocidos para los planes de grado.&lt;br /&gt;
&lt;br /&gt;
= Lugar =&lt;br /&gt;
&lt;br /&gt;
El curso se impartirá en el edificio '''CRAI Antonio de Ulloa''', Avenida Reina Mercedes, s/n 41012 Sevilla. ([http://www.openstreetmap.org/way/27486919#map=19/37.35971/-5.98621 ver en mapa]). Se utilizará el aula TIC1, situada en la 2ª planta del edificio.&lt;br /&gt;
&lt;br /&gt;
Todas las aulas disponen de ordenadores para los alumnos. Si desea llevar su portátil, puede hacerlo siempre que disponga de alguna distribución GNU/Linux (preferiblemente Ubuntu nativo o en máquina virtual).&lt;br /&gt;
&lt;br /&gt;
= Fechas y horario =&lt;br /&gt;
&lt;br /&gt;
El curso comprenderá entre los días '''2 de Mayo''' y '''14 de Junio'''. Las clases serán los '''Lunes''', '''Miércoles''' y '''Viernes''' de '''17:00 a 19:30''' (salvo excepción). &lt;br /&gt;
Para más información consultar: http://1984.lsi.us.es/curso-programacion-c/&lt;br /&gt;
&lt;br /&gt;
[[File:horario.png|thumb|700px]]&lt;br /&gt;
&lt;br /&gt;
= Lista de correo =&lt;br /&gt;
El curso se apoya en una [https://listas.us.es/mailman/listinfo/programacion-c lista de correo] que puedes emplear para plantear dudas y discusiones relacionadas con la programación en C.&lt;br /&gt;
&lt;br /&gt;
= Criterios de evaluación = &lt;br /&gt;
El curso tendrá un enfoque muy práctico, por lo que la evaluación se basará en diversos ejercicios y trabajos realizados individualmente y repartidos a lo largo del curso.&lt;br /&gt;
&lt;br /&gt;
= Profesores =&lt;br /&gt;
* '''Pablo Neira Ayuso''': pneira &amp;lt;AT&amp;gt; us &amp;lt;DOT&amp;gt; es&lt;br /&gt;
* '''Carlos Falgueras García''': carfalgar &amp;lt;AT&amp;gt; alum &amp;lt;DOT&amp;gt; us &amp;lt;DOT&amp;gt; es&lt;br /&gt;
&lt;br /&gt;
= Contacto y más información =&lt;br /&gt;
Para más información puedes consultar la [https://cfp.us.es/cursos/fc/programacion-en-c/3831/ web del Centro de Formación Permanente] o contactar por email: '''carfalgar &amp;lt;AT&amp;gt; alum &amp;lt;DOT&amp;gt; us &amp;lt;DOT&amp;gt; es'''&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=P%C3%A1gina_principal&amp;diff=282</id>
		<title>Página principal</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=P%C3%A1gina_principal&amp;diff=282"/>
				<updated>2019-03-21T07:56:48Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Fechas y horario */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Bienvenid@ al wiki del IV Curso de programación en C.&lt;br /&gt;
&lt;br /&gt;
Este curso ofrecerá una visión moderna de la programación en C, partiendo de los estándares de C99 y C11. Se realizará siempre un enfoque práctico. Es por ello que el curso introducirá al estudiante en el uso de las bibliotecas nativas en C de referencia para el desarrollo de software en entornos gráficos, red, importación/exportación de datos de ficheros. Consulta el [https://1984.lsi.us.es/curso-programacion-c/ contenido del curso].&lt;br /&gt;
&lt;br /&gt;
= Matrícula y preinscripción =&lt;br /&gt;
&lt;br /&gt;
* '''Preinscripción''': Si estás interesado debes realizar la preinscripción gratuita cuanto antes para reservar tu plaza.&lt;br /&gt;
* '''Matrícula''': El periodo de matrícula está comprendido entre los días '''1 y 7 de Abril''' (&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;si quieres matricularte fuera de plazo contacta con nosotros&amp;lt;/span&amp;gt;) y tiene un coste total de '''180€'''&lt;br /&gt;
&lt;br /&gt;
Puedes realizar tanto la matrícula como la preinscripción a través de esta web: https://cfp.us.es/cursos/fc/programacion-en-c/3831/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:20px;color:red&amp;quot;&amp;gt; ¡¡ATENCIÓN: Los créditos ECTS de este curso NO son convalidables!!&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Los créditos de los cursos de formación continua tienen una validez meramente curricular y no pueden ser reconocidos para los planes de grado.&lt;br /&gt;
&lt;br /&gt;
= Lugar =&lt;br /&gt;
&lt;br /&gt;
El curso se impartirá en el edificio '''CRAI Antonio de Ulloa''', Avenida Reina Mercedes, s/n 41012 Sevilla. ([http://www.openstreetmap.org/way/27486919#map=19/37.35971/-5.98621 ver en mapa]). Se utilizará el aula TIC1, situada en la 2ª planta del edificio.&lt;br /&gt;
&lt;br /&gt;
Todas las aulas disponen de ordenadores para los alumnos. Si desea llevar su portátil, puede hacerlo siempre que disponga de alguna distribución GNU/Linux (preferiblemente Ubuntu nativo o en máquina virtual).&lt;br /&gt;
&lt;br /&gt;
= Fechas y horario =&lt;br /&gt;
&lt;br /&gt;
El curso comprenderá entre los días '''2 de Mayo''' y '''14 de Junio'''. Las clases serán los '''Lunes''', '''Miércoles''' y '''Viernes''' de '''17:00 a 19:30''' (salvo excepción). &lt;br /&gt;
Para más información consultar: https://1984.lsi.us.es/curso-programacion-c/&lt;br /&gt;
&lt;br /&gt;
[[File:horario.png|thumb|700px]]&lt;br /&gt;
&lt;br /&gt;
= Lista de correo =&lt;br /&gt;
El curso se apoya en una [https://listas.us.es/mailman/listinfo/programacion-c lista de correo] que puedes emplear para plantear dudas y discusiones relacionadas con la programación en C.&lt;br /&gt;
&lt;br /&gt;
= Criterios de evaluación = &lt;br /&gt;
El curso tendrá un enfoque muy práctico, por lo que la evaluación se basará en diversos ejercicios y trabajos realizados individualmente y repartidos a lo largo del curso.&lt;br /&gt;
&lt;br /&gt;
= Profesores =&lt;br /&gt;
* '''Pablo Neira Ayuso''': pneira &amp;lt;AT&amp;gt; us &amp;lt;DOT&amp;gt; es&lt;br /&gt;
* '''Carlos Falgueras García''': carfalgar &amp;lt;AT&amp;gt; alum &amp;lt;DOT&amp;gt; us &amp;lt;DOT&amp;gt; es&lt;br /&gt;
&lt;br /&gt;
= Contacto y más información =&lt;br /&gt;
Para más información puedes consultar la [https://cfp.us.es/cursos/fc/programacion-en-c/3831/ web del Centro de Formación Permanente] o contactar por email: '''carfalgar &amp;lt;AT&amp;gt; alum &amp;lt;DOT&amp;gt; us &amp;lt;DOT&amp;gt; es'''&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=P%C3%A1gina_principal&amp;diff=281</id>
		<title>Página principal</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=P%C3%A1gina_principal&amp;diff=281"/>
				<updated>2019-03-21T07:56:37Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Fechas y horario */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Bienvenid@ al wiki del IV Curso de programación en C.&lt;br /&gt;
&lt;br /&gt;
Este curso ofrecerá una visión moderna de la programación en C, partiendo de los estándares de C99 y C11. Se realizará siempre un enfoque práctico. Es por ello que el curso introducirá al estudiante en el uso de las bibliotecas nativas en C de referencia para el desarrollo de software en entornos gráficos, red, importación/exportación de datos de ficheros. Consulta el [https://1984.lsi.us.es/curso-programacion-c/ contenido del curso].&lt;br /&gt;
&lt;br /&gt;
= Matrícula y preinscripción =&lt;br /&gt;
&lt;br /&gt;
* '''Preinscripción''': Si estás interesado debes realizar la preinscripción gratuita cuanto antes para reservar tu plaza.&lt;br /&gt;
* '''Matrícula''': El periodo de matrícula está comprendido entre los días '''1 y 7 de Abril''' (&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;si quieres matricularte fuera de plazo contacta con nosotros&amp;lt;/span&amp;gt;) y tiene un coste total de '''180€'''&lt;br /&gt;
&lt;br /&gt;
Puedes realizar tanto la matrícula como la preinscripción a través de esta web: https://cfp.us.es/cursos/fc/programacion-en-c/3831/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:20px;color:red&amp;quot;&amp;gt; ¡¡ATENCIÓN: Los créditos ECTS de este curso NO son convalidables!!&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Los créditos de los cursos de formación continua tienen una validez meramente curricular y no pueden ser reconocidos para los planes de grado.&lt;br /&gt;
&lt;br /&gt;
= Lugar =&lt;br /&gt;
&lt;br /&gt;
El curso se impartirá en el edificio '''CRAI Antonio de Ulloa''', Avenida Reina Mercedes, s/n 41012 Sevilla. ([http://www.openstreetmap.org/way/27486919#map=19/37.35971/-5.98621 ver en mapa]). Se utilizará el aula TIC1, situada en la 2ª planta del edificio.&lt;br /&gt;
&lt;br /&gt;
Todas las aulas disponen de ordenadores para los alumnos. Si desea llevar su portátil, puede hacerlo siempre que disponga de alguna distribución GNU/Linux (preferiblemente Ubuntu nativo o en máquina virtual).&lt;br /&gt;
&lt;br /&gt;
= Fechas y horario =&lt;br /&gt;
&lt;br /&gt;
El curso comprenderá entre los días '''2 de Mayo''' y '''12 de Junio'''. Las clases serán los '''Lunes''', '''Miércoles''' y '''Viernes''' de '''17:00 a 19:30''' (salvo excepción). &lt;br /&gt;
Para más información consultar: https://1984.lsi.us.es/curso-programacion-c/&lt;br /&gt;
&lt;br /&gt;
[[File:horario.png|thumb|700px]]&lt;br /&gt;
&lt;br /&gt;
= Lista de correo =&lt;br /&gt;
El curso se apoya en una [https://listas.us.es/mailman/listinfo/programacion-c lista de correo] que puedes emplear para plantear dudas y discusiones relacionadas con la programación en C.&lt;br /&gt;
&lt;br /&gt;
= Criterios de evaluación = &lt;br /&gt;
El curso tendrá un enfoque muy práctico, por lo que la evaluación se basará en diversos ejercicios y trabajos realizados individualmente y repartidos a lo largo del curso.&lt;br /&gt;
&lt;br /&gt;
= Profesores =&lt;br /&gt;
* '''Pablo Neira Ayuso''': pneira &amp;lt;AT&amp;gt; us &amp;lt;DOT&amp;gt; es&lt;br /&gt;
* '''Carlos Falgueras García''': carfalgar &amp;lt;AT&amp;gt; alum &amp;lt;DOT&amp;gt; us &amp;lt;DOT&amp;gt; es&lt;br /&gt;
&lt;br /&gt;
= Contacto y más información =&lt;br /&gt;
Para más información puedes consultar la [https://cfp.us.es/cursos/fc/programacion-en-c/3831/ web del Centro de Formación Permanente] o contactar por email: '''carfalgar &amp;lt;AT&amp;gt; alum &amp;lt;DOT&amp;gt; us &amp;lt;DOT&amp;gt; es'''&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Horario.png&amp;diff=280</id>
		<title>Archivo:Horario.png</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Horario.png&amp;diff=280"/>
				<updated>2019-03-21T07:53:21Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Deleteme.svg&amp;diff=278</id>
		<title>Archivo:Deleteme.svg</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Deleteme.svg&amp;diff=278"/>
				<updated>2019-03-21T07:53:11Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: Carfalgar trasladó la página Archivo:Horario.svg a Archivo:Deleteme.svg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Horario.svg&amp;diff=279</id>
		<title>Archivo:Horario.svg</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Horario.svg&amp;diff=279"/>
				<updated>2019-03-21T07:53:11Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: Carfalgar trasladó la página Archivo:Horario.svg a Archivo:Deleteme.svg&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECCIÓN [[Archivo:Deleteme.svg]]&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=P%C3%A1gina_principal&amp;diff=277</id>
		<title>Página principal</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=P%C3%A1gina_principal&amp;diff=277"/>
				<updated>2019-03-05T19:01:30Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Bienvenid@ al wiki del IV Curso de programación en C.&lt;br /&gt;
&lt;br /&gt;
Este curso ofrecerá una visión moderna de la programación en C, partiendo de los estándares de C99 y C11. Se realizará siempre un enfoque práctico. Es por ello que el curso introducirá al estudiante en el uso de las bibliotecas nativas en C de referencia para el desarrollo de software en entornos gráficos, red, importación/exportación de datos de ficheros. Consulta el [https://1984.lsi.us.es/curso-programacion-c/ contenido del curso].&lt;br /&gt;
&lt;br /&gt;
= Matrícula y preinscripción =&lt;br /&gt;
&lt;br /&gt;
* '''Preinscripción''': Si estás interesado debes realizar la preinscripción gratuita cuanto antes para reservar tu plaza.&lt;br /&gt;
* '''Matrícula''': El periodo de matrícula está comprendido entre los días '''1 y 7 de Abril''' (&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;si quieres matricularte fuera de plazo contacta con nosotros&amp;lt;/span&amp;gt;) y tiene un coste total de '''180€'''&lt;br /&gt;
&lt;br /&gt;
Puedes realizar tanto la matrícula como la preinscripción a través de esta web: https://cfp.us.es/cursos/fc/programacion-en-c/3831/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:20px;color:red&amp;quot;&amp;gt; ¡¡ATENCIÓN: Los créditos ECTS de este curso NO son convalidables!!&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Los créditos de los cursos de formación continua tienen una validez meramente curricular y no pueden ser reconocidos para los planes de grado.&lt;br /&gt;
&lt;br /&gt;
= Lugar =&lt;br /&gt;
&lt;br /&gt;
El curso se impartirá en el edificio '''CRAI Antonio de Ulloa''', Avenida Reina Mercedes, s/n 41012 Sevilla. ([http://www.openstreetmap.org/way/27486919#map=19/37.35971/-5.98621 ver en mapa]). Se utilizará el aula TIC1, situada en la 2ª planta del edificio.&lt;br /&gt;
&lt;br /&gt;
Todas las aulas disponen de ordenadores para los alumnos. Si desea llevar su portátil, puede hacerlo siempre que disponga de alguna distribución GNU/Linux (preferiblemente Ubuntu nativo o en máquina virtual).&lt;br /&gt;
&lt;br /&gt;
= Fechas y horario =&lt;br /&gt;
&lt;br /&gt;
El curso comprenderá entre los días '''2 de Mayo''' y '''12 de Junio'''. Las clases serán los '''Lunes''', '''Miércoles''' y '''Viernes''' de '''17:00 a 19:30''' (salvo excepción). &lt;br /&gt;
Para más información consultar: https://1984.lsi.us.es/curso-programacion-c/&lt;br /&gt;
&lt;br /&gt;
= Lista de correo =&lt;br /&gt;
El curso se apoya en una [https://listas.us.es/mailman/listinfo/programacion-c lista de correo] que puedes emplear para plantear dudas y discusiones relacionadas con la programación en C.&lt;br /&gt;
&lt;br /&gt;
= Criterios de evaluación = &lt;br /&gt;
El curso tendrá un enfoque muy práctico, por lo que la evaluación se basará en diversos ejercicios y trabajos realizados individualmente y repartidos a lo largo del curso.&lt;br /&gt;
&lt;br /&gt;
= Profesores =&lt;br /&gt;
* '''Pablo Neira Ayuso''': pneira &amp;lt;AT&amp;gt; us &amp;lt;DOT&amp;gt; es&lt;br /&gt;
* '''Carlos Falgueras García''': carfalgar &amp;lt;AT&amp;gt; alum &amp;lt;DOT&amp;gt; us &amp;lt;DOT&amp;gt; es&lt;br /&gt;
&lt;br /&gt;
= Contacto y más información =&lt;br /&gt;
Para más información puedes consultar la [https://cfp.us.es/cursos/fc/programacion-en-c/3831/ web del Centro de Formación Permanente] o contactar por email: '''carfalgar &amp;lt;AT&amp;gt; alum &amp;lt;DOT&amp;gt; us &amp;lt;DOT&amp;gt; es'''&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Deleteme.svg&amp;diff=276</id>
		<title>Archivo:Deleteme.svg</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Deleteme.svg&amp;diff=276"/>
				<updated>2019-03-05T18:55:45Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=P%C3%A1gina_principal&amp;diff=275</id>
		<title>Página principal</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=P%C3%A1gina_principal&amp;diff=275"/>
				<updated>2018-02-28T12:00:50Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: Actualización a IV edición&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Bienvenid@ al wiki del IV Curso de programación en C.&lt;br /&gt;
&lt;br /&gt;
Este curso ofrecerá una visión moderna de la programación en C, partiendo de los estándares de C99 y C11. Se realizará siempre un enfoque práctico. Es por ello que el curso introducirá al estudiante en el uso de las bibliotecas nativas en C de referencia para el desarrollo de software en entornos gráficos, red, importación/exportación de datos de ficheros y bases de datos. Consulta el [[contenido del curso]].&lt;br /&gt;
&lt;br /&gt;
= Matrícula y preinscripción =&lt;br /&gt;
&lt;br /&gt;
* '''Preinscripción''': Si estás interesado debes realizar la preinscripción gratuita cuanto antes para reservar tu plaza.&lt;br /&gt;
* '''Matrícula''': El periodo de matrícula está comprendido entre los días '''1 de Marzo y 8 de Marzo''' (&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;si quieres matricularte fuera de plazo contacta con nosotros&amp;lt;/span&amp;gt;) y tiene un coste total de '''180€'''&lt;br /&gt;
&lt;br /&gt;
Puedes realizar tanto la matrícula como la preinscripción a través de esta web: http://www.cfp.us.es/cursos/fc/programacion-en-c-moderno/3240/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:20px;color:red&amp;quot;&amp;gt; ¡¡ATENCIÓN: Los créditos ECTS de este curso NO son convalidables!!&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Los créditos de los cursos de formación continua tienen una validez meramente curricular y no pueden ser reconocidos para los planes de grado.&lt;br /&gt;
&lt;br /&gt;
= Lugar =&lt;br /&gt;
&lt;br /&gt;
[[Archivo:Map.png | thumb | 500px]]&lt;br /&gt;
&lt;br /&gt;
El curso se impartirá en el edificio '''CRAI Antonio de Ulloa''', Avenida Reina Mercedes, s/n 41012 Sevilla. ([http://www.openstreetmap.org/way/27486919#map=19/37.35971/-5.98621 ver en mapa]). Se utilizará el aula TIC5, situada en la 3ª planta del edificio.&lt;br /&gt;
&lt;br /&gt;
Todas las aulas disponen de ordenadores para los alumnos. Si desea llevar su portátil, puede hacerlo siempre que disponga de alguna distribución GNU/Linux (preferiblemente Ubuntu nativo o en máquina virtual).&lt;br /&gt;
&lt;br /&gt;
= Fechas y horario =&lt;br /&gt;
&lt;br /&gt;
El curso comprenderá entre los días '''3 de Abril''' y '''22 de Mayo'''. Las clases serán los '''Martes''' y '''Jueves''' de '''17:00 a 19:30'''. Para saber en qué aula es cada clase ver [[Horario | Horario desglosado]].&lt;br /&gt;
&lt;br /&gt;
= Lista de correo =&lt;br /&gt;
El curso se apoya en una [https://listas.us.es/mailman/listinfo/programacion-c lista de correo] temática disponible en [https://listas.us.es/mailman/listinfo/programacion-c] que puedes emplear para plantear dudas y discusiones relacionadas con la programación en C.&lt;br /&gt;
&lt;br /&gt;
= Criterios de evaluación = &lt;br /&gt;
El curso tendrá un enfoque muy práctico, por lo que la evaluación se basará en diversos ejercicios y trabajos realizados individualmente y repartidos a lo largo del curso.&lt;br /&gt;
&lt;br /&gt;
= Profesores =&lt;br /&gt;
* '''Pablo Neira Ayuso''': pneira &amp;lt;AT&amp;gt; us &amp;lt;DOT&amp;gt; es&lt;br /&gt;
* '''Carlos Falgueras García''': carfalgar &amp;lt;AT&amp;gt; alum &amp;lt;DOT&amp;gt; us &amp;lt;DOT&amp;gt; es&lt;br /&gt;
&lt;br /&gt;
= Contacto y más información =&lt;br /&gt;
Para más información puedes consultar la [http://www.cfp.us.es/cursos/fc/programacion-en-c-moderno/3013/ web del Centro de Formación Permanente] o contactar por email: '''carfalgar &amp;lt;AT&amp;gt; alum &amp;lt;DOT&amp;gt; us &amp;lt;DOT&amp;gt; es'''&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Discusi%C3%B3n:P%C3%A1gina_principal&amp;diff=274</id>
		<title>Discusión:Página principal</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Discusi%C3%B3n:P%C3%A1gina_principal&amp;diff=274"/>
				<updated>2018-02-28T11:56:53Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Material */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Material =&lt;br /&gt;
* [[Temas, transparencias y anexos]]&lt;br /&gt;
* [[Tareas]]&lt;br /&gt;
* [[Extras]]&lt;br /&gt;
* [https://goo.gl/forms/YFYJOT2nbP4dSrei1 Encuesta]&lt;br /&gt;
&lt;br /&gt;
= Ediciones anteriores =&lt;br /&gt;
&lt;br /&gt;
* [[I Curso de programación en C moderno]]&lt;br /&gt;
* [[II Curso de programación en C moderno]]&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Discusi%C3%B3n:P%C3%A1gina_principal&amp;diff=273</id>
		<title>Discusión:Página principal</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Discusi%C3%B3n:P%C3%A1gina_principal&amp;diff=273"/>
				<updated>2018-02-28T11:56:22Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: Página creada con « = Material = * Temas, transparencias y anexos * Tareas * Extras * [https://goo.gl/forms/YFYJOT2nbP4dSrei1 Encuesta]»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Material =&lt;br /&gt;
* [[Temas, transparencias y anexos]]&lt;br /&gt;
* [[Tareas]]&lt;br /&gt;
* [[Extras]]&lt;br /&gt;
* [https://goo.gl/forms/YFYJOT2nbP4dSrei1 Encuesta]&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=P%C3%A1gina_principal&amp;diff=270</id>
		<title>Página principal</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=P%C3%A1gina_principal&amp;diff=270"/>
				<updated>2017-05-24T00:58:13Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: /* Material */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Archivo:banner.png | 1000px]]&lt;br /&gt;
&lt;br /&gt;
Bienvenid@ al wiki del II Curso de programación en C.&lt;br /&gt;
&lt;br /&gt;
Este curso ofrecerá una visión moderna de la programación en C, partiendo de los estándares de C99 y C11. Se realizará siempre un enfoque práctico. Es por ello que el curso introducirá al estudiante en el uso de las bibliotecas nativas en C de referencia para el desarrollo de software en entornos gráficos, red, importación/exportación de datos de ficheros y bases de datos. Consulta el [[contenido del curso]].&lt;br /&gt;
&lt;br /&gt;
= Matrícula y preinscripción =&lt;br /&gt;
&lt;br /&gt;
* '''Preinscripción''': Si estás interesado debes realizar la preinscripción gratuita cuanto antes para reservar tu plaza.&lt;br /&gt;
* '''Matrícula''': El periodo de matrícula está comprendido entre los días '''1 de Marzo y 19 de Marzo''' (&amp;lt;span style=&amp;quot;color:red&amp;quot;&amp;gt;si quieres matricularte fuera de plazo contacta con nosotros&amp;lt;/span&amp;gt;) y tiene un coste total de '''180€'''&lt;br /&gt;
&lt;br /&gt;
Puedes realizar tanto la matrícula como la preinscripción a través de esta web: http://www.cfp.us.es/cursos/fc/programacion-en-c-moderno/3240/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:20px;color:red&amp;quot;&amp;gt; ¡¡ATENCIÓN: Los créditos ECTS de este curso NO son convalidables!! &amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Los créditos de los cursos de formación continua tienen una validez meramente curricular y no pueden ser reconocidos para los planes de grado.&lt;br /&gt;
&lt;br /&gt;
= Lugar =&lt;br /&gt;
&lt;br /&gt;
[[Archivo:Map.png | thumb | 500px]]&lt;br /&gt;
&lt;br /&gt;
El curso se impartirá en el edificio '''CRAI Antonio de Ulloa''', Avenida Reina Mercedes, s/n 41012 Sevilla. ([http://www.openstreetmap.org/way/27486919#map=19/37.35971/-5.98621 ver en mapa]). Se utilizarán las aulas '''TIC 1, TIC 3 y TIC 4''' (en la 2ª planta del edificio).&lt;br /&gt;
&lt;br /&gt;
Todas las aulas disponen de ordenadores para los alumnos. Si desea llevar su portátil, puede hacerlo siempre que disponga de alguna distribución GNU/Linux.&lt;br /&gt;
&lt;br /&gt;
= Fechas y horario =&lt;br /&gt;
&lt;br /&gt;
El curso comprenderá entre los días '''3 de Abril''' y el '''10 de Mayo'''. Las clases serán los '''Lunes''' y '''Miércoles''' de '''17:00 a 19:30'''. Para saber en qué aula es cada clase ver [[Horario | Horario desglosado]].&lt;br /&gt;
&lt;br /&gt;
= Material =&lt;br /&gt;
* [[Temas, transparencias y anexos]]&lt;br /&gt;
* [[Tareas]]&lt;br /&gt;
* [[Extras]]&lt;br /&gt;
* [https://goo.gl/forms/YFYJOT2nbP4dSrei1 Encuesta]&lt;br /&gt;
&lt;br /&gt;
= Lista de correo =&lt;br /&gt;
El curso se apoya en una [https://listas.us.es/mailman/listinfo/programacion-c lista de correo] temática disponible en [https://listas.us.es/mailman/listinfo/programacion-c] que puedes emplear para plantear dudas y discusiones relacionadas con la programación en C.&lt;br /&gt;
&lt;br /&gt;
= Criterios de evaluación = &lt;br /&gt;
El curso tendrá un enfoque muy práctico, por lo que la evaluación se basará en diversos ejercicios y trabajos realizados individualmente y repartidos a lo largo del curso.&lt;br /&gt;
&lt;br /&gt;
= Profesores =&lt;br /&gt;
* '''Pablo Neira Ayuso''': pneira &amp;lt;AT&amp;gt; us &amp;lt;DOT&amp;gt; es&lt;br /&gt;
* '''Carlos Falgueras García''': carfalgar &amp;lt;AT&amp;gt; alum &amp;lt;DOT&amp;gt; us &amp;lt;DOT&amp;gt; es&lt;br /&gt;
&lt;br /&gt;
= Contacto y más información =&lt;br /&gt;
Para más información puedes consultar la [http://www.cfp.us.es/cursos/fc/programacion-en-c-moderno/3013/ web del Centro de Formación Permanente] o contactar por email: '''carfalgar &amp;lt;AT&amp;gt; alum &amp;lt;DOT&amp;gt; us &amp;lt;DOT&amp;gt; es'''&lt;br /&gt;
&lt;br /&gt;
= Ediciones anteriores =&lt;br /&gt;
&lt;br /&gt;
* [[I Curso de programación en C moderno]]&lt;br /&gt;
* [[II Curso de programación en C moderno]]&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Tareas&amp;diff=269</id>
		<title>Tareas</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Tareas&amp;diff=269"/>
				<updated>2017-05-24T00:46:13Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Tarea 1: Versión inicial del mundo ==&lt;br /&gt;
&lt;br /&gt;
# Haz un fork del repositorio con tu nombre&lt;br /&gt;
# Clona tu repositorio&lt;br /&gt;
# Completa el esqueleto proporcionado para implementar una primera versión funcional del juego de la vida&lt;br /&gt;
# Sube los cambios al tu repositorio&lt;br /&gt;
# Haz un pull request&lt;br /&gt;
# Arregla las correcciones del profesor&lt;br /&gt;
# Sube las correcciones a tu repo&lt;br /&gt;
# ¿Has conseguido que te acepten el pull request?&lt;br /&gt;
## NO -&amp;gt; goto 6&lt;br /&gt;
## Sí -&amp;gt; ¡Enhorabuena! Ya has terminado la tarea 1&lt;br /&gt;
&lt;br /&gt;
== Tarea 2: Código modular, estructuras y makefile ==&lt;br /&gt;
&lt;br /&gt;
a) Divide tu programa en 3 fichero:&lt;br /&gt;
* &amp;lt;code&amp;gt;main.c&amp;lt;/code&amp;gt; : Implementará el bucle principal del juego&lt;br /&gt;
* &amp;lt;code&amp;gt;gol.h&amp;lt;/code&amp;gt;  : Tendrá las declaraciones de las funciones relacionadas con el juego de la vida&lt;br /&gt;
* &amp;lt;code&amp;gt;gol.c&amp;lt;/code&amp;gt;  : Tendrá las definiciones de las funciones anteriores&lt;br /&gt;
&lt;br /&gt;
b) Crea un &amp;lt;code&amp;gt;makefile&amp;lt;/code&amp;gt; para gestionar la compilación y dependencias&lt;br /&gt;
&lt;br /&gt;
== Tarea 3: Primera aproximación a objetos ==&lt;br /&gt;
&lt;br /&gt;
1. Encapsula tu mundo en la siguiente estructura:&lt;br /&gt;
 struct world {&lt;br /&gt;
         bool w1[W_SIZE_X][W_SIZE_Y];&lt;br /&gt;
         bool w2[W_SIZE_X][W_SIZE_Y];&lt;br /&gt;
 };&lt;br /&gt;
2. Modifica tus funciones para que reciban un puntero a tu objeto. Añade el modificador &amp;lt;code&amp;gt;const&amp;lt;/code&amp;gt; siempre que no sea necesario modificar el objeto&lt;br /&gt;
&lt;br /&gt;
Tu &amp;lt;code&amp;gt;main.c&amp;lt;/code&amp;gt; debería quedar más o menos así:&lt;br /&gt;
 #include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
 #include &amp;quot;gol.h&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
 int main()&lt;br /&gt;
 {&lt;br /&gt;
 	int i = 0;&lt;br /&gt;
 	struct world w;&lt;br /&gt;
 &lt;br /&gt;
 	world_init(&amp;amp;w);&lt;br /&gt;
 	do {&lt;br /&gt;
 		printf(&amp;quot;\033cIteration %d\n&amp;quot;, i++);&lt;br /&gt;
 		world_print(&amp;amp;w);&lt;br /&gt;
 		world_step(&amp;amp;w);&lt;br /&gt;
 	} while (getchar() != 'q');&lt;br /&gt;
 &lt;br /&gt;
 	return EXIT_SUCCESS;&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
== Tarea 4: Objetos: Reserva dinámica de memoria ==&lt;br /&gt;
==== Interfaz pública ====&lt;br /&gt;
&amp;lt;code&amp;gt;gol.h&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 struct world;&lt;br /&gt;
 &lt;br /&gt;
 struct world *world_alloc(int size_x, int size_y);&lt;br /&gt;
 void world_free(struct world *w);&lt;br /&gt;
 &lt;br /&gt;
 void world_print(const struct world *w);&lt;br /&gt;
 void world_iterate(struct world *w);&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;world_alloc&amp;lt;/code&amp;gt;: Reserva en memoria e inicializa nuestro objeto &amp;lt;code&amp;gt;struct world&amp;lt;/code&amp;gt;. Esto implica reservar memoria para la estrucutra y para los dos arrays que tiene dentro.&lt;br /&gt;
* &amp;lt;code&amp;gt;world_free&amp;lt;/code&amp;gt;: Libera la memoria que ocupa nuestro objeto. Esto implica liberar primero la memoria de los arrays que tiene dentro la estrucutra, y luego la propia estructura.&lt;br /&gt;
* &amp;lt;code&amp;gt;world_print&amp;lt;/code&amp;gt;: Imprime el mundo&lt;br /&gt;
* &amp;lt;code&amp;gt;world_iterate&amp;lt;/code&amp;gt;: Realiza una iteración del juego de la vida&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Implementación (privada) ====&lt;br /&gt;
&amp;lt;code&amp;gt;gol.c&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 struct world&lt;br /&gt;
 {&lt;br /&gt;
 	bool *cells[2];&lt;br /&gt;
 	int size_x;&lt;br /&gt;
 	int size_y;&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 static void fix_coords(const struct world *w, int *x, int *y);&lt;br /&gt;
 static bool get_cell(const struct world *w, int x, int y);&lt;br /&gt;
 static void set_cell(struct world *w, int buf, int x, int y, bool val);&lt;br /&gt;
 static int count_neighbors(const struct world *w, int x, int y);&lt;br /&gt;
 &lt;br /&gt;
 /* ... */&lt;br /&gt;
 /* Definiciones de funciones privadas y públicas */&lt;br /&gt;
 /* ... */&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;fix_coords&amp;lt;/code&amp;gt;: Recibe unas coordenadas (x,y) y las modifica para implementar un mundo toroidal&lt;br /&gt;
* &amp;lt;code&amp;gt;get_cell&amp;lt;/code&amp;gt;: Devuelve la célula en la posición (x,y), arreglando las coordenadas.&lt;br /&gt;
* &amp;lt;code&amp;gt;set_cell&amp;lt;/code&amp;gt;: Cambia el valor de la célula de la posición (x,y), arreglando las coordenadas.&lt;br /&gt;
* &amp;lt;code&amp;gt;count_neighbors&amp;lt;/code&amp;gt;: Cuenta las células vecinas '''haciendo uso de''' la función &amp;lt;code&amp;gt;get_cell&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== NOTAS ====&lt;br /&gt;
* No olvides comprobar que has podido realizar correctamente la reserva de memoria:&lt;br /&gt;
&lt;br /&gt;
En &amp;lt;code&amp;gt;world_alloc()&amp;lt;/code&amp;gt;:&lt;br /&gt;
 w = (struct world *)malloc(sizeof(struct world));&lt;br /&gt;
 if (!w)&lt;br /&gt;
 	return NULL;&lt;br /&gt;
&lt;br /&gt;
En &amp;lt;code&amp;gt;main()&amp;lt;/code&amp;gt;:&lt;br /&gt;
 w = world_alloc(WORLD_X, WORLD_Y);&lt;br /&gt;
 if (!w) {&lt;br /&gt;
 	perror(&amp;quot;Can't allocate world&amp;quot;);&lt;br /&gt;
 	exit(EXIT_FAILURE);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
* Las funciones privadas se declaran como &amp;lt;code&amp;gt;static&amp;lt;/code&amp;gt; y '''no''' aparecen el el .h&lt;br /&gt;
* Ahora debes calcular a mano el offset en el array para llegar a la célula (x,y) con la fórmula: &amp;lt;code&amp;gt;size_x*y + x&amp;lt;/code&amp;gt;. Encapsula esta fórmula en las funciones &amp;lt;code&amp;gt;get_cell&amp;lt;/code&amp;gt; y &amp;lt;code&amp;gt;set_cell&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Tarea 5: Argumentos y lectura de ficheros ==&lt;br /&gt;
Al final de esta tarea tu juego de la vida deberá poder configurarse tanto por '''paso de argumentos''' como mediante un '''archivo de configuración'''.&lt;br /&gt;
La ayuda del programa devolvería lo siguiente:&lt;br /&gt;
 Usage: gol&lt;br /&gt;
 	[-h|--help]&lt;br /&gt;
 	[-x|--size_x &amp;lt;num&amp;gt;]&lt;br /&gt;
 	[-y|--size_y &amp;lt;num&amp;gt;]&lt;br /&gt;
 	[-i|--init &amp;lt;init_mode&amp;gt;]&lt;br /&gt;
 	[config_file]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Esta tarea '''se divide en 3 subtareas distintas''' que deben corresponder con '''3 commits, uno por subtarea'''. La subtarea 3 es **opcional**.&lt;br /&gt;
&lt;br /&gt;
=== Tarea 5.1: Objeto &amp;lt;code&amp;gt;struct config&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Completa la plantilla que encontrarás aquí: [[Archivo:Cfg template.tar]] para agrupar toda la lógica de configuración en un objeto.&lt;br /&gt;
&lt;br /&gt;
Intégrala después en tu main de esta forma (debes modificar también &amp;lt;code&amp;gt;world_alloc&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; &amp;gt;&lt;br /&gt;
int main(int argc, char *argv[])&lt;br /&gt;
{&lt;br /&gt;
	struct config config;&lt;br /&gt;
	struct world * w;&lt;br /&gt;
&lt;br /&gt;
	if (!config_parse_argv(&amp;amp;config, argc, argv)) {&lt;br /&gt;
		printf(&amp;quot;ERROR\n&amp;quot;);&lt;br /&gt;
		config_print_usage(argv[0]);&lt;br /&gt;
		return EXIT_FAILURE;&lt;br /&gt;
	} else if (config.show_help){&lt;br /&gt;
		config_print_usage(argv[0]);&lt;br /&gt;
		return EXIT_SUCCESS;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	w = world_alloc(&amp;amp;config);&lt;br /&gt;
	if (!w) {&lt;br /&gt;
		perror(&amp;quot;Can't allocate world&amp;quot;);&lt;br /&gt;
		exit(EXIT_FAILURE);&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	do {&lt;br /&gt;
		printf(&amp;quot;\033cIteration %d\n&amp;quot;, i++);&lt;br /&gt;
		world_print(w);&lt;br /&gt;
		world_iterate(w);&lt;br /&gt;
	} while (getchar() != 'q');&lt;br /&gt;
&lt;br /&gt;
	world_free(w);&lt;br /&gt;
	return EXIT_SUCCESS;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
De esta plantilla hay que destacar los siguientes puntos:&lt;br /&gt;
&lt;br /&gt;
* Se define un objeto sencillo, público, sin reserva dinámica de memoria&lt;br /&gt;
* Se usa un enumerado para definir el tipo de inicialización con las siguientes peculiaridades:&lt;br /&gt;
** El primer elemento representa un modo no válido y forzamos su valor a -1&lt;br /&gt;
** El último elemento se usa para tener en una macro el número de elementos del enumerado. Por ello el nombre está entre barras bajas, para marcarlo como una opción no válida&lt;br /&gt;
** En el .c se define un array constante de cadenas, asociando cada cadena con su correspondiente valor en el enumerado. Se utiliza un inicializador un tanto particular, dónde inicializamos explicitamente los elementos del array mediante su índice: El índice se indica entre corchetes y se le asigna un valor con el operador igual: &amp;lt;code&amp;gt;[3] = 41&amp;lt;/code&amp;gt;&lt;br /&gt;
** Se usa el array anterior para convertir el enumerado a una cadena, simplemente hay que acceder al array con el valor del enumerado como índice: &amp;lt;code&amp;gt;init_mode_str[CFG_GLIDER]&amp;lt;/code&amp;gt;&lt;br /&gt;
* Se define una función privada &amp;lt;code&amp;gt;check_config&amp;lt;/code&amp;gt; que agrupa la lógica de validación de argumentos. Devuelve false si los argumentos nos son válidos y true si lo son&lt;br /&gt;
* La función &amp;lt;code&amp;gt;str2init_mode&amp;lt;/code&amp;gt; recibe una cadena y la va comparando una por una con las cadenas de modos de inicialización para ver con cual coincide. Si no coincide con ninguna devuelve &amp;lt;code&amp;gt;CFG_NOT_DEF&amp;lt;/code&amp;gt; para indicar que no es un modo válido.&lt;br /&gt;
&lt;br /&gt;
=== Tarea 5.2: Cargar fichero de configuración ===&lt;br /&gt;
Ahora has de permitir que tu programa lea la configuración de un archivo:&lt;br /&gt;
&lt;br /&gt;
* El nombre del archivo ha de recibirse a través de los argumentos del programa, pero **no a través de un flag con getopt**. Ejemplo: &amp;lt;code&amp;gt;&amp;gt; gol config.txt&amp;lt;/code&amp;gt;&lt;br /&gt;
* Las configuraciones del archivo tienen preferencia sobre los argumentos por consola&lt;br /&gt;
* El archivo de configuración constará de 3 líneas:&lt;br /&gt;
*# Ancho del mundo&lt;br /&gt;
*# Alto del mundo&lt;br /&gt;
*# Tipo de inicialización&lt;br /&gt;
Ejemplo &amp;lt;code&amp;gt;config.txt&amp;lt;/code&amp;gt;:&lt;br /&gt;
 20&lt;br /&gt;
 15&lt;br /&gt;
 glider&lt;br /&gt;
* Crea una función privada &amp;lt;code&amp;gt;static bool load_config(struct config *config);&amp;lt;/code&amp;gt; que se encarge de abrir, parsear y cerrar el fichero. Devolverá cierto si todo ha ido bien y falso en caso contrario.&lt;br /&gt;
* La función &amp;lt;code&amp;gt;fgets&amp;lt;/code&amp;gt; devuelve una cadena con un salto de línea (si lo hay). Vas a tener que quitárselo haciendo uso de la función [http://es.cppreference.com/w/c/string/byte/strchr strchr]&lt;br /&gt;
* Échale un ojo a este fragmento de código:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; &amp;gt;&lt;br /&gt;
int config_parse_argv(struct config *config, int argc, char *argv[])&lt;br /&gt;
{&lt;br /&gt;
	...&lt;br /&gt;
&lt;br /&gt;
	// Check for config file name&lt;br /&gt;
	if (optind != argc) {&lt;br /&gt;
		if (optind == argc - 1) {&lt;br /&gt;
			config-&amp;gt;cfg_file = argv[optind];&lt;br /&gt;
			if (!load_config(config))&lt;br /&gt;
				return false;&lt;br /&gt;
		} else {&lt;br /&gt;
			return false;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	return check_config(config);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Y a este otro:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line=&amp;quot;1&amp;quot; &amp;gt;&lt;br /&gt;
	// Size x&lt;br /&gt;
	char line[LINE_LEN];&lt;br /&gt;
	fgets(line, LINE_LEN, file);&lt;br /&gt;
	if (ferror(file)) {&lt;br /&gt;
		perror(&amp;quot;Error reading config file&amp;quot;);&lt;br /&gt;
		return false;&lt;br /&gt;
	}&lt;br /&gt;
	config-&amp;gt;size_x = strtol(line, NULL, 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tarea 5.3 [opcional]: Guarda y carga de estado ===&lt;br /&gt;
Haz que tu juego de la vida guarde el estado del mundo antes de salir, en un archivo con el nombre que elijas. Haz también que este archivo se pueda cargar al lanzarlo de nuevo, para que comience por el mismo estado.&lt;br /&gt;
&lt;br /&gt;
Notas:&lt;br /&gt;
* Has de crear dos nuevas opciones getopt para indicar el nombre del archivo a guardar y a cargar&lt;br /&gt;
* Para guardar el estado, haz un volcado directo en binario del array en un archivo. Utiliza la función [http://es.cppreference.com/w/c/io/fwrite fwrite] pasándole tu array y su tamaño. Ten en cuenta que debes guardar también las dimensiones de tu mundo.&lt;br /&gt;
* Para cargar el estado, haz una lectura directa del archivo binario con la función [http://es.cppreference.com/w/c/io/fread fread]. Puedes volcar el contenido del archivo directamente en el array de tu estructura, pero no olvides reservar la memoria primero (para esto debes leer antes las dimensiones de tu mundo)&lt;br /&gt;
&lt;br /&gt;
== Tarea 6: Herencia ==&lt;br /&gt;
&lt;br /&gt;
* Divide tu arquitectura en tres objetos:&lt;br /&gt;
** '''world''': Objeto '''abstracto''' que no tienen implementada las funciones &amp;lt;code&amp;gt;world_get_cell&amp;lt;/code&amp;gt; y &amp;lt;code&amp;gt;world_set_cell&amp;lt;/code&amp;gt;, pero sí el resto&lt;br /&gt;
** '''world_limited''': Objeto que hereda de ''world'' e implementa las funciones &amp;lt;code&amp;gt;world_get_cell&amp;lt;/code&amp;gt; y &amp;lt;code&amp;gt;world_set_cell&amp;lt;/code&amp;gt; de forma que se devuelva una célula muerta si los índices se salen del array y no haga nada en el caso del setter&lt;br /&gt;
** '''world_toroidal''': Objeto que hereda de ''world'' e implementa las funciones &amp;lt;code&amp;gt;world_get_cell&amp;lt;/code&amp;gt; y &amp;lt;code&amp;gt;world_set_cell&amp;lt;/code&amp;gt; para accedar al mundo de forma toroidal. Aquí además debes implementar la función &amp;lt;code&amp;gt;fix_coords&amp;lt;/code&amp;gt; para usarla en tu getter y setter.&lt;br /&gt;
&lt;br /&gt;
[[Archivo:Herencia.png | 1000px]]&lt;br /&gt;
&lt;br /&gt;
'''NOTA''': Ejercicio de ejemplo resuelto: [[Archivo:Herencia res.tar]]&lt;br /&gt;
&lt;br /&gt;
== Tarea 7: Listas ==&lt;br /&gt;
Modifica tu mundo para utilizar la doble estructura (array + lista) que se ha explicado en clase. Repasar [[:Archivo:Gol-list-new.pdf|descargar]]&lt;br /&gt;
&lt;br /&gt;
* Debes modificar tus tres objetos (world, world_limited y world_toroidal), aunque la mayor parte de los cambios van en el objeto padre, mientras que en los hijos solo debes cambiar la forma en la que accedes al array (puesto que ahora habrá solo un array).&lt;br /&gt;
* Creamos un objeto nuevo, &amp;lt;code&amp;gt;struct cell&amp;lt;/code&amp;gt;, muy sencillo y con todos sus atributos públicos. Este objeto será el elemento de nuestras listas.&lt;br /&gt;
* Ten en consideración las siguientes pistas y consulta esta plantilla: [[:Archivo:gol_list.tar]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Estructura celula  ===&lt;br /&gt;
Guarda un par de coordenadas para identificarla y facilitarnos el acceso al array&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; &amp;gt;&lt;br /&gt;
struct cell {&lt;br /&gt;
	int x,y;&lt;br /&gt;
	struct list_head lh;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Estructura del objeto padre ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; &amp;gt;&lt;br /&gt;
struct world&lt;br /&gt;
{&lt;br /&gt;
	bool *cells; // Observa que ahora solo necesitamos un array&lt;br /&gt;
	int size_x;&lt;br /&gt;
	int size_y;&lt;br /&gt;
	// TODO: Crea las cabezas de lista (tipo `struct list_head`)&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Constructor objeto padre ===&lt;br /&gt;
* A la hora de reservar espacio para el array, lo hacemos solo una vez y guardamos la dirección en &amp;lt;code&amp;gt;w-&amp;gt;cells&amp;lt;/code&amp;gt;&lt;br /&gt;
* A la hora de inicializar nuestro array revivir cada célula en dos pasos:&lt;br /&gt;
*# Crear el nodo de lista (tipo &amp;lt;code&amp;gt;struct cell&amp;lt;/code&amp;gt;) y comprobar que se ha realizado correctamente la reserva de memoria&lt;br /&gt;
*# Establecer a cierto la celula en el array&lt;br /&gt;
Esto lo podemos realizar a mano o creando una función auxiliar, digamos &amp;lt;code&amp;gt;add_initial_cell&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Función &amp;lt;code&amp;gt;count_neighbors&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Para facilitar la implementación de la nueva función &amp;lt;code&amp;gt;world_step&amp;lt;/code&amp;gt;, os propongo esta mejora para contar vecionos.&lt;br /&gt;
&lt;br /&gt;
# Creamos un array estático con las 8 sumas/restas que hay que aplicar a unas coordenadas (x,y) para obtener sus 8 vecinas&lt;br /&gt;
# Recorremos este array sumando estas diferencias para obtener las coordenadas de las células vecinas&lt;br /&gt;
# Usamos siempre nuestro método &amp;lt;code&amp;gt;get_cell&amp;lt;/code&amp;gt; (implementado por los hijos) para que tenga en cuenta los límites del mundo&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; &amp;gt;&lt;br /&gt;
static const int neighbors_coords[8][2] = {&lt;br /&gt;
	{-1, -1}, {0, -1}, {1, -1},&lt;br /&gt;
	{-1,  0},          {1,  0},&lt;br /&gt;
	{-1,  1}, {0,  1}, {1,  1}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
static int count_neighbors(const struct world *w, int x, int y)&lt;br /&gt;
{&lt;br /&gt;
	int count = 0;&lt;br /&gt;
&lt;br /&gt;
	for (int i=0; i &amp;lt; 8; i++)&lt;br /&gt;
		count += get_cell(w,&lt;br /&gt;
			x + neighbors_coords[i][0],&lt;br /&gt;
			y + neighbors_coords[i][1]);&lt;br /&gt;
&lt;br /&gt;
	return count;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Función &amp;lt;code&amp;gt;fix_coord&amp;lt;/code&amp;gt; ===&lt;br /&gt;
Cambiamos el prototipo de esta función para que devuelva un booleano indicando si las coordenadas que ha recibido son validas o no. Esto nos hará falta posteriormente en la función &amp;lt;code&amp;gt;world_step&amp;lt;/code&amp;gt;.&lt;br /&gt;
* En un mundo **toroidal** unas coordenadas fuera del mundo, ej &amp;lt;code&amp;gt;(-1, TAM_Y)&amp;lt;/code&amp;gt;, serán corregidas, por lo &amp;lt;code&amp;gt;fix_coord&amp;lt;/code&amp;gt; debe devolver siempre **cierto**&lt;br /&gt;
* En un mundo **limitado** unas coordenadas fuera del mundo, ej &amp;lt;code&amp;gt;(-1, TAM_Y)&amp;lt;/code&amp;gt; son inválidas, por lo que &amp;lt;code&amp;gt;fix_coord&amp;lt;/code&amp;gt; debe devolver **falso** en estos casos.&lt;br /&gt;
&lt;br /&gt;
=== Función &amp;lt;code&amp;gt;world_step&amp;lt;/code&amp;gt; ===&lt;br /&gt;
* Consultar la plantilla para tener una idea de cómo implementar esta función&lt;br /&gt;
* Fijaos que, cuado estamos comprobando las células vecinas, tenemos que tener especial cuidado con las que caen fuera de nuestro mundo:&lt;br /&gt;
*# En un mundo **toroidal** corregimos las coordenadas y aplicamos el algoritmo normal. Debemos corregirlas para no crear un nodo en nuestra lista con coordenadas inválidas.&lt;br /&gt;
*# En un mondo **limitado** no tiene sentido añadir a nuestra lista nodos con coordenadas fuera del array, puesto que estas células limítrofes siempre están muertas. Por ello, si &amp;lt;code&amp;gt;fix_coords&amp;lt;/code&amp;gt; nos devuelve falso, no procesamos esa célula.&lt;br /&gt;
&lt;br /&gt;
== Tarea 8: Iterfaz Gráfica ==&lt;br /&gt;
Implementa una interfaz gráfica para tu mundo con GTK. Sigue este código de ejemplo: [[:Archivo:gol_gui.tar]]&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	<entry>
		<id>https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Gol_gui.tar&amp;diff=268</id>
		<title>Archivo:Gol gui.tar</title>
		<link rel="alternate" type="text/html" href="https://1984.lsi.us.es/wiki-c/index.php?title=Archivo:Gol_gui.tar&amp;diff=268"/>
				<updated>2017-05-24T00:46:05Z</updated>
		
		<summary type="html">&lt;p&gt;Carfalgar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Carfalgar</name></author>	</entry>

	</feed>