Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Programación en C +
Programación en C +
Fundamentos de programacin
UNED
ndice
VALORES Y TIPOS ........................................................................................... 5
Valores constantes ...................................................................................... 5
Valores numricos enteros ................................................................................... 5
Valor numricos reales ........................................................................................ 5
Caracteres............................................................................................................ 6
Cadena de caracteres (strings) ............................................................................ 6
Secuencia ........................................................................................................... 35
Sentencia IF ....................................................................................................... 36
Sentencia WHILE ............................................................................................... 38
Sentencia FOR ................................................................................................... 39
Procedimientos ......................................................................................... 57
Paso de argumentos .................................................................................. 59
Paso de argumentos por valor ........................................................................... 59
Paso de argumentos por referencia ................................................................... 60
VALORES Y TIPOS
VALORES CONSTANTES
Valores numricos enteros
Los valores enteros representan un nmero exacto de unidades y no pueden
tener parte fraccionada. Se escribe mediante una secuencia de uno o ms
dgitos del 0 al 9 sin separadores de ninguna clase entre ellos y precedidos de
los smbolos ms (+) o menos (-). Ejemplos:
2
+25
0
-2564832
Por lo tanto un valor real, al contrario que el entero tiene muy diversas
representaciones vlidas. Ejemplo:
4.623
46.23E-1
4.623E0 0.4623E1
Caracteres
Dentro de un texto en C el valor de un carcter concreto se escribe poniendo
dicho carcter entre apstrofos (). Ejemplos:
a
TIPOS PREDEFINIDOS
Tipo de datos define:
a) Una coleccin de valores posibles.
b) Las operaciones significativas entre ellos.
b) Operaciones:
+
*
/
%
+
-
Suma de enteros
Resta de enteros
Multiplicacin de enteros
Divisin de enteros
Resto de la divisin
Identidad de un entero
Cambio de signo de un entero
a+b
a-b
a*b
a/b
a%b
+a
-a
15 % 4 = 3
Se cumple:
a = b * (a / b) + (a % b)
Es decir:
Dividendo = Divisor x Cociente + Resto
7
b) Operaciones:
+
*
/
+
-
Suma de reales
Resta de reales
Multiplicacin de reales
Divisin de reales
Identidad de un real
Cambio de signo de un real
a+b
a-b
a*b
a/b
+a
-a
char(10)
char(13)
char(65)
65
90
123
Resultado
Mira este texto
Cmo ests?
10
Cdigo
d
f
e
g
c
s
Nemotcnico
(ingls)
decimal
fixed point
exponential
general
character
string
Tipo de valor
entero
real
real con notacin exponencial
real con/sin notacin exponencial
un carcter
una cadena de caracteres
As por ejemplo:
Operacin de escritura
printf( %d , 120/12 );
printf( Datos:%d#%d , 23*67 , -25 );
printf( Datos: %d # % d , 23*67 , -25 );
Resultado
10
Datos:1541#-25
Datos:1541#-25
Resultado
10
Datos:138#-25
670000
Resultado
1.200
0.1557E+04
-50.600E-6
Resultado
rea=24.4500
Mi ciudad es vila
Descuento:12.50%
ESTRUCTURA DE UN PROGRAMA
12
13
CONSTANTES Y VARIABLES
IDENTIFICADORES
En programacin se llaman identificadores a los nombres usados para
identificar cada elemento de un programa. En C los identificadores son una
palabra formada por caracteres alfabticos o numricos seguidos, sin espacio
en blanco ni signos de puntuacin intercalados y deben comenzar por una
letra. Pueden usarse las 52 letras maysculas y minsculas del alfabeto
ingls, el guin bajo (_), y los dgitos decimales del 0 al 9. Adems el
lenguaje distingue las letras maysculas y minsculas. Ejemplos: Indice
diaDelMes Nombre_Apellidos j5 Eje_3.
El Manual de Estilo recomiendan las siguientes reglas para los
identificadores:
VOCABULARIO C
and
bool
compl
delete
enum
friend
mutable
or
reinterpret
static
this
typename
volatile
and_eq
break
const
do
explicit
goto
namespace
or_eq
t_cast
static_cast
throw
union
wchar_t
asm
case
const_cast
double
extern
if
new
private
return
true
unsigned
while
auto
catch
dynamic_cast
false
inline
not
protected
short
struct
try
using
xor
bitand
char
continue
float
int
not_eq
public
signed
switch
typedef
virtual
xor_eq
14
bitor
class
default
else
for
long
operator
register
sizeof
template
typeid
void
CONSTANTES
Una constante es un valor fijo que se utiliza en un programa, no vara durante
la ejecucin del mismo. La declaracin de una constante con nombre, se
realiza por medio de la palabra clave const seguida del tipo y nombre
simbolico de la misma, a continuacin del signo igual el valor asociado:
const float Pi = 3.14159265;
Si una constante es del tipo cadena de caracteres, esta se declara utilizando
los smbolos [] a continuacin del nombre de la constante:
const char Pregunta[] = Cdigo postal?;
Las constantes con nombre son declaradas antes de ser utilizadas.
Se puede declarar una constante en forma de una expresin, siempre que sean
valores constantes ya declaradas y que las operaciones entre ellas sean
operadores fijos del lenguaje o funciones predefinidas. Por ejemplo la
constante diametro esta declarada como una expresin:
const float radio = 1.5;
const float diametro = 2*radio;
Todas las constantes con nombre se pueden utilizar exactamente igual que el
valor literal que representan.
15
VARIABLES
El concepto de variable en los lenguajes de programacin difiere del
algebraico. Una variable representa un valor almacenado que se puede
conservar indefinidamente para ser usado tantas veces como se quiera. El
valor de una variable se puede modificar en cualquier momento y ser este
nuevo valor el almacenado a partir de entonces.
Las variables han de ser declaradas en el programa antes de ser utilizadas. La
declaracin simple de una variable especifica su nombre y el tipo de valor
asociado. Por ejemplo la variable edad, que es un nmero entero de aos se
declara:
int edad;
As para declarar una variable se indica en tipo, el nombre y termina con un
punto y coma (;). Si son varias variables tienen el mismo tipo, se pueden
declarar todas conjuntamente, escribiendo sus nombres separados por comas
(,) despus del tipo comn de todas. Por ejemplo:
int dia, mes, anno;
El valor almacenado de una variable puede ser empleado como orerando en
una expresin aritmtica, siempre que no se combinen tipos diferentes. Por
ejemplo:
int
int
float
char
Variables
base, altura;
saldo, meses, das;
volumen, area, gastos;
modelo, codigo;
Expresiones correctas
Expresiones inadecuadas
base * altura
dias + int( cdigo )
volumen / area
area / base
saldo + gastos
base + modelo
Para usar una variable de manera correcta hay que inicializarla. Inicializar
una variable es simplemente darle un valor determinado la primera vez. Para
inicializarla solo hay que poner al nombre de la variable un signo igual
seguido de su valor. Ejemplo:
float gastos = 0.0;
char modelo = '?';
16
SENTENCIA DE ASIGNACIN
La forma de conseguir que una variable guarde un determinado valor es
mediante una sentencia de asignacin. Por ejemplo:
base = 18;
area = 56.89;
codigo = ' z ';
El signo igual (=) es el operador de asignacin, este operador indica que el
valor de la derecha debe ser asignado a la variable cuyo identificador est a la
izquierda. As en el ejemplo, base, area y codigo sustituyen el valor que
tenan por 18, 56.89 y el carcter z respectivamente. Siempre se utiliza el
valor de la variable en ese momento, as ante la secuencia:
meses = 2; /* meses toma el valor 2*/
dias = meses; /* dias toma el valor actual de meses que es 2*/
meses = 7; /* meses sustituye el valor 2 que tena por 7*/
saldo = meses; /*saldo toma el valor actual de meses que es 7*/
Existe un caso especial, es aquel en que una variable se le asigna el valor de
na expresin de la que forma parte la propia variable. Por ejemplo:
dias = dias + 30;
As si la variable dias tena el valor 16, esta sentencia almacenara el nuevo
valor en 46, que ser 16+30. En general cada vez que pase el programa por
esta sentencia la variable dias incrementar su valor actual en 30 unidades.
En ocasiones hay que incrementar o disminuir una variable en una unidad, es
decir:
variable = variable + 1;
variable = variable - 1;
17
saldo = int(gastos);
saldo = 4.5
dia = 6
float saldo;
En este caso habra que pulsar intro cada vez que se introduce el dato.
20
Resultado
Cdigo del producto? A
Cantidad? 12
Precio unitario? 2345
IVA aplicable? 16
RECIBO DE COMPRA
Cantidad Concepto
Euros/unidad
Total
12
Producto A
2345.00
28140.00
16% IVA
4502.40
TOTAL
32642.40
21
22
23
24
Calcular suma
suma = dato1 + dato2
Imprimir resultado
printf( "La suma es%10d\n:" , suma);
Uniendo todos las fragmentos finales de cdigo en el orden adecuado y
aadiendo la declaracin de las variables tenemos el programa completo:
/** Programa sumaDosNumeros */
/* Obtener la suma de dos nmeros enteros*/
#include <stdio.h>
int main() {
int dato1, dato2, suma;
printf(
scanf(
scanf(
printf(
25
ASPECTOS DE ESTILO
El estilo de redaccin del programa en su forma final es algo fundamental
para conseguir que sea claro y fcilmente comprensible por parte de quienes
hayan de leerlo. Analizaremos algunas recomendaciones en la manera de
presentar un programa para su fcil compresin. Estas pautas se encuentran
en el Manual de Estilo del lenguaje C
Encolumnado
Comentarios
Otro recurso utilizable para mejorar la calidad de un programa es el empleo
de cometarios, que en el lenguaje C se consigue intercalndolos en el texto
de un programa entre los smbolos /* y */.
El lenguaje permite el uso de comentarios con total libertad, pero es
aconsejable seguir unas pautas que corresponden a diferentes clases de
comentarios, cada uno con un propsito diferente, entre ellas podemos
mencionar:
26
Eleccin de nombres
Los nombres que tenga que inventar el programador deben ser elegidos con
criterio nemotcnico, de manera que se recuerden fcilmente el significado
de los elementos nombrados. Se suele elegir una categora gramatical acorde
con el element nombrado:
Los valores (constantes, variables, etc.) deben ser designados
mediante sustantivos.
Las acciones (procedimientos, etc.) deben ser designadas con
verbos. Estos verbos hay que utilizarlos en el mismo tiempo
verbal, en este caso en infinitivo.
Los tipos deben ser designados mediante nombres genricos. Se
suele emplear el sufijo T_
28
Diagramas de flujo
Las estructuras de los programas se representan tradicionalmente mediante
los diagramas de flujo (flow-chart). Estos diagramas contienen dos
elementos bsicos, correspondientes a acciones y condiciones, que se
representan mediante tringulos y rombos respectivamente (Fig. 5). El flujo
de control durante la ejecucin del programa se refleja mediante lneas o vas
que van de un elemento a otro.
29
Las acciones tienen una sola entrada o comienzo y una terminacin o salida.
Las condiciones tienen una entrada y dos vas de salida marcadas con Si y
No. Durante la ejecucin, cuando el flujo llega a la entrada de una accin,
la accin se realiza y el flujo se dirige hacia la salida. Cuando se llega a la
entrada de una condicin, la condicin se evala, y si resulta ser cierta se
contina por la salida Si, pero si es falsa se contina por la salida No.
Secuencia
Fig. 7 Secuencia
Seleccin
Fig. 8 Seleccin
31
Iteracin
Fig. 9 Iteracin
Estructura anidadas
Cualquier parte de un programa puede estar compuesto por cualquiera de las
estructuras descritas, por lo que el anidamiento entre ellas puedes er tan
complejo como sea necesario. Mediante la tcnica de refinamientos sucesivos
se definen inicialmente las estructuras ms externas del programa y en los
pasos sucesivos de van detallando la estructura de cada accin compuesta.
EXPRESIONES CONDICIONALES
Para poder utilizar las estructuras de seleccin e iteracin es necesario
expresar las condiciones <?> que controlan ambas estructuras. Esto se realiza
mediante la construccin de expresiones condicionales. Estas expresiones slo
pueden dar como resultado dos valores: Si (cierto), cuando se cumple la
condicin de la expresin, y No (falso), en el caso que no se cumpla.
32
Smbolo matemtico
>
<
Operador C
>
>=
<
<=
==
!=
Operacin lgica
Conjuncin (E1 y E2)
Disyuncin (E1 o E2)
Negacin (no E1)
Smbolo matemtico
Operador C
&&
||
!
34
Operadores Unarios
Operadores Multiplicativos
Operadores Aditivos
Operadores de comparacin
Operadores de igualdad
Operador de Conjuncin
Operador de Disyuncin
!+*/ %
+> >= < <=
== =
&&
||
ESTRUCTURAS BSICAS EN C
Secuencia
Es una secuencia de acciones o partes que se ejecutan de forma sucesiva, tal
como se ve en la Fig. 7, es decir se escribe:
Accin A
Accin B
35
Sentencia IF
En C la estructura de la seleccin (Fig. 8) se programa como una sentencia
IF que tiene el siguiente formato:
if ( Condicin ) {
Accin A
} else {
Accin B
}
La ejecucin de la sentencia if consiste en evaluar la expresin Condicin, y
a continuacin ejecutar la Accin A (si se cumple la condicin), o bien la
Accin B (si la condicin no se cumple) Las palabras clave if y else separan
las distintas partes de la sentencia. Por ejemplo:
if ( largo > ancho ) {
ladoMayor = largo;
} else {
LadoMayor = ancho;
}
En ocasiones no es necesario ejecutar nada cuando la Condicin no se
cumple (Fig. 10)
36
37
Gratis
50 %
100 %
25 %
Sentencia WHILE
En C la secuencia de iteracin (Fig. 9) se consigue mediante la sentencia
WHILE, que tiene el siguiente formato:
38
while ( Condicin ) {
Accin
}
Su significado es que mientras la expresin Condicin resulte cierta, se
ejecutar la Accin de forma repetitiva. Cuando el resultado es falso finaliza
la ejecucin de la sentencia. Si la Condicin es falsa en la primera
evaluacin, la Accin no se ejecuta nunca.
Por ejemplo para calcular la factorial de un nmero entero n:
n! = 1 x 2 x 3 x 4 x x n
Se calcula utilizando una sentencia while de la siguiente forma:
factorial = 1
while ( n > 1 ) {
factorial = factorial * n;
n--;
}
As con la sentencia de autodecremento la variable n va disminuyendo su
valor de uno en uno en cada repeticin del bucle, al tiempo que esos valores,
se van multiplicando sucesivamente, guardando el producto acumulado en
factorial, hasta que n se reduce a 1. Si inicialmente el valor de n es igual o
menor que 1, no se pueden ejecutar nunca las sentencias dentro del bucle, por
lo que la variable factorial termina con el mismo valor inicial igual a 1.
Sentencia FOR
Existen ocasiones en que las iteraciones del bucle se controlan mediante una
variable que va contado las veces que se ejecuta. La cuanta puede ser en
sentido ascendente o descendente. La Condicin de la iteracin se limita a
comprobar si se ha alcanzado el lmite correspondiente al nmero de
repeticiones previstas.
Dado que es habitual esta situacin los lenguajes existen sentencias que
simplifican su construccin. El C se dispone de la sentencia FOR, cuya
forma para incremento creciente es:
39
40
41
42
if ( anno % 4 == 0 ) {
dias = 29;
} else {
dias = 28;
}
De manera similar se pueden desarrollar esquemas de seleccin simplificados
con solo una accin combinada o esquema de seleccin en cascada en que
haya un nmero ms o menos grande de alternativas.
Esquema de iteracin
Una interaccin o bucle consiste en la repeticin de una accin o grupo de
acciones hasta conseguir el resultado deseado (Fig. 9). Para desarrollar un
esquema de interaccin, deberemos identificar sus elementos, as como las
variables adecuadas para almacenar la informacin necesaria, es decir:
(a) Identificar las acciones tiles a repetir, y las variables necesarias.
Precisar el significado de cada una de ellas al comienzo y al final de
cada repeticin.
(b) Identificar como actualizar la informacin al pasar de cada iteracin
a la siguiente. Puede ser necesario introducir nuevas variables.
(c) Identificar la condicin de terminacin. Puede ser necesario
introducir nuevas variables e incluso acciones adicionales para
mantenerlas actualizadas.
(d) Identificar los valores iniciales de las variables, y si es necesario
alguna accin para asignrselos antes de entrar en el bucle.
Por ejemplo, si queremos hallar los trminos de la serie de Fibonacci, en la
que cada termino es la suma de los dos anteriores. La serie comienza con los
trminos 0 y 1, que se suponen ya impresos antes del bucle. Se trata de
imprimir tantos como sean posibles.
(a) Acciones tiles a repetir: Imprimir un trmino
printf( "%10d\n:" , termino);
43
44
int termino;
int anterior;
int aux;
.....
anterior = 0;
termino = 1;
while (INT_MAX-termino >= anterior) {
aux = termino + anterior;
anterior = termino;
termino = aux;
printf( "%10d\n:" , termino);
}
VERIFICACIN DE PROGRAMAS
La verificacin de un programa es la tcnica que permite comprobar el
perfecto funcionamiento del mismo. En la prctica, esta verificacin se puede
hacer mediante ensayos. Un ensayo (testing) consiste en ejecutar un
programa con datos preparados de antemano y de los cuales se sabe el
resultado que debe dar. Si en la ejecucin no se dan los resultados esperados
entonces el programa tiene un error, el cual hay que detectar y eliminar. Este
proceso se denomina depuracin (debugging).
Pero puede pasar que el programa sea correcto o que solo lo es para los datos
preparados, es decir que con este mtodo, no estamos seguros al cien por cien
de la correccin del programa. Por lo que la manera ms fiable de verificar
un programa es demostrar formalmente que el programa cumple con las
especificaciones. Para ello es preciso escribir estas especificaciones con toda
precisin en forma de expresiones lgico-matemticas y luego realizar la
demostracin lgico-matemtica que el programa las cumple.
Con esta tcnica se comprueba que el programa cumple con las
especificaciones del mismo, pero que estas describan realmente el problema a
resolver es una cuestin aparte.
Usando expresiones y reglas de la lgica, y conociendo la semntica
(significado) de las acciones, es posible demostrar si un programa es o no
correcto respecto a una especificacin. Para programas que siguen el modelo
imperativo el proceso de demostracin se realiza en dos partes:
45
delante de dicha sentencia todas las condiciones que sabemos que se cumplen
inmediatamente antes de ejecutarla. A continuacin anotaremos detrs de la
sentencia las condiciones que podemos demostrar que se cumplen despus de
su ejecucin y que sern:
Ahora se puede escribir la asercin final como unin de las dos alternativas:
if ( a > b ) {
ASERTO: a > b
m = a;
ASERTO: (a > b) (m = a) ASERTO: m = Max(a,b)
} else {
ASERTO: a b
m = b;
ASERTO: (a > b) (m = b) ASERTO: m = Max(a,b)
}
ASERTO: m = Max(a,b) m = Max(a,b) ASERTO: m = Max(a,b)
Luego el funcionamiento es el correcto.
51
3
(Regla 2)
1
Total =
(Regla 1)
5(n-1)
(Regla 3)
2
Total =
5n-3
(Regla 1)
52
FUNCIONES Y PROCEDIMIENTOS
CONCEPTO DE SUBPROGRAMA
Un subprograma es una parte de un programa que se desarrolla por separado
y se utiliza invocndolo mediante un nombre simblico. El empleo de
subprogramas, desarrollando por separado ciertas partes del programa, resulta
espacialmente ventajoso en los siguientes casos:
1. En programas complejos. Si el programa se escribe todo seguido
resulta muy complicado de entender, porque se difumina la visin
de su estructura global entre la gran cantidad de operaciones que
forman el cdigo del programa. Aislado ciertas partes como
subprogramas separados se reduce la complejidad del mismo.
2. Cuando se repiten operaciones anlogas: Definiendo esa operacin
como subprograma separado, su cdigo se escribir solo una vez,
aunque luego se use en muchos puntos del programa. As el tamao
total del programa ser menor que si se escribiera el cdigo
completo.
FUNCIONES
Una funcin es un tipo de subprograma que calcula como resultado un valor
nico a partir de otros valores dados como argumento. En lneas generales
una funcin se asemeja bastante a la idea matemtica de funcin F(x,y,)
con argumentos x,y, Por ejemplo:
xn
lado3
(base * altura)/2
((x1 x2)2 + (y1 y2)2)1/2
Potencia:
Volumen de un cubo:
rea de un tringulo:
Distancia entre dos puntos:
return expresin;
Se puede utilizar ms de una sentencia return en una funcin. Pero hay que
tener claro que la ejecucin acaba cuando se ejecuta cualquiera de las
sentencias return.
As la definicin completa de las funciones definidas queda:
Potencia:
Volumen de un cubo:
rea de un tringulo:
Como ejemplo de una funcin con varias sentencias de retorno, podemos ver
la que nos devuelve el mximo valor de dos nmeros enteros:
int Maximo2( int x, int y) {
if (x>0 y) {
return x;
} else {
return y;
}
}
55
Para usar una funcin en los clculos de un programa se invoca dicha funcin
escribiendo el nombre y a continuacin, entre parntesis, los valores
concretos de los argumentos, separados por comas. El efecto de una funcin
puede describirse de forma simplificada de la siguiente manera:
1. Se evalan las expresiones de los valores de los argumentos.
2. Se asignan dichos valores a los correspondientes argumentos
formales,
3. Se ejecuta el cdigo de la definicin de la funcin, hasta alcanzar
una sentencia de retorno.
4. El valor retornado se usa en el punto donde se invoc la funcin.
isalpha( char c )
isascii(char c )
isblank(char c )
iscntrl(char c )
isdigit(char c )
islower(char c )
isspace(char c )
isupper(char c )
tolower(char c )
toupper(char c )
56
sqrtf( float x )
expf( float x )
logf( float x )
powf( float x, float y )
sinf( float x )
cosf( float x )
tanf( float x )
atanf( float x )
roundf( float x )
raz cuadrada de x
exponencial ex
logaritmo neperiano de x
potencia xy
seno de x
coseno de x
tangente de x
arcotangente de x
valor de x redondeando a entero
PROCEDIMIENTOS
Un procedimiento es un subprograma que realiza una determinada accin. A
diferencia de las funciones, un procedimiento no tiene como objetivo, en
general, devolver un valor obtenido por clculo.
un procedimiento es una forma de subprograma que agrupa una sentencia o
grupo de sentencias que realizan una accin, y permite darles un nombre por
el que se puede identificar posteriormente. Estas sentencias se pueden
parametrizar con una serie de argumentos, tal como se haca con las
funciones, pero a diferencia de ests no nos devuelve ningn valor.
Ejemplo de procedimientos seran:
Trazar una lnea de longitud dada
Imprimir un resultado
Ordenar dos valores
Leer las coordenadas de un punto
Estas acciones se pueden definir como procedimientos y luego invocarlas en
el programa cuando interese.
57
PASO DE ARGUMENTOS
La manera fundamental de comunicar la informacin entre las sentencias de
un subprograma y e programa que lo utilizan es mediante los argumentos. En
C existen dos formas distintas de realizar esta comunicacin: paso de
argumentos por valor y paso de argumentos por referencia.
60
EJEMPLO DE UN PROGRAMA
Escribamos un programa que calcule las races de una ecuacin de segundo
grado:
ax 2 + bx + c = 0
61
b b 2 4ac
2a
62
/**Programa principal */
int main() {
float valorA, valorB, valorC; /* Coeficientes de la ecuacin */
float parteUno, parteDos;
/* Variables intermedias de clculo */
float valorD;
/* Discriminante de la ecuacin */
LeerValor( 2, valoraA );
LeerValor( 1, valoraB );
LeerValor( 0, valoraC );
if (valorA == 0.0) {
if (valorB == 0.0) {
if (valorC == 0.0) {
printf( Ecuacin no vlida\n );
} else {
printf( Solucin imposible\n );
}
} else {
printf( Raiz nica = %10.2f\n, -valorC/valorB );
}
} else {
parteUno = - valorB/(2.0*valora);
valorD = Discriminante( valorA, valorB, valorC );
if (valorD >= 0.0) {
parteDos = sqrt (valorD)/(2.0*valorA)
printf( Races reales :\n );
printf( %10.2f y \n, parteUno+parteDos );
printf( %10.2f \n, parteUno-parteDos );
} else {
parteDos = sqrt (-valorD)/(2.0*valorA)
printf( Races complejas :\n );
printf( Parte real=
%10.2f y\n, parteUno );
printf( Parte imaginaria = %10.2f \n, parteDos );
}
}
}
63
Resultado
Solucin a la ecuacin: x2 + 2x + 2 = 0
Coeficientes de grado 2? 1.0
Coeficientes de grado 1? 2.0
Coeficientes de grado 0? 2.0
Races complejas :
Parte real=
-1.00 y
Parte imaginaria =
1.00
64
65
Especificacin:
Sintaxis
Semntica
Realizacin
Especificacin:
Sintaxis
Semntica
Realizacin
Funciones. Argumentos
En programacin la idea de funcin surge al aplicar el concepto de
abstraccin a las expresiones aritmticas. Si buscamos que el concepto de
funcin en programacin se aproxime al concepto matemtico de funcin, el
paso de argumentos siempre debe ser por valor.
As para conseguir una transparencia referencial, es decir que una funcin
devolver siempre el mismo resultado cada vez que se invoque con los
mismos argumentos, es necesario que la funcin no utilice datos exteriores a
ella, es decir, si NO emplea:
67
/* (a,b) = (b, a) */
Sintaxis
Semntica
int aux;
aux = a;
a = b;
b = aux;
}
Realizacin
68
Desarrollo descendente
La estrategia del desarrollo descendente (Top-Down), es simplemente el
desarrollo de refinamientos sucesivos, teniendo en cuenta adems la
posibilidad de definir operaciones abstractas. En cada etapa de refinamiento
habr que considerar la posibilidad de optar por cada una de las siguientes
opciones:
Para decidirse por una operacin abstracta habr que analizar las ventajas que
conlleva, como alguna de las siguientes:
Desarrollo ascendente
El desarrollo ascendente (Bottom-Up), consiste en ir creando subprogramas
que realicen operaciones significativas de utilidad para el programa que se
intenta construir, hasta que finalmente sea posible escribir el programa
principal, de manera relativamente sencilla, apoyndose en los subprogramas
desarrollados hasta ese momento.
69
PROGRAMAS ROBUSTOS
La correccin de un programa exige que los resultados sean los esperados,
siempre que el programa se ejecute con los datos de entrada aceptables.
Ahora hay que plantearse cul va ser el comportamiento del programa si los
datos son incorrectos? Para ello se busca un programa robusto, es decir que
la operacin del mismo se mantenga controlada aunque se suministren datos
errneos.
La postura ms cmoda es declinar toda responsabilidad por parte del
programador, si se suministran datos errneos, sin embargo esta postura no es
admisible en la prctica, para ello se emplea la programacin a la defensiva
(defesive programming), que consiste en que cada programa o subprograma
est escrito de manera que desconfe sistemticamente de los datos o
argumentos con que se le invoca y devuelva siempre como resultado:
(a) El resultado correcto, si los datos son admisibles, o bien
(b) Una indicacin precisa del error, si los datos no son admisibles.
Lo que no hace nunca es devolver un dato como si fuera correcto, cuando en
realidad es errneo, ni abortar, ya que es mucho ms difcil encontrar
donde se ha producido el error.
As pues ante la posibilidad de la existencia de errores en los datos con que se
opera, hay que considerar dos actividades diferentes:
1. Deteccin de la situacin de error.
2. Correccin de la situacin de error.
El modelo denominado modelo de terminacin, detecta el error en una
seccin o bloque del programa, la accin de tratamiento del error remplaza al
resto de acciones pendientes de dicha seccin, con lo cual tras la accin
correctora se da por terminado el bloque.
70
71
Tratamiento de la Excepcin
}
La sentencia try agrupa el cdigo sin tener en cuenta las excepciones y catch
agrupa el cdigo de tratamiento de la excepcin que se declara entre
parntesis.
72
DEFINICIN DE TIPOS
TIPOS DEFINIDOS
Uno de las ventajas de los lenguajes de alto nivel es que el programador tiene
la posibilidad de definir sus propios tipos de datos. Los tipos predefinidos
int, char y float, en la mayora de los casos no se consigue que la
informacin que maneja el ordenador tenga un significado especfico. As el
tipo establece los posibles valores que puede tener un dato. Adems asociado
al tipo viene determinada una serie de operaciones que se pueden realizar con
l. Por lo tanto, la definicin de tipos supone crear un nuevo nivel de
abstraccin dentro del programa.
En C la declaracin de tipos se realiza dentro de las Declaraciones del
programa principal o en cualquiera de sus procedimientos y funciones. La
declaracin de tipos se inicia con la palabra clave typedef, antes del nombre
o identificador, se debe enumerar a que tipo, ya definido, es equivalente o
sinnimo:
typedef Identificador de tipo Identificador de tipo nuevo;
Por ejemplo
typedef int TipoEdad;
typedef char TipoSexo;
typedef float TipoAltura;
Esto quiere decir que TipoEdad, por ejemplo, ahora tiene las caractersticas y
operaciones que se pueden hacer un tipo entero (int), es decir que la edad es
positiva y no puede ser superior a un valor determinado o que el TipoSexo
solo puede tomar unos determinados valores.
Una vez definidos los nuevos tipos, es necesario declarar las variables
asociadas a los mismos, as se podran utilizar los tipos annimos anteriores
para declarar las variables edad1, edad2, sexo y altura, por ejemplo:
Tipoedad edad1, edad2;
TipoSexo sexo;
73
TipoAltura altura;
edad2 = edad1 + 5;
sexo = "V";
altura = 1.75;
El tipo sinnimo, as definido permite utilizar slo tipos con nombres
propios. Por ejemplo:
typedef int entero;
typedef char character;
typedef float real;
A partir de ese momento los tipos nuevos: entero, caracter y real, sustituyen a
los predefinidos por el lenguaje.
TIPO ENUMERADO
Aparte de los valores bsicos en C se pueden definir y utilizar nuevos
valores simblicos de la manera que se indica a continuacin.
El tipo enumerado se define detrs de la palabra clave enum mediante un
identificador de tipo y a continuacin se detalla la lista con los valores
separados por comas (,), y encerrados entre llaves {}. Cada posible valor
se describe mediante una identificacin. Estos identificadores al mismo
tiempo quedan declarados como valores constantes.
typedef enum Identificador de tipo nuevo { identificador1, identificador2, identificador (N-1)};
Por ejemplo:
typedef enum TipoDia {
Lunes, Martes, Miercoles, Jueves,
Viernes, Sabado, Domingo
};
typedef enum TipoMes {
Enero, Febrero, Marzo, Abril, Mayo, Junio, Julio
Agosto, Septiembre, Octubre, Noviembre, Diciembre
};
74
TipoEnumerado (N)
Por ejemplo:
TipoOrientacion(3) == Este
TipoMes (3) == Abril
Operador C
&&
||
!
b
true
false
true
false
a && b
true
false
false
false
a||b
true
true
true
false
!a
false
false
true
true
El tipo booleano, como cualquier otro tipo enumerado, se puede pasar como
argumento de un procedimiento o funcin y puede ser devuelto como
resultado de una funcin. Las funciones cuyo resultado es un valor booleano
se denominan predicados.
TIPOS ESTRUCTURADOS
Un tipo estructurado de datos o estructura de datos, es un tipo cuyos valores
se construyen agrupando datos de otros tipos ms sencillos. Los elementos de
informacin se integran un valor estructurado se denominan componentes. A
continuacin veremos una primera aproximacin a estos tipos estructurados
formacin (vector) y tupla.
TIPO VECTOR
Un vector (Fig. 15) est constituido por una serie de valores, todos ellos del
mismo tipo, a los que un nombre comn que identifica a toda la estructura
globalmente.
Nombre comn
ndice
Elementos
V0
V0
V0
Vector
n-3
n-2
n-1
Vn-3
Vn-2
Vn-1
77
Declaracin de vectores
La estructura de tipo vector se declara de la siguiente forma:
typedef TipoElemento TipoVector[NumeroElementos]
TipoVector es el nombre del nuevo tipo vector que se declara y
NumeroElementos es un valor constante que indica el nmero de elementos
que constituyen un vector. TipoElemento corresponde al tipo de dato de cada
uno de los elementos del vector y puede ser cualquier tipo de dato
predefinido del lenguaje o definido por el programador. Los siguientes
ejemplos utilizan tipos predefinidos y algunos tipos definidos por
enumeracin:
typedef enum TipoDia {
Lunes, Martes, Miercoles, Jueves,
Viernes, Sabado, Domingo
};
typedef enum TipoColor { Rojo, Amarillo, Azul };
typedef float TipoMedidas[3];
typedef TipoColor TipoPaleta[5];
typedef char TipoCadena[30];
typedef TipoDia TipoAgenda[7];
typedef bool TipoEstados[8];
typedef int TipoVector[10];
En ocasiones el tamao de un vector es un parmetro del programa que
podra tener que cambiarse al adaptarlo a las nuevas necesidades. Por
ejemplo, estas constantes podran haber sido declaradas previamente de la
siguiente forma:
78
const int
const int
const int
const int
NumeroEstados = 8;
LongitudAgenda = 7;
NumeroLetras = 30;
NumeroElementos = 10;
Inicializacin de un vector
Para inicializar un vector hay que hacerlo en todos los elementos, para ello la
notacin es algo especial y en ella se indica el valor inicial de todos los
elementos agrupndolos entre llaves {} y separndolas con comas (,). A
continuacin se declaran algunas de las variables anteriores nuevamente
incluyendo su inicializacin.
TipoAgenda agendaUno = {
Lunes, Viernes, Domingo, Martes,
Martes, Martes, Sabado,
};
TipoEstados estadoMotor = {
true, false, true, true, false,
false, false,true
};
TipoVector vectorUno = { 12, 7, 34. -5, 0, 0, 4, 23, 9, 11 };
TipoVector miVector = { 1, 1, 1. 1, 1, 0, 0, 0, 0, 0 };
79
80
81
EscribirVector( vectorDos );
PintarEstado( estadoPanel );
Las variables vectorDos y estadoPanel permanecern inalteradas despus de
ejecutar en correspondiente procedimiento, es decir es como si hubiramos
pasado este argumento por valor.
asignar una cadena con los diecinueve, veinte o treinta caracteres. Los
caracteres asignados ocupan posiciones seguidas desde el principio y al final
e coloca el carcter especial nulo '\0' que no se puede escribir. lo que nunca
se puede hacer es asignar ms caracteres de los declarados.
En C se dispone de una librera de cabecera <string.h> que facilita el
manejo de caracteres, la librera incluye una variedad de funciones y de ellas
las ms comunes son las siguientes:
strcpy( c1, c2 )
strcat( c1, c2 )
strlen( c1 )
strcmp( c1, c2 )
Copia c2 en c1
Concatena c2 a continuacin de c1
Devuelve la longitud de c1
Devuelve en resultado cero si c1 y c2
son iguales, menor que cero si c1
precede a c2 en orden alfabtico, y
mayor que cero si c2 precede a c1 en
orden alfabtico.
Produce el resultado:
83
TIPO TUPLA
Otra forma de construir un dato estructurado es agrupar elementos de
informacin usando el esquema tupla o agregado. En este esquema, el dato
estructurado est formado por una coleccin de componentes, cada uno de los
cuales puede ser de un tipo diferente. Por ejemplo, una fecha es un conjunto
formado por los elementos da, mes y ao. Un punto en un plano cartesiano
se describe mediante dos nmeros que son sus coordenadas. El nombre
completo de una persona es la coleccin formada por si nombre de pila y sus
dos apellidos.
As podemos definir:
Tupla: Coleccin de elementos componentes, de diferentes tipos, cada uno de
los cuales se identifica por un nombre.
84
Tipo-campo-N nombre-campo-N;
};
Cada una de las parejas Tipo-campo y nombre-campo, separadas de punto y
coma (;), define un campo o elemento componente y su correspondeinte tipo.
Adems hay que tener en cuenta que la estructura acaba siempre con punto y
coma (;). Por ejemplo:
typedef enum TipoMes {
Enero, Febrero, Marzo, Abril, Mayo,
Junio, Julio, Agosto, Septiembre,
Octubre, Noviembre, Diciembre
};
typedef struct TipoFecha {
int dia;
TipoMes mes;
int anno;
};
typedef struct TipoPunto {
float x;
float y;
};
Para declarar variables de tipo registro es necesario haber realizado
previamente la definicin del tipo de registro, para a continuacin declarar las
variables:
TipoFecha ayer, hoy;
TipoPunto punto1, punto2;
Estas variables se pueden inicializar en la declaracin de uan manera
semejante a las formaciones agrupando los valores iniciales entre llaves {}
y separndolas por una coma (,), por ejemplo:
85
86
87
Fig. 16 Repeticin
88
do {
Operacin
Sentencia CONTINUE
La sentencia continue dentro de cualquier clase de bucle (while, for o do)
finaliza la iteracin en curso e inicia la siguiente iteracin. En ocasiones no
tiene sentido terminar la iteracin que se est realizando y resulta ms
adecuadoiniciar una nueva. Esto puede suceder cuando alguno de los datos
suministrados para realizar los clculos es errneo y puede dar una operacin
imposible (dividir por cero, raz de un nmero negativo, etc.). Por ejemplo
supongamos que tenemos un vector con N coeficientes por los que hay que
dividir al realizar un clculo salvo obviamente cuando uno de los coeficientes
sea cero. Esto se evitara de la siguiente manera:
for ( int i = 0; i < N; i++) {
if ( vectorCoeficientes[i] == 0) {
continue;
}
89
91
92
Repeticin
La sentencia do se puede transformar en while forzando la ejecucin
incondicional de la primera iteracin. La estructura:
do {
Sentencias;
while (Condicin);
}
93
ESTRUCTURA DE DATOS
ARGUMENTOS DE TIPO VECTOR ABIERTO
Si un subprograma debe operar con un vector recibido como argumento,
necesita toda la informacin del tipo de dicho vector, es decir, el tipo y
nmero de sus elementos, por ejemplo en este fragmento de cdigo:
const int NumeroElementos = 10;
typedef int TipoVector[NumeroElementos];
void EscribirVector( const TipoVector v ) {}
TipoVector vectorUno, vector Dos;
EscribirVector ( vectorDos );
El cdigo EscribirVector puede redactarse con seguridad ya que se conoce
toda la informacin de tipo de argumento:
void EscribirVector( const TipoVector v ) {
for (int i = 0; i < NumeroElementos; i++) {
printf( "%10d", v[i] );
}
printf( "\n" );
}
Si ahora tenemos que trabajar con vectores de otro tamao, tenemos que
definir un nuevo tipo y, lamentablemente otro nuevo procedimiento de
escritura:
const int NumeroElementos = 100;
typedef int TipoVector[NumeroElementosLargo];
void EscribirVectorLargo( const TipoVectorLargo v ) {
for (int i = 0; i < NumeroElementosLargo; i++) {
printf( "%10d", v[i] );
}
printf( "\n" );
}
94
95
97
EL TIPO UNIN
Hay aplicaciones en las que resulta deseable que el tipo de un dato vare
segn las circunstancias Si las posibilidades de variacin son un conjunto
finito de tipos, entonces se pueden decir que el tipo de dato corresponde a un
esquema unin de los tipos particulares posibles. Cada uno de os tipos
particulares constituyen una variante o alternativa del tipo unin.
Las situaciones tpicas que se pueden aplicar los esquemas unin tenemos,
entre otras, las siguientes:
Por ejemplo un programa que opere con nmeros de distintas clases (entero,
fraccin, real) o dos sistemas de coordenadas (cartesianas o polares).
En C se define un tipo unin como una coleccin de campos alternativos,
de tal manera que cada dato particular solo usar uno de esos campos en un
momento dado, dependiendo de la alternativa aplicable. La definicin es
similar a la de un agregado o struct, usando ahora las palabras clave unin.
typedef struct TipoFraccin {
int numerador;
int denominador;
};
typedef union TipoNumero {
int valorEntero;
float valorReal;
TipoFranccion valorRacional;
};
La referencia a los elementos componentes se hace tambin como en los tipos
struct:
98
99
case Real:
printf( "%d" , n.valor.valorReal );
break
case Fraccin:
printf( "%d" , n.valor.valorRacional.numerador,
n.valor.valorRacional.denominador );
break
default
printf( "????" );
}
ESTRUCTURAS COMBINADAS
Como cualquier lenguaje de programacin actual se pueden combinar las
estructuras tupla, unin y formacin para definir estructuras de datos
complejas, exactamente como se combinan la secuencia, seleccin e iteracin
para construir el cdigo de acciones complejas.
Con las estructuras de datos se pueden definir estructuras cuyas componentes
son a su vez estructuras, sin lmite de complejidad de los esquemas de datos
resultantes.
100
Formas de combinacin
La manera de combinar las estructuras de datos es hacer que los elementos de
una estructura sean a su vez otras estructuras, sin limitacin en la
profundidad del anidamiento.
Tablas
En el esquema tabla, la estructura de datos puede plantearse como una
formacin simple de registros. En otros contextos se le da tambin el nombre
de diccionario o relacin. Los esquemas tabla son el fundamento de las bases
de datos relacionales.
101
iniciar operacin
for (int i = 0; i<N; i++) {
tartar v[i]
}
completar operacin
Por ejemplo esta funcin calcula la sume de los elementos de un vector
abierto de nmeros reales:
102
Recorrido de matrices
Si la formacin es de tipo matriz se necesitan, para hacer el recorrido, tantos
for anidados como dimensiones tenga la formacin. El recorrido tpico es
cuando se quieren inicializar todos los elementos de la matriz. El siguiente
fragmento de cdigo inicializa todos los elementos de una matriz z de
nmeros enteros:
cont int N = ;
typedef int T_Matriz[N][N];
t_Matriz z;
103
Recorrido no lineal
En los ejemplos anteriores el ndice usado para controlar el bucle nos
sealaba directamente al elemento de procesar en cada iteracin. En ciertos
casos el elemento a procesar debe elegirse realizando ciertos clculos, y el
contador de iteraciones sirve fundamentalmente para contabilizar el avance
del recorrido y detectar el final del bucle.
fil = 0;
col = N/2;
for (int k = 1; k <= N*N; k++) {
cuadro[fil][col] = k;
fil = (fil+N-1) % N;
col = (col+1) % N;
if (cuadro[fil][col] ! = 0) {
fil = (fil+2) % N;
col = (col+N-1) % N;
}
}
BSQUEDA SECUENCIAL
En las operaciones de bsqueda secuencial se examinan uno a uno los
elementos de la coleccin para tratar de localizar los que cumplen una
determinada condicin. Si lo que queremos es encontrar todos los que
existan, estamos ante un recorrido como los mostrados en la seccin anterior.
Como ejemplo, si queremos determinar el nmero de Apariciones de un
cierto elemento buscado dentro de un vector v podemos utilizar el programa
de recorrido siguiente:
typedef T_Elemento ;
int Apariciones( T_Elemento buscado, cont T_Elemento v[], int N ) {
int veces = 0;
for (int i = 0; i < N; i++) {
if (v[i] == buscado) {
105
veces++;
}
}
return veces;
}
Si no queremos localizar todos los elementos que cumplen la condicin sino
solo uno de ellos, si lo hay, entonces no necesitamos recorrer la coleccin en
su totalidad. El recorrido se debe detener en cuanto se encuentre el elemento
buscado dentro de la coleccin. Ahora se utiliza:
iniciar operacin
while (quedan elementos sin tratar y no se ha encontrado ninguno aceptable) {
elegir uno de ellos y ver si es aceptable
}
completar operacin
INSERCIN
El problema que se plantea es insertar un nuevo elemento en una coleccin
de elementos ordenados, manteniendo el orden de la coleccin. Se supone
que los elementos estn almacenados en un vector, ocupando posiciones
desde el principio, y que queda algo de espacio libre al final del vector, (si el
vector estuviera lleno no se podran insertar nuevos elementos).
106
tipedef T_Elemento ;
void Ordenar( T_Elemento v[ ], int N) {
T_Elemento valor;
int j;
for (int i = 1; i<N; i++) {
valor = v[i];
j = I;
while (j > 0 && valor < v[j-1]) {
v[j] = v[j-1];
j--;
}
109
v[j] = valor;
}
}
Tcnica centinela
En el procedimiento de bsqueda es necesario comprobar en cada iteracin
una condicin doble: si no se ha alcanzado todava el final del vector, y si se
encuentra el elemento buscado. Esta doble condicin complica el cdigo y
supone un tiempo adicional de bsqueda. Si garantizamos que el dato
buscado est dentro de la zona de bsqueda, antes o despus se terminar
encontrndolo, y no ser necesario comprobar explcitamente si se alcanza el
final del vector.
112
tipedef T_Elemento ;
void Ordenar( T_Elemento v[ ], int N) {
T_Elemento valor;
int j;
for (int i = 1; i<N; i++) {
valor = v[i];
/*-- Buscar la nueva posicin del elemento, sin mover nada --*/
j = 0;
while (valor < v[j]) {
j--;
/*-- Mover elementos mayores y poner el elemento en su sitio --*/
for (int k = i-1; k>=j; k--) {
v[k+1] = v[k];
}
v[j] = v[k];
}
}
Matrices orladas
113
114
imagen[i][j] = Borde;
fin = false
}
}
}
Esta forma de operar se denomina fuerza bruta, y puede ser poco eficiente
pero es muy sencilla de programar.
116
LA ESTRUCTURA SECUENCIA
Las estructura secuencia pueden definirse como un esquema de datos del tipo
interactivo, pero con un nmero variable de componentes. La estructura
secuencia resulta parecida a una formacin con nmero variable de
elementos.
Existe en realidad diferentes esquemas secuenciales de datos, para describir
las distintas alternativas distinguiremos entre operaciones de construccin y
acceso, con las primeras podemos aadir o modificar el valor de las
componentes de la secuencia. Con las segundas podemos obtener o modificar
el valor de las componentes que existen en un momento dado.
Las operaciones de construccin pueden incluir:
118
VARIABLES DINMICAS
Una manera de realizar estructuras de datos ilimitadas es mediante el empleo
de variables dinmicas. Una variable dinmica nos e declara como tal, sino
que se crea en el momento necesario, y se destruye cuando ya no se necesita.
Las variables dinmicas no tienen nombre, sino que se designan mediante
otras variables llamadas punteros o referencias.
Punteros
Un puntero o referencias en C son variables simples cuyo contenido es
precisamente una referencia a otra variable. El valor del puntero no es
representable como nmero o texto. En su lugar usaremos usa representacin
grfica que utilizaremos una flecha para enlazar una variable de tipo puntero
con la variable que hace referencia:
119
*pe = 33;
printf( "%d", *pe );
Estas sentencias asignan el valor 33 a la variable dinmica sealada por el
puntero pe, y luego la imprimen. Para que las sentencias funcionen
correctamente es necesario que exista reamente la variable apuntada. Si el
puntero no seala realmente a la variable dinmica, el resultado de usar
*puntero ser imprevisible.
Para poder detectar si un puntero seala realmente o no a otra variable, existe
el valor especial NULL. Este valor debe ser asignado a cualquier puntero que
no seala a nadie, y normalmente se usar para inicializar lso punteros al
comienzo del programa. Por ejemplo:
if (pe != NULL) {
*pe = 33;
printf( "%d", *pe );
}
120
Las variables dinmicas, una vez creadas, siguen existiendo hasta que se
indique explcitamente que ya no son necesarias, en cuyo caso el espacio que
se haba reservado para ellas quedar otra vez disponible para crear nuevas
variables. Pare ello existe la sentencia delete, que permite destruri la variable
dinmica a la que seala el puntero:
delete puntero;
Una variable dinmica puede estar referenciada a ms de un puntero. Esto
ocurre cuando se copia un puntero en otro. Por ejemplo:
typedef int* Tp_Entero;
Tp_Entero p1, p2;
p1 = new int;
p2 = p1;
Grficamente ocurre lo siguiente:
121
En este caso la variable creada p2 = new int; queda perdida, sin posibilidad
de ser usada, esto puede generar una prdida de capacidad de memoria en la
ejecucin del programa (memory leak), ya que la variable dinmica sigue
ocupando un espacio pero ya no est sealada por ningn puntero.
122
123
124
125
126
Igual que antes se ha marcado don una lnea discontinua los enlaces
modificados por las operaciones de borrado. Adems, el elemento borrado
aparece con un fondo diferente. Para hacer el cdigo ms robusto se ha
forzado el cursor a valor nulo, ya que de no hacerlo as quedara apuntando a
un lugar que ya no existe (marcado con X en la figura). El cdigo ser:
TipoPuntNodo cursor, anterior;
anterior->siguiente = cursor->siguiente;
delete cursor;
cursor = NULL;
127
128
129
Tp_Entero p1;
p1 = new int;
Imprimir( p1 );
Incrementar( p1 );
130
131
133
TipoPunto p, q;
p.x = 3.3;
p.y = 4.4;
p.Leer();
p.Escribir():
printf( %f, p.Distancia( q ) );
Como complemento de la declaracin de la interfaz se necesita adems
definir la implementacin de las operaciones. Esta implementacin se hace
fuera de la declaracin del tipo registro, usando la notacin Tipo:: Operacin
como nombre de subprograma. El cdigo de la implementacin sera:
#include <stdio.h>
#include <math.h>
/* Excepcin en lectura */
type enum TipoPuntoError { PuntoNoLeido };
/** Leer un punto con formato (x,y) */
void TipoPunto: :Leer() {
int campos;
campos = scanf( ( %f , %f ), &x, &y );
if ( campos < 2) { /* comprobar que se ha ledo dos valores */
throw PuntoNoLeido;
}
}
134
Una vez definido el cdigo abstracto se puede escribir el cdigo que lo use:
#include <stdio.h>
/* Definicin del tipo abstracto PUNTO*/
/* aqu se incluye el cdigo anterior */
/** Programa principal */
int main() {
TipoPunto a, b;
bool seguir = true;
while (seguir) {
try {
a.Leer();
b.Leer();
printf( Segmento: );
a.Escribir();
printf( )
b.Escribir();
printf( Logitud: %f\n, a.Distancia( b ) );
} catch (TipoPuntoError e) {
seguir = false;
}
}
}
Ocultacin
Para que un tipo sea realmente abstracto hara falta que los detalles de
implementacin no fueran visibles. Los subprogramas, como mecanismo de
abstraccin, ya ocultan de talles de la realizacin de operaciones. Sin
embargo queda la cuestin de como ocultar la manera de representar los
valores del tipo abstracto.
Por ejemplo si se almacena el valor de una fecha como un tupla numrica
(da, mes, ao) no se puede admitir cualquier combinacin de valores. La
fecha (26, 2, 1961) es correcta, pero (2, 26, 1961) no lo es, y menos an (45, 5, 5210). si se quiere definir el tipo fecha como tipo abstracto ser necesario
ocultar los detalles de la representacin interna de los valores, de manera que
slo se puedan construir fechas usando operaciones que garanticen la
correccin de los valores del tipo.
Para permitir la ocultacin los tipos struct admiten l posibilidad de declarar
ciertos elementos componentes como privados, usando la palabra clave
private para delimitar una zona de declaraciones privadas dentro de la
estructura. La interfaz de TipoFecha podra ser:
typedef struct TipoFecha {
/* Dar valor a un dato fecha */
void Poner( int dia, int mes, int anno );
/* Obtener el contenido de un dato fecha */
int Dia();
int Mes();
int Anno();
private:
int dia, mes, anno;
};
136
137
138
MDULOS
CONCEPTO DE MODULO
En programacin un mdulo es, en general, un fragmento de programa
utilizado en algn momento en la ejecucin de un programa. Lo que
distingue un fragmento arbitrario del programa es que ese fragmento haya
sido reconocido como tal. As pues podemos definir:
Mdulo. Fragmento de programa desarrollado de forma independiente.
Este desarrollo independiente debe ser serlo en el mximo grado posible.
Atendiendo a las tcnicas de preparacin de programas en lenguajes de
programacin simblicos, diremos que un mdulo debera ser compilado y
probado por separado, y no tratarse de un simple fragmento de texto dentro
de un nico programa fuente.
La necesidad de copilar por separado los distintos mdulos obedece a
criterios de limitar la complejidad de lo que se est elaborando por un
programador. El concepto de mdulo est ligado a la idea de abstraccin. Un
mdulo debe definir un elemento abstracto(o varios relacionados entre s) y
debe ser usado desde fuera con slo saber qu hace el mdulo, pero sin
necesidad de conocer cmo lo hace.
Como todo elemento abstracto, en un mdulo deberemos distinguir los dos
puntos de vista, correspondientes a su especificacin y a su realizacin, es
decir que hace y como lo hace.
La realizacin del mdulo consistir en la realizacin de cada uno de los
elementos abstractos contenidos en dicho mdulo.
La especificacin de un mdulo es todo lo que se necesita para poder usar los
elementos definidos en l. Esta especificacin constituye la interfaz (en
ingls interface) entre el mdulo (incluida su realizacin) y el programa que
lo usa. Referida a los mdulos, la ocultacin consiste en que el programa que
usa un elemento de un mdulo slo tiene visible la informacin de la interfaz,
pero no su realizacin.
139
Compilacin separada
Los lenguajes de programacin que permiten programar usando mdulos
pueden emplear diversas tcnicas para definirlos e invocar los elementos
definidos en ellos. Para ellos es importante que stos puedan compilarse por
separado. Por otra parte, para que el uso de los elementos de un mdulo sea
correcto, habr que hacerlo de acuerdo con la interfaz establecida. La interfaz
debe ser tenida en cuenta al compilar un programa que use elementos de un
mdulo separado.
140
(a)
(b)
(c)
(d)
No hay compilacin
segura
Compilacin ms
segura pero con
posibilidad de
errores
Compilacin
completamente
segura
Descomposicin modular
La posibilidad de compilar mdulos de forma separada permite repartir el
trabajo de desarrollo de un programa, a base de realizar su descomposicin
modular. Los diferentes mdulos pueden ser encargados a programadores
distintos y as pueden trabajar al mismo tiempo.
La descomposicin modular de un programa puede reflejarse en un diagrama
de estructura, tal como el de la Fig. 36. En este diagrama se representa cada
mdulo como un rectngulo, con el nombre del mdulo en su interior, y se
usan lnias para indicar las relaciones de uso entre ellos.
141
MDULOS EN C
Un programa descompuesto en mdulos se escribe como un conjunto de
ficheros fuente relacionados entre s, y que pueden compilarse por separado.
Cada fichero fuete constituye as una unidad de compilacin.
142
Mdulo principal
Cuando se descompone un programa C en varios mdulos uno de ellos ha
de ser el programa principal o mdulo principal. Este mdulo ser el que
contenga la funcin main(). La ejecucin del programa completo equivale a
la ejecucin de dicha funcin principal.
Mdulos no principales
Los mdulos de la aplicacin que no contienen un funcin main() no
permiten generar un programa ejecutable por si solos. Al escribir el cdigo de
estos mdulos no principales hay que distinguir claramente entre los
elementos pblicos, que deben ser visibles desde fuera del mdulo para poder
usarlos, y los elementos privados, que no necesitan ser visibles en el interior
del mdulo. la distincin de estos dos elementos pblicos y privados, se hace
repartiendo el cdigo del mdulo en dos ficheros fuente separados: un fichero
interfaz o cabecera y fichero de implementacin.
143
144
Uso de mdulos
Para usar los elementos pblicos definidos en un mdulo hay que incluir la
interfaz de ese mdulo donde se vaya a utilizar. Esto se consigue con la
directiva #include poniendo el nombre del fichero entre comillas "" y no
entre ngulos <> como las libreras, esto indica que el compilador buscara
el fichero en donde reside el cdigo fuente de la aplicacin, y no donde est
instalada la herramienta de compilacin. Por ejemplo:
/************************************************************
* Programa: Serie
* Este programa imprime la serie de nmeros
* del 1 al 20 en varias columnas
************************************************************/
145
#include "Tabulacion.h"
int main() {
Iniciar( "-- Columnas por defecto --" );
for (int k = 1; k <= 20; k++) {
imprimir(k)
}
Terminar();
numColumnas = 3;
anchoColumna = 13;
iniciar( "-- 3 columnas de 13 caracteres --" );
for (int k = 1; k <= 20; k++) {
imprimir(k)
}
Terminar();
numColumnas = 6;
anchoColumna = 5;
iniciar( "-- 6 columnas de 5 caracteres --" );
for (int k = 1; k <= 20; k++) {
imprimir(k)
}
Terminar();
}
El resultado es:
-- Columnas por defecto
1
5
9
13
17
2
6
10
14
18
3
7
11
15
19
4
8
12
16
20
146
-- 3 columnas de 13 caracteres
1
4
7
10
13
16
19
2
5
8
11
14
17
20
3
6
9
12
15
18
-- 6 columnas de 5 caracteres
1
7
13
19
2
8
14
20
3
9
15
4
10
16
5
11
17
6
12
18
147
Declaracin (fichero.h)
typedef TipoNuevo ;
const Tipo constante = valor;
extern Tipo variable;
Tipo Subprograma(argumentos);
Definicin (fichero.cpp)
(no aplicable)
(no aplicable)
Tipo variable = valor;
Tipo Subprograma(argumentos) {
cdigo
}
148
Unidades de compilacin en C
Por lo tanto tenemos como unidades de compilacin:
149
150
151
Datos encapsulados
Al definir un tipo abstracto de datos hay que declarar luego variables de ese
tipo para trabajar con ellas. En algunos casos concretos resulta solo necesaria
una nica variable del tipo abstracto. Si es as, existe la posibilidad de
encapsular dicha variable en un mdulo y evitar la declaracin explcita del
tipo. La facilidad de ocultacin que provee la programacin modular es
suficiente para conseguir la abstraccin del dato, de forma que solo sean
visibles las operaciones que lo manipulan pero no los detalles de su
implementacin.
La siguiente tabla compara los esquemas generales de cdigo
correspondiente a la declaracin y uso de un tipo abstracto de datos y a un
dato encapsulado. En ambos casos se usa un mdulo separado para el
elemento abstracto:
Tipo abstracto
Dato encapsulado
Interfaz
}
void Tipo: :Operacion1() {
valorInterno
}
void Tipo: :Operacion2() {
valorInterno
}
void Operacion1();
void Operacion2();
Implementacin
static UnTipo valorInterno;
static void Operacin3() {
}
void Operacion1() {
valorInterno
}
void Operacion2() {
valorInterno
}
Uso
Tipo dato;
Operacio1();
Dato.Operacion1();
152
Reutilizacin de mdulos
Los expertos de desarrollo de software consideran que la descomposicin
modular basada en abstracciones es una buena metodologa para desarrollar
mdulos con bastantes posibilidades de reutilizarlos de nuevo en un futuro.
Los mdulos que definen abstracciones pueden agruparse en bibliotecas o
libreras (library) que se ponen a disposicin para desarrollar aplicaciones
en un campo determinado.
153