Practica 1

Anuncio
ESCUELA POLITÉCNICA SUPERIOR
INFORMÁTICA. CURSO 2015-2016
PRÁCTICA 1: INTRODUCCIÓN A LA PROGRAMACIÓN EN C
PRERREQUISITOS
•
•
Para el correcto desarrollo de esta práctica, el alumno ANTES DE LA SESIÓN DE PRÁCTICA, debe leer con
atención y comprender el contenido de la parte teórica de la misma.
Además, se recomienda que descargue, instale e intente habituarse al entorno de programación que se utilizará durante
todo el curso: C-Free (tiene disponible en enseñanza virtual los archivos necesarios para instalar el entorno en su
ordenador).
OBJETIVOS
Esta práctica tiene como objetivo la iniciación en la programación en lenguaje C:
• Se introduce el concepto de programa y programación.
• Se presentan los primeros conceptos del lenguaje C: variables, sus tipos y la instrucción de asignación.
• Se describe el entorno de programación C-Free 4.0 que se usará en el presente curso académico.
Al finalizar esta práctica, el alumno debe ser capaz de:
• Usar correctamente el entorno de programación.
• Crear nuevos ficheros de código fuente en C, abrir ficheros existentes, editar e identificar código correctamente,
compilar, identificar errores de compilación y ejecutar el código compilado.
• Escribir programas en C que manejen variables y observar su funcionamiento usando el depurador.
PROGRAMACIÓN IMPERATIVA
Los circuitos electrónicos de un computador pueden reconocer datos e instrucciones que están constituidos por conjuntos
de unos y ceros. Es lo que se conoce por lenguaje máquina. El lenguaje máquina es difícil de manejar y raramente puede
contener operaciones más complejas que realizar operaciones aritméticas con dos números, mover datos de una parte de la
memoria a otra y saltar a una instrucción si se cumple una condición. Una forma de enfrentarse a este problema es crear un
nuevo lenguaje, llamado lenguaje de programación de alto nivel, que sea más fácil de utilizar por un humano, pero no para
el computador. Para que el computador pueda ejecutarlos es necesario traducirlos a su propio lenguaje máquina. Ésta es una
tarea que realiza un programa especial llamado compilador. Los programas, que son secuencias de instrucciones, escritos en
lenguaje de alto nivel se almacenan con una extensión determinada: para el caso del lenguaje de alto nivel que estudiamos en
este curso, el lenguaje C, la extensión de los ficheros es .c. La tarea del compilador se suele descomponer en dos etapas:
- En la primera etapa traduce el programa del fichero .c al lenguaje ensamblador produciendo el fichero .o. El lenguaje
ensamblador es un lenguaje más próximo al del computador.
- En la segunda etapa genera el programa ejecutable en lenguaje máquina, que es el fichero con extensión .exe (en
sistemas operativos Windows)
Como se ha descrito previamente, un programa es una secuencia de instrucciones que describe cómo ejecutar cierta tarea.
Las instrucciones de los programas se ejecutan –ordinariamente- de modo secuencial, es decir, cada una a continuación de la
anterior. Recientemente se está haciendo un gran esfuerzo en desarrollar programas paralelos, es decir, programas que se
pueden ejecutar simultáneamente en varios procesadores. La programación paralela es mucho más complicada que la
secuencial y no se hará referencia a ella en este curso.
PROGRAMACIÓN EN LENGUAJE C
Función main
Un programa C suele estar dividido en funciones (que se llaman procedimientos o rutinas en otros lenguajes). Cada
función ejecuta una parte de un programa, pudiendo recibir unos valores (de entrada) y pudiendo devolver otro (de salida). El
programador puede hacer cuantas funciones necesite y darles los nombres que quiera, pero siempre debe haber una función
main (en inglés significa “principal”). En las primeras prácticas ÚNICAMENTE trabajaremos con esta función principal.
La apariencia de la función main es un bloque encerrado entre llaves donde habrá comentarios e instrucciones:
main ()
{
// Esto es un comentario y se ignora hasta el final de la linea
/* Esto también
es un comentario y no se traduce a código máquina */
lista de instrucciones;
}
1
Todo lo que hay entre las llaves { ... } es el cuerpo de la función. El cuerpo está formado por una lista de instrucciones,
donde cada instrucción termina con el carácter ‘;’. Las instrucciones se procesan de forma secuencial.
En esta práctica se trabajará con programas secuenciales. En prácticas posteriores veremos otras estructuras de control
para los programas.
Variables
Las variables nos permiten almacenar datos. Estos datos pueden ser de distinto tipo o formato numérico y de distinto
tamaño (en bits o bytes). Hay diversos tipos de variables en C: enteras, caracteres, flotantes, vectores... Es necesario declararlas
al principio (después de main () { ...) con el objetivo de indicar al compilador que reserve un espacio determinado en memoria.
La longitud en bytes de este espacio será función del tipo de variable. La sintaxis de la declaración de variables es:
tipo lista_de_nombres;
- tipo: indica el tipo de dato que se almacena en la variable (entero, flotante, carácter ASCII, ...).
- lista_de_nombres: uno o más nombres de variables separados por comas.
Existen una serie de normas para los nombres de variables: pueden contener el carácter guion bajo (_), dígitos numéricos
y letras del código ASCII estándar (no pueden contener eñes ni caracteres con tildes). No pueden comenzar por un dígito
numérico. Se diferencian mayúsculas y minúsculas.
Ejemplos:
- Nombres correctos: importe3, hora_comienzo, dia, Dia, DIA
- Nombres incorrectos: día, 3importe, año
Tipos básicos de variables:
Nomenclatura
int
unsigned int
short
unsigned short
long
unsigned long
float
Tipo
Entero 32 bits
Natural de 32 bits
Entero de 16 bits
Natural de 16 bits
Entero de 64 bits
Natural de 64 bits
Real 32 bits
Almacenamiento
Complemento a 2
Binario natural
Complemento a 2
Binario natural
Complemento a 2
Binario Natural
Punto Flotante de simple precisión
Rango de valores
[-231, 231-1]
[0, 232-1]
[-215, 215-1]
[0, 216-1]
[-263, 263-1]
[0, 264-1]
[1.18-38, 3.4038]
(precisión: 7 dígitos)
double
Real 64 bits
Punto Flotante de doble precisión
[2.23-308, 1.79308]
(precisión: 15 dígitos)
long double
Real 80 bits
Punto Flotante precisión extendida
[3.37-4932, 1.184932]
(precisión: 18 dígitos)
char
Entero de 8 bits (carácter*)
Complemento a 2
[-128, 127]
unsigned char
Natural de 8 bits (carácter*)
Binario Natural
[0, 255]
*El tipo char suele utilizarse para representar el valor numérico de un carácter de la tabla ASCII, debido al rango de valores
que abarca. Esto se verá en la práctica de “Cadenas de caracteres”.
Constantes
Una constante es un dato con un nombre, un tipo y un valor asociado que no puede modificarse una vez definido. La
sintaxis de la declaración de una constante es:
#define NOMBRE valor_cte
Nótese que detrás del valor constante no hay un punto y coma.
Las constantes se definen al principio del programa, antes de la función main(). No se dice explícitamente de qué tipo es la
constante ya que el compilador lo reconoce por el aspecto de valor_cte.
Instrucción de asignación
Instrucción que sirve para almacenar un dato en una variable. Su sintaxis es:
Nombre_de_variable = expresión ;
- nombre_de_variable: Nombre de variable que ha de estar declarada previamente
- operador de asignación (=): Indica que el valor calculado en la expresión debe ser almacenado en
Nombre_de_variable.
- expresión: Indica cómo se calcula el valor a almacenar en la variable.
Nótese que el sentido de la asignación es de derecha a izquierda
2
Ejemplo de programa con los conceptos explicados:
#define PI 3.14
main()
{
double perimetro;
double radio = 3; // Declaración de variable con inicialización
perimetro = 2 * PI * radio;
area = PI * radio * radio ; //Fallo porque la variable área no está declarada
}
PRIMERA PARTE: Creación, edición, compilación y ejecución de un programa C
1. Haz clic en este icono, o pulsa Ctrl+N,
para crear un nuevo fichero de código C
2. En la ventana principal del editor,
teclea estas líneas de código. ¡No pongas
los números de línea, eso ya lo hace
solo!
3. Haz clic en este icono, o pulsa Ctrl+S,
para grabar el código fuente al disco duro.
4. Elige un sitio en el disco duro para
guardar tu programa, y ponle un nombre.
¡No olvides el .c al final del nombre!
5. Haz clic en este icono, o pulsa la tecla
F5, para compilar y ejecutar el programa
que has hecho.
6. Comprueba el resultado. Va a fallar
porque la variable área no está declarada
7. Haz los cambios necesarios en el código
fuente, para corregir los errores. (declara
la variables area).
8. Guarda tu programa con los cambios
corregidos, compílalo y ejecútalo. ¡Ya
funciona!
3
SEGUNDA PARTE: Depuración de programas
C-Free, como la mayoría de los entornos de programación, tiene dos formas de compilar un programa: modo “Debug” y
modo “Release”. El modo “Debug” se usa cuando se está comenzando a escribir el programa y es muy probable que éste tenga
errores. Nos permite ejecutar paso a paso nuestros programas e ir viendo en cada uno de ellos qué es lo que ocurre, viendo si
en algún momento el resultado no es el que debiera. De esta forma podemos detectar errores lógicos o de funcionamiento. El
entorno nos va mostrando el contenido de las variables, resultado de operaciones, rumbos que va tomando la ejecución, etc.
La depuración sólo puede realizarse cuando el programa compila con 0 errores (da igual el número de “warnings” que
tenga), ya que la depuración se realiza durante la ejecución y para ello el compilador tiene que haber sido capaz de generar un
fichero ejecutable. Para depurar un programa, primero hay que asegurarse de que el compilador está en modo “Debug”. Esto se
indica con una D entre corchetes en el cuadro de selección del compilador. En la imagen siguiente por ejemplo, aparece una R
(de “Release”), así que tenemos que cambiar a modo “Debug” usando el botón indicado.
De esta forma ya podemos “depurar” el programa que estemos editando en ese momento. Para ello, en lugar lo que
hicimos anteriormente, lanzamos la depuración usando la opción mostrada o pulsando F9.
TAREA:
Escribir el siguiente código en un nuevo fichero y lanzar la depuración:
#include <stdio.h>
main()
{
int a;
a = 10;
a = a + 5;
printf("Hola mundo\n");
}
Cómo veis no ocurre nada diferente. La razón es que para que la ejecución vaya paso a paso debemos interrumpirla en
algún punto de nuestro programa: Son los denominados puntos de ruptura o Breakpoints. En C-Free los puntos de ruptura se
establecen o se anulan haciendo un simple clic con el botón izquierdo del ratón a la izquierda del número de línea en la que se
quiere colocar el punto de ruptura.
4
Si hacemos eso, aparece un punto rojo a la izquierda del número de línea, y toda la línea se marca para destacarla. Si
colocamos un punto de ruptura como se indica en la imagen y ejecutamos en modo de depuración nuestro programa veremos
que se detiene en dicho punto.
En la parte inferior de la ventana podéis ver un cuadro en el que aparece nuestra variable y el valor que contiene. Podéis
comprobar que el valor de '10' no ha sido asignado. Eso es porque la línea en la que hemos puesto el breakpoint AUN NO SE
HA EJECUTADO. El programa, por lo tanto, está ahora interrumpido, a la espera de una orden para seguir: tenemos varias
opciones, todas ellas resumidas en un pequeño panel que aparece solamente cuando se está en medio de una sesión de
depuración.
El significado de los iconos que usaremos es el siguiente:
Termina la sesión de depuración y vuelve al editor. Esta opción termina bruscamente el programa.
Cuando se identifica un error durante la depuración, es necesario cerrar la sesión antes de realizar
cambios en el código fuente. Si el programa se bloquea o deja de responder durante la depuración,
este botón puede ayudarnos a retomar el control terminándolo prematuramente.
STEP INTO. Tiene el mismo efecto que pulsar la tecla F7 durante la depuración. Ejecuta la línea
de código que está marcada en este momento en el depurador y pasa a la siguiente. Si la línea de
código es una llamada a una función (lo veremos en su momento), la siguiente línea que se marca
es la primera línea de código de la función llamada.
5
STEP OVER. Tiene el mismo efecto que pulsar la tecla F8 durante la depuración. Ejecuta la
línea de código que está marcada en este momento en el depurador y pasa a la siguiente. Si la
línea de código es una llamada a una función (lo veremos en su momento), se ejecuta a
velocidad normal, parándose de nuevo la ejecución en la línea siguiente a aquella que contiene
la llamada a la función. Esta opción por tanto, trata a las funciones como instrucciones simples,
y debe usarse para evitar “entrar” en funciones que ya sabemos que funcionan correctamente.
STEP OUT. Mismo efecto que pulsar Mayúsculas-F7. Usando esta opción desde el contexto de
una función cualquiera, ejecuta dicha función hasta el final, a velocidad normal, parándose en la
siguiente línea a aquella que tenía la llamada a la función. Puede usarse para ejecutar funciones
a velocidad normal cuando hemos entrado en ellas por error con F7 (cuando lo que queríamos
era pulsar F8) o bien cuando la inspección visual determina que la función opera correctamente
y no tiene sentido seguir ejecutándola paso a paso.
RUNS TO CURSOR. Mismo efecto que pulsar Ctrl-F8. Permite “saltar” una parte del código
que no nos interesa ejecutar paso a paso. Simplemente movemos el cursor de escritura a la línea
en la que queremos volver a parar la ejecución y pulsamos esta opción: el programa se ejecutará
a velocidad normal hasta llegar a la línea donde está el cursor, entonces se parará.
Por tanto, si en este momento pulsamos F7 ó F8, la línea con el breakpoint se ejecutará, y veremos como el valor de la variable
a ha cambiado. La línea resaltada pasa a ser ahora la siguiente. Si volvemos a pulsar F8, el contenido de la variable vuelve a
cambiar. Si seguimos pulsando F7 ó F8 seguiremos ejecutando el programa hasta el final. Si no queremos ir paso a paso
podemos ejecutar F9 para que el programa siga ejecutándose normalmente de forma automática, hasta que el entorno encuentre
otro breakpoint.
EJERCICIOS
1.
2.
3.
4.
Crear al menos una variable de cada uno de los tipos explicados, asignarles diversos valores y comprobar mediante el
depurador la asignación de los mismos.
Crear una constante llamada PI cuyo valor sea el del número pi. Use tantos decimales como le sea posible (20
decimales está bien). Asigne el valor de PI a las variables de distinto tipo creadas en el punto anterior. ¿Qué
limitaciones observa en el valor almacenado según el tipo de variable?
Intentar asignar un valor a PI dentro de nuestra función main. ¿Es posible?
Escribir en un nuevo programa el siguiente código:
#include <stdio.h>
main()
{
int a, b;
a = 10;
b = 20;
b = a;
a = 40;
printf ("Hola mundo\n");
}
¿Cambia el valor de b tras asignarle un nuevo valor a la variable a (a=40)?
6
Expresiones aritméticas
Como ya hemos visto en el epígrafe anterior, podemos asignar valores a las variables mediante una sentencia de
asignación. La asignación en lenguaje C tiene la siguiente sintaxis:
variable = expresión;
Tanto las variables como las operaciones de suma que pusimos en el lado derecho de la asignación constituyen dos tipos
de expresiones aritméticas básicas del lenguaje C. El resto de expresiones que podemos utilizar las mostramos en el siguiente
cuadro:
EXPRESIÓN ARITMÉTICA
Resultado de la expresión
Constante
El resultado de la expresión es el valor de la constante
Nombre_de_Variable
El resultado de la expresión es el valor de la variable
Expresión1 + Expresión2
Suma Expresión1 y Expresión2, que son, a su vez, expresiones
más pequeñas
Expresión1 – Expresión2
Resta Expresión2 a Expresión1
Expresión1 * Expresión2
Multiplica Expresión1 por Expresión2
Expresión1 / Expresión2
Divide Expresión1 entre Expresión2
- Expresión
El resultado es la Expresión cambiada de signo (operador unario)
Expresión1 % Expresión2
Operador módulo: Devuelve el resto de la división entera
Expresión1 entre Expresión2
variable --
Auto-Decremento: Devuelve el valor de la variable; después resta
1 al valor de la variable
variable ++
Auto-Incremento: Devuelve el valor de la variable; después suma
1 al valor de la variable.
Veamos algunos ejemplos de expresiones incluyendo algunos errores. Vamos a suponer que en alguna parte de nuestro
programa hemos definido la constante PI y las variables radio y perímetro:
#define PI 3.141592
double radio = 3000000;
double perimetro;
EXPRESIÓN ARITMÉTICA
Constante
EJEMPLOS
3.32
PI
‘A’
perimetro
area
Radio
Expresión1 + Expresión2
area+perimetro
3+radio+34
‘A’+3
Expresión1 – Expresión2
perimetro-PI
‘A’-’a’+3
3+4-5.6-3
Expresión1 * Expresión2
2*PI*radio
PI*radio*radio
PI*(radio+2)
Expresión1 / Expresión2
perimetro/PI
3/2 resultado:1
3.0/2.0
resultado:
1.5
-2
-PI
-sqrt(radio)
3%2 resultado:1
7%4 resultado:3
7.0%5 ERROR
variable --
radio--
(area+3)--ERROR
PI-- ERROR
variable ++
area++
sqrt(34)++
ERROR
PI++ ERROR
Nombre_de_Variable
- Expresión
Expresión1 % Expresión2
7
Como vemos en las tablas, una expresión puede contener como operando otras expresiones, de esta forma podemos
escribir algo como:
a = 12*x*x + 4*x + 2;
La forma en la que se evalúan o interpretan las expresiones siguen unas reglas similares a las de la aritmética de las
matemáticas. Primero se evalúan las de mayor precedencia y al final la de menor. La precedencia de las operaciones
aritméticas es:
Mayor
Menor
++, --
- unario
*, / y %
+, -
En el caso de que haya varios operadores de la misma precedencia, se evalúan de izquierda a derecha. Con los
paréntesis podemos cambiar la precedencia.
a = 12*x*(x + 4)*x + 2; //El paréntesis se evalúa primero
Ejercicio 5. Dado el siguiente código:
main() {
float result;
result = 3 / 2;
result = 3 / 2.0;
result = 3.0 + 3/2;
}
Realizar las operaciones en papel y comprobar el valor calculado por el ordenador mediante la depuración. ¿Por qué no realiza
la operación como esperábamos?
Solución: Conversión implícita de datos
result = 3 / 2;
int: 1
float: 1.0
main() {
float result;
result = 3 / 2;
result = 3 / 2.0;
result = 3.0 + 3/2;
}
result = 3 / 2.0;
float: 3.0
float: 1.5
result = 3.0 + 3/2;
int: 1
float: 1.0
float: 4.0
8
Descargar