Skip to content

Latest commit

 

History

History
166 lines (107 loc) · 7.04 KB

2.0 La terminal y C.md

File metadata and controls

166 lines (107 loc) · 7.04 KB

Cualquier duda, reclamo o error que encuentres en esta guía por favor avisa por un Issue en este repositorio

De aquí en adelante, harás todo desde la terminal de tu respectivo sistema operativo. Está guía tiene como objetivo orientarte por las distintas funcionalidades que tiene la terminal.

Si ya te manejas con la terminal, puedes ir a la sección de Compilar C

Comandos

Todo en la terminal son comandos. Son programas cuya mayoría vienen con el sistema operativo y cumplen propósitos muy específicos. Por ejemplo:

  • pwd : Imprime el directorio donde estás parado
  • ls : Lista todos los archivos y carpetas presentes en el directorio actual.

Hay comandos que reciben parámetros, como

  • cd <directorio> : Cambia de directorio al directorio especificado.
    • En particular, cd .. sube un nivel.
  • echo <texto> : Imprime el texto en consola.
  • cat <archivo> : Imprime todo el contenido del archivo en la consola.
  • head <archivo> : Imprime las primeras 10 lineas del archivo en consola.
  • mkdir <carpeta> : Crea una nueva carpeta con el nombre especificado.
  • rm <archivo> : Elimina el archivo especificado, sin pasar por la papelera.

Un tipo especial de parametro son los flags. Estos cambian el comportamiento del programa según lo parámetros dados. Por lo general son de la forma --flag o -f. Por ejemplo:

  • rm <archivo> : Elimina el archivo especificado, sin pasar por la papelera.
    • rm -f <archivo> : Forzar la ejecución del comando.
    • rm -r <archivo> : Efectuar el comando recursivamente dentro de archivo.
    • rm -rf <archivo> : Combina los dos anteriores (Puede ser peligroso).

Existen también comandos que afectan el comportamiento del siguiente comando, como:

  • sudo : (Unix) Super-User DO, efectúa el siguiente comando con privilegios de administrador.
  • time : Mide el tiempo que demora en correr el siguiente comando.
  • timeout : Detiene la ejecución del siguiente comando luego de cierto tiempo.
  • valgrind : Sigue paso a paso el siguiente comando, notificando los errores que tenga.

Los comandos retornan un valor que indica como terminaron. Si retornan 0, todo está bien. Cualquier otro número indica que hubo un error. Esto existe para poder hacer cosas como esta:

if comando; then
    echo "El comando terminó correctamente";
else
    echo "El comando falló";
fi

Lo cual es muy importante a la hora de escribir scripts. Para ti, significa que debes preocuparte de lo que retornan tus tareas en el main: si terminas correctamente debes retornar 0, de otro modo el script que lo corrija considerará que falló su ejecución.

Input / Output

Existen 3 canales que manipulan el texto que circula por la terminal:

  • stdin : Standard Input. Lo que se escriba en la consola mientras el programa corre aparecerá aquí.
  • stdout : Standard Output. Lo que imprima tu programa aparecerá por aquí.
  • stderr : Standard Error. Canal especial para imprimir acerca de errores.

Por ejemplo:

# Nos conectamos al sistema de la estrella de la muerte
$ ./deathstar

# El sistema imprime algo en stdout
Bienvenido al sistema de la estrella de la muerte.
¿Qué planeta quiere destruir hoy?

# Y espera a que escribamos algo en stdin y apretemos enter
Alderaan

# El sistema comunica el error a traves de stderr
ERROR. PLANETA NO EXISTE. INICIANDO AUTODESTRUCCIÓN.

Una funcionalidad importante de la terminal es que te permite manejar estos canales, lo que significa reemplazar algun canal por un archivo, o simplemente descartar un canal.

Los más básicos son los redirect:

# archivo = programa.stdout
programa > archivo

# archivo += programa.stdout
programa >> archivo

# programa.stdin = archivo
programa < archivo

Un archivo especial es /dev/null. Redirigir el output a ese archivo es equivalente a descartarlo. Esto es especialmente útil cuando te interesa medir cuanto tiempo toma tu programa sin importar que es lo que imprime. (Imprimir en consola toma tiempo adicional).

# Descartar el output del programa
programa > /dev/null

Compiladores

Vamos al grano: C es un lenguaje compilado, por lo que cada vez que hagas un cambio en tu código, deberás volver a compilar tu programa. Debido a esto, es crucial que sepas usar los comandos encargados de eso: make y gcc

GCC

GNU C Compiler o ahora último, GNU Compiler Collection, es el comando encargado de compilar los programas de C. Puede llevar a cabo muchas funciones según los parámetros que se le entreguen, pero la más básica es la siguiente:

# Compila el programa creando un ejecutable con el nombre especificado
gcc programa.c -o nombre
# El flag -o indica que lo siguiente será el nombre del archivo final

# Ejecuta el programa
./nombre <parametros>

Cuando tienes un programa que depende de muchos archivos de código, puedes compilar cada uno por separado, formando los llamados "archivos de objeto" (.o): un estado intermedio de compilación. La gracia es que si modificas solo uno, no es necesario recompilar nuevamente para poder volver a probar el programa, acelerando mucho el proceso. Un ejemplo de esto es lo siguiente:

# Compilamos las distintas partes del programa
# El flag -c indica que se debe generar un archivo de objeto
# El flag -I. indica que de haber headers, los busque en la misma carpeta
gcc reales.c -c -o reales.o -I.
gcc imaginarios.c -c -o imaginarios.o -I.
gcc demostracion.c -c -o demostracion.o -I.

# Las unimos. El compilador buscará la que tenga el main automáticamente
gcc reales.o imaginarios.o demostracion.o -o ejecutable

El problema es que mientras más módulos tenga un programa, este comando se vuelve cada vez más engorroso, en especial si debes espeficar flags adicionales al compilador:

gcc -std=gnu11 -Wall reptilario.o cocodrilo.o iguana.o dragon.o serpiente.o camaleon.o tiranosaurio.o tortuga.o -o reptilario -I. -lm

Escribir un comando como este cada vez que quieras probar tu programa es desgastante. Siquiera una vez. Si tan solo hubiera otra forma de hacerlo...

Make

Ha llegado make al rescate. Si bien de manera básica, make es equivalente a gcc:

# Busca un archivo llamado programa.c y efectua gcc sobre el.
make programa

La gracia de Make es cuando se usa en conjunto con las Makefiles: archivos que especifican como debe compilarse el programa. Una Makefile bien escrita se encargará de detectar automáticamente las dependencias, y de recompilarlas solo cuando sea necesario. Lo más importante: usando únicamente el comando make: este se encargará de leer las instrucciones en el archivo llamado Makefile en ese directorio. Por lo tanto, teniendo una buena Makefile podrás compilar con lo siguiente:

# Esto es todo
make

La mejor parte es que los ayudantes han preparado ya una Makefile para el uso con las tareas del semestre, la cual te permitirá compilar fácilmente.

Misión #1

Tu primera misión será entonces clonar el repositorio del curso y probar compilar y ejecutar los programas que se encuentran en la carpeta "Código/Ejemplos". Si algo no te resulta, reportalo en el foro.