Anda di halaman 1dari 13

L.A.M.M.

- Uned Denia

Tema 6: Tipos de datos

ndice de contenidos

Ejercicio 6.3:...................................................................2
Ejercicio 6.4:................................................................................................................................2
Ejercicio 6.5:................................................................................................................................2
Ejercicio 6.6:................................................................................................................................3
Ejercicio 6.7:................................................................................................................................3
Ejercicio 6.9:................................................................................................................................3
Ejercicio 6.10:..............................................................................................................................4
Ejercicio 6.11:...............................................................................................................................4
Ejercicio 6.12:..............................................................................................................................4
Ejercicio 6.14:..............................................................................................................................5
Ejercicio 6.15:..............................................................................................................................5
Ejercicio 6.17:..............................................................................................................................6
Ejercicio 6.18:..............................................................................................................................6
Ejercicio 6.19:..............................................................................................................................6
Ejercicio 6.22:..............................................................................................................................7
Ejercicio 6.23:..............................................................................................................................7
Ejercicio 6.25:..............................................................................................................................7
Ejercicio 6.26:..............................................................................................................................7
Ejercicio 6.28:..............................................................................................................................8
Ejercicio 6.29:..............................................................................................................................8
Ejercicio 6.30:..............................................................................................................................9
Ejercicio 6.34:..............................................................................................................................9
Ejercicio 6.36:..............................................................................................................................9
Ejercicio 6.37:............................................................................................................................10
Ejercicio 6.38:............................................................................................................................10
Ejercicio 6.44:............................................................................................................................10
Ejercicio 6.46:.............................................................................................................................11
Ejercicio 6.49:.............................................................................................................................11
Ejercicio 6.51:............................................................................................................................12

1/13

L.A.M.M. - Uned Denia


Ejercicio 6.3:
El tipo de datos booleano puede o no tener una relacin de orden, y puede o no ser convertible a tipos
enteros, dependiendo del lenguaje. Compare el tratamiento del tipo booleano con respecto a estas dos
alternativas, en al menos dos lenguajes de los siguientes: Java, C++, Ada, ML.
Es til ordenar a los booleanos? Son convertibles a enteros?
Compararemos Java y C++.
En C++ los valores booleanos son convertibles implcitamente ha enteros y viceversa, y los punteros
en C tambin lo son utilizando la convencin de que los valores cuyo valor sea distinto de cero se
convierte en true y los que sean cero en false.
Puesto que en C++ los valores booleanos se convierten automticamente en enteros, todas las
operaciones con los enteros, incluyendo la comparacin, se pueden aplicar a los tipos booleanos.
La comparacin false < true es correcta puesto que false representa el 0 y true representa un 1.
En Java esto no es cierto. Los tipos enteros y los punteros son convertibles a booleanos, pero no a
la inversa. En java no se pueden convertir los booleanos a ningn otro tipo de datos y por tanto, las
operaciones de comparacin entre booleanos en Java no pueden aplicarse.
Uno puede intentar construir un caso en el que la relacin de orden de las expresiones booleanas
tenga sentido. Por ejemplo: if ((x<=y)<(x<=z)) x=y else x=z
Es equivalente al a: if ((x<=z)&&(x>y)) x=y else x=z
De echo, a<b es equivalente b and not a, y a<=b es equivalente a b or not a. Eso es probablemente
en lugar de ayuda, ocasiona confusin.
Por otro lado, la conversin de booleanos a enteros en C++ es esencial para la compatibilidad con C,
puesto que C no tiene el tipo de datos booleano.

Ejercicio 6.4:
Dadas las declaraciones en C:
Struct
{ int i;
Double j;
} x, y;
Struct
{ int i;
Double j;
} z;
La asignacin x=z genera un error de compilacin, pero la asignacin x=y no lo hace. Por qu?
Proponga dos formas diferentes de arreglar el cdigo anterior de manera que x=z funcione. Cul es la
mejor manera y por qu?
La razn es porque x e y tienen el mismo tipo, puesto que estn definidas en la misma declaracin.
La variable z es de un tipo diferente, puesto que est declarada en una declaracin struct separada.
Una forma de solucionar el problema es aadir z a la definicin de x e y, esto es:
Struct
{ Int i;
Double j;
} x, y, z;
Esta no es una buena solucin, puesto que el tipo de datos de x, y y z son annimos.
Una forma mejor es dar al tipo de datos struct un nombre y despus definir las variables x, y y z
como variables de dicho tipo.
Struct S
{ Int i;
Double j;
};
Struct S x, y, z;

Ejercicio 6.5:
Suponga que tenemos dos arreglos en C:
Int x [10];
Int y [10];

2/13

L.A.M.M. - Uned Denia


Por qu no se compila la asignacin x=y en C? Pueden arreglarse las declaraciones de manera que
funcione la asignacin?
La asignacin no compilar porque C trata los arreglos como punteros, los cuales son constantes y no
pueden ser reasignados.
Hay diversas formas de modificar la declaracin para que funcione. Quizs la ms simple sea:
Int*x;
Inty[10];
...
x=y;/*ahorasquefunciona*/
x[2]=17;/*formacorrectadeusarxcomounarreglo*/

En esta versin, x se convierte en un alias de y (por lo menos hasta que x sea reasignada)

Ejercicio 6.6:
Dadas las siguientes declaraciones de variables en C/C++:
enum {one} x;
enum {two} y;
La asignacin x=y es correcta en C, pero genera un error de compilacin en C++. Explique las razones.
El motivo es que las declaraciones enum no son constructores de tipos realmente en C, pero son
atajos de definiciones de subrangos de enteros.
En C++ enum es un constructor de tipo de datos, por lo que diferentes definiciones de enum crean
diferentes tipos, al igual que diferentes struct crean diferentes tipos.

Ejercicio 6.7:
Dadas las siguientes declaraciones de variables de funcin en C/C++:
Int (*f) (int);
Int (*g) (int);
Int (*h) (char);
La asignacin f=g es correcta en C y C++, pero la asignacin h=g genera una advertencia del compilador
en C y en C++ un error de compilacin. Explique las razones.
Tanto C como C++ usan la equivalencia estructural para tipos de funciones, por eso, la asignacin f=g
o g=f es correcta, ya que los tipos son estructuralmente idnticos.
Por otro lado, h tiene un tipo diferente (char) en su parmetro, y por ello no existe equivalencia de
tipo.
As, la asignacin h=g genera una advertencia de incompatibilidad en C, y un error en C++ puesto
que ste es ms estricto en las conversiones de tipos.
De hecho, esta asignacin puede o no funcionar, dependiendo del entorno de ejecucin.
Los caracteres pueden verse como enteros, pero pueden tener diferente tamao, y esto ocasionara
un error.

Ejercicio 6.9:
Considere la ecuacin de conjunto: x char =
(a) Demuestre que cualquier conjunto que satisfaga a esta ecuacin debe ser infinito.
(b) Demuestre que cualquier elemento de un conjunto que satisfaga a esta ecuacin debe contener un
nmero infinito de caracteres.
(c) Existe una solucin que sea la ms pequea a esta ecuacin?
Supongamos que es finito y que contiene n elementos.
Entonces la expresin x char es tambin finita y tiene ms elementos de los que tiene (si char
tiene 128 elementos, entonces x char tiene n veces 128 elementos)
Pero esto contradice la expresin x char = . Por tanto debe ser infinito.
Considere un elemento x del conjunto , y suponga que satisface la ecuacin = x char. Entonces
x=(x', c) para algn x' en y algn carcter c. Ahora podemos expresar lo mismo para x': x'=(x'', c'),
donde x'' es un elemento de . Si continuamos con este proceso, llegamos a un nmero infinito de
caracteres, los cuales deben formar parte de x.

3/13

L.A.M.M. - Uned Denia

Considere el producto cartesiano infinito. P=char x char x char x


El valor P consiste en todas las tuplas con valor (c1, c2, c3, ) donde cada C es un carcter. Esto
satisface la ecuacin, puesto que P x char se obtiene en el valor ((c1, c2, c3, ),c0) que es lo mismo
que (c0, c1, c2, c3, ), y que es igual que P mismo.

Ejercicio 6.10:
Considere la siguiente declaracin en sintaxis C:
Struct CharTree
{ char data;
Struct CharTree left, right;
};
(a) Vuelva a escribir CharTree como una unin similar a la declaracin unin CharList de la seccin 6.3.5
(b) Escriba una ecuacin de conjunto recursiva para la declaracin que hizo en el apartado (a).
(c) Describa un conjunto que sea la solucin ms pequea posible a la ecuacin que encontr en el
apartado (b).
(d) Demuestre que el conjunto que form en el apartado (c) es la solucin ms pequea posible.
(e) Vuelva a escribir todo esto como una declaracin vlida de C.

Ejercicio 6.11:
A continuacin se dan unas declaraciones en C:
Typedef struct Rec1 * Ptr1;
Typedef struct Rec2 * Ptr2;
Struct Rec1
{ int data;
Ptr2 next;
};
Struct Rec2
{ double data;
Ptr2 next;
};
Deben permitirse? Estn permitidas? Por qu S o por qu no?
Estas declaraciones de tipos son todas legales en C. Su equivalencia en Ada tambin es legal:
typeRec1;
typeRec2;
typePtr1isaccessRec1;
typePtr2isaccessRec2;
typeRec1isrecord
data:Integer;
next:Ptr2;
endrecord;
typeRec2isrecord
data:Integer;
next:Ptr1;
endrecord;
De hecho, en un tipo de nombre que se utiliza indirectamente en Ada, se puede declarar en cualquier
punto despus de su mismo alcance.
En C tampoco existen requerimientos para las estructuras de datos declaradas con anterioridad a su
uso indirecto.

Ejercicio 6.12:
(a) Cual es la diferencia en Ada entre un subtipo y tipo derivado?
(b) En Ada a qu declaracin de tipo en C es equivalente la siguiente declaracin?
Subtype New_Int Is integer;
(c) Y la siguiente declaracin?
Type New_int is new integer;
Un subtipo en Ada no es un nuevo tipo, sino que se considera siempre como parte de su tipo base.

4/13

L.A.M.M. - Uned Denia


Un subtipo es una indicacin al compilador para realizar una serie de verificaciones en sus valores
durante la ejecucin.
Por el contrario, un tipo derivado es totalmente un nuevo tipo y es incompatible con su tipo base y
otros tipos que no tengan conversin explcita.
La declaracin en Ada establece al nombre New_int un alias para designar enteros puesto que no
hay un rango especfico.
Una instruccin typedef hace lo mismo en C: typedef int New_int; sera equivalente a la declaracin
de Ada.
La declaracin en Ada crea un nuevo tipo llamado New_int, el cual no se puede implementar en C
mediante una simple reutilizacin. As, no existe una declaracin totalmente equivalente a la
declaracin de Ada. Es posible imitarla utilizando un constructor como:
typedef struct {int i;} New_int;
Esto no es equivalente a la declaracin de Ada puesto que para acceder al valor de la variable x
deberemos escribir x.i.

Ejercicio 6.14:
Describa las reglas de correccin e inferencia de tipos en C para la expresin condicional: e1 ? e2 : e3.
Deben tener e2 y e3 el mismo tipo? Si son del mismo tipo, pueden tratarse de cualquier tipo?
Una regla de correccin para la expresin condicional en C requerira que e1 fuera del tipo int y que
e2 y e3 fueran de tipos equivalentes entre ellos; la inferencia de tipo de la expresin completa sera
del tipo de e2 y e3. Como siempre, las conversiones automticas con punteros y tipos numricos en
C complican seriamente la situacin. Aqu, por ejemplo, se usa la regla utilizada en Kernighan y
Ritchie [1988]:
Si el segundo y tercer operando son aritmticos, la conversin aritmtica normal produce que ambos
sean de un tipo comn, y que ste sea el tipo del resultado. Si ambos son void, o estructuras o
uniones del mismo tipo, o punteros a objetos del mismo tipo, el resultado tiene un tipo comn. Si uno
es un puntero y el otro una constante 0, el 0 se convierte en un puntero, y el resultado tiene este tipo.
Si uno es un puntero a void y el otro es otro puntero, el otro puntero se convierte en un puntero a
void, y ste es el tipo del resultado.

Ejercicio 6.15:
Suponga que usamos el cdigo de C++, que intenta evitar el uso de un static_cast para imprimir el valor
interno de true (vea el cdigo al final de la seccin 6.7).
Unin
{ int i;
Bool b;
} x;

x.b = true;
cout << x.i << endl;
El problema es que el valor bool ocupa normalmente un byte de memoria, pero un valor int ocupa 4.
Cuando, por ejemplo, realizamos la asignacin x.i = 20000, los 4 bytes de x aparecern ahora en
hexadecimal como 00004E20. Cuando asignamos x.b = true, los ltimos dos dgitos de ste valor
(20) son reemplazados por el valor interno de true (normalmente 1), y el resultado es 00004E01, o
19969 en decimal.
As, este cdigo imprimira 19969, y no 1 como cabra esperar. Por supuesto, si inicializamos primero
x.i a 0, se corregir este problema, por ello el siguiente cdigo sera ms correcto:
unin
{inti;
boolb;
}x;

x.i=0;
x.b=true;
cout<<x.i<<endl;

5/13

L.A.M.M. - Uned Denia


Ejercicio 6.17:
Este captulo no menciona el problema de la inicializacin de variables. Describa las reglas para la
inicializacin de variables en C, Ada, ML, o en algn otro lenguaje similar. En particular se inicializan todas
las variables de todos los tipos, cuando el programa comienza a ejecutarse? Si es as, cmo se construye
el valor inicial?
El problema principal al formular la inicializacin de requerimientos es encontrar valores distintos para
todos los tipos de datos para usarlos como valores iniciales. Para construir tipos como integer, real,
char o bolean no hay demasiada dificultad: 0, 0.0, null y false. Para arreglos esto puede extenderse
para inicializar cada componente con el valor inicial de su tipo, y para los registros igual.
Los punteros pueden inicializarse a null. Para definiciones de tipos enumerados, el primer valor
puede usarse como valor inicial (por ejemplo, rojo sera el valor inicial del tipo enum={rojo, verde,
azul}).
El problema ocurre con las uniones puesto que no se puede averiguar qu campos estn activos.
Un problema similar puede ocurrir con tipos especializados como set y file.
Un lenguaje de programacin puede permitir al programador especificar valores iniciales.
Normalmente esto se hace en la declaracin de variables, como en la declaracin de C int x=0;.
Ocurre un problema con los tipos estructurados, puesto que debemos inventar una sintaxis que nos
permita la asignacin de valores mltiples. C utiliza llaves para las estructuras y los arreglos.
intx[5]={0,1,2,3,4};
struct{inti;doubler;}y={0,1.2};
Tambin sera una buena idea el permitir a los usuarios especificar un valor inicial con cada
declaracin nueva de tipos, as esta inicializacin puede asumirse para cada variable de los tipos
creados a menos que venga implcita.
Un problema con esto es que dos tipos equivalentes deben tener la misma inicializacin, puesto que
los valores iniciales slo se pueden asociar a las declaraciones que crean nuevos tipos de acuerdo
con la equivalencia algortmica.
El mismo lenguaje de programacin debe especificar las inicializaciones para todos los tipos
predefinidos.

Ejercicio 6.18:
A continuacin, algunas declaraciones de tipo y variables en sintaxis de C:
Typedef char* Tabla1;
Typedef char* Tabla2;
Tabla1 x, y;
Tabla2 z;
Tabla2 w;
Diga qu variables son equivalentes en tipo, segn equivalencia estructural, equivalencia de nombre y
algoritmo de equivalencia actual de C. asegrese de identificar, a partir de la informacin suministrada,
aquellos casos que sean ambiguos.
Equivalencia estructural: X, Y, Z y W son equivalentes estructuralmente.
Equivalencia de nombre: X e Y son posiblemente equivalentes en nombre (con ambigedad, en Ada
no lo sera). Z y W tambin son equivalentes en nombre (sin ambigedad). De otra forma, ninguna de
las variables sera equivalente.
Puesto que C utiliza la estructura de equivalencia por punteros, todas las variables son equivalentes
bajo el punto de vista de C.

Ejercicio 6.19:
Dadas las declaraciones:
Int x[10];
Int y[5];
Son x e y equivalentes en C?

6/13

L.A.M.M. - Uned Denia


S: la comparacin x == y no genera ningn mensaje de advertencia o de error (pero devuelve siempre 0,
puesto que x e y son diferentes localizaciones asignadas en memoria). De hecho x e y se ven como tipos
equivalentes (constantes) del tipo "puntero a entero"; sus tamaos no forman parte de sus tipos.

Ejercicio 6.22:
A continuacin damos varias declaraciones de tipo y de variable sen sintaxis de C:
Typedef struct
{ int x;
Char y;
} Rec1;
Typedef Rec1 Rec2;
Typedef struct
{ int x;
Char y;
} Rec3;
Rec1 a, b;
Rec2 c;
Rec3 d;
Diga qu variables son equivalentes en tipo segn equivalencia estructural, equivalencia de nombres y,
algoritmo de equivalencia actual de C. asegrese de identificar a partir de la informacin suministrada,
aquellos casos que son ambiguos.
Equivalencia estructural:
Estructuralmente a, b, c y d son equivalentes.
Equivalencia de nombres:
a y b son equivalentes en nombre.
Algoritmo de equivalencia: Las variables a, b, y c son equivalentes en C, puesto que C utiliza
equivalencia de declaracin, y las definiciones de las tres variables se refieren a la misma
declaracin de struct (Rec1). La variable d no es equivalente a las otras, puesto que viene de
una declaracin struct diferente.

Ejercicio 6.23:
En C++, la prueba de igualdad == puede aplicarse a arreglos, pero prueba algo equivocado, y no es posible
en absoluto aplicar el operador de asignaciones = a operadores. Explique las razones.
Un arreglo en C es implcitamente un puntero que apunta a la primera posicin de memoria; en otras
palabras, si a es un arreglo, entonces a es lo mismo que &a[0]. Puesto que los arreglos son
localizados por el sistema (en la pila), un arreglo es tambin una constante, y no puede ser
reasignada. Por ello, la verificacin de igualdad en C verifica la igualdad de punteros y no la igualdad
de valores.
Adems, la asignacin no se puede usar, puesto que un arreglo es una direccin de una constante.

Ejercicio 6.25:
Segn las reglas de tipos descritas en este texto, el constructor de arreglos en C no construye un tipo
nuevo; esto es, a los arreglos se les aplica equivalencia estructural. Cmo escribira un cdigo para probar
esto? (sugerencia: Podemos emplear una prueba de igualdad? Existe alguna otra forma de probar la
compatibilidad?)
La verificacin de igualdad se puede utilizar, incluso si no lo hace correctamente: siempre devuelve
falso, puesto que verifica la identidad en memoria, es decir, igualdad de punteros. Pero en este
problema no nos preocupa el resultado, slo cuando se genera un mensaje del compilador.
intx[10];
inty[5];
charz[20];
if(x==y);/*verificacincorrecta*/
if(x==z);/*verificacinincorrecta*/
Por ejemplo, el compilador Gnu C genera la siguiente advertencia en la ltima lnea del cdigo
indicado: "comparacin de distintos tipos de punteros carece de modelo". As, C utiliza la equivalencia
estructural para los arreglos.
Observe que la asignacin no se puede utilizar para probar esto, puesto que la asignacin a una
variable arreglo es ilegal por otras razones.

7/13

L.A.M.M. - Uned Denia


Ejercicio 6.26:
Puede utilizarse una unin en C para convertir int en double y viceversa? long en float? Por qu s o
por qu no?
Normalmente hay problemas de alineacin entre enteros y doubles, puesto que normalmente son de
longitudes diferentes. Pero incluso sin estos problemas, una unin no puede utilizarse para dichas
conversiones, pues la representacin del bitwise no estn relacionadas, y las uniones no realizan ninguna
conversin en las configuraciones de bits al cambiar de una representacin a otra. Por ejemplo, considere el
programa en C:
#include <stdio.h>
union
{ long int x;
float y;
} u;
int main()
{ printf("%d\n%d\n",sizeof(u.x),sizeof(u.y));
u.x = 1;
printf("%g\n",u.y);
return 0;
}

Usando tambin el Gnu C, este programa produce la siguiente salida:


4
4
1.4013e-045

Note que no hay problemas de alineacin para esta arquitectura, puesto que tanto long como
float son de 4 bits. Sin embargo, el resultado en coma flotante es incorrecto.
Ejercicio 6.28:
Demuestre cmo concluye la verificacin de tipos Hindley-Mildner donde la siguiente funcin (en sintaxis
ML) toma un parmetro entero y devuelve un resultado entero (es decir, es del tipo int -> int en la
terminologa ML).
Fun factorial n = if n = 0 then 1 else n * factorial (n-1);
El rbol sintctico para esta definicin es el siguiente:

Definicin
Factorial
()

if
=

n 0
()

*
n

call

Factorial
()

Ahora, si realiza un recorrido de izquierda a derecha o de abajo arriba de este rbol, descubrir que =int
(de la comparacin de n con 0), y que =int (de la multiplicacin de n y el resultado de la llamada recursiva
a factorial).

Ejercicio 6.29:
A continuacin aparece la funcin en sintaxis de ML: fun f (g, x) = g (g (x));
(a) Qu tipo polimrfico tiene esta funcin?

8/13

L.A.M.M. - Uned Denia


(b) Demuestre la forma en la que la verificacin de tipos Hindley-Milner infiere el tipo de esta funcin.
(c) Vuelva a escribir esta funcin como una funcin de plantilla en C++.
Es el Producto cartesiano de una funcin del tipo a s misma con un valor del tipo , produciendo
un valor devuelto tambin del tipo .
Si recorremos el rbol de abajo arriba, vemos que la llamada de la derecha del todo tiene los tipos (,
).
La siguiente llamada es de la forma (, (,)) y por tanto (,) debe ser igual a , obteniendo de la
expresin (, (,)) el resultado de (, ()).
La funcin f ser del tipo (, ()), devolviendo finalmente un tipo de datos .

Definicin
f
()*(, )

Producto
g
()

x
()

call
g call
()
g
x
()
()

La funcin de plantilla en C sera:


template <typename T>
T f (T (*g) (T y), T x)
{ return g(g(x)); }

Ejercicio 6.30:
Escriba una funcin swap polimrfica que intercambie los valores de dos variables del mismo tipo en C++.
template<typenameT>
voidswap(T&x,T&y)
{Tt=x;
x=y;
y=t;
}

Ejercicio 6.34:
El polimorfismo paramtrico explcito no necesariamente debe quedar restringido a un parmetro de tipo
nico. Por ejemplo, en C++ uno puede escribir:
Template <typename Primero, typename Segundo>
Struct Par
{ Primero primero;
Segundo segundo;
};
Escriba una funcin de plantilla hazPar en C++ que tome dos parmetros de tipos diferentes y devuelva un
Par que contenga los dos valores.
template <typename Primero, typename Segundo>
Par < primero, Segundo> hazPar (Primero f, Segundo s)
{Par < primero, Segundo> p;
p.primero = f; p.segundo= s;
return p;
}

Ejercicio 6.36:
Es el polimorfismo paramtrico de C++, polimorfismo let-bound? (sugerencia: Vea las funciones makepair
y makepair2 en la pgina 221)

9/13

L.A.M.M. - Uned Denia

De hecho, el polimorfismo en C++ es let-bound, puesto que cualquier argumento de una funcin
polimrfica debe ser instanciado a una funcin actual en el punto donde es llamada. Considere, por
ejemplo el siguiente cdigo:
(1)
template<typenameT>
(2)
Tid(Tx)
(3)
{returnx;}
(4)
template<typenameFirst,typenameSecond>
(5)
structPair
(6)
{Firstfirst;
(7)
Secondsecond;
(8)
};
(9)
template<typenameFirst,typenameSecond,typenameThird>
(10)
Pair<First,Second>makePair(Firstx,Secondy,Thirdf)
(11)
{Pair<First,Second>p;
(12)
p.first=f(x);p.second=f(y);
(13)
returnp;
(14)
}
(15)
intmain()
(16)
{Pair<int,char>z=makePair(1,'a',id);//dequtipoesid?
(17)
cout<<z.first<<endl;
(18)
cout<<z.second<<endl;
(19)
return0;
(20)
}
El uso del id no instanciado de la lnea 16 causa el siguiente mensaje de error generado por el
compilador Gnu C++:
No hay concordancia en la llamada a la funcin 'makePair(int, char, <tipo desconocido>)'

Por eso, debemos sustituir la funcin id instancindola especficamente, y la misma funcin se


utilizar para ambas llamadas a f en la funcin makePair.

Ejercicio 6.37:
En C++ se presenta el problema de la verificacin de ocurrencias? Explique las razones.
El problema de la verificacin de ocurrencias no puede ocurrir en C++ porque C++ utiliza polimorfismo
paramtrico explcito, y los tipos recurrentes auto-referenciados no se pueden escribir explcitamente.

Ejercicio 6.38:
Un problema relacionado con el polimorfismo let-bound en ML es el de la recursin polimrfica, en
donde una funcin se llama a s misma en forma recursiva, pero en diferentes tipos y puntos del cdigo. Por
ejemplo, considere la siguiente funcin en ML:
Fun f x = if x = x then true else (f false);
Qu tipo tiene esta funcin en ML? ste es el tipo ms general que podra tener? Demuestre como llega
ML a esta respuesta.
ML llega al tipo fun : bool -> bool debido a la funcin f dada en el ejercicio, la cual no es de ninguna
manera el tipo ms general al que podemos llegar.
El motivo es simple: durante la verificacin de tipos, cuando el motor de la interfaz llega a la llamada
(f false), f todava tiene un tipo indeterminado, y el argumento booleano produce que el analizador
restrinja el tipo del parmetro a bool.

Ejercicio 6.44:
Qu nuevos constructores de tipos agrega C++ a los de C? Agregue stos al rbol de tipos de la figura 6.5.
C++ aade el constructor de tipo clase. Adems, C++ tiene tipos de referencia (vea la pgina 212), los
cuales difieren del tipo puntero, ya que los tipos de referencia tambin se convierten en nuevos tipos
derivados en C++. La construccin enum llega al nivel de tipo original en C++. C++ tambin provee de un
tipo bool, que es considerado como un tipo numrico. Finalmente, C++ ofrece un nuevo tipo wchar_t para
soportar caracteres unicode.

10/13

L.A.M.M. - Uned Denia

Tipos en C++
Bsicos

Derivados

void

Numrico
Entero
Sin signo

Puntero

Referencia

Arreglo

Funcin

float

Struct

Unin

Enum

Float
booleano

Con signo

char

Double

Wchar_t

int

Long double

Short int

Long int

Ejercicio 6.46:
Qu operaciones considerara necesarias para un tipo de datos de cadena? Cmo soportan los arreglos
de caracteres estas operaciones?
Operaciones tpicas para los arreglos son: longitud, asignacin, comparacin, concatenacin, extraccin de
subcadenas, posicin de un carcter, carcter de una posicin, reemplazo de caracteres en una cadena.
Los arreglos de caracteres en lenguajes como Modula-2 soportan asignaciones, comparacin, extraccin de
carcter y reemplazo de carcter. Las otras operaciones no se soportan directamente.
Concatenacin o extraccin de cadenas son particularmente problemticas debido a las restricciones que
tienen los arreglos de tamao fijo.
En un lenguaje con arreglos de tamao variable, como puede ser C o Algol 60, hay pocos problemas con las
restricciones de tamao, pero la mayor parte de las operaciones dadas no se soportan (incluyendo la
asignacin y comparacin en C).
C tiene una librera estndar de la funcin string que elimina muchos de estos problemas (pero no los de
almacenamiento).
Java tiene la clase String definida como parte del lenguaje, la cual tambin elimina muchos problemas
(excepto por el uso del == y unos pocos ms).
Ada tiene el tipo predefinido string que es equivalente a un arreglo de caracteres con tamao ilimitado. Ada
directamente soporta asignaciones, comparaciones, concatenacin y extraccin de subcadenas.

Ejercicio 6.49:
Debera estar disponible la prueba de igualdad para los tipos de punto flotante? Razone su respuesta.
La igualdad de tipos en coma flotante es problemtica porque casi siempre se implementa en hardware
como una verificacin de memoria a nivel de bit, y los valores sufren redondeos, truncamientos y otros
errores introducidos por la aritmtica en coma flotante.
Por ejemplo, el siguiente programa en C++ podra o no imprimir OK para ciertos valores de y:
#include <iostream>
using namespace std;
int main()
{ double x, y;
cin >> y;

11/13

L.A.M.M. - Uned Denia


x = 1/y;
if (x*y == 1) cout << "ok!\n";
return 0;
}
Por esta razn, uno puede pensar que es un buen argumento para no permitir la verificacin de tipos en
coma flotante, pero como los programadores debern implementar sus propias funciones para aproximar la
verificacin de tipos a la precisin deseada.
ML, por ejemplo, prohbe el uso de la verificacin de igualdad para tipos en coma flotante (pero provee
funciones de comparacin en el mdulo estndar Real).
Por supuesto que en C, est permitida la verificacin de igualdad de tipos en coma flotante.
Quizs sorprendentemente, tambin est disponible en Ada.
Java tambin permite la verificacin de igualdad de tipos en coma flotante. Para compensar, Java tambin
especifica la precisin de todos los tipos en coma flotante, y va ms lejos que Ada permitiendo a los
programadores especificar cualquier mtodo, clase o internas como strictfp, significando que todas las
implementaciones deben proporcionar el mismo resultado para todas las operaciones en coma flotante.
Por ello, los programadores pueden estar seguros que la verificacin de coma flotante proveer los mismos
resultados en cualquier implementacin de Java.

Ejercicio 6.51:
Las reglas de conversin para una expresin aritmtica como e1 + e2 en C estn establecidas en
Kerningham y Ritchie como sigue:
En primer lugar, todos los operandos de tipo char o short son convertidos a int y todos los tipos
float son convertidos a double. Despus, si alguno de los operandos es double, el otro es
convertido a double y ste es el tipo del resultado.
Por otra parte, si alguno de los operandos es long, el otro es convertido a long y ste es el tipo del
resultado.
Por otra parte, si alguno de los operandos es unsigned, el otro es convertido a unsigned y ste es
el tipo del resultado.
Por otra parte, ambos operandos deben ser int, y ste es el tipo del resultado.
Dada la siguiente expresin en C, suponiendo que x es unsigned con valor 1, describa las conversiones de
tipo que ocurren durante la evaluacin y el tipo del valor resultante.
Cul es el valor resultante?
'0' + 1.0 * (-1 + x)

+
*
1.0

'0'
+

-1

char

int

double +

int

double

double

double double
U

12/13

int

U
+

int
U

double
int

double

int

double U

double double

U
+

int

*
double +

+
int

double

int

float +

+
*

float +
x

int

double

int

double double
U

L.A.M.M. - Uned Denia

El primer recuadro muestra el rbol correspondiente a la expresin dada, y el segundo se han sustituido los
valores de cada nodo por el tipo de datos al que corresponde.
En el tercer recuadro se ha sustituido char por int y en el cuarto recuadro float por double.
En el quinto recuadro tenemos la expresin int + unsigned por lo que se sustituye int por unsigned
asignando el resultado de la suma el tipo unsigned (sexto recuadro).
En el sptimo recuadro tenemos la expresin double + unsigned, por lo tanto cambiamos unsigned por
double y devolvemos el tipo double a la expresin (octavo recuadro).
En el noveno recuadro nos queda la expresin double + int por lo que cambiamos int por double y
devolvemos como resultado el tipo double (dcimo recuadro).
Las conversiones de tipos realizadas son:
char + float * (int + unsigned)
char + float * (unsigned + unsigned)
char + float * (unsigned)
char + float * (float)
char + float
float + float
float.

int = unsigned
(unsigned + unsigned) = unsigned
float * (unsigned) = float
float * (float) = float
char + float = float + float
float + float = float

13/13

Anda mungkin juga menyukai