Sei sulla pagina 1di 15

Universidad Nacional de San Juan

Facultad de Ingeniería

GUIA DE USO DEL ENTORNO ZINJAI PARA


PROGRAMACIÓN EN C

Este Documento fue desarrollado por el Ing. Pablo Novara en la


Facultad de Ingeniería y Ciencias Hídricas de la Universidad Nacional
del Litoral. Se modificó para ser adaptado a las asignaturas de
Computación II e Informática II del Departamento de Electrónica y
Bioingeniería de la Facultad de Ingeniería de la Universidad Nacional
de San Juan

AÑO 2014
Introducción a las
Herramientas de Desarrollo

Para desarrollar un programa utilizando C++ sólo se requiere un editor de textos para
poder escribir el código fuente (por ejemplo el Block de Notas de Windows) y
un compilador (en el sentido amplio de la palabra, suele conformarse por
varios programas) para poder generar el ejecutable. Es decir, el compilador toma un
archivo de texto con un código fuente, verifica si la sintaxis es correcta y realiza los
pasos necesarios para generar el archivo ejecutable correspondiente a dicho código
(traducir de C++ a lenguaje de máquina). Sin embargo, en la práctica se suele utilizar
alguna herramienta que integre un editor y un compilador, junto con muchas
características adicionales destinadas a brindar comodidad y velocidad al
programador. Estas herramientas se denominan IDEs (del inglés: Integrated
Development Enviroment = Entorno Integrado de Desarrollo).

Un IDE incluye una interfaz visual, que permite trabajar con comodidad y que se
encarga de dialogar internamente con el compilador, el enlazador y demás
herramientas. De esta forma, el programador nunca debe llamarlas
directamente, sino que con solo hacer un click, la IDE genera y ejecuta todos los
comandos necesarios para la compilación y presenta los resultados de forma
adecuada. Esto, además de ser más rápido, evita al programador la necesidad de
recordar los numerosos parámetros que el compilador y el enlazador reciben y los
reemplaza por un cuadro de diálogo mucho más simple. De igual manera, simplifica
otras tareas como la depuración (ejecución paso a paso, inspección de variables, etc.),
o la edición, y suele presentar además, diferentes asistencias para la escritura del
programa, como sugerencias de autocompletado, coloreado de la sintaxis del código
fuente, ayuda acerca del lenguaje, etc.

Figura 1: Izquierda: estructura de un IDE. Derecha: ejemplo de IDE (ZinjaI)

Es común para el usuario inexperto confundir un IDE con un compilador, ya que en


la mayoría de los productos de desarrollo todo el conjunto de herramientas
necesarias se proveen e instalan junto con la IDE, y puede que el programador jamás
necesite entrar en contacto directo con estas.
Ventajas y desventajas del uso de una IDE

Cuando el alumno realiza sus primeros pasos en un lenguaje de programación es


altamente recomendable que utilice una IDE. De no hacerlo, deberá lidiar con
cuestiones relacionadas al proceso de compilación y al manejo de la linea de
comandos para el uso de un compilador en particular. Es conveniente, en una primer
etapa, concentrarse en las cuestiones relacionadas al lenguaje y a la lógica de los
problemas a resolver.
Sin embargo, un programador avanzado debe conocer con cierto detalle qué ocurre
detrás de su IDE, y cómo se gestiona internamente el proceso de
compilación. Estos conocimientos le ayudan a entender con mayor grado de
profundidad el lenguaje, y le permiten abordar proyectos de mayor envergadura donde
intervengan distintos lenguajes, bibliotecas externas, se requiera soporte para múltiples
plataformas, etc.
En esta primera guía relacionada a las herramientas para la programación en C++, nos
centraremos sólo en la primer parte (el uso de una IDE). El conocimiento
adicional sobre el proceso de compilación será tema de otro anexo más adelante cuando
el alumno disponga de cierto grado de experiencia con el lenguaje.
En este curso, cada alumno es libre de utilizar el IDE que desee. Sin
embargo, en esta guía se presentará uno de ellos (ZinjaI), que tiene la ventaja de estar
desarrollado dentro de la cátedra y pensando para su uso en el aula por parte de
estudiantes, además de ser de libre distribución.

Introducción al uso de ZinjaI

ZinjaI es un IDE para programar en C++ inicialmente desarrollado para el dictado de


clases y para ser utilizado por estudiantes. Invoca internamente al compilador GCC
para generar los ejecutables y se encuentra disponible, como Software Libre, tanto
para Windows como para GNU/Linux. Cuenta con numerosas facilidades de
edición y asistencias para la codificación, así como un sistema de depuración integrado
y ayuda en castellano. Se puede descargar desde “http://zinjai.sourceforge.net”.

El proceso de instalación en Windows es similar a la instalación de cualquier otro


programa. Para una instalación normal se debe ejecutar el instalador, aceptar
la licencia y presionar siguiente tres veces. El instalador copiará los archivos del
IDE, así como también de MinGW (compilador, depurador, etc.).
En GNU/Linux, no es necesario un proceso de instalación del IDE. Sólo se debe
descomprimir el archivo, y lanzar el ejecutable zinjai dentro de la carpeta con el
mismo nombre que se creará al descomprimir. Para descomprimirlo, puede
utilizar alguna herramienta gráfica (como ark o file-roller), o desde una consola
(escribiendo por ejemplo “tar -xzvf zinjai-l64-20100415.tgz”). El paquete no incluye al
compilador (g++) ni al depurador (gdb). Los mismos, deberán ser instalados con el
gestor de paquetes que corresponda según la distribución (aptitude, sinaptics,
installpkg, yum, etc.).

ZinjaI presenta dos modos de trabajo:


• Cuando se inicia ZinjaI se encuentra en un modo pensado para
desarrollar rápidamente ejercicios simples. Aquí, cada pestaña (cada
archivo abierto) será considerado un programa diferente, al compilar y ejecutar,
se considera sólo la pestaña actual. Permite trabajar sin necesidad de
crear un proyecto ni realizar configuración alguna. Tampoco es necesario
(aunque si recomendable) que grabe su código fuente. Cuando se crea
un programa simple, se crea un único archivo. El ejecutable de un
programa simple, será un archivo con su mismo nombre, pero con
extensión .bin o .exe (según se utilice GNU/Linux Windows) en el mismo
directorio (carpeta) que el código fuente.
• El otro modo, que se utiliza cuando se abre un proyecto, no permite tener más de un
programa abierto al mismo tiempo, y todos los códigos fuentes con que se trabaje
pertenecerán a un mismo proyecto. El proceso de compilación tendrá en
cuenta todos los archivos que pertenecen al proyecto, y las posibilidades
de configuración del mismo serán mucho más amplias que en el caso anterior.
Cuando se crea un proyecto, se crea un nuevo directorio, en el cual se
guardarán el archivo de configuración del proyecto, los archivos objetos y el
ejecutable, y todas las fuentes, cabeceras y otros archivos que el usuario cree
dentro de su proyecto.
A continuación se desarrollará paso a paso un ejemplo para crear un
programa simple. Este ejemplo está basado en uno de los tutoriales de ZinjaI.
Puede encontrar más y conocer otras características accediendo a los mismos a través
del menú de ayuda del programa.

Primer programa con ZinjaI


Vamos a resolver un pequeño ejercicio para ejemplificar el manejo básico de
la interfaz. El enunciado del ejercicio sería:

Realice un programa que permita calcular las raíces


de una función cuadrática.

Paso 1:
Lo primero que debe hacer, es crear un nuevo programa. Para ello seleccione la opción
Nuevo... del menú Archivo.
Se desplegará inmediatamente el Asistente para Nuevo Archivo. Allí
seleccione la opción Utilizar Plantilla y haga click en el botón Continuar.

A continuación seleccione la plantilla Programa C en Blanco y presione Crear. Para


nuestro curso se sugiere seleccionar también la casilla Guardar como predeterminada.

Esta acción cerrará el asistente y le abrirá una nueva pestaña con el


esqueleto de un programa C++ (incluye la cabecera iostream y define la función
main), y le posicionará el cursor en la primer línea de la función main para que
comience a escribir.
También puede configurar ZinjaI presionando Ctrl+N, de es forma se crea
automáticamente un nuevo programa utilizando la plantilla por defecto sin mostrar
ninguno de los cuadros del asistente.

Paso 2:
Lo siguiente que haremos será escribir el programa. Una forma de resolver el ejercicio
que se presenta a continuación:
Guardamos el archivo como Prob_raices.c, por ejemplo, o cualquier nombre pero
simpre con la extensión .c. Véase también que se agregó la biblioteca <math.h> para la
función sqrt(). Mientras escribe, no se preocupe por el sangrado de las líneas, observe
como ZinjaI acomoda el cursor en el lugar adecuado cada vez que presiona enter.
Indentar el código es una costumbre altamente recomendable, ya que facilita
enormemente la legibilidad del mismo.

Paso 3:
Para intentar ejecutar el programa presione F9, o seleccione la opción
Ejecutar del menú Ejecutar.

Esta acción guarda el archivo (si aún no tiene nombre la hará en un directorio temporal),
lo compila, y si la compilación es exitosa lo ejecuta. Aparecerá en la parte inferior de la
ventana principal el Panel de Resultados del Compilador, en el cual se muestra el estado
de la compilación y los resultados de la misma.
En caso de que el código copiado contenga algún un error (que no se haya incluido un
punto y coma ; ), el árbol de dicho panel desplegará la sección Errores mostrando un
error similar a “Pob_raices.c:8.2: error: expected ; befote `scanf ´ “ (falta un ; en la
línea anterior). Notar que además de errores (de sintaxis), pueden aparecer advertencias
en el panel de resultados de la compilación. Las advertencias (warnings) no impiden la
compilación del programa (ya que la sintaxis no es incorrecta), pero indican posibles
fuentes de error (como usar una variable sin inicializarla), malas prácticas
(como no cumplir parcialmente el estándar, o declarar variables que no se utilizan), u
otras construcciones dudosas. Pueden resultar útiles para encontrar errores de
lógica.

Paso 4:

Haga doble click sobre el error en el panel de compilación y observe como en el editor
el cursor se desplaza hacia la línea que lo provocó, y subraya con rojo la función a la
cual el mensaje de error hace referencia.
Para solucionar el error debería incluir el punto y coma (;) en la final de la función
printf().
Otra forma de resolver el problema sería presionar Shift+F1 para abrir el panel de
ayuda rápida, el cual brinda información sobre los elementos estándar del lenguaje, así
como ejemplos de uso y enlaces a elementos relacionados.
En caso de no encontrar la ayuda aparece el siguiente mensaje:

Paso 5:

Presione nuevamente F9 para correr el programa. Esta vez se compilará y ejecutará


correctamente en una nueva ventana. Luego de finalizar la ejecución, ZinjaI informará
el código de retorno de su programa (el 0 de la línea final "return 0;", el cual sirve
para saber si se ejecutó correctamente) y esperará a que presione enter una vez más
antes de cerrar la ventana, para permitirle observar los resultados.
Otras consideraciones

Atajos de teclado de utilidad

Es importante que el programador se sienta cómodo con las facilidades de edición que
le brinda la IDE que utiliza. Conocer los atajos de teclado para acciones muy
frecuentes aumenta mucho la velocidad de escritura del código evitando destinar
tiempo a tareas tediosas o repetitivas que nada tienen que ver con la lógica del
problema.A continuación se listan algunas combinaciones de teclas para aprovechar
mejor algunas facilidades de edición ZinjaI:

• F9: Este atajo realiza todos los pasos necesarios para probar un programa (guardar,
compilar y ejecutar). Si se presiona Shift+F9, se evita el último paso; es decir, sólo se
compila. Esto sirve para saber si el código es sintácticamente correcto.

• Ctrl+<: Si la compilación arroja errores o advertencias, con esta combinación se


pueden recorrer los mismos. Al utilizarla, se selecciona un error y el cursor se posiciona
en la línea que ocasionó el mismo. El error que se selecciona va variando en cada
pulsación.

• Ctrl+H: Como se vio en el ejemplo, esta combinación busca la cabecera


que contiene la declaración de una determinada clase, función, variable o
macro e inserta al principio del archivo el #include que corresponda para poder
utilizarla. La palabra que se busca es siempre la seleccionada o la sobre la cual está el
cursor de texto.

• Ctrl+L, Ctrl+Shift+L: La primera duplica la linea actual o las líneas seleccionadas.


Es útil en muchos casos en que el código incluye líneas casi idénticas (por
ejemplo, en el cálculo de las dos raices del ejemplo anterior), equivale a copiar y pegar
esas líneas. La segunda combinación elimina la línea actual o las líneas seleccionadas.
• Ctrl+T, Ctrl+Shift+T: estas combinaciones desplazan la línea actual o las líneas
seleccionadas una posición más arriba en el código. Sirven para mover fragmentos de
código lineas arriba o abajo.

• Ctrl+D, Ctrl+Shift+D: Estas combinaciones sirven para comentar/descomentar


respectivamente una o más líneas.

• Ctrl+I: Este atajo corrige el indentado (los espacios al principio de cada línea) de un
conjunto de líneas para facilitar la lectura del código.

• Shift+F1: Estando posicionado con el cursor de texto sobre una palabra


clave o un identificador, este atajo invoca al panel de ayuda rápida
presentando un texto de ayuda relacionado al mismo.

Herramientas de Depuración
Herramientas a utilizar

La depuración, según las etapas de resolución de problemas planteadas alcomienzo de


la asignatura, es el proceso de encontrar y corregir errores (de lógica, no de sintaxis)
en un programa. Existen herramientas que nos permiten observar detalladamente como
evolucionan los datos a medida que se avanza el programa, y qué acciones son las que
en verdad se ejecutan. Es decir, con estas herramientas podemos pausar la ejecución en
un punto dado, avanzar paso a paso observando por qué líneas del código va pasando el
control del programa, observar cuanto valen determinadas variables en cada paso, etc.
El tipo de depuración que se presentará aquí se puede catalogar como depuración a nivel
de código fuente, dado que el programador dispone del código fuente del programa
a depurar y controla el proceso utilizándolo como referencia. No es el único tipo de
depuración que existe, pero sí el más utilizado durante el desarrollo de un software. La
mayoría de los IDEs actuales incluyen herramientas para la depuración. En esta guía
se utilizará el IDE ZinjaI para los ejemplos presentados, pero los conceptos
generales son aplicables también en cualquier otro entorno. ZinjaI, funciona en
realidad como una interfaz visual para gdb, el verdadero depurador.

Consideraciones Previas

En el proceso de compilación, el código fuente se traduce en código de máquina.


Sabemos que teniendo sólo el ejecutable (código de máquina) es imposible
recuperar el código fuente, pero aún teniendo ambos (ejecutable y fuentes) no es
trivial relacionar ambos códigos y saber por ejemplo, qué dirección de
emoria le asignó el sistema operativo a una variable, o qué conjunto de
instrucciones de máquina se corresponden a una línea de código. Es por esto que para
que la depuración desde el código fuente sea posible, el compilador debe introducir
dentro del ejecutable información adicional que le permita establecer esta relación.
Este ejecutable (llamado común mente versión Debug), por lo tanto, será más
grande, y eventualmente más lento que el ejecutable final que el programador
entregará al usuario una vez finalizado el proceso de desarrollo (versión Release).
La inclusión o no de la información de depuración no es la única diferencia entre las
compilaciones Debug y Release. Hay otras diferencias (como niveles de
optimización) que afectan de forma más perceptible la velocidad de ejecución del
programa. Además, una vez compilado el ejecutable en versión Debug, se debe
recordar que si se modifican los códigos fuentes, se pierde la relación que existe
entre éstos y el código de máquina del ejecutable, y en este caso el depurador
podría mostrar información incorrecta.
Otro detalle a tener en cuenta, es que para poder controlar correctamente un programa,
en muchos casos, el depurador debe encargarse de cargarlo y ejecutarlo, por
lo que el IDE presentará generalmente dos formas de ejecución: la ejecución normal, y
la ejecución para depuración (que será más lenta aún para el mismo ejecutable).

Ejemplo Nro 1: Control básico e inspección de variables

Paso 1: El programa ejemplo

Para llevar a cabo este ejemplo utilizaremos el siguiente código:

Cree un nuevo archivo utilizando la plantilla predeterminada y copie el código fuente


del recuadro. Este código corresponde a un programa que calcula y muestra el promedio
de n números (donde n es un dato ingresado también por el usuario). La variable sum
acumula (suma) todos los enteros ingresados, la variable cant contiene la cantidad de
enteros a ingresar, y finalmente, prom guardará el promedio (sum/cant).
Dentro del bucle, i es el contador, y n es una variable auxiliar para leer los datos que se
deben sumar en sum.
Paso 2: Detener el programa
Para que podamos inspeccionar las variables, o controlar el avance del
programa, primero debemos hacer que se detenga en medio de la ejecución. Para esto,
antes de comenzar a ejecutarlo, debemos establecer “puntos de interrupción”
(breakpoints). Estos son puntos en el código (números de línea) donde el depurador
debe detener el programa. Por lo general, se indican con un círculo rojo sobre el
margen izquierdo. Para colocarlo en ZinjaI, puede hacer click sobre dicho margen, o
posicionar el cursor de texto en la línea de interés y presionar F8. Es muy importante
destacar que en la línea que se debe colocar el breakpoint debe contener una instrucción
o sentencia, en caso contrario el depurador no se detendrá.

Una vez colocado el punto de interrupción, ejecute el programa con la tecla F5 (o la


opción “Ejecutar” del menú “Depuración”). La ventana de ZinjaI desplegará
dos nuevos paneles: el panel de trazado inverso y el panel de inspecciones.
Inmediatamente, el programa comenzará a correr normalmente. Así comienza la
depuración paso por paso.
Observará que la ventana de ZinjaI pasa al frente (o parpadea en la barra de tareas).
En el margen izquierdo del código encontrará una flecha verde sobre el punto de
interrupción. Esta flecha indica dónde se ha detenido el programa. Cuando se marca
una línea, quiere decir que el programa se detuvo justo antes de ejecutar esa línea.
Luego presione <F7> dos veces y el programa se detendrá para leer desde la consola el
primer dato que corresponde a la cantidad cant.
Ingrese un valor entero para asignárselo a la variable cant y presione Enter. Observará
que el programa se detiene luego de leer el dato y la ventana de ZinjaI pasa al frente
(o parpadea en la barra de tareas). En el margen izquierdo del código encontrará una
flecha verde sobre el punto de interrupción. Esta flecha indica dónde se ha detenido el
programa. Cuando se marca una línea, quiere decir que el programa se detuvo justo
antes de ejecutar esa línea.
Debe notar que no puede detener el programa en cualquier línea. Algunas, como
comentarios, declaraciones de variables o líneas en blanco, no tienen
correspondencia con ningún fragmento del ejecutable, por lo que no son puntos de
interrupción válidos. Si define un punto de interrupción en una posición
inválida, el depurador se detendrá en realidad en la siguiente posición válida.
Los puntos de interrupción, pueden tener una condición asociada, de forma que el flujo
del programa, si pasa varias veces por la misma línea, sólo se detenga si se cumple
dicha condición. Por ejemplo, para detenerse sólo en la cuarta iteración del bucle, la
condición sería i==3. Para definir una condición, haga click sobre el punto de
interrupción (en el margen) manteniendo presionada la tecla Shift.

Paso 3: Inspeccionar variables

Una vez que se ha detenido el programa, se pueden inspeccionar los


contenidos de las variables. Existen dos formas básicas de hacerlo:
• Colocar el puntero del ratón sobre el nombre de la variable (o seleccionar una
expresión) y esperar unos segundos (en la figura se muestra el valor de
cant).
• Agregar la variable o expresión en la columna “Expresión” del “Panel de
Inspecciones” (abajo a la izquierda, en la figura se muestran las variables.
Observe que el programa se detuvo justo antes de comenzar el bucle, por lo que aún no
inicializó el contador. A esto se debe el extraño valor de cant y de las otras variables.

El primer método es más rápido, pero el segundo muestra más información (el tipo, el
ambiente, etc.), y permite modificar el valor de una variable haciendo doble click
sobre el mismo. Además, las entradas en la tabla de inspecciones permanecen allí
cuando avanza el programa, por lo que en la próxima detención se actualizarán
mostrando los nuevos valores.

Paso 4: Continuar la ejecución

En este ejemplo, podemos continuar la ejecución de dos formas básicas. Una es


avanzando un solo paso (una línea en el código); la otra es avanzando hasta el próximo
punto de interrupción.
Para avanzar paso por paso, utilice la tecla F7 (step over en el menú
“Depuración”). Cada vez que presione F7 el programa ejecuta una línea de código.
Para continuar ejecutando normalmente presione F5. Esta acción retomará la ejecución
continua hasta que el programa alcance otro punto de interrupción. Si el programa no
alcanzase nunca otro punto de interrupción se ejecutará hasta finalizar. En este caso, la
consola de ejecución se cerrará automáticamente sin esperar a que presione una tecla.
Pruebe continuar la ejecución paso por paso y observe como varían las
variables.
Para detener definitivamente el programa sin finalizar la ejecución presione Shift+F5
(o haga click en “Detener” en el menú “Depuración”).
Recuerde que en todo momento, la parte derecha de la barra de herramientas le informa
en letras azules el estado de la ejecución.

Resumen de comandos

Se resumen a continuación los comandos presentados para controlar la


ejecución6:
Una vez familiarizado con el depurador, puede investigar por su cuenta estas
funcionalidades.

Depurar Funciones

La ejecución paso a paso debería detenerse justo antes de calcular el resultado que
devuelva cualquier función. La línea que corresponde ejecutar a continuación
contiene la llamada a la función a ejecutara, por lo que en realidad, la próxima
línea de código a ejecutar debería ser la primer línea de la función (primero hay que
evaluarla para luego poder mostrar el resultado). En estos casos, tenemos dos formas de
continuar la ejecución: step over y step in.

La primera (step over, con la tecla F7) es la que utilizamos hasta ahora, avanza a la
siguiente línea dentro del ámbito actual. En este caso, avanzará a la siguiente línea del
main(), realizando la evaluación de la función y mostrando el resultado en un solo paso.

La segunda forma de avanzar (step in, con F6), nos permite meternos dentro de la
función. Es decir, si presionamos F6 el depurador avanzará hasta la primer línea de la
función, y nos permitirá analizar qué ocurre dentro de la misma.

Conclusiones

Ya habrá observado que las herramientas de depuración pueden ser de gran ayuda a la
hora de encontrar errores. Sin embargo, estas herramientas no señalan el
problema, sino que sólo se limitan a exponer ante el programador la evolución del
programa. Es el programador quien debe saber donde colocar los puntos de
interrupción y qué variables inspeccionar para poder encontrar el problema. Por lo
general, tendrá una sospecha o intuición acerca del fragmento de código que causa un
problema, y realizará pruebas con datos simples de modo que pueda comparar sus
respuestas calculadas con lápiz y papel con los valores observados en las inspecciones
en cada paso. Poder encontrar el lugar y las variables adecuadas, aunque no es trivial al
principio, es una “habilidad” que se mejora con la práctica, y que requiere un buen
conocimiento del lenguaje y del problema por parte del programador.

Potrebbero piacerti anche