Sistema Linux y compilación C

¿Qué sistema Linux instalar?

Lubuntu es una versión de Ubuntu que tiene la misma tienda de aplicaciones que Ubuntu pero viene con un escritorio más liviano por defecto. Arranca y anda bien en computadoras más viejas.

Si tienen una compu sin sistema operativo, pueden instalar Lubuntu desde un pendrive armado a partir de ese archivo .iso (no es suficiente copiar el .iso al pendrive como simple archivo, hay que usar un programa especial.

Si tienen Windows, se puede instalar el programa VirtualBox. Dentro VirtualBox, pueden instalar ese .iso de Lubuntu. Por ejemplo.

Manejo de las ventanas

En los entorno gráficos de Linux, se puede "agarrar" las ventanas en cualquier lugar (no solo el borde) si usamos la tecla ALT:

Instalar aplicaciones con apt-get

apt-get es un comando que permite buscar, instalar y desinstalar aplicaciones. Lo vamos a usar para instalar los software que nos hacen falta para esta materia.

Primero, abrir una terminal (buscar en el menú de aplicaciones del sistema).

Tenemos que poner al día la lista de aplicaciones disponibles:

$ sudo apt-get update

El comando sudo permite ejecutar programas con privilegios del sistema, por eso pide la contraseña.

No se ve la contraseña, es normal!

Instalamos dos compiladores para el lenguaje C, gcc y clang:

$ sudo apt-get install gcc
[...]
$ sudo apt-get install clang
[...]

Apretar Enter para confirmar la instalación y esperar.

Para editar programas, vamos a instalar el editor gráfico geany y el paquete libvte9 que permite tener una terminal dentro de geany:

$ sudo apt-get install geany libvte9

Configuración de Geany para que la terminal siga los archivos abiertos

Entrar a Editar , Preferencias, pestaña Terminal.

Activar la opción "Seguir la ruta del archivo actual" (en inglés "Follow path...").

geany config 

Recorrido de comandos

pwd

$ pwd
/home/lab7

Muestra el camino absoluto de la carpeta actual de la shell.

pwd significa print working directory (mostrar carpeta de trabajo/actual)

Los caminos tienen la forma a/b/c/d, significa que la carpeta a contiene la carpeta b, que a su vez contiene la c, que a su vez contiene la d.

mkdir

Tipear succesivamente (ayudarse de la flecha ↑ para completar comandos anteriores):

$ mkdir prog1
$ mkdir prog1/lab
$ mkdir prog1/lab/ejercicios
$ mkdir -p prog1/lab/ejercicios/01/a

mkdir significa make directory (hacer carpeta)

mkdir toma como parametro el camino de la carpeta que quieren crear.

mkdir acepta la opción (o flag) -p para crear de una vez todas las carpetas que no existen en el camino. Sin esa opción, no se puede escribir lo siguiente si a no existe:

$ mkdir a/b

Probar.

Hacer cinco carpetas más dentro de prog1.

cd

cd significa change directory (cambiar de carpeta)

$ cd prog1
$ pwd
/home/lab7/prog1
$ cd lab
$ pwd
/home/lab7/prog1/lab
$ cd ejercicios
$ pwd
/home/lab7/prog1/lab/ejercicios
$ cd 01
$ pwd
/home/lab7/prog1/lab/ejercicios/01
$ cd a
$ pwd
/home/lab7/prog1/lab/ejercicios/01/a
$ cd ..
$ pwd
/home/lab7/prog1/lab/ejercicios/01
$ cd ..
$ pwd
/home/lab7/prog1/lab/ejercicios
$ cd ..
$ cd ..
$ cd ..
$ pwd
/home/lab7

cd .. permite cambiarse a la carpeta "madre" de la actual.

ls

$ cd prog1
$ ls
lab
$ cd lab
$ ls
ejercicios
$ cd ejercicios
$ ls
01
$ mkdir 02
$ mkdir 03
$ ls
01 02 03

ls significa "list" y muestra el contenido de la carpeta actual.

touch

touch : crear archivos vacíos

$ cd
$ mkdir listas
$ cd listas
$ touch listaCompras.txt
$ ls
listaCompras.txt

touch permite también de cambiar la fecha de modificación de un archivo existente.

Esa fecha se puede ver con ls -l.

cp

cp significa "copy". cp crea un archivo nuevo que es la copia de un archivo existente.

Su sintaxis es: cp EXISTENTE NUEVO o cp EXISTENTE CARPETA para copiar un archivo existente dentro de una carpeta (existente).

Para copiar una carpeta existente, hay que pasarle el flag -r, que significa "recursivo", porque hay que copiar también el contenido de la carpeta: cp -r CARPETA_EXISTENTE CARPETA_NUEVA.

mv

Sintaxis: mv VIEJO NUEVO para renombrar el archivo VIEJOa NUEVO, o mv VIEJO CARPETA/ para mover el archivo VIEJO dentro de la carpeta CARPETA.

rm

rm (remove) borra archivos y carpetas (con el flag -r).

¡Cuidado con rm -r que puede borrar mucho trabajo de una vez!

$ cd
$ cd move
$ ls
dejaMe hecho.txt
$ rm hecho.txt
$ ls
dejaMe
$ rm -r dejaMe
$ ls
$ cd ..
$ rm -r move

wget y cat

wget permite descargar un archivo de la web.

cat permite mostrar el contenido de un archivo en la shell.

$ wget http://hub.darcs.net/gh/prog1/raw-file/README.md
[...]
$ cat README.md
# Programación I #
[...]

cat es conveniente para archivos cortos. Para ver archivos más largos, vamos a ver less.

less

$ wget http://hub.darcs.net/gh/prog1/raw-file/prog1.md
[...]
$ less prog1.md

Dentro de less se usan los atajos siguientes:

Para buscar dentro de less:

Buscar y encontar todas las occurencias de:

Hay que usar g entre cada búsqueda.

less permite solamente ver archivos sin modificarlos.

wc

wc significa "word count".

Permite conocer el tamaño de un archivo en cantidad de carácteres, palabras y (lo más útil), líneas:

$ wc README.md        # ver las 3 cuentas
21 61 558 README.md
$ wc -l README.md     # ver solo la cantidad de líneas
21 README.md
$ wc -l *             # ver la cantidad de líneas de todos los archivos
[...]

Autocompleción

La tecla "tabulación" (Tab ↹) permite autocompletar un nombre de archivo o carpeta. Hay que dejar el cursor justo después de unas primeras letras del nombre y apretar tabulación:

$ cd
$ cd lis

Ahora, apretar la tecla ↹ para autocompletar el nombre de carpeta:

$ cd listas

La autocomplecion funciona con los nombres de archivos, de carpetas y hasta los nombres de comandos.

Historial de la shell

La shell viene con historial. Apretando las flechas ↑ y ↓ se puede volver a los comandos ya entrados, y modificarlos o confirmarlos con ENTER.

Correr el último comando que empieza con…

Este atajo puede ser útil para no tipear todo de vuelta:

$ !clang       # correr último comando que empieza con "clang"
clang hola.c -o hola

El comodín *

El simbolo * sirve como comodín. Significa "cualquier cosa".

$ mkdir match
$ cd match
$ touch a.txt b.txt c.txt d.txt main.c old-d.txt old-main.c
$ ls *.txt
a.txt b.txt c.txt d.txt old-d.txt
$ ls *.c
main.c old-main.c
$ rm old*
$ ls
a.txt b.txt c.txt d.txt main.c
$ mkdir textos
$ mv *.txt textos/
$ ls
main.c textos

Un primer programa en C

Vamos a editar un archivo hola.c con el editor geany. Es decir, ejecutamos el editor geany (que hemos instalado previamente).

  1. Ejecutar geany: se puede hacer de dos formas
    1. buscarlo en el menú de aplicaciones
    2. apretar ALT+F2 y tipear geany y ENTER
  2. geany arranca con un archivo vacío sin nombre. Antes que nada lo guardamos con un nombre que termine en .c, por ejemplo hola.c. Se puede hacer de dos formas:
    1. la lenta con el mouse: ir al menu Archivo y Guardar como.
    2. la rápida con el teclado: CTRL+s Aparece un menu donde hay que eligir la carpeta y el nombre del archivo (poner hola.c).
  3. Ahora vamos a llenar nuestro archivo hola.c.

Tipear al archivo el texto siguiente:

#include <stdio.h>

int main(void){
  printf("Hola!\n");
  return 0;
}

Todo debe estar colorido, salvo los nombres de funciones main y printf:

geany 

Si algo no está colorido, es que está mal escrito.

Abajo de la ventana de geany, hacer click en la pestaña Terminal. Ahi vamos a poder tipear comandos, por ejemplo para compilar nuestro archivo.

Tenemos que asegurarnos que estamos en la carpeta donde se encuentra hola.c. Para eso, hay dos formas:

  1. Hacer click derecho en el fondo de la terminal y seleccionar "Establecer ruta desde el documento".
  2. Lo podemos automatizar. Entrar al menu de arriba Editar luego seleccionar Preferencias. En la ventana nueva, hacer click en la pestaña Terminal, y hacer click en la casilla que corresponde a la opción Seguir la ruta del archivo actual.

Asegúremonos que la terminal está en la carpeta de hola.c:

  1. Entrar el comando ls (o ls hola.c) para ver que el archivo está.
  2. Entrar el comando cat hola.c, debería aparecer el la terminal el mismo contenido que en el editor arriba.

Compilemos el programa con clang:

$ clang hola.c -o hola

Y lo ejecutamos:

$ ./hola
Hola!

Felicitaciones!

¿return 0?

En Linux todos los comandos devuelven al sistema operativo algun valor que indica si se ejecutó correctamente. Ese valor se llama estado de salida. Nuestro programita dice return 0 para devolver el valor 0. El valor 0 que significa que no hubo problemas. Cualquier valor más grande que 0 significa que ocurrió un error.

Se puede ver desde la shell este valor:

$ ./hola
Hola, mundo!
$ echo $?
0

Editar el programa para que devuelva algun otro valor (tiene que ser entre 0 y 255), compilarlo y averiguar que el valor cambió.

Atajos del editor geany

CTRL+o abrir archivo
CTRL+s guardar
CTRL+q cerrar el editor
CTRL+z deshacer cambios
CTRL+y rehacer cambios
MAY+flechas seleccionar texto
CTRL+a seleccionar todo el contenido del archivo
CTRL+c copiar texto seleccionado al portapapel
CTRL+x cortar texto seleccionado
CTRL+v pegar texto previamente copiado o cortado
F4 pasar a la terminal
F2 pasar al editor
F11 maximizar ventana
CTRL+page up pestaña anterior
CTRL+page down pestaña siguiente
CTRL+l indicar la línea adonde saltar

El editor nano

Si se quedan sin conexión a internet y no pueden instalar geany pueden usar editores más básicos. Ubuntu trae por defecto nano que hay que arrancar desde la terminal:

$ nano hola.c

Para usar nano de manera comoda, pueden mantener abiertas dos ventanas de shell, una para nano y la otra para entrar los otros comandos (compilación, ejecución, etc.).

Comprimir/descomprimir archivos con el formato zip

Preparemos unos archivos para un ejemplo de uso de los comandos zip y unzip.

$ mkdir proy1
$ touch proy1/p proy1/q proy1/r proy1/s

Ahora creamos un archivo comprimido:

$ zip -r proy1.zip proy1/
  adding: proy1/ (stored 0%)
  adding: proy1/q (stored 0%)
  adding: proy1/p (stored 0%)
  adding: proy1/s (stored 0%)
  adding: proy1/r (stored 0%)
$ ls *.zip
proy1.zip
$ rm -r proy1
$ # ahora descomprimimos nuestro archivo zip
$ unzip proy1.zip
Archive:  proy1.zip
   creating: proy1/
 extracting: proy1/q
 extracting: proy1/p
 extracting: proy1/s
 extracting: proy1/r
$

Prueba rápida de programas con el compilador tcc

tcc es un compilador sencillo para C. Se llama tcc por Tiny C Compiler. No detecta tan bien errores y warnings como gcc o clang pero permite directamente compilar y correr un programa con la opción -run:

$ tcc -run hola.c
Hola!

Eso permite rápidamente probar cambios en sus programas en Geany:

  1. editar el programa en el editor
  2. guardarlo (CTRL+s)
  3. pasar a la shell (F4)
  4. probar el programa con tcc (flecha arriba y enter)
  5. volver al editor (F2) y repetir.

Se puede instalar como cualquier programa bajo Ubuntu:

$ sudo apt-get install tcc

Una vez que tienen un programa que hace lo que quieren, acuérdense de compilarlo con clang para averiguar que no tiene warnings!

Interrupción de un proceso

Hay dos formas de interrumpir un proceso que no puede terminar:

Si lo están ejecutando con tcc:

$ killall tcc

O si lo tienen compilado y lo ejecutan:

$ killall miprograma

Probar las dos formas de matar el proceso infinito.

Indentación (o sangrado) de código para mejorar la legibilidad

Primero, leer el artículo Wikipedia acerca de la indentación con su ejemplo de programa C.

Averiguar que tienen el comando indent instalado (sino, instalarlo):

$ indent --version
GNU indent 2.2.11

Si tienen un archivo de código fuente C, pásenlo a indent para que lo indente:

$ indent while.c

indent modifica el archivo mismo. Recargar o abrirlo de vuelta en su editor de texto (CTRL-r en geany). ¿Ven alguna diferencia?

Probar de vuelta con el flag -kr

$ indent -kr while.c

Recargar o reabrir el archivo. ¿Qué cambió?

Configuración de geany para aplicar la indentación en el archivo corriente

En geany, entrar al menú: Editar > Formato > Enviar texto seleccionado a > Establecer comandos personalisados

Hacer click en "+ Añadir", en comando ingresar indent -kr y en Etiqueta , poner indent.

Esto añade el atajo CTRL-1 (uno) a geany. Este atajo reindenta el texto seleccionado. Entonces, para formatear un archivo entero, se podrá seleccionar todo su contenido con CTRL-a y luego armonizar el formato con CTRL-1.

Lecturas recomendadas