Beruflich Dokumente
Kultur Dokumente
Volumen 2
Csar Liza A vila
Grupo.
Creadores
lV/nTllJnn.r1n tu naturaleza Creativa
w
.. .. .... .
. .... .
.:
/ Datos de catalogacin bibliogr:;
Liza A vila, Cesar
Algoritmos y su Codificacin en C++. Volumen 2
Editorial Creadores .
Trujillo, Per, 2002
Tema: Programacin de computad'0ras
Formato: 14.5 x 20.5 Pginas: 234
Algoritmos y su Codificacin en CH. Vol 2.
Primera Edicin, Agosto 2002
El contenido de esta obra esta protegido por ley. Queda prohibida la
Jeproduccin total o parcial de este libro, por cualquier medio, sin permiso
escrito del autor.
2002, Derechos Reservados por Csar liza Avila.
Distribucin y Ventas
Editorial Creadores
Av. Amrica Norte 401 - Trujillo.
Telfono (044) 221363
e-mail: creadores@hotmail.com
Web Site: li?-
j
DEDICATORIA
A mis padres:
Dr. Csar Liza Ortz y Nery Avila Acosta por el esfuerzo
constante en la formacin de sus hijos.
Sin su ejemplo y apoyo nunca hubiera llegado a ser un
profesional de xito y mucho menos haber publicado algn
libro.
A mis amigos y colaboradores:
LoudesDaz, limar Goicochea, Kevin Llontop y Alfredo del
Castillo, por su importante crtica y aporte en el contenido
del libro. A mi querido amigo, que ya no est con nosotros,
Rogelio Briceo.
A mi modelo, amiga y futura colega:
Ana Luisa Doig Ascate, que adorna nuestra portada con
sus lindos ojos y bella sonrisa.
Al fotgrafo y amigo:
Vctor Torres Garca, por captar la belleza de nuestra
modelo.
Al diseador de la portada:
Javier Asmat, mi gratitud por su amistad y el buen gusto en
el diseo de la portada.
1
DILE NO A LA PIRATERA
Escribir un libro cuesta muchas horas de
esfuerzo intelectual. Publicarlo y distribuirlo
. constituye un esfuerzo econmico muy
grande donde no se espera obtener grandes
ganancias econmicas.
Si copias este libro cometes un delito y
adems matas la difusin del conocimiento
tcnico contribuyendo a que nuestro Per
siga siendo subdesarrollado.
NO COPIES MIS LIBROS
Hemos detectado que debido al gran xito
alcanzado por nuestros libros, stos se
encuentran fotocopiados y anillados listos
para su VENTA ILEGAL en muchos
"centros de fotocopiado" frente a
Universidades e Institutos.
Cuando menos lo esperen, los
visitaremos cayndoles con todo el peso
de la ley
PRESENTACION
f:sta obra es la continuacin de "Algoritmos y su Codificacin en
C++", y viene a completar el vaco que exista respecto a temas que no
tratamos en ella. Manejo de caracteres, arreglos bidimensionales,
estructuras, uniones, enumeraciones, manipulacin de bits, generacin de
nmeros aleatorios, simulacin, punteros, asignacin. dinmica de
memoria, y archivos, son tratados mediante ms de 81 ejemplos
completos de' programacin. Asimismo, encontrar ms de 140
ejercicios propuestos que le serviran para practicar lo aprendido, y que
sern de valiosa ayuda para los docentes en la elaboracin de prcticas y
exmenes.
Para la compilacin de los programas' presentados en este libro,
utilizamos el Microsoft Visual C++, en aplicaciones en modo consola,
pero puede utilizar otros compiladores haciendo pequeas modificacions
al cdigo.
En este segundo volumen, no utilizamos los diagramas N/S, pues
consideramos que el programador tiene la suficiente madurez lgica y
puede estructurar la solucin al problema para luego pasar a su
codificacin.
El primer captulo, trata sobre las cadenas de caracteres, que
son implementadas en C/C++ como arreglos, donde cada uno de sus
elementos es un carcter. Es importante su estudio puesto que el hombre
se comunica con palabras ms que con nmeros, y la computadora solo
utiliza nmeros para todo, inclusive para representar cada una de las
letras, ya sea mediante el cdigo ASCII o su sucesor el UNICODE.
Los arreglos bidim'Emsionales o matrices, constituyen un
elemento importante en matemticas pues permiten resolver un amplio
conjunto de problemas con muchsimas aplicaciones reales, as como
almacenar datos que necesitan 2 dimensiones para ser identificados. El
segundo captulo, aborda este tema mediante numerosos ejemplos.
I
/1
Las estructures, uniones '1 enumeraciones son tratadas en el
tercer captulo. Las estructuras son construcciones en C/C++, que
permiten agrupar un conjunto de atributos de diferentes tipos de datos, en
una nica variable; las estructuras constituyen los predecesores de las
clases. Las uniones definen en una misma zona de memoria uno o ms
elementos, permitiendo su ahorro; mientras que las enumeraciones hacen
mas claro nuestro programa, ya que podemos usar nombres en vez de
nmeros.
En el cuarto mostramos cmo g,enerar filmems
con distribuciones tales como ?oisson,
V Normal; abordando problemas mediante la tcnica conocida como
Simulacin Montecarlo.
la manipulacin de bits, la tratamos en el quinto captulo, y es
uno de mis favoritos, pues en l, mostramos cmo la computadora
almacena y procesa internamente los datos operando sobre bits; adems
existen muy pocos libros que traten adecuadamente este tema, y lo tratan
con escasos ejemplos. Este libro es la excepcin pues mostramos diversas
e interesantes aplicaciones.
Los datos que usamos y los programas que ejecutamos en una
computadora, ocupan memoria. Mediante los punteros podemos acceder
a cualquier zona de memoria asignada a nuestro programa. Asimismo,
mostramos como usar la asignacin dinmica, para reservar la memoria
necesaria segn como la vayamos necesitando. Estos temas son tratados
en el sexto captulo.
En el stimo y ltimo captulo, mostramos cmo hacer
persistentes nuestros datos en archivos; as como, analizar e interpretar
os diversos formatos de almacenamiento, abrindonos la puerta a un
mundo de aplicaciones.
Espero que la presente, supere la acogida que tuvo el primer
volumen. Le rogamos que cualquier crtica, sugerencia, o inquietud, la
. dirija a la siguiente direccin electrnica: creadores@hqtmail.S;.QI!L que
gustosos la responderemos con el nimo de mejorar cada da. Asimismo,
le invitamos a visitar nuestra pgina web www.geocities.com/cesarJi;;:a.
Csar Liza Avila
I
"-'-,
CONTENIDO
Presentacin"."., ... , .................................. ' .... , .. ,." .. , ............ , ............. ', . , "" 7
CAPITULO 1: Cadenas de Caracteres ..................................... " ..... 15
i .1 Muestre la tabla de cdigos ASCii
1.2 Programa que muestre el uso de las secuencias de escape
1.3 Convierta una palabra en maysculas a minsculas
1.4 Muestre la suma de verificacin de un mensaje
1.5 Dada una cadena numrica obtenga el nmero que representa
1.6 lea una frase y mustrela palabra por palabra
1.7 Cree su propia funcin para ingresar caracteres desde teclado
1.8 Encripte una cadena sumando sus ASCII con los dela clave
1.9 Encripte una cadena con una tabla de equivalencia
1.10 Diga como es alfabticamente, una palabra respecto a otra
1.11 Programa que utiliza las macros y funciones provistas en ctype.h
1.12 Uso de las funciones estndar provistas en el archivo string.h
1.13 Diga si una palabra es palndroma
CAPITULO 2: Arreglos Bidimensionles ......................................... 41
2.1 Lea una matriz con f filas y c columnas y iuego la imprmala
2.2 Encuentre la transpuesta de una matriz
2.3 Genere una matriz identidad de orden n
2.4 Dada una matriz diga si sta es una matriz triangular superior
2.5 Dada dos matrices obtenga la matriz ampliada
2.6 Inserte un vector en una columna determinada de una matriz
2.7 Cul es la produccin mensual de un grupo de fbricas?
2.8 Posiciones a las que se mueve la reina en un tablero de ajedrez
2.9 Suma de dos matrices
2.10 Producto de dos matrices
2.11 Determinante de una matriz
2.12 Resuelva un sistema de ecuaciones simultneas
2.13 Inversa de una matriz
2.14 Programa que juega "tres en raya"
2.15 Lea un conjunto de palabras en una matriz y ordnelas
t
CAPITULO 3: Estructuras Uniones y Enumeraciones ........ 00 oo 89
3.1 Suma de dos nmeros complejos
3.2 A cunto debe venderse cada kilo para no ganar ni perder?
3.3 Encuentre el valor numrico de un polinomio f(x)
3.4 Busque una fecha y diga cul fue su temperatura
3.5 Gestione los datos de un conjunto de alumnos
;3.6 Programa que permita al usuario resolver un crucigrama
3.7 Defina, en una misma zona de memoria, un entero y un flotante
3.8 Pida un nmero de da de la semana, y muestre el nombre del da
3.9 Lea una moneda y diga a cuntos cntimos equivale
CAPITULO 4: Manipulacin de 8Its ........................................ 00 115
4.1 Muestra el uso de operadores a nivel de bits: -, &, I , ", y
4.2 Lea un nmero, muestre sus bits tal como se ven en memoria
4.3 Encripte un mensaje por manipulacin de bits con XOR
4.4 Programa que genera una baraja de cartas. Use campos de bits
4.5 Programa que lee una hora y obtiene el nmero que la representa
4.6 Lea un nmero que represente una fecha vlida y obtenga la fecha
4.7 Lee una hora y da el nmero que la representa. Campos de Bits
4.8 Muestre cada bit de un punto flotante de simple precisin
4.9 Estndar IEEE 754 de un flotante de simple precisin
CAPITULO 5: Generacin de Nmeros Aleatorios y Simulacin ...... 143
5.1. Genera nmeros aleatorios por el Mtodo Congruencial Lineal
5.2. Genera aleatorio discreto en [O, RAND_MAX], [O, a-1], y [a, b]
5.3. Genera aleatorio en el intervalo continuo entre [0,1] Y [a, b]
5.4. Caminata aleatoria de borrachito, a igual distancia de casa-cantina
5.5. Ley Fuerte de los Grandes Nmeros
5.6. Calcule la integral definida de una funcin f(x), por simulacin
5.7. Calcule el valor de PI, por simulacin
5.8. Obtenga los nmeros ganadores del siguiente sorteo de la Tinka
5.9. Genera aleatorios con Distribucin Poisson y media lambda
5.10. Genera aleatorios con Distribucin Exponencial y media 1/1-1
5.11. Genera aleatorios con Distribucin Normal
5.12. Genera una permutacin aleatoria (mezcla) de n elementos
5.13. Genera combinacin aleatoria de n elementos, en grupos de r
CAPITULO 6: Punteros y Asignacin Dinmica de Memoria ........... 173
6.1 Declare variables y muestre sus direcciones de memoria
6.2 Funcin que intercambia dos valores
6.3 Lea coordenadas cartesianas, y convirtalas a polares
6.4 Direcciones de memoria que ocupan los elementos de un arreglo
6.5 Usando arreglos y punteros, lea n elementos y ordnelos
6.6 Lea una palabra y reemplace una letra por otra
6.7 Determine si una palabra es palndroma
6.8 Concatene 2 palabras
6.9 Ordene los elementos de arreglo, usando un arreglo de punteros
6.10 Funcin que lee n empleados, usando un puntero a una estructura
6.11 Arreglo dinmico de n flotantes
6.12 Puntero a funcin
6.13 Funcin que intercambia dos valores. Use referencias
CAPITULO 7: Archivos ............................................................... 201
7.1 Lea una serie de caracteres y cree un archivo con ellos
7.2 Lea el nombre de un archivo y muestre su contenido por pantalla
7.3 Lea un archivo y cpielo hacia otro
7.4 Divida un archivo en otros, similar al Hacha
7.5 Lea una serie de registros y gurdelos en un archivo
7.6 Construya un Visor Hexadecimal
7.7 Comprima un archivo por reduccin de caracteres repetidos
7.8 Lista los archivos comprimidos en *.ZIP
7.9 Dada una carpeta, muestre los directorios y archivos que contiene
Acerca del Autor
Otras Obras del Autor.
Distribucin y Ventas
l
Cadenas de
Caracteres
m
Cadena de Caracteres 15
Solucin:
Es conocido que las computadoras son capaces de almacenar solo CEROS
y UNOS, es decir nmeros en binario. Pero el humano adems de nmeros
utiliza smbolos, por lo que fue necesario codificarlos, para que sean
almacenados en las computadoras. Por ejemplo, podramos decir que si
almacenamos el nmero en binario 0100 0001 (equivalente a 65 en
decimal) estaremos almacenando la letra 'A'. Otro grupo de programadores
pudo haber definido como cdigo de 'A' el nmero 0000 0000, esto trajo,
all por la dcada del 60, la necesidad de definir un estndar.
Este estndar se llama Tabla de Cdigos ASCII (American Standar Code
for /Ilformation /nterchallge, Estndar Americano de Codificacin para
el Intercambio de Informacin), la cual nos proporciona una lista de
cdigos a los que se les ha asociado un smbolo, que permite que los
equipos y programas puedan intercambiar informacin con otros equipos y
programas.
La Tabla de Cdigos ASCII original contiene 128 cdigos (del O al 127),
puesto que este es la mxima combinacin de valores que se puede obtener
con un byte (8 bits) sin ocupar el bit del signo (2
7
). Posteriormente, se
ampli esta tabla para ms smbolos como los caracteres con tilde, a esta
tabla se le conoce como Tabla de Cdigos ASCII Extendida y consta de
256 smbolos (del O al 255), pues esta es la mxima cantidad de valores que
se pueden conseguir con un byte (2
8
) usando inclusive el bit del signo.
Como es de esperarse los 128 primeros caracteres de la Tabla ASCII
Extendida son los mismos que la Tabla ASCII original.
En la Tabla ASCII los 32 primeros caracteres (del O al 31) son caracteres
de control, esto es; realizan una accin, en vez de mostrar un smbolo.
Csar Liza Avila. Mis libros son econmicos, no hay razn para copiarlos.
16 Algoritmos y su Codificacin en C++. Volumen 2. Csar Liza Avila
Tabla de Cdigos ASCn
Cadena de Caracteres f7
IDee Hex IChal: Ji)'ee lBIex Clluil: IDee lBIex I;hal: IDee ex I:har
128 80 r; 160 AO 192 CO
,-
22"1 EO ex
129 81 161 Al i 193 Cl
1..
225 .1\1
e,
130 82 162 A2 194 C2
T
226 E2 r
131 83 a 163 A3 195 C3 .. 227 E3 n
132 8"1 a 164 A4 196 C4 228 E4 E
133 85 a 165 AS 197 C5
+
229 ES CJ
134 $6 a 166 A6
.
198 C6
230 E6 11
135 87 C;
167 A7
o
199 C7
231 E7
136 88 168 AS 200 CS
I!. 232 E8
137 89 e 169 A9 r 201 C9
IF
233 E9 (')
138 SA e 170 AA
.., 202 CA
,!!:
234 EA Q
139 8B i 171 AB 11 203 CB
'ir
235 EB !J
1"10 BC i 172 AC 1,.,; 20"1 CC
Ir
236 EC
""
141 8D i 173 AD i
205 CD 237 ED 0
1"12 .8E ii. 174 .II.E 206 CE
JL
23S EE
lr
1"13 8F A 175 AF 207 CF
,b
239 EF n
1"14 90 176 BO
.:.;.:
...
208 DO
lL 240 FO -
145 91 <e 177 B1
209 Di
T
241 n
1"16 92 lE 178 B2
11
210 . D2
"Ir
242 F2
147 93 179 B3
I
211 D3
IL 243 F3
148 94 ti . 180 B4
i
212 D4
b 244 F4
r
149 95 6 181 B5
213 D5
F
245 F5
J
150 96 ti 182 B6
il
214 D6
Ir
246 F6
151 97 u 183 B7
11
215 D7
t
247 F7
152 98 Y
184 B8
'1
216 D8
+-
248 F8
153 99 o 185 B9 {I 217 D9
J 249 F9
154 9A 186 BA
11
218 DA
r
250 FA
155 9B e 187 BB
il
219 DB
I
251 FB '
156 9C f. 183 BC JI 220 DC
lW
252 FC
157 9D Y 169 BD
.u
221 DD
253 FD
158 9E E. 190 BE
d 222 DE
254 FE
159 9F :f 191 BF
1
223 DF
l1li
2.5.5 Ff o
------_.-
Podemos generar el smbolo a partir de su cdigo ASCII, usando el teclado
numrico. Esto lo conseguimos pulsando simultneamente la tecla Aj +
Cdi.go ASen ingresado con el teclado numrico.
Csar Li(:a Av!a. Mis libros son econmicos. IZO ha.\" razn para (oliarlos.
18 Algoritmos y su Codificacin en C++. Volumen 2.
Csar Liza Avila
Para mostrar cada cdigo ASCII, nuestro programa genera nmeros del O al
255, imprimiendo el cdigo i, y el smbolo (char) i. Note el uso de la
conversin tipo casi que usamos para forzar a la computadora a mostrar el
smbolo en vez del nmero. Una conversin casi, consiste en colocar el tipo
de dato deseado, entre parntesis, delante de la variable a la cual queremos
cambiarle de tipo solo para la operacin actual.
Hay gente que practica el "ASCn Art" (Arte ASCII), que consiste en
disear figuras utilizando nicamente caracteres ASCII, se realizan reidos
torneos internacionales para premiar la mejor creacin ASCII. Puede
buscar en www.google.com "Arte ASCII", inclusive encontrar programas
en donde se ingresa una imagen y sta sale en caracteres ASCII.
Adicionalmente, el lector debe saber que, debido a la necesidad de
incorporar al juego de caracteres otros smbolos y alfabe"tos de otros
idiomas, y que stos rebasan la capacidad que puede almacenarse en
variables de un byte (tipo char en DOS), se ampli este juego de caracteres,
denominndose a este nuevo estndar UNICODE en donde cada cdigo
ocupa 2 bytes por lo que puede tener un mximo de 65,536 cdigos (esto es
i
6
), es por ello que en los sistemas que lo utilizan, como Windows, cada
variable de tipo char ocupa 2 bytes.
Csar Liza A vila. No mates la produccin intelectual, no copies ste libro.
Cadena de Caracteres 19
Solucin:
Ya sabemos que los primeros 32 caracteres de la Tabla ASCII son
caracteres de control. Con el fin de poder represet1tarlos en el cdigo
fuente, se recurri al artificio de utilizar la barra invertida ( \ ) seguida de
una serie de caracteres; estas son las llamadas Secuencias de Escape o
caracteres de barra invertida, las cuales representan un carcter que
realiza una accin y estn precedidos siempre por \ (back slash).
Adicionalmente, como para su representacin se utilizan los caracteres " \ Y
", se hizo necesario crear secuencias de escape que permitan mostrar estos
caracteres.
Secuencias de Escape
Cdsar Liza A vita. Mis libros son econmicos, no hay razn para copiarlos.
20 Algoritmos y su Codificacin en e + +. Volumen 2.
Csar Liza A vila
Nuestro programa imprime cada una de las secuencias de escape
deseada, mostrando su efecto. Note como podemos utilizar directamente el
cdigo ASCII en vez de la secuencia de escape, y como usamos las
comillas simples', en vez de las dobles ", pues las secuencias de escape
representan un nico carcter.
Csar Liza Avila. No mates la produccin intelectual, no copies ste libro.
Solucin:
,
Observando la Tabla de
Cdigos ASen notamos
que las maysculas van
desde el 65 (carcter A)
hasta el 90 (carcter Z) y
que las minsculas van
desde el 97 (carcter a)
hasta el 122 (carcter z)
Es decir, que para convertir
un carcter de mayscula a
minscula se le suma 32
(97 -65), mientras que para
convertirlo de minsculas a
maysculas se le resta 32.
La cadena de caracteres o el
arreglo de caracteres cad[ ]
sirve para almacenar cada
carcter de la frase
ingresada.
Cadena de Caracteres 21
.. -.
..... ,'. :COD1FIGAdNitNC++
. . . .
. ':
Yoi,dcadT91l'lin(chrUJ;
,', ';;e ',: ......... ;:
[LM]i . . ',,{.,-
'. -'
, .. ,....:
;' :cout}'la qil.denaeq' lililissulases
. < .... ,yv ....
.. >
.< ','.;4," .:. e "
La funcin cadToMin( ) aprovecha el hecho que las cadenas de
caracteres siempre terminan en NULL. Esta funcin toma uno a uno los
caracteres y si estn en maysculas, esto es su cdigo est entre 65 y 90, les
suma 32 para convertirlas a minsculas (cad[i] = cad[i] + 32).
Recuerde que, todo cambio que haga una funcin sobre un arreglo,
ser conocido por el resto del programa, por ello no es necesaria la
sentencia return para devolver la nueva cadena. Esto es, debido a que los
arreglos se pasan a las funciones por referencia. Comprender ms sobre
ello en el captulo sobre punteros.
Csar Liza Avila. Mis libros son econmicos, 110 hay razn para copiarlos.
22 Algoritl1lo.! y su Codi/icllt"in en C++. Volumen 2. Csar Liza A vi/a
Solucin:
.Las sumas de verificacin, son tcnicas no criptogrficas que permiten
detectar errores en la transmisin de mensajes. Consiste en calcular un
valor (checksum) a partir de una serie de caracteres. Cuando enviamos un
mensaje, tambin enviamos su checksum, el destinatario puede entonces
calcular el cbecksum al mensaje y compararlo con el checksum recibido,
si fueran distintos habr un error en la transmisin del mensaje. Un ejemplo
de sumas de verificacin son los CRC's o Cdigos de Redundancia
Cclica, como el CRC-32, o el Protocolo de Datagrama de usuario UDP,
entre otros. Un algoritmo sencillo para calcular el checksum es sumar los
cdigos ASCII (o UNICODE) y obtener la suma como residuo de 2
32
, es
decir para el caso que la suma sobrepase el lmite de los enteros (4 bytes
32 bits) la suma de verificacin contendr el residuo respecto a 2
32
. . La sentencIa ,>'
cm.gethne(cad, LlM) lee caracteres . .
desde el teclado y los
en frase hasta un mximo de
LIM. El ingreso termina cuando
se presiona enter y, a diferencia
de cin, ste ltimo adems
termina la lectura, con el primer
espacio en blanco o con la tecla
tab, por lo que cin no puede
usarse para ingresar una frase.
La funcin checkSum(
), toma cada carcter ( for (i=O;
frase[i]; i++) ) calculando la
suma de sus cdigos ASCII,
(s+=frase[i] ) esto es a pesar
que frase[i] es de tipo charo
- En C/C++/C# no debemos preocupamos por obtener del residuo
respecto a 2
32
, puesto que para tipos unsigned, cuando rebasamos este
lmite, automticamente se regresa la cuenta a cero.
Csar Liza Avila. No mates la produccin intelectual, no copies ste libro.
Cadena de Caracteres 23
Los algoritmos de suma de verificacin estn persados para la transmisin
de mensajes por canales no maliciosos, pues es fcil alterar el mensaje sin
que vare el checksum. Los llamados CCV (cryptographic check values)
evitan esto, y son simlares a las sumas de verificacin con la diferencia
que usa una funcin hjlsh para
que dos mensajes diferentes no
tengan el mismo checksum.
Estos algoritmos son de
dominio pblico, no hay claves
y cualquiera puede cal,?ularlas.
Entre ellos podemos resaltar:
SHA-l (Secure Hash Algorithm),
RIPEMD-160, MDS (Message
Digest A 19orithms) , de ellos el
.,.,.
" ..... ,
..
ms usado es el MD5 implementado, por ejemplo, en el MD5Summer
(www.md5summer.org). en el fileAlyzer (http://www.safcr-nclwOrking.org/es/
downJoadlindex.html, de paso le sugiero descargar en la misma pgina el Spybot -
Search & Destroy excelente software detector de spywares o software espa).
Muchas pginas en Internet muestran los MD5 qe los archivos, con el fin
que el usuario al descargarlos compruebe que no han sufrido alteraciones
(por ejemplo, la pgina de descarga del Spybot - Search & Destroy usa los MD5).
Programas como los antivirus, usan un CCV para actualizarse, otros 10
crean para archivos ejecutables y notar si han sido alterados. El uso comn
hace que tanto los checksum como los CCV sean llamados solo
checksum, pero usted ya conoce las diferencias.
Para autenticar el emisario, se usan los llamados MAC (Cdigos de
Autenticacin de Mensajes). En ellos tanto el emisor como el receptor
comparten una clave, lo que permite al recept9rverificar si el documento es
autntico y que fue enviado por quien dice enviarlo. Es similar a una
funcin hash, es decir se aplica a un mensaje y genera un valor MAC, pero
las hash no tienen claves, mientras que las MAC si. Entre ellos destaca
CBC-DES, HMAC, UMAC, PMAC.
Una tcnica an ms poderosa son las firmas digitales, que permiten al
receptor verificar la autenticidad e integridad del mensaje, es decir el
emisor no puede negar la autora del mensaje, pues es el nico poseedor
de la clave, a diferencia de las MAC donde la clave es compartida por
varias entidades. Ejemplos de algoritmos para firmas digitales tenemos:
RSA, ESIGN (Efficient digital SIGNAture), MacEliece, entre otros.
Csar Liza A vilo. Mis libros son econmicos, no hay razn para copiarlos.
\1
24 Algoritmos)! su Codificacin en C+ +. Volumen 2.
Csar LiGa A ]lila
Solucin:
Cada carcter de la cadena ingresada, por ejemplo "581", es un smbolo
que representa un nmero, pero no es el valor del nmero. As '8' es el
carcter ocho, y no el valor 8. Nuestro programa debe lograr que a partir de
la cadena "581" de tipo mar I ], obtengamos el valor de 581 de tipo Ini.
48 'O'
49 '1 '
50 '2'
51 '3'
Para ello nos apoyamos en el subconjunto mostrado de la
Tabla ASCII, del cual deducimos, que si deseamos el
valor numrico correspondiente al "carcter nmero",
necesitamos restar 48 a cada ASCn que represente el
nmero.
52 '4'
53 '5'
La cadena "581" se representara como:
1'5' I '8' 1 '1' I NULL I
Pero internamente se almacenar como:
54 '6'
55
56
57
'7'
'8'
'9'
Si restamos 48 a cada cdigo y lo multiplicamos por su
valor posicional correspondiente tendremos: (53-
48)xl0x10 + (56-48)xl0 + (49-48) = 581
\
Esto es lo que hacemos en
nuestro programa. La funcin
cadTolnt( ), procesa cada
carcter ( while (cad[i) !=
NULL), recuerde que toda
cadena termina en NULL )
restndole 48 (cad[i]-48), y
va acumulando el resultado
no sin antes aumentar un
valor posicional al resultado
anterior (nro*10).
".' ........ CODIFIcCtoNEN'++ "' ..
;..'
'".' {,J.:, ;:'
-:},>' ,t(:;} "'';'. ";".,,".; .
" ".; . '
irttc(lT
o
l*Ccr<tt ;cadf n
.{
. \yhi1 e(cad[i] !;'NULt)'
{oro;= nm,*l (J +
<9 Csar Liza A vila. No mates la produccin intelectual, /lO copies ste libro.
:.pal(kj'=3 NUL,L;
"
Cadena de Cara(:teres 25
iniciamos una
palabra haciendo que la siguiente palabra tenga cero caracteres (k=O).
Csar Liza Avila. Mis libros son econmicos, 110 IllIr razn para copiar/os.
1
26 Algoritmos y su Codificacin en C++. Volumen 2.
Solucin:
La funcin leerFrase( ),
hace lo pedido. En ella el
mtodo cout.flush( ), obliga
a mostrar por pantalla todas
las salidas que an no han
sido impresas. El bucle do{
}while (fraseri-l]!=l3); se
repite mientras el carcter
ingresado no sea ENTER
(ASCII 13). Dicho carcter
es ledo en frase[i]= (unsigned
char) getch( ); la' funcin
getch( ), devuelve el entero
correspondiente al ASCII de
la tecla pulsada y su
prototipo se encuentra en
conio.h, razn por la cual lo
incluimos al inicio del
programa. S i pulsamos
cualquier tecla diferente de
BackSpace (BS, ASCII 8),
entonces lo imprnmmos
hacindolo parte de la frase
(i++), De haber sido BS,
eliminamos el ltimo
carcter (i--), siempre y
cuando exista (i>O).
Csar Liza Avila
modificar nuestra funcin leerFrase( ), para permitir slo el
mgreso de nmeros, slo letras, slo maysculas, o minsculas, es decir un
control de los caracteres cuyo ingreso aceptamos, inclusive cuando
mgresemos un password podemos mostrar el carcter que deseemos.
@ Csar Liza Avila. No males la produccin intelectual, 110 copies ste libro.
-, w-
SoluCin:
Este tipo de
encriptamiento consiste
en cambiar un carcter
por otro, utilizando la
tabla ASCII. Para ello
reemplazamos cada
carcter por otro
ubicado a una distancia
igual al ASCII de la
clave utilizada.
Nuestra funcin
encriptar( ), toma cada
carcter mientras no sea
CERO o NULL, esto
se escribe de manera
simplificada en el for,
como frase[i], que
equivale a escribir
frase[i]!=NULL. A
cada carcter le
sumamos el cdigo
ASCII de la clave,
transformndolo en otro
cdigo y por ende en
otro smbolo.
Cadena de Caracteres 27
El proceso de desencriptado es similar, pero ahora desencriptar( ) resta a
cada carcter el cdigo ASCII de la clave, retornndola a su cdigo
original.
Csar Liza A vi/a. Mis libros son econmicos, no hay razn para copiarlos.
28 Algoritmos y su Codificacin en C++. Volumen 2. Csar Uza A vila
i.
Solucin:
Dado que la tabla ASCII es estndar, el algoritmo de encriptamiento del
problema anterior (2.8) tiene algunas desventajas. Sin embargo, podemos
mejorarlo definiendo nuestra propia tabla de caracteres a reniplazar.
La cadena (arreglo de caracteres) tablal contiene los caracteres que
deseamos sean remplazados por otros, aqueUos que no estn en esta tabla
no sern remplazados. La cadena tabla2, contiene los caracteres de
reemplazo, observe que la tabla2 debe tener la misma cantidad de
caracteres que la tablal, no debe tener caracteres repetidos y es posible que
tenga cualquiera de los 256 caracteres ASCII, a excepcin del NULL, que
es usado como terminador de cadena.
Note como
inicializamos tablal,
tabla2 y cad, en lugar
de ingresarlas desde
teclado.
}
'i;; '
--
"I ....
(.) ("psar Liza Avila. No Illllfes la produccin intelectual. 110 copies t5ste libro.
La funcin encripta( ),
toma cada carcter de la
cadena a encriptar cad[i]
y lo busca en la cadena tl
( ir (cad[i] == HU] ), si lo
encuentra lo reemplaza
con el carcter asociado
(cad[i] = t2[j]) Y sale del
bucle ms intemo
(break), para tomar el
siguiente carcter a
encriptar.
La funcin desencripta( )
es similar, nada mas que
ahora busca el carcter en
la t2, y lo remplaza por su
carcter correspondiente
en tl.
Cadella de Carac,tere.\ 29
Aunque es valido inicializar la cadena tal como se muestra, es
recomendable encriptar las tablal y tabla2 y mejor aun, inicializarlas
usando sus cdigos ASCII en vez de los caracteres. Esto es as, puesto que
con un editor
hexadecimal
es posible ver
las cadenas
definidas
como
constantes
dentro de
nuestro
ejecutable; tal
como se
puede
observar al
utilizar el
FileAlyzer.
na.
3A2:000GO ('DOOOOOO 43i,164GE. .... f e
6E6.s";29 ,07461':4 61'202021) .3.t.2 1)OO
__
,)(!OCOOOOO OClOODOOO r-07S420 8('1 ':4C:I)Ct -.- ... _L..:.l' .:;-r,j:
oonOO(Jf)O 20;f,4?OQ -;OUA!)(:O
000:)(:000 f:rSOGI)(!O 696F7:37<\ f<.t?IS.E.6?
.textOOO . .. " ,,'
... J.:.sttini
(i;) Char Liza Avila. Mis libros son econmicos, 110 ha,- ra;::n para ("Ol/illrlo\'.
...:J
30 Algoritmos y su Codificacin en C+ +. Volumen 2.
Solucin:
La funcin
mayorPalabrn( ), toma
cada carcter de cada
cadena y los compara.
Si son diferentes retorna
la diferencia de los
cdigos ASCII del
carcter de la primera
cadena, con el carcter de
la segunda.
. Si esta diferencia es
mayor que O, la primera
palabra ser
alfabticamente mayor
que la segunda.
Si retorna menor que O,
la primera palabra ser
alfabticamente menor.
En caso de no ser ni
mayor ni menor pasamos
a probar el siguiente
carcter (i++).
De haber' analizado todos
los caracteres, salimos del
buclewhile, y retornamos
O indicando que son
iguales.
Csar Liza Avila
ID Csar Liza Avila. No mutes la produccin intelectual, 110 copies ste libro.
Cadena de Caracteres 3 J
Solucin:
La librera estndar ctype.h, contiene un conjunto de macros y funciones,
que nos permiten saber si un carcter es un dgito, una letra, convertirla a
maysculas o minsculas, si s un signo de puntuacin, entre otras.
El programa adjunto hace uso de esta librera.
, . "."
. " 1.' . ",,,
,,:;5,,:" thf;:: ;
, !,., '
, 1"' 1
Recuerde, si una funcin devuelve un valor siempre podr usarlo en una
expresin condicional
ir ( isdigitCl ') ) cout"Es dgito";
else cout"No es dgito";
Csar Liza Avila. Mis libros son ecof/rni('us, no hay razn pam copiar/os.
,1
:1
:1
32 Algoritmos y su Codificacin en C+ +. \lo/limen 2. Csar Liza A vila
Solucin:
Debido a que el e, no cuenta con el tipo base string, lo implementa como
un arreglo de tipo char, en donde el fin de cadena es indicado por el
terminador NULL y, siendo tan frecuente su uso, es que los compiladores
del lenguaje e, proveen el archivo string.h, el cual contiene las
declaraciones prototipo de funciones para manejo de cadenas, algunas de
las cuales mostramos en el siguiente cuadro.
strcmp( )
strupr( )
strncat( )
strcpy( )
strncpy( ) rmrnpr,,< caracteres de una
strstr( )
strchr( ) un carcter (car) dentro de la
). Si lo encuentra devuelve UIl puntero a
sino devuelve NULL.
if(stremp(el, (2)==0)
{ ,"
strupr(ead)
strlwr(ead)
stmeat(el, e2, n)
strepy(e 1, (2)
strnepy( el, e2, n)
strstr(el, c2)
strchr( el, car)
(i':l Csar Liza A vila. No la pruducn intelectual. /lO copie.\ ste libro.
Cadena de Caracteres 33
"." .. "'
strcat(
cot "Ahora lil,c;adJ, '" .,;
Csar Li::.a A vila. Mis libros son econmicos, /lO ha" razn para CflJliarlos.
34 Algoritmos y su Codificacin en e + +. Volumen 2.
. Csar Liza A vila
Le sugiero probar el uso d ~ las funciones strncmp( ), strstr( ),
strchr( ), strrchr( ), entre otras, que no han sido utilizas en este programa.
Otras funciones interesantes para el manejo de cadenas se
encuentran en stdlib.h, y mostramos su uso en un pequeo ejemplo
adicional.
# inclllde <iostream.h>
# inclllde <stdlib.h>
void main(void)
{
int entero = atoi ("123");
double doble = atof.("567.45");
long largo = atol ("1234567890");
char cad[IOO];
int base = 2;
itoa (722, cad. base);
cout"cadena a entero :" entero endl;
cout"cadena a doble :" doble endl;
cout"cadena a long :" largo endl;
cout"Entero a cadena en base dada: " cad endl;
L
' \
1\
(0 C.l(lr Li;:a Avila. No m a t e ~ la produccin intelectual, /'lO copies ste libro.
fe,.
Cadena de Caracteres 35 .
Solucin:
Nuestro algoritmo consiste en:
Tomar el prmer carcter y compararlo con el ltimo,
Tomar el segundo carcter y compararlo con el penltimo,
Tomar el tercer carcter y compararlo con el antepenltimo,
y as sucesivamente. Si alguna vez los caracteres han sido diferentes
retomar CERO, o sea falso, no es palndroma, pero en caso de haber
evaluado todos los caracteres retomaremos 1, indicando que es
palndroma. Para obtener la cantidad de caracteres que tiene una palabra
usamos la funcin strkn( ), cuyo prototipo se encuentra en string.h, razn
por la cual la incluimos al inicio del programa.
Csar Liza A vi/a. Mis libros son econmicos. no hay razn para copiarlos.
l,
36 Algoritmos y su Codificacin en C++. Volumen 2.
Csar Liza A vila
i. Escriba una funcin que devuelva la posicin de la primera
de un carcter dentro de una cadena. Por ejemplo, la przmera
ocurrencia de 'a' en "ulala" esta en la posicin 2. Si no existe que
devuelva -l. No use strchr( ).
2. Escriba una funcin que reemplace todas las ocurrencias de un
carcter por otro. ,., .,
3. Dados dos palabras muestre las letras que estan en la
4. Escriba un pequeo corrector ortogrfico que haga lo slgUlente: SI la
palabra termina en "don" agrguele el tilde
5. A una cadena se le ha cambiado los caracteres de las pOSICIOnes pares
por las impares. Obtenga la cadena original. Por ejemplo, si .ingresa
use pirro debe obtener superior. Sugerencia: use un algorztmo de
intercambio.
6. Convierta una frase de minsculas a maysculas.
7. Escriba una funcin que permita ingresar un password, mostrando
asteriscos *, para cada carcter. El password ser
dentro del programa, para que 110 pueda ser VIsto por algun edaor
hexadecimal.
8. Diga si una frase es palndroma, esto es leda de izquierda a derecha
es lo mismo que de derecha a izquierda. Sugerencia: Lea la frase con
gets( ), cill.getline( ) o con nuestra funcin del p:oblema
1.7, luego elimine los espacios en blanco y determme Si es palmdroma.
Por ejemplo, "Abajo me mojaba" y "Anita la gorda lagartona no
traga la droga latina" son frases palindromas.
9. Lea un nmero entero y escriba una funcin que obtenga una cadena
COIl el nmero. Por ejemplo, para el entero 384 debe obtener la cadena
"384". No use itoa( ).
i O. Lea una cadena que representa un nmero con punto decimal y
transfrmela a nmero Por ejemplo, la cadena "183.59" ser el
nmero 183.59. No use ato/( ).
i 1. Lea un nmero con punto decimal y obtenga una cadena. Por ejemplo,
si el nmero es 38.72, la cadena ser "38.72".
12, Escriba un programa que verifique si un mensaje ha sido alterado.
Sugerencia: use un checksum.
@ Csar Liza Avila. No mates la produccin intelectual, 110 copies ste libro.
Cadena de Caracteres 37
13. Lea una frase y convierta cada letra inicial a maysculas. Por ejemplo,
"juan prez mamani" ser "Juan Prez Mamani".
14. Escriba un programa que diga cul es la palabra ms Larga de una
frase indicando el nmero de letras.
15. Obtenga una subcadena empezando desde una posicin inicial hasta
otra final. Por ejemplo, dada la cadena "La belleza est en los ojos del
que ama", la subcadena desde la posicin 3 hasta la 10 es "belleza".
Usted debe realmente obtener la subcadena no imprimir desde esos
subindices
16. Escriba ufJa funcin que concatene dos cadenas. Por ejemplo: las
cadenas "ojitos" y "lindos", concatenadas ser "ojitoslindos': No use
strcat( ). Usted realmente debe concatenar las cadenas y no slo
imprimirlas juntas.
17. Lea tres enteros que representen las horas, minutos y segundos y forme
una cadena. Por ejemplo: h= 10, m=20 y s=45, la cadena ser
"10:20:45".
18. Escriba su propia funcin que busque una cadena dentro de otra. No
use strstr( ). .
19. Cuntas letras diferentes tiene una palabra ingresada por teclado?
20. Una forma de encriptar un mensaje con clave de varios caracteres es
repetir la clave hasta tener el tamao del mensaje a encriptar y luego
sumar cada ASCII del mensaje con cada ASCII de la clave. Por
ejemplo:
Mensaje = "Arriba Per"
Clave = "abc."
Sera:
lA', r 1 r b a I pie l. r NULL
I a I b I c I a I b I c I a lb' UiJILNULL I
Luego debemos sumar los cdigos ASCII de 'A' con 'a', 'r' con 'b',
'r' con 'e' y as sucesivamente, obteniendo el mensaje eniptado. Para
desencriptalo tendramos que ingresar nuevamente la clave, repetir la
clave hasta tener el tamaiO del mensaje y luego restarlos del ASClI de
cada carcter del mensaje encriptado.
@ Csar Liza Avila. Mis lihros son econmicos, /10 hay razn para copiarlos.
;1'
~ " :
I
,
J
Arreglos
Bidimensionales .
Arreglos Bidimensionales 41
Solucion:
Una matriz o arreglo bidimensional es
un conjunto de nmeros dispuestos en
f filas (lneas horizontales) y c
columnas (lneas verticales). Se dice
que la matriz es de orden fxc, mientras
, que si tuviera igual cantidad de filas y
columnas sera una matriz cuadrada.
;'}i!,
La probabilidad de que ocurran i + 1 eventos es: Pi+l = e Ie A,i+lCi+ 1)1
La razn entre dos trminos consecutivos ser:
Pi+1 e'AA,i+ll(i+l)! A,
= - - - - - - - - - - ~ - ~ - ~ = ~ =
Pi e 'A 'A,i i! i + ]
factor que usaremos en nuestro programa para facilitar los clculos.
Podemos demostrar que es una verdadera distribucin de probabilidad
pues: PO+P+P2+ ... = e i, 2
%
! + e" ).//1! + e .J. 2212! + ...
= e i. (2
%
! + }///! + 2212! + ... )
= e .'.e!.
= /
Csar Liza A Fila. No mates la produccin intelectual, 110 copies ste libro.
Generacin de Nmeros Aleatorios y Simulacin 157
!)i deseamos simular cuntos eventos (i) OCUlTen en una unidad de tiempo,
haremos uso del "Mtodo de la Transformada Inversa", esto es
generamos un nmero aleatorio r uniformemente distribuido entre O y 1 Y
buscamos el valor de i correspondiente al intervalo en donde se encuentra r.
La funcin poisson(), genera
un nmero entero aleatorio
que cumple una Distribucin de
Poisson con parmetro lambda.
Primero, generamos un
nmero aleatorio (r)
uniformemente distribuido
entre O y 1, e iniciamos la
bsqueda de i. Si i=O,
entonces la probabilidad
correspondiente p es e .,1 (pues
A,=l y 0!=1) Y la probabilidad
acumulada F es igual a p.
Debemos ir acumulando las
probabilidades hasta encontrar
el primer valor de
probabilidad acumulada que
sea mayor a r, cuando esto
ocurra terminar el bucle y el
valor de i ser la cantidad
buscada. Observe el uso del
factor Iambda/(i+1) para el
clculo de las probabilidades
de 2 nmeros consecutivos.
Csar Liza A vila. Mis libros SOIl econmicos, no hay razn para copiarlos.
158 Algoritmos y su Codificacin en C++. Volumen 2. Csar Liza Avila
Solucin: ,
. Antes de mostrar el programa, veamos como utilizamos el metodo de la
transformada inversa para valores continuos y luego hablemos sobre la
distribucin exponencial.
Transformada inversa para valores continuos .
Note que el mtodo de la transformada inversa para dIscretos,
consiste en ir sumando las probabilidades de cada valor. SI dIchos valores
son continuos entonces la sumatoriase transforma en una integral.
Si X es una variable aleatoria continua, y p(x) es la probabilidad de cada
resultado x, entonces las probabilidades acumuladas estn dadas por:
x
F(x) = J p(x) dx
o
si generamos un valor aleatorio r, uniformemente distribuido, .e.ntonces nos
debemos preguntar para que valor de x, la suma de las probablhdades da r.
Entonces debemos resolver la ecuacin:
x
r = I p(x) dx
o
resolviendo la ecuaCIon, el valor de x, ser el aleatorio generado que
cumpla con la distribucin p(x).
La Distribucin Exponencial . .
Es una distribucin continua que est completamente defmIda cuando se
conoce la media de la distribucin 1IJ.l. Est dada por f(x) = J.l.e""X, donde e
es la base de los logaritmos neperianos e = 2.718281828, J.l es el .valor
esperado (tasa media), 1/J.l es la media de la Una. propIedad
importante de la Distribucin Exponencial, es que no tIene memona; esto es,
lo que ocurra en el futuro no depende de lo ocurrido anteriormente
independientes) y la mayora de sus valores son de .la
esperada (1/,..). A diferencia de la Distribucin de POIsson, la Dlstnbuclon
('sar Liza Avila. No mates la produccin intelectual, no copies ste libro.
(
"1
Generacin de Nmeros Aleatorios y Simulacin 159
Exponencial, es una distribucin continua, por lo que puede tomar valores
fraccionarios.
La Distribucin Exponencial es una verdadera distribucin de probabilidad
pues:
'" '"
F(x) = f /le"'" = e-"x lo = 1 - e""'" = 1
o
Para simular una variable aleatoria (x) con distribucin exponencial,
haremos uso del "Mtodo de la Transformada Inversa". Empezamos generando
un nmero aleatorio (r) entre O y 1 uniformemente distribuido y nos
preguntamos que valor de x, hace que la funcin de densidad acumulativa
(fda) sea igual a r. Siendo una distribucin continua, la funcin de
densidad acumulativa (fda) desde O hasta x, ser:
x x
F(x) = f /le'''' = e-J.Ix lo = 1- e""X
o
Esta expresin debe igualarse al nmero aleatorio generado: r = 1- e -"x. lo
que equivale a: e""x = 1 - r, aplicando logaritmos neperianos para despejar x
tenemos: In(e""X) = In(1-r), esto es: -J.l.x.ln e = In(l-r), puesto que In e =1,
tendremos:
x = -In(l-r)/ J.l
En otras palabras si generamos un nmero aleatorio r distribuido
uniformemente entre O'y 1, aplicando la frmula anterior podremos obtener
un nmero aleatorio x distribuido exponencialmente.
La grfica de una Distribucin Exponencial se
muestra en la figura adjunta. Aqu poderhos
observar el valor medio 1/J.l y el rea r
encerrada bajo la curva f(x) y los lmites O y x.
y
r
X
1/11 x
Csar Liza Avila, Mis libros son econmicos, no hay razn para copiarlos,
I
I
1
l'
160 Algoritmos y su Codificacin en C++. Volumen 2.
Csar Liza A vi/a
La distribucin exponencial, es muy usada en la simulacin de lneas de
espera (colas) para generar el tiempo de atencin; en la teora de
confiabilidad, para estimar el tiempo entre fallas de los componentes
elctricos; as como en la desintegracin de partculas radiactivas, como por
ejemplo para calcular la edad de los fsiles mediante el carbono 14.
Existe una estrecha relacin entre la Distribucin Exponencial y la Distribucin
de Poisson, puesto que si la distribucin exponencial modela el tiempo
(continuo) entre dos eventos, para un tiempo t habrn ocurrido una cantidad
entera de eventos que estar dada por la Distribucin de Poisson.
La funcin exponencial( ), se
encarga de generar una
variable aleatoria que sigue
una Distribucin Exponencial.
Aqu, generamos un nmero
aleatorio (r) uniformemente
distribuido entre O y 1, para
luego aplicar directamente la
frmula y obtener la variable
aleatoria distribuida
exponencialmente.
Note que si r es un nmero
aleatorio uniformemente
distribuido entre O y 1,
entonces 1 - r tambin lo es,
por lo que podramos haber
optimizado el programa y
escribir -Iog (r) en vez de -
log (l-r). Recuerde que en
C/C++ la funcin log( )
obtiene el Logaritmo Natural
o Neperiano, mientras que el
f
l[' Logaritmo Decimal o de
Briggs lo podemos obtener
Generacin de Nmeros Aleatorios JI Simulacin 161
Solucin: .
La Distribucin Normal, llamada tambin campana o curva de Gauss, es
una distribucin continua muy utilizada en estadstica, pues muchos
fenmenos naturales se comportan en forma normal. Esto es evidente
puesto que la mayora de caractersticas de los fenmenos presentes en la
natura)eza son similares y cercanos a la media, algunos poco se desvan de
ello. Por ejemplo, las tallas y pesos de los seres vivos, el efecto de una
dosis de algn frmaco, las notas de los alumnos, errores de medicin, la
demanda de productos, etc.
(X-I1- )'
I
I( x) = -----::.:::::--- e
uY2n
J1 = valor medio
u = desviacin estndar
2 .
U = vananza
n = 3.1415 ...
x = valor de la abscisa
e = 2.717282818
La Distribucin Normal, esta definida por dos parmetros su 'media y su
desviacin estndar; N(I-l, u)
Caractersticas:
Puede tomar cualquier valor (- 00, +00).
Son ms probables los valores cercanos al valor medio.
Conforme nos separamos del valor medio, la probabilidad va
decreciendo de igual forma a derecha e izquierda (es simtrica).
Conforme nos separamos del valor medio, la probabilidad va
decreciendo de forma ms o menos rpida dependiendo de un
parmetro cr, que es la desviacin estndar. .
Csar Liza A vi/a. Mis libros son econmicos, no hay razn para copiarlos.
~ - ~ ~ - - - - - - - - - - - - - - - - - - - - - - - - - - - - ~ - - ~ . - - - ~ _ . - ~ -_o -
f"
'"
';
.
162 Algoritmos y su Codificacin en C++. Volumen 2. Csar Liza Avila
Para generar una variable aleatoria que siga una DistribuCin Normal,
podramos hacer uso de la transformada inversa, pero como se habr dado
cuenta dicha integral no es calculable por mtodos manuales, debiendo
hacer uso del clculo y de los mtodos numricos, o de la misma
simulacin, tal como se mostr en el Problema 5.5.
Una forma ms fcil de generar esta variable aleatoria, se basa en el
Teorema del Lmite Central: la suma de variables aleatorios tiende a una
distribucin cuando la cantidad de variables es grande.
Segn este teorema, si los valores "o, Xl. . . ., X
n
estn distribuidos
independientemente con media J.l y varianza ci entonces la variable
(XO+XI+" .+xn) - nJ.l
Zn = ---------.--.---.-------
... (n 0'2)
est aproximadamente distribuida en forma normal con media O y varianza
1, cuanto mayor sea el valor de n mejor ser la aproximacin.
Sabiendo que una variable aleatoria x que sigue una distribucin uniforme
de O a 1, tiene una media 1/2 y una varianza de 1/12, si generamos n
nmeros aleatorios uniformemente distribuidos entonces, la expresin
anterior se transforma en:
(XO+XI+" .+xn) - 012
Zn = ------------_.-.-------.
... (n /12)
y puede usarse para calcular para calcular una variable aleatoria normal
estndar con media O y varianza 1.
Esta frmula funciona bien para valores pequeos de n, por lo general se
escoge n=12 para eliminar la raz cuadrada, quedando como:
n=11
Zn = :Ex- 6,
i=O
donde Xi es un aleatorio distribuido uniformemente, Zn es la variable
aleatoria Normal Estndar, por lo que si deseamos una variable aleatoria
Z con Distribucin Normal, con media J.l y varianza 0'2 usamos el
resultado anterior haciendo:
Z= J.l+O'Zn
relacin que utilizamos en nuestro programa.
Csar Liza Avila. No mates la produccin intelectual, no copies ste libro.
Generacin de Nmeros Aleatorios y Simulacin 163
(
Csar Liza Avila. Mis libros son econmicos 110 hay ra ' . 1
. ., zon para Coptar.os.
I
10..,
164 Algoritmos y su Codificacin en C++. Volumen 2.
Solucin:
Si tenemos 3 elementos {I, 2, 3}
al mezclarlos podemos obtener 3!
= 6 resultados diferentes que son:
{ 1, 2, 3}, (l, 3, 2}, {2, 1, 3}, {2, 3,
l}, {3, 1, 2}, {3, 2, l}; ha esto se le
conoce como permutacin, si de
todas estas posibles formas de
ordenar los elementos tomarnos
una al azar, estaremos hablando de
una permutacin aleatoria.
Como recordar (hablamos de
permutaciones en mi libro
Algoritmos y su Codificacin en
C++, Volumen 1), la cantidad de
permutaciones crece rpidamente,
por esto no es recomendable
obtener todas las permutaciones
para elegir una. Es mejor aplicar
el siguiente mtodo: Tomemos el
primer elemento e intercambimoslo por
olro ubicado en una posicin aleatoria.
Tomemos el segundo elemento ti
intercambimoslo por otro ubicado en una
posicin aleatoria, y as sucesivamente-
Csar Liza A vila
hasta el ltimo elemento. Esto es lo que hace la funcin permutaAleatoria( ).
Note que no se repite ningn elemento, puesto que solo los cambiamos de
lugar aleatoriamente.
Podemos necesitar una permutacin aleatoria en varias situaciones: al
barajar las cartas, para determinar el orden en que llegarn los caballos en
una carrera donde todos tienen la misma probabilidad de ganar, el orden en
que llegarn los alumnos al saln de clase; es decir, en todas aquellas
situaciones en donde necesite mezclar un conjunto de elementos.
Csar Lizo Avila. No mates la prodUlocilI intelectual, no copies ste libro.
Generacin de Nmeros Aleatorios y Simulacin 165
Solucin:
La cantidad total de combinaciones o formas diferentes de agrupar n
elementos tornados de r en res:
n!
c
n
r =
(n-r)! r!
Si tenemos 3 elementos { 1, 2, 3} podemos escoger 2 de ellos de:
3!
C
3
2 = ----------- = 3 formas diferentes
(3-2)! 2!
al igual que con las permutaciones, obtener todas las combinaciones y
escoger una de ellas, resulta computacionalmente costoso.
Sin embargo, podemos modificar ligeramente el algoritmo del problema
anterior:
Tomemos el primer elemento e intercambimoslo por otro ubicado en una posicin
Tomemos el segundo elemento e intercambimoslo por otro ubicado en
una posicin aleatoria, y as sucesivamente hasta el elemento r-simo.
Como notar la nica diferencia, es que solo llegamos hasta el elemento r y
no procesamos el resto de elementos. Esto es lo que hace la funcin
combAleatoria( ).
Las combinaciones aleatorias estn presentes en muchas situaciones, por
ejemplo, si tengo n individuos y deseamos tomar una muestra de r
elementos, escogida al azar, en la generacin de una cartilla de Bingo en
donde para cada columna debemos escoger 5 nmeros dentro de J 5
posibles; en el popular juego de la Tinka, si deseamos simular que bolitas
saldrn en el sorteo cuando todas tienen la misma probabilidad de salir,
pues de 45 bolitas sacamos 6 sin que se repitan, entre otras situaciones.
Csar Liza A vda. Mis libros son econmicos, no Iza,. f"CI;::Il para copiarlos.
166 Algoritmos y su Codificacin en C++. Volumen 2.
Csar Liza Avila
A propsito la Tinka puede producir:
45!
C456 = ____________ = _______ = 8' 145,060 resultados diferentes
(45-6)! 6! ,3'9! * 6*5*4*3*2
de los cuales solo uno es el ganador del premio mayor, esto es la
probabilidad de sacarse la Tinka es 1 entre 8'145,060, o sea: 0.000000123
Liza Avila. No mates la produccin intelectual, no copies ste libro.
I
Generacin de Nmeros Aleatorios y Simulacin 167
l. Un generador de nmeros aleatorios desarrollado por Jhon Von
Neumann hacia 1946, y que mostr el camino para generar nmeros
aleatorios por computadora, es conocido como "mtodo del cuadrado
central". Consiste en elevar al cuadrado el anterior aleatorio
generado y extraer los dgitos centrales. El valor inicial es conocido
como semilla y el usuario lo ingresa o lo toma de la computadora a
partir del reloj interno. Por ejemplo, si la semilla eS 121, la elevamos
al cuadrado tendremos 14641, extraemos sus 3 dgitos centrales se
obtiene 464, a partir del cual se obtendr el siguiente aleatorio.
Genere n aleatorios con este mtodo. Aunque no es un mtodo
adecuado, pues genera secuencias muy cortas de nmeros y parece
existir correlacin entre ellos; tiene un valor histrico, puesto que fue
el primer mtodo implementado en computadora y nada menos que por
el creador de la arquitectura en la que se basan las computadoras
modernas.
2. Genere aleatoriamente una fecha vlida. Considere los aos bisiestos.
3. Genere aleatoriamente un entero y luego permute sus dgitos.
4. Se coloca una reina en un tablero de ajedrez vaco, muestre una
caminata aleatoria de la reina.
5. El volumen de una esfera es v=4/3 nr
3
, supongamos que no conocemos
la constante C=4/3, estime por simulacin el valor de C sabiendo que
la ecuacin de la esfera es x
2
+l+l=1. Sugerencia: extienda el
Problema 5.7, dado en dos dimensiones, hacia el espacio
tridimensional.
6. Genere una baraja de cartas y luego mzclelas.
7. Genere aleatoriaf1!-ente una cartilla de Bingo.
8. En que orden llegarn n alumnos a unflula de clases. Considere el
cdigo y el nombre del alumno. Sugerencia: Use una permutacin
aleatoria de un arreglo de estructuras.
9. Se desea emparejar n hombres con m mujeres pero de manera
aleatoria, muestre una forma en que pueden emparejarse. Quines
quedan sin pareja? Sugerencia: Use una permutacin aleatoria.
10. Coloque en una matriz de nxn los nmeros del 1 al n
2
aleatoriamente,
sin que se repitan. A esto se le llama Cuadrado Latino.
Csar Liza Avila. Mis libros son econmicos, no hay rqzn para copiarlos.
l8 Algoritmos y su Codificacin en C++. Volumen 2.
Csar Li:Ci A vila
l. Se desea realizar un estudio mdico paro comprohar la efectividad de
un nuevo medicamento. Para ello se divide a los voluntarios en dos
grupos, uno llamado grupo de control, al cual solo se les dar un
plarebo (una sustancia que no causa ningn efecto) y al otro se le
aplica el nuevo medicamento. Si tenemos iJl voluntarios selecone
aleatoriamente un grupo de n/2 personas, ai cual se va a aplicar el
nuevo medicamento. Sugerencia: use una combinacin aleatoria.
12. Se tiene m carreras con 11 caballos en cada carrera, todos los caballos
tienen la misma probabilidad de ganar. Muestre el orden en que
llegarn en cada carrera e indique cuntas veces va ganando cada
caballo. Sugerencia: use una permutacin aleatoria por cada carrera.
13. Genere n elementos de un arreglo, luego elimine todos los elementos
aleatoriamente. Muestre el orden en que se van eliminando.
14. Un dispositivo incluye dos componentes. La probabilidad que uno de
ellos falle es p, el dispositivo deja de funcionar si los dos componentes
fallan. Escriba un programa que simule el encendido del equipo 11
veces y diga cuntas veces falla.
15. El juego Memoria contiene n pares de figuras diferentes y consiste en
descubrir dos figuras; si son iguales, stas se retiran y se contina
escogiendo otra pareja. Escriba un programa que permita jugar
memoria. Sugerencia: llene un arreglo de nxll elementos con n
2
f2
pares de elementos iguales, y fuego mzclelos.
16. Muestre a un cuerpo que se mueva aleatoriamente, dentro de los
lmites de una matriz, y una casilla a la vez. Debe verificar los lmites
de la matriz. Este movimiento aleatorio se llama movimiento
Browniano y representa el nwvimiento de una partcula muy pequea
(dimetro inferior de una milsima de milmetro) en un fluido debido al
impacto de los tomos o molculas del fluido sobre la partcula. Por
ejemplo el humo que se dispersa por el aire o la tinta que se difunde en
el agua o los granos de polen en el agua.
17. Un Bull o Diana contiene n crculos concntricos cada
uno de radio conocido, se lanza un dardo que cae en
alguno de los crculos, cada uno de ellos tiene un
puntaje definido. Simule el lanzamiento de d dardos en
el Bull y muestre el puntaje total obtenido. Sugerencia:
Genere dos nmeros aleatorios dentro del intervalo continuo desde
cero hacia el radio mayor, use la ecuacin de la circunferencia
X2 +l=r
2
, para determinar dentro de qu crculo cay.
Csar Liza A vi/a. No mates la produccin intelectual, no copies ste libro.
Generacin de Nmeros Aleatorios y Simulacin 169
18. Se tiene una cerradura compuesta de tres dgitos (del O al 9). Se
ingresa la clave, pero sta se olvida. Si generamos claves al azar En
cuntos intentos habremos logrado abrir la cerradura? Asegrese de
no repetir una combinacin ya probada.
19. Se realiza un minicampeonato deftbol con 6 equipos: A, B, C, D, E Y
F; en el cual cada equipo juega 5 partidos. Se desea simular los
resultados de dicho campeonato generando aleatoriamente el nmero
de goles que consiguen y recibe cada equipo. El puntaje es 3 puntos
para el ganador y 1 punto para cada uno, si empatan. El Campen
ser aquel que tenga el mayor puntaje, o si hay empate la mejor
diferencia d goles. Asuma que en un partido no puede haber ms de
12 goles en total ya sea recibidos o anotados por ambos equipos.
20. Una empresa de carga, dispone de un camin y est considerando
comprar otro camin. En la actualidad alquila los camiones
adicionales necesarios a 250 soles al da. El camin de la empresa
ocasiona un gasto de 150 soles al da se use o no. La compra de un
nuevo camin ocasionara el gasto de 175 soles al da. De los datos
histricos se sabe que el nmero de camiones requeridos sigue la
siguiente distribucin:
O 0.10
1 0.40
2 0.35
3 0.15
Realice una simulacin para decidir si es conveniente la compra de un
nuevo camin.
Csar Liza Avda. Mis libros SOI1 econmicos, no hay razn para
!
Punteros y
Asignacin
Dinmica de
Memoria
i
l
b
Punteros 173
oludn:
La memoria puede verse como una serie de casilleros consecutivos que
tienen un nmero que las identifica, llamado direccin de memoria, cada
casillero ocupar byte. Estas direcciones de memoria se acostumbran a
escribir en hexadecimal.
Cmo se almacenan las variables en memoria?
Si declaramos las variables: int a = 50;
char b = 'M';
fioal e = 3.75f;
double d = 2.1;
se almacenan en memoria tal como se muestra:
OxOO12FF6B L-
OxOO12FF6C c= d
0,00"'1'60 ~
OxOOl2FF6E
OxOOl2FF6F 2.1_
OxOOl2FF70
OxOOl2FF71 [
OxOOI2FF72
c=
OxOO12FF73
c::-=:-
OxOO12FF74
, " OxOOl2FF75
OxOOl2FF76
OxOOI2FF77
I
OxOOi2FF78
~ b
OxOOl2FF79
' ~ : " , . ~ / . /,- "
OxOOI2FF7A
OxOOJ2FF7B
Primer byte
OxOO12FF7C
libre de
OxOO 12FF7D ~
memoria
OxOOl2FF7E ~
;". OxOOI2FF7F
I
}
Los 3 bytes
quedan libres,
pues las variables
se alinean a un
mltiplo del
tamao de la
palabro del
sistema (32 bits)
Csar Liza Avila. Mis libros son econmicos, no hay razn para copwrlos.
174 Algoritmos y su Codificacin en C++. Volumen 2. Csar Liza Avila
Es decir la computadora almacena las variables primero en las posiciones
ms altas de la memoria, alinendolas al inicio del tamao de la palabra. En
nuestro caso la primera direccin de memoria libre fue Ox0012FF7F, pero
puede variar para usted, pues depender de la gestin de su sistema
operativo.
Si tenemos el nombre de la variable, podemos obtener fcilmente la
direccin de memoria en la cual se inicia. Para esto usamos el operador &
colocado delante de III variable. No debemos confundir con el AND a nivel
de Bits. Si declaramos la variable int a=50; podemos mostrar su direccin
de memoria de la siguiente manera: cout&aendl;
Al imprimir la direccin de una variable char, tal como b, nos sale la
direccin de memoria pero en decimal, por lo que tuvimos que imprimirla
en hexadecimal mediante hex.
Csar Liza A vila. No mates la produccin intelectual, no copies ste libro.
I
Punteros 175
En muchas ocasiones necesitamos almacenar una direccin de memoria, es
por ello que surgen variables capaces de hacerlo. A este tipo de variables se
les conoce como punteros. .
Qu son punteros?
Son variables como cualquier otra. Pero NO almacenan un valor sino que
almacenan una Direccin de Memoria
p
Ox0012FF70
una variable comn
una variable puntero
Declaracin de punteros
Se declaran como cualquier variable pero se coloca un asterisco (*) antes
del nombre de la variable:
int *p; 11 p guardar una direccin de memoria, en dicha direccin habr un entero
double *r; 11 r guardar una direccin de memoria, en dicha direccin habr un doble
El tipo de dato nos dice que si vamos a la direccin de memoria
almacenada en la variable puntero, en esa zona encontraremos un valor del
tipo declarado.
El Operador Direccin: &
Ya dijimos que un & (ampersand) colocado delante de la variable, nos da la
direccin de la memoria de la variable. En la declaracin anterior, p y r son
variables (que almacenan direcciones de memoria), y por lo tanto tambin
ocupan memoria, cuya- direccin de inicio podemos obtener mediante &p y
&r.
Por ejemplo:
int *p, x;
cout&x;
cout&p;
1/ p es un puntero, x es un entero
II imprime la direccin de memoria la variable x
II imprime la direccin de memoria la variable p
Csar Liza A vi/a. Mis libros son econmicos, no hay razn para copiarlos.
176 Algoritmos y su Codifiracn en C+ +. Volumen 2.
Csar Liza A vila
Podemos hacer: p = &x;
puesto que &x es ua direccin de memoria y p es una variable capaz de
almacenar una direccin de memoria.
El Operador Indireccin: *
Nos da el contenido de la direccin de memoria almacenada en la variable
puntero.
Por ejemplo:
float x=5, *z;
z == &x
cout*z;
En la ltima lnea el * aplicado a una variable puntero z, significa "ve a la
direccin de memoria que almaceno y toma el valor que encuentres".
No confundir el * en las declaraciones de un puntero (como en float *z),
con el operador * en las instrucciones (obtn el contenido de, como en
cout*z), ni en las operaciones aritmticas donde * es el signo de
multiplicacin.
Como vemos, cada variable ocupa una direccin de memoria. Esto es cierto
para otros elementos, as las funciones tambin tienen una direccin de
inicio, los arreglos de igual manera, y cualquier tipo de dato definido por el
programador como las estructuras, y las enumeraciones. Asimismo, se
puede declarar una variable que almacena una direccin de memoria en
cuya celda hay otra direccin de memoria, o sea un puntero a un puntero.
Recuerde:
Todo puntero debe ser inicializado antes de ser utilizado, sino se tendr un
puntero que apunta a una direccin desconocida.
Csar Liza A vila. No mates la produccin intelectual, no copies ste libro.
Punteros j 77
Solucin:
Aunque las funciones puedan contener varios retum, no es posible para una
funcin devolver ms de un valor. Para que la funcin "devuelva" ms de
un valor se debe usar punteros.
dos formas de pasar parmetros a funciones. La primera es el paso de
parame.tros por valor, en donde el valor de la variable se coPia a la zona de
memOrIa aSIgnada a la funcin. Todo cambio que se haga en esta zona, solo
afectar a la funcin, y no ser conocida por maine ). La segunda forma, es
el paso por referencia, en donde a la funcin, se le enva la direccin de
memoria de las variables, de tal manera que la funcin pueda acceder a esa
zona de memoria y modificar su contenido, para esto se usan los punteros y
su operador & para obtener la direccin y * para obtener el contenido.
,que arreglo se pasa por referencia, es por ello que cuando
una funclOn modIfIca los datos del arreglo, main( ) conoce los cambios.
Podramos escribir el siguiente programa:
# include <iostream.h>
void swap(int, inO;
void main(void)
{ int a, b;
cout"Ingrese a: "; cina;
cout"Ingrese b: "; cinb;
swap(a, b);
couk<"a= " a endl;
cout"b== " b endI;
void swap( nt a, nt b )
{ int t;
t == a;
a == b;
b == t;
esperando que funcione correctamente, sin embargo, no se producir
ningn cambio. Veamos por que ocurre esto:
Csar Liza Avila. Mis libros son econmicos, no hay razn para copiarlos.
178 Algoritmos y su Codificacin en C++. Volumen 2, Csar Liza A vila
Cuando se enva parmetros por valor a una funcin, significa que se copia
el valor que actualmente tiene la variable, hacia otra zona de memoria
asignada a la funcin que se invoc.
b) 1 1 1 1 t 1 d
t = a
a =b
b = t
termina el cdigo de
la funcin y por lo
tanto la memoria
asignada a esta, se
libera, perdindose
los cambios locales.
]
maine )
maine )
maine )
swap( )
swap( )
swap( )
swap( )
,
a b t
'"
f'
20 20 llY
.","
?
Para que no se pierdan los cambios realizados, la funcin debe ser capaz de
modificar los datos en las direcciones de memoria que correspondan con las
variables de main( ). Esto solo se puede hacer cuando se realiza el paso de
parmetros por referencia, es decir mediante el uso de punteros.
Csar Liza Avila. No mates la producrin intelectual, no copies ste libro.
(
Punteros 179
Consideremos que en main( ), las variables a y b son de tipo int, mientras
que en swap( ), sus variables locales a y b son punteros a enteros int *, y
mostremos grficamente lo que debemos hacer:
Se invoca a la funcin
envindole las
direcciones de memoria
de las variables
swap(&a, &b)
maine ) swap( )
Una forma comn de representar las variables punteros locales de swap( ) a
y b, es usar una flecha, que significa "el a local de swap( ), apunta a la
direccin de memoria donde se ubica el a de main( )" y "el b local de
swap( ), apunta a la direccin de memoria donde se ubica b de main( )"
a-de swap( ), apunta a
a de main().
b de swap( ), apunta a
b de main().
t = *a
*a = *b
*b = t
maine ) swap( )
IQNi I $r--r-:--;r 1'-------'
maine )
swap( )
maine ) swap( )
1 1 1
------
maine )
swap( )
..
Csar Liza Avila. Mis libros son econmicos, no hay razn para copiarlos.
'1
....
180 Algoritmos y su Codificacin en C++, Volumen 2.
Se libera la memoria
asignada a swap( ), y
main( ) conoce los
cambios
main( )
Csar Liza Avila
swap() , .....
r[FrJ
De esta manera, los cambios, que hicimos en la funcin swap( ), sobre el
contenido de a y b, afectan a main().
El programa que hace esto, se muestra a continuacin:
@ Csar Liza A vi/a. No mates la preduccin intelectual, /lO copies ste libro.
Punteros 18J
Solucin:
Sea el punto (a, b) del sistema de coordenadas cartesianas.
y
b (.,b)
/'
P/
./
;Z
lA 1
V,U
a
x
las coordenadas polares estn dadas por un ngulo (9), y la distancia del
punto al origen (p).
Matemticamente:
8 = arctg(b/a)
p = ...JCa
2
+ b
2
)
. relaciones que usaremos en nuestro programa.
Como la funcin debe ser capaz de cambiar ms de un valor, entonces
debemos usargl pasQ por referencia/,es decir
La invocacin a LeeCartesianasC&x, &y), indica que se le enva las
direcciones de me1f1oria correspondientes a las variables a y b, que maine )
conoce, de tal manera que la funcin pueda realizar los cambios al
contenido de esas direcciones.
La invocacin aPolares(x, y, &a, &b), indica que x yy, se pasan por valor,
es decir los cambios que haga sobre estas variables la funcin aPolares( ),
no sern conocidas por maine ); mientras que a y b, se pasan por
referencia, es decir los cambios que haga la funcin aPoJares( ), sern
conocidos por maine ).
@ Csar Liza A vi/a. Mis libros son eronmicos, no hay razn para copiarlos.
182 Algoritmos y su Codificacin en C++. Volumen 2. Csar Liza A vi/a
La funcin LeeCartesianas( ), lee la abscisa y ordenada, ya travs de los
punteros, cambia los valores en la zona de memoria correspondiente a
main( ), de tal manera que cuando se libere la memoria asignada a
LeeCartesinas( ), los valores ledos, sean conocidos por main( ).
En aPolares( ), x y y no deben ser cambiados por la funcin,entonces se
pasan por valor, mientras que el ngulo y la distancia calculados en
aPolares{ ), se pasan por referencia, puesto que se debe modificar los
valores conocidos por main(). .
Csar Liza Avila. No mates la produccin intelectual, no copies ste libro.
Punteros 183
Solucin:
Existe una estrecha relacin entre punteros y arreglos, lo primero que
debemos recordar es que el nombre del arreglo indica la direccin de
memoria a partir del cual se almacenan sus elementos, y que estos se
almacenan en posiciones consecutivas de memoria. Es decir si hacemos:
int x[] = {lO, 20, 30};
cout x endl;
imprimiremos una direccin de memoria, osea x es un puntero, pero como
este valor es asignado por la computadora y, es el punto de entrada a un
conjuntwde elementos, no podemos cambiarlo a nuestro gusto, por ello se
dice que el nombre de una arreglo es un puntero constante.
Para mostrar el valor contenido en ese puntero usamos el operador
indireccin esto es cout*x, por lo que *x ser el valor del primer
elemento o sea 10
Si deseamos el segundo elemento, tendremos que sumar a la direccin x la
cantidad de bytes que ocupa el primer elemento. Esto lo hace
automticamente la computadora utilizl).ndo aritmtica de punteros, basta
con hacer *(x+l). As, la direccin de memoria del elemento x[i] ser (x+i),
mientras que el valor ser *(x+i).
Aritmtica de punteros
Suma
Al incrementar un puntero, se suma a la direccin almacenada, la cantidad
de bytes que tiene el tipo del puntero. Por ejemplo:
double x[] = {1O.1, 20.3, 5.7};
double *p = x;
cout p endl; /1 imprime la direccin de 1er elemento (equivale a imprimir x)
cout*p endl; II imprime 10.1 (equivale a usar 'x)
p++; /1 p=p+ 1; avanza al siguiente elemento tipo double (suma 8 bytes)
cout p endl; /1 imprime direccin del2do elemento (equivale a imprimir x + 1)
cout*p endl; /1 imprime 20.3 (equivale a imprimir '(x+ 1) )
Csar Liza Avila. Mis libros son econmicos, no hay razn para copiarlos.
184 Algoritmos y su Codificacin en e + + Volumen L Csar Liza Avila
El programa sabe cuntos bytes debe sumar a la variable puntero, pues
toma los bytes del tipo declarado p<1ra el puntero, en este caso dmib!e, le
sumar 8 bytes. No es posible sumar i,a cantidad de bytes que deseemos,
sino que el compilador suma la canti(i:ld de segn el tipo del puntero.
Por ejemplo, en: !11 :: P -1- 2;
suma 2*8 =16 bytes a p, pues p apunta <1 01,1
o sea apuntar al tercer elemento ppr lo que *p ser 5.7, (tambin pudimos
haber usado *(x+2) ).
La diferencia entre usar x y usar p, es que x, al ser el nombre de un arreglo,
es un puntero constante, es decir no podemos cambiar su valor, mientras
que p es un puntero, es decir pode1I
1
os cambiar su valor. Por ejemplo, no
podramos hacer x++, pero si p++.
Resta
Al decrementar un puntero, se resL) a la direccin almacenada, la cantidad
de bytes que tiene el tipo del puntero. Por ejemplo:
float x[] = {lO.lf, 20.3f, 5.7f};
fIoat *p = x+2;
cout p endl;
cout*p endl;
cout p endl;
cout*p endl;
// imprime direccin del ltimo elemento
11 imprime 5.7
II resta 4 bytL, apunta al elemento anterior
// imprime dimrcin del penltimo elemento
11 imprimA ;n J
El programa sabe cuntos bytes deh' restar a la variable puntero, pues toma
los bytes del tipo declarado para e, puntero, en este caso float, restar 4
bytes. No es posible restar una cantidad de bytes que deseemos, sino que el
compilador resta la cantidad de bytes segn el tipo del puntero.
Por ejemplo:
p = p - 2; II resta 2*4 =8 bytes a p, pues p apunta a un float
Recuerde tener cuidado en NO acceder a una zona de memoria que no
ha sido asignada a alguna de las variables del programa. Esto era posible
en Modo Real (DOS), pero no es posible en Modo Protegido (Windows).
@ Csar Liza A vila. No mates la I'mduccil1 intelectual, no copies ste libro.
Cmo se almacena un arreglo?
Si declaramos un arreglo y un entero:
int x[] = {65, 66, 67, 68};
int n=4;
Punteros 185
se almacenan en memoria tal como se muestra
Primer byte
libre de,
memoria
OxOO12FF6C
OxOO12FF6D
OxOO12FF6E
OxOO12FF6F
OxOO12FF70
OxOO12FF71
OxOO12FF72
OxOO12FF73
OxOOI2FF74
OxOO12FF75
OxOO12FF76
OxOO12FF77
OxOO12FF78
OxOO12FF79
OxOO12FF7A
OxOO12FF7B
OxOO12FF7C
OxOO12FF7D
OxOO12FF7E
OxOO12FF7F
La memoria se
asigna desde las
posiciones ms altas,
pero el primer
elemento del arreglo
se asigna desde la
ms baja
Aqu est el programa
pedido. Para cada
elemento del arreglo,
slo mostramos las
,
yoid'
rl1
a1?(Void): .' ..' .' '., ....
.{
.
direcciones de
memoria y sus
contenidos, as como la
direccin de n.
.\ edntehido"tldl'.'
"f,'{ ,t'::::(:i);';;,;''';\J ".",'. ' . ,", . .'
Ofv.tn J""J,J,)<: -rOl"., .,', '
'''"' " . ','
Csar Liza Avda. Mis libros son econmicos, no hay razn para copiarlos .
186 Algoritmos y su Codificacin en C++. Volumen 2.
y qu ocurre si declaramos n antes que x?
. int n=4;
int x[ ] = {65, 66, 67, 68};
Primer byte
libre de
memoria
>
OxOOl2FF6C
OxOOl2FF6D
OxOO12FF6E
. OxOOl2FF6F
OxOO12FF70
OxOOI 2FF7 1
OxOO12FF72
OxOO12FF73
OxOO12FF74
OxOO1 2FF75
OxOO12FF76
OxOO12FF77
OxOO12FF78
OxOO12FF79
OxOOI2FF7A
OxOO12FF7B
OxOO12FF7C
OxOO12FF7D
OxOO12FF7E
OxOOI2FF7F
Csar Liza A vila
o sea que si leemos x[4]
sobre escribiramos el
valor de n!
Csar Liza Avila. No mates la produccin intelectual, no copies ste libro.
Solucin:
El programa usa la
notacin puntero,
para indicar cada
elemento. Por lo
dems es similar al
mostrado en el
captulo sobre
arreglos de mi libro
"Algoritmos y su
Codificacin en
C++", Volumen 1.
Note que en la
funcin int *p, es
equivalente a escribir
int p[ ]. Ahora puede
entender porque,
cuando una funcin
hace cambios sobre
un arreglo, main ( )
conoce los cambios,
pues en realidad se
pasa un puntero en
IngresoDatos(n, x),
donde x es el nombre
del arreglo, es decir la
direccin de inicio del
arreglo. Recuerde que
todos los arreglos se
pasan por referencia.
Punteros 187
Csar Liza A vila. Mis libros son econmicos, no hay razn para copiarlos.
..,
188 Algoritmos y su Codificacin en C++. Volumen 2. Csar Liza A vila
. Si ingresamos la palabra "lhloN", el carcter a buscar C:f!lJr "" H, Y el carcter
de reemplazo entonces podramos representar la memoria ocupada,
como:
memoria asignada a maine )
palabra I h I o 11 I a I NULL I
car [2J
memoria asignada a reemplazar( )
p
car [2J
El bucle while(*p ), recorre cada
letra hasta encontrar el terminador
NULL. Si la letra es igual a la
buscada (*p==car), se reemplaza
por otra (*p=c). En cada vuelta
siempre se avanza hacia la
siguiente direccin de memoria
(p++).
Csar Liza A vda. No mates la prodUCcin intelectual, no copies ste libro.
Para resolver este problema debemos
colocar dos punteros al inicio de la
cadena: char *r;
r=p;
LBJ E I e I 01 N I o I e E R I NULL 1
avanzamos uno de ellos.hasta que apunte
al ltimo elemento:
while (*r)
r++;
r--;
IRIElclolNlolclEIRINULO
rb
p
cJ,
Comparamos el contenido apuntado por
r y p, avanzando un elemento y mientras
p < r:
I R I E I e I o I N I o I e I E I R I NULL]
Punteros 189
en caso de encontrarse en el camino con contenidos de r y p diferentes
entonces retornar O. De haber terminado el bucle entonces ser
palndroma, retornando 1. Esto es lo que hacemos en el programa.
Note que el p de maine ) es constante y no puede cambiar pero el p de
EsPaJindroma ( ) es una variable puntero por 10 que podemos modificarla.
Csar Liza A vi/a. Mis libros son econmicos, no hay razn para copiarlos.
190 Algoritmos y su Codificacin en C++. Volumen 2. Csar Liza A vila
Solucin:
Coloquemos un puntero a cada palabra:
p
J lo 11 I al NULL I
Imlu In Id lo I NULL I
q
rrf
A vanzamos hasta la primera posicin libre
de la primera palabra.
1m lulnldlolNuLLI
qm
a partir de la poslclOn actual de p,
empezamos a copiar cada letra apuntada
por q, (*p=*q), y avanzamos p y q una
posicin (p++, q++)
I h I o I 1 I a I mi u In I d I ~ I p
I m I u I n I d I 01 NULL I
q[iJ
Finalmente, colocamos el NULL, que toda cadena debe tener (*p=NULL).
Ih lo 11 la Imlu In Id lo I NULLt"W
p
Note que pal1[ ], debe tener el tamao suficiente para almacenar las dos
palabras.
Csar Liza Avila. No mates la produccin intelectual, no copies ste libro.
- - - - - - - - - - - - - - - - - - - - - ~ - - - ~ - - - - - ~
Solucin: _
Leemos un arreglo
x[ J, de n elementos
mediante
IngresoDatos( ). Cada
una de las
direcciones de
memoria de los
elementos de x[ J,
los asignamos a un
arreglo de punteros
(p[ D, mediante
lIenaArregloPunteros( ).
Los punteros
almacenados en p[
J sern los que
cambiaremos, para
que apunten a los
elementos de tal
manera que se
muestren
ordenados.
Punteros 191
Csar Liza A vila. Mis libros son econmicos, no hay razn para copiarlos.
192 Algoritmos y su Codificacin en C++. Volumen 2.
La funcin
), asigna
la direccin de memoria de
cada elemento del arreglo
(fjll+i), en cada elemento del
arreglo de punteros
(y[i]=p+i).
La funcin
IOrdenaDatosPunteros( ), usa el
mtodo de la burbuja y
compara los valores del
arreglo ( *pU-l] > *p[i] ),
pero hace el intercambio en
el arreglo de punteros. El
equivalente eliminando la
notacin de arreglos es:
if ( **(p+j-l**(p+j) )
{
temp == *(p+ j-l);
*(p+j-l)= *(p+j);
*(p+j) == temp;
puesto que p + j - 1 es la
direccin del elemento al
aplicarle un * obtendremos
un puntero, y al aplicarle el
segundo * obtenemos el
valor al cual apunta. Sin
embargo, en esta funcin,
hemos preferido dejarlo en
su notacin como arreglo,
para resaltar el hecho que
estamos trabajando con un
arreglo de punteros.
Csar Liza A vila
En ImprimeOrdenadoPunteros( ), tomamos cada elemento del arreglo de
punteros y mostramos su contenido, es decir mostramos el arreglo de datos
ordenados segn lo indicado en el arreglo de punteros.
Csar Liza A vi/a. No mates la produccin intelectual, no copies ste libro.
Solucin:
Este ejemplo, pretende
explicar el uso de punteros a
estructuras.
Recordar que cuando
tenemos una estructura como:
struct empleado emp;
codigo sueldo
emp I I
y queremos acceder a uno de
sus miembros usamos el
operador ., cada miembro
puede ser accedido mediante
emp.codigo y emp.sueldo
Pero si tenemos un puntero a
una estructura tal como:
struct empleado *q;
.
codigo sueldo
. I
y queremos acceder a uno de
los miembros de la estructura
al cual apunta, usamos el
operador o>, as sus miembros
sern q->codigo y q->sueldo.
Esto es lo que hacemos en el
programa, solo que el puntero
avanza t.omando cada elemento
del arreglo. Note que pudemos
usar p[iJ.codigo (p+i)->codigo
Punteros 193
Csar Liza A vila. Mis libros son econmicos, no hay razn para copiarlos.
194 Algoritmos y su Codificacin en C++. Volumen 2.
Solucin:
. Cuando definimos un arreglo, le
indicamos la mxima cantidad de
elementos que puede contener. Esta
. cantidad puede ser demasiado grande
para los datos que utilicemos trayendo
como consecuencia el desperdicio de
memoria, o lo que es peor, puede
quedamos demasiado corta, teniendo
que ir al cdigo "fuente modificarlo y
volverlo a compilar. A esta forma de
trabajar la memoria, se denomina
esttica, y el tipo de enlace con sus
elementos se denomina enlace esttico o
temprano (antes de compilar). Es por
ello que se ide un mecanismo que, en
tiempo de ejecucin, llamado tambin
enlace tardo o dinmico, el usuario
pueda decirnos cunta memada
requerir. Esta forma se llama asignacin
dinmica de memoria, y consiste en pedirle a
la computadora que nos de una zona de
memoria capaz de almacenar la variable
que le pidamos. Esta nos devolver un
puntero a la -zona de memoria asignada.
Para ello usamos el operador new,
mientras que para liberar la memoria
asignada usamos delete, tal como se
muestra en el programa.
Csar Liza A vila
La asignacin dinmica de memoria y los punteros a estructuras son usados
ampliamente cuando trabajamos con listas enlazadas. Este tema lo tratamos
en mi libro "Estructuras de Datos con C++".
Csar Liza Avila. No mates la produccin intelectual, no copies ste libro.
Solucin:
Las funciones tambin tienen una
direccin de inicio en memoria, y
por lo tanto podemos almacenar
esa direccin en un puntero. Al
igual que los arreglos el nombre
de la funcin nos da la direccin
de InICIO asignado por la
computadora, el cual no se puede
cambiar, por lo que no est
permitida la aritmtica de
punteros.
En el programa declaramos un
puntero a una funcin que recibe
dos argumentos enteros y que
devuelve un entero int (*ptr)(int,
int); es necesario escribir (*ptr),
puesto que, si eliminamos los
parntesis, diramos al compilador
que ptr es una funcin que
devuelve un puntero a un dato
tipo int, que no es lo deseado. La
direccin de inicio de la funcin
suma es asignada a ptr
(ptr=suma), luego leemos los
valores a operar e invocamos a la
Punteros 195
funcin, mediante el puntero ptr(x, y ). Como la funcin suma( ) retoma
valor hacemos s=ptr(x, y). De manera similar para la funcin resta( )
Invocamos a ptr(x, y), e imprimimos el resultadQ. '
El uso de punteros a es .un mecanismo muy potente, ya que podemos
tener arreglos de p.unteros a funcIOnes y hasta podemos usar funciones como
argument?s de funcIOnes. En los lenguajes ms recientes los punteros a funciones
se denomman delegados.
Csar Liza A vila. Mis libros son econmicos, no hay razn para
]96 Algorilnlo" \. su Cod(ficacin en C+ +. Volumen 2. Csw Li"a A vilo
oRucin:
Trabajar con punteros suele ser muy
delicado, puesto que podemos acceder
inadvertidamente a zonas de memoria y
cambiar sus datos, provocando la cada
del sistema. Es por este motivo que
pensando en una forma ms fcil de
trabajar con direcciones de memoria se
ide las referencias. No debe confundir la
referencia con el paso de parmetros por
referencia, que aunque son conceptos
relacionados directamente pues, para pasar
parmetros por referencia, se puede usar
un puntero o una referencia, las
referencias son una forma de ocultar el
trabajo con punteros.
Cuando definimos una referencia,
estamos dicindole a la computadora que
le de un nombre alternativo a la misma
zona de memoria asignada a otra variable.
Grficamente podramos representarlo as:
b
.-,-....,..,,.,...,...-_ ....._---_._._-_.-....
#fuclllde ..
v{Mswap(int &, iriti;); .'
vianlii)(Yoid)
int a=5;
nt &b=a;
La misma zona de memoria tiene 2
nombres a y b, si modificamos b,
estaremos modificando a, y viceversa
en este caso b es una referenci, y se declara anteponiendo el signo &
(ampersalld) delante de la variable. En realidad b es un puntero a la
direccin de memoria ocupada por a, pero con la ventaja que ocultamos la
complejidad eliminando los *. Las referencias fueron introducidas con el
C++. Los lenguajes de programacin ms recientes, dicen no usar punteros
pero si referencias, pero como ve, las referencias son "punteros
encubiertos" .
El programa que presentamos es el mismo que el ejemplo 6,1, pero usando
el operadOl' I"t'fercnda.
@ Csar Liz:u A vi/a, No mates la produccin intelectual, no copies sfe libro.
PUllteros 197
l. Escriba una funcin que acepte un puntero x de lal manera que rada
vez que se llame a la funcin duplique su valor. Llame a esa funcin
varias veces y muestre los valores de x.
2. Escriba una funcin de tipo void que reciba un entero positivo y
obtenga la suma de todos los nmeros hasta dicho entero. El resultado
deber imprimirlo desde maine ).
3. Escriba una funcin que debe ser invocada como mximo II veces y
cada vez que se invoque, sta debe mostrar cuntas veces le queda por
ejecutarse. La funcin debe restar el contador.
4. Escriba una funcin que lea los tres lados de un tringulo y, otra
funcin que determine qu tipo de tringulo es segn sus lados
(issceles, escaleno, equiltero). Las funciones deben ser invocadas
desde maine ), y el resultado impreso desde maill( ). Note que la
primera funcin necesita 3 punteros y la segunda ninguno.
5. Lea dos fracciones y calcule su su/na, el resultado debe ser mostradc'
como una fraccin simplificada. Use una funcin que lea el numerador
y denominador, luego una funcin que los sume y otra que simplifique
la fraccin. Las funciones deben ser invocadas desde mallO y el
resultado impreso en mallO.
6. Escriba una funcin que lea las horas, minutos y segundos, y otra que
le sume una cantidad de segundos. La nueva hora deber ser impresa
desde maill( ).
7. Escriba una funcin que lea los coeficientes (a, by c) de una ecuacin
de 2do grado (ax
2
+ bx + c)y otra funcin que "devuelva" sus races
reales. Las races deben ser impresas desde maine ). Considere que las
races podrn tener parte imaginaria.
8. Escriba una funcin que calcule la parte entera de cualquier nmero
real y tambin la parte decimal del mismo.
9. Escriba Ulla funcin que lea una fecha y otra que tome como
parmetros el da, mes y ao y obtenga la fecha del da siguiente. La
fecha debe imprimirla desde maillO.
10. Se tienen 3 valores a, b y e, cada vez que se invoca a la funcin, a fnma
el valor de c, b toma el valor de a, y e el de b. Escriba una funcin que
haga este trabajo, luego imprima desde maine ) los valores de a, b y c
Csar Liza Avila. Mis libros son econmicos. no hay razn para copiar/os.
198 Algoritmos y su Codificacin en C++. Volumen 2. Csar Liza Avi/a
cada vez que se invoque a la funcin. La funcin se invocar 3 veces.
Por ejemplo, si a, b y e son 1, 2 Y 3, en las tres llamadas debe imprimir
312, 231 Y 123.
11. En qu direccin de memoria se encuentra el menor elemento de un
arreglo y cul es el valor? Deber imprimir esta direccin y el valor
desde maine ). Sugerencia: Escriba una funcin que busque el menor
elemento y retorne un puntero. Ya en maine ), imprima el puntero y su
contenido.
12. Usando punteros, escriba una funcin que calcule la longitud de una
cadena. Muestre los resultados desde maine ).
13. Usando punteros, escriba su propia funcin que determine que cadena
es mayor. Muestre el resultado desde maine ).
14. Se tiene un arreglo con valores desde a hasta b. Se pide llenar en otro
arreglo las direcciones de memoria de los nmeros primos en el
intervalo dado. Luego mustrelos desde maine ).
15. Escriba una funcin para invertir los elementos de' una cadena.
Muestre la cadena final desde maine ).
16. Lea dos cadenas de caracteres e intercale sus caracteres, esto es la
cadena resultante tendr un carcter de la primera cadena, seguida de
un carcter de la segunda, a continuacin otro carcter de la primera,
seguida de otro carcter de la segunda, y as sucesivamente, hasta
terminar las cadenas. La cadena resultante deber imprimirse desde
maine ).
17. Escriba unafuncin que genere aleatoriamente un arreglo dinmico de
n elementos tipo char, con las letras del abecedario, y otra funcin que
mezcle sus elementos. Deber imprimir el resultado desde maine ). Use
punteros.
18. Se tiene un conjunto de datos, y se desea mezclarlos pero sin alterar el
arreglo original. Para esto, se crea un arreglo de punteros, los cuales
se mezclan. Escriba un programa que haga esto.
19. Cree un arreglo de caracteres de manera dinmica, luego usando
punteros y funciones lea n caracteres, imprima todos los caracteres, y
muestre sus direcciones de memoria.
20. Escriba un programa en el que maine ) invoque a una funcin que lea
la cantidad de filas y columnas de una matriz; luego, asigne memoria
dinmicamente para almacenar la matriz, invoque a una funcin que
lea los datos y finalmente, imprima las direcciones de memoria de
cada elemento de la matriz.
(f) Csar Liza Avila. No nw!es la produccin intelectual, no copies ste libro.
Archivos
i
l
J
An:hivos 201
Solucin:
Hasta el momento solo hemos almacenado datos en memoria, ya sea
cuando utilizbamos variables, arreglos o estructuras. Cada dato 10 leamos
desde el teclado o lo asignbamos dentro de nuestro programa. Sin
embargo, tambin podemos leer los datos desde un archivo, mejor an
hacer persistentes los datos y resultados de nuestros programas
almacenndolos en archivos. Existen diversos mtodos para manejar
archivos. Nosotros hablaremos solo de la forma estndar, y dentro de ellas
el acceso byte x byte y en bloques. No hablaremos de los objetos stream
para manejo de archivos, ni sus mtodos pues esto implicara una
explicacin adicional sobre programacin orientada a objetos, la cual
tratamos en otra obra. En su lugar utilizaremos las funciones estndar
provistas por el archivo de cabecera stdio.h, y eventualmente en io.h.
Qu es un flujo o corriente?
Son canales de comunicacin entre el archivo y el programa. El C/C++/C#
ve cada uno de los archivos simplemente corno un grupo de secuencia de
bytes sobre los cuales hay que abrir una corriente o flujo (stream). El flujo
de entrada estndar (stdin) permite que un programa lea datos desde el
teclado, el flujo de 'salida estndar (stdout) permite que un programa
imprima datos en la pantalla, rtentras que un flujo se relaciona con un
archivo utilizando una operacin de apertura fopen( ), y se desliga del
archivo con una operacin de cierre felose(). Todos los archivos terminan
con un marcador de fin de archivo, dado por la constante EOF o por la
funcin feof( ).
Formas de apertura de archivos
Podemos abrir archivos en dos diferentes formas:
Texto: Utiliza conversiones de algunos caracteres. Es decir, puede no haber
correspondencia entre lo que se enva al flujo y lo que se escribe o lee en el
archivo. Por ejemplo: el salto de lnea en archivo se representa por 2
caracteres: retorno de carro (ASCII 10) y salto de lnea (ASCII 13).
Csar Liza AvUa. Mis libros son econmicos, no hay rt.l,:Il para copiarlos.
202 Algoritmos y su Codificacin en C++. Valumen 2. Csar Liza A vila
Binario: Tiene una correspondencia directa entre lo que se enva y lo que
se escribe en el archivo, es decir los bytes que lees (o escribes) son
idnticos a los que estn almacenados en disco.
Sugerencia: Si usa un archivo .txt utilice el modo texto en caso contrario
use el modo binario.
feof( ) Devuelve verdadero si fin del if( !feof(pfich) )
archivo
Modo de Apertura de archivos
Un puntero a un dato tipo FILE, nos permite leer y escribir un flujo o
corriente (stream). Este tipo es una estructura definida en stdio.h.
Sintaxis: FILE * fopen(char *f, char *modo);
Ejemplo: FILE *pfich=fopen("c:\\a.txt", "w");
____ __
"w" "wt" : Abre para escritura modo texto. Si archivo no existe se crea.
, existe se crea de nuevo
.... .................._.' .. ' . . ........_ .........." , .. ............. ,-_ .........._ . '" .. . ...
"a
tl
Itat" ; .. ... ... .. .. ... ... .. ... existe se crea.
"rb" ..... .
"wb" Abre un archivo binario para escritura. Si el archivo no existe se
.1 ... . .........
"ab" : Se abre un archivo binario para escribir al final de l. Si el archivo
i no existe se crea.
Csar Liza Avila. No mates la produccin intelectual, no copies ste libro.
Nuestro programa hace
lo pedido. La funcin
crearArchivo( ), abre
una corriente ( fopen( )
) para grabar en modo
texto ("wt") y usa la
macro getchar( ),
definida en stdio.h, para
capturar el carcter
pulsado y mostrarlo por
pantalla, dicho carcter
es colocado hacia el
fichero ( putc(car,
fichero) ). Esto se repite
mientras este no sea el
final del ingreso
(while(car!=EOF)).
El terminador del
ingreso se puede
producir mediante el
teclado, presionando la
tecla F6, o en su defecto
con la combinacin de
teclas Ctrl + Z, seguida
por la tecla ENTER.
Finalmente, cerramos la corriente con fclose( ).
Contenido del archivo {
El ingn'sn termina
prcsinmllldo F{i
Archivos 203
Csar Liza A vila. Mis libros son econmicos, no hay razn para copiarlos.
204 Algoritmos y su Codifiracin en C++. Volumen 2, .
Solucin:
. La funcin verArchivo( ), abre un
archivo para lectura en modo
texto ( fopen(arch, "rt") ), cuyo
camino y nombre se almacena en
arch. El flujo que nos dirige hacia
el contenido del archivo lo indica
el puntero de tipo FILE llamado
pfich. En caso de no encontrar el
archivo, sonar un pitido na'),
mostrar el
correspondiente y retornar a
maine ). En caso contrario, toma
cada carcter ( caracter=getc(pfich) )
y lo muestra en pantalla.
Algunas funciones y macros tales
como getc( ), devuelven -1,
cuando detectan el fin del archivo,
ya que la constante EOF que
indica el final de un archivo ha
sido definida en stdio.h como -1.
Esto lo utilizamos para termiriar la
lectura.
Finalmente, cerramos el camino
hacia los bytes del archivo con
fclose( ).
Csar Liza Avila
(J Csar Liza Avila. No mates la produccin intelectual, no copies ste libro.
Solucin:
En la funcin
copiaArchivo( ), abrimos el
archivo de origen en modo
de lectura en binario ("rb"),
pues deseamos una copia
idntica, sin que haya una
conversin de caracteres. El
archivo destino tendr que
ser abierto para escritura
("wb").
El bucle simplemente toma
cada byte de un archivo y
los enva hacia otro.
En vez de usar la constante
EOF, pudimos haber usado
la funcin feof( ), para
detectar el final del archivo,
tal como se
continuacin:
while( !feof(pfich 1) )
{
Finalmente
archivos
fcIose( ).
cerramos
abiertos
Archivos 205
Csar Liza A vila. Mis libros son econmicos, no hay razn para copiar/os,
206 Algoritmos y su Codificacin en C+ +. Volumen 2. Csar Uza A vila
Solucin:
@ Csar Liza Avila. No mate,', . produccin intelectual, no copies ste libro.
-
Luego de abrir el
archivo e indicar la
cantidad de bytes que
contendr cada uno de
los archivos finales, y
ya entrando al bucle,
debemos generar el
nombre del primer
archivo destino, que
tendr el mismo nombre
que el archivo origen,
pero agregndole la
extensin ".0", es por la
necesidad de las
instrucciones
itoa(nro, eNro, 10);
strepy(destino, origen);
streat( destino, ". ");
streat( destino, eN ro);
la funcin itoa( ), cuyo
prototipo se encuentra
en stdlib.h, toma el
primer argumento
entero y lo convierte en
una cadena que
almacenaremos en el
segundo argumento. El
tercer argumento indica
la base en la cual se
expresar el resultado.
Una vez generado el nombre del
archivo lo abrimos para grabar en
binario.
El bucle for( ), toma n caracteres del
archivo origen (car=getc(pf y si no se
llega al final de archivo ( if (feof(pt) ),
lo colocamos en el archivo de salida
actual ( putc(car, ps) ).
Archivos 207
Csar Liza Avila. Mis libros son econmicos, no hay razn para copiarlos.
I
208 Algoritmu,\ y su Codificacin en C++. Volumen 2.
Para unir los archivos
debemos ingresar el primer
archivo en que fue dividido
el archivo original, o sea el
de extensin "Jl". La
funcin Unir( ), abre
primero este archivo y copia
cada uno de sus bytes hacia
el archivo destino, luego
toma el archivo con
extensin ".1", copia sus
bytes, toma el archivo con
extensin ".2" y as
sucesivamente, hasta ya no
encontrar ms archivos
correlativos.
La creacin de los n o m b r e ~
correlativos, 10 hace las
instrucciones:
nro++;
itoa(nro, cNro, 10);
strcpy(origen,origenO);
strcat(origen, ".");
strcat(origen, cNro);
El bucle while(l),
muestra el archivo que esta
siendo procesado, tomando
cada uno de los bytes
(while(!feof(pf) ) y los
guarda en el archivo de
salida, luego intenta abrir el
siguiente archivo, si no lo
encuentra sale del bucle (if
(pf==NULL) break;)
Csar Liza Avila
Csar Liza A vila. No mates la produccin intelectual, no ('opies ste libro.
Archivos 209
Solucin:
En este programa usamos dos nuevas funciones: read( ) y write( ).
Funcin fl'cad:
Sintaxis: size_t fread(void puntero, size_t tamao, size_t nregistros, FILE fichero);
Trabaja con registros de longitud fija. Lee desde un fichero uno o varios
registros de la misma longitud ya partir de la posicin actual en el archivo.
El valor de retomo es el nmero de registros ledos, de tipo size_t que
est definida como tipo unsigned nt. Sus parmetros son:
Un puntero a la zona de memoria donde se almacenarn los datos
ledos
El tamao de cada registro
El nmero de registros a leer
Un puntero a la estructura FILE del fichero del que se har la lectura
Funcin fwritc
Sintaxis: size_t fwrite(void puntero, size_t tamao, size.J nregistros, FILE fichero);
Trabaja con registros de longitud constante y forma pareja con fread.
Escribe uno o varios registros de la' misma longitud hacia un fichero. El
valor de retomo es el nmero de registros escritos, de tipo size._t que est
definida como tipo unsigned int Sus parmetros son:
Un puntero a la zona de memoria donde se encuentran los datos
El tamao de-eada registro
El nmero de registros a grabar
Un puntero a la estructura FILE del fichero del que se grabar
Dentro de un archivo un conjunto de bytes pueden representar un registro.
Csar Liza A vi/a. Mis libros son econmicos, no hal' rm,n para copiarlos.
1
210 Algoritmos y su Codificacin en C++. Volumen 2.
El programa guarda los datos
en c:\datos.txt. En fopen( ),
son necesarios las 2 barras
invertidas \\, pues una barra,
indica un carcter de escape.
Luego, leemos n elementos de
tipo struct registro y los
guardamos en el archivo
c:\datos.txt, mediante fwrite(
), como el primer argumento
debe ser la direccin de
memoria donde se encuentran
los datos hacemos ®. El
segundo argumento, es el
tamao en bytes que debemos
tomar a partir de esa direccin
de memoria; el tercer
argumento, indica cuntos
bloques de ese tamao vamos
a grabar y, el cuarto y ltimo
argumento, es el stream, al
cual dirigimos nuestros bytes.
Ahora procedemos a leer los
datos del archivo y mostrarlos
por pantalla. La funcin
fread( ), lee bloques de bytes
desde el stream indicado. El
primer argumento es la
direccin de memoria a partir
de la cual se llenarn los datos; el segundo, es el
tamao en bytes de cada bloque, en este caso es el
tamao del registro; el tercero, es el nmero de
bloques a leer, en este caso leemos de registro en
registro por lo que ser 1, Y el cuarto argumento, es
el stream desde donde vienen los datos.
En base a este programa, podemos escribir las funciones
para grabar y leer en disco, y combinarlas con las
funciones del Problema 3.5 para obtener una base de datos.
Csar [,iza A vi/a
Csar Liza A vila. No mates la produccin intelectual, no copies ste libro.
Solucin:
La funcin verArchivoHexa(
), luego de abrir el archivo
para lectura en binario,
lee en bloques de 16 bytes
mediante fread( ), y
mientras no sea fin de
archivo. Esta funcin
toma 4 parmetros, el
primero, es la zona de
memoria en donde se
almacenar lo ledo; el
segundo indica el tamao
de cada elemento, el
tercero la cantidad de
elementos que sern
ledos; el cuarto y ltimo
argumento el stream
desde donde sern ledos
los datos.
La funcin fread( ),
intenta leer un bloque de
bytes de tamao conocido
(en este caso 16), y
devuelve la cantidad de
elementos
ledos.
realmente
Archivos 211
Csar Liza Avila. Mis libros son econmicos, no hay razn para copiarlos.
212 ALgoritmos y su Codificacin en C++. Volumen 2. Csar Liza A vila
El primer bucle for, imprime cada byte ledo en 3 espacios y en
hexadecimal.
La expresin setw( 3*(16-bytesLeidos) + 2) permite dejar una
cantidad de espacios en blanco adecuada entre los cdigos ASCII impresos
en hexadecimal y sus respectivos smbolos. Esto es particularmente
necesario en el ltimo bloque ledo, puesto que los bytes tomados pueden
ser menores que 16, debiendo imprimir varios espacios en blanco' '.
El segundo bucle for, imprime los smbolos, para esto pregunta si
el cdigo ASCn del carcter es mayor que 31, en cuyo caso ser un
carcter imprimible procediendo a mostrarlo; mientras que, en caso
contrario, ser un carcter de control por lo que solo imprime un punto (.).
Finalmente, cerramos la corriente mediante fdose( ).
<r) Csar Liza A vila. No mates la produccin intelectual, no copies ste libro.
Archivos 213
Solucin:
Csar Liza A vi/a. Mis libros son econmicos, no hay razn para copiarlos.
214 Algoritmos y su Codificacin en C+ +. Volumen 2.
La funcin comprimir(
), toma cada carcter y
lo compara con el
anterior (ir
(carAnt==carAct) ), en
caso de ser el mismo
'aumenta la cuenta de
caracteres iguales
(Iargo++), si esta
cantidad es ms que
255, lo grabamos
puesto el nmero
mximo que podemos
almacenar en un byte es
255. Si dos caracteres
consecutivos son
diferentes, y la cantidad
de veces que se repite
carAnt es mayor que 3,
entonces los guardarnos
codificados. Si no es
mayor que 3 (1 2) los
guardamos sin ningn
tipo de codificacin. Al
salir del bucle
while.(carAct!=EOF),
nos aseguramos grabar
los ltimos caracteres,
es por ello la repeticin
fuera de while del
bloque if else.
Finalmente, cerramos
todos los archivo
mediante fcIoseall( ).
Csar Li:a Avila
Csar Liza A vilo.. No mates la produccin intelectual, no copies ste libro.
Archivos 215
Si por ejemplo, tenemos el archivo a.txt en la unidad C:, cuyo contenido se
muestra con el Notepad. I
y ejecutamos el programa,
resultar
el cual en realidad ya no es un archivo de texto puesto que contendr
caracteres no imprimibles que no se presentan en los archivos de texto. As
que nos ayudamos de nuestro Visor Hexadecimal (Problema 7.5), para
uedara el archivo mido.
Por ejemplo, las repeticiones del carcter a, han sido codificados como OxO,
Ox8 y Ox61, donde O es el indicador de codificacin, 8 es la cantidad de
repeticiones, y Ox61 o sea 6*16+1 = 97 en decimal, es el cdigo ASCII del
carcter 'a', los 3 espacios en blanco Ox20 (32 en decimal) no se codifican,
pues codificados ocuparn tambin 3 bytes.
Csar Liza Avila. Mis libros son econmicos, no hay razn para copiarlos.
'1
216 Algoritmos y su Codificacin en C++. Volumen 2.
La funcin
descomprimir(), es
bastante simple, lee
un byte y pregunta si
es O, en caso de serlo
pregunta por el
siguiente byte, el cual
indica la cantidad de
veces que se repite el
carcter siguiente, y
luego lee el siguiente
byte que es el
carcter a repetir.
Mediante el bucle
for, graba el carcter
tantas veces corno se
indique.
En caso de no ser O,
entonces el carcter
se coloca
directamente en el
archivo destino.
Csar Liza Avila
Csar Liza Avda. No mates la produccin intelectual, no copies ste libro.
Archivos 217
Solucin:
Para mostrar los datos de un archivo guardados con algn formato
comercial, es necesario conocer dicho formato.
El Formato ZIP
Todo archivo .zip consta de 3 zonas bien definidas: La Data, el Directorio y
el Control.
La Data
En esta zona, se almacena cada uno de los comprimidos. Para cada
h' "1 1 d 1 bl arc IVO, eXIste una estructura SUTIl ar a a mostra a en a ta a sIgUIente:
Byte O 1 2 3 4567 8 9 10 11 12 13 14 15 16 17 18 192021 22232425262728 29 30 ... 1
Carac 80 75 03 04 ? ? ? ? M ? H H F F C C C C T T T T I I I I L ? ? ? NomArch Dalos
Compr
Bytes O al 3: Contienen los caracteres P (ASCII 80) Y K (ASCII 75),
seguidos por los ASCII 03 Y 04 que confirman el inicio de un archivo
comprimido.
Byte 8: indica el mtodo de compresin utilizado. Si contiene el ASCII O,
no se utiliz ningn mtodo, solo se almacen el archivo porque es muy
pequeo y no necesita compresin. El Winzip utiliza el ASCn 8, para
indicar su mtodo de compresin.
Bytes 10 y 11: Guarda el nmero que representa la hora de
almacenamiento del archivo original y como es costumbre en la familia PC
utilizan el almacenamiento inverso; es decir, el byte signado como 10, es el
menos significativo, mientras que el ms significativo es signado como 11.
De esta manera, el nmero que representa la hora ser: NroHora = (byte
11)*256 + (byte 10)
Adems sabemos, por lo descrito en el Capitulo 4 sobre manipulacin de
bits, que: NroHora = Horas*2048 + Minutos*32 + Segl2
Por lo tanto si conocemos NroHora, podemos obtener las horas como la
parte entera resultante de dividir NroHoras/2048. Esto lo conseguimos por
corrimiento de bits.(un corrimiento de un bit a la derecha es una divisin
Csar Liza Avda. Mis libros son econmicos, no hay razn para copiarlos.
218 Algoritmos y su Codificacin en C+ +. Volumen 2. Csar Liza A vila
entre 2), lo mismo es vlido para obtener los Minutos y los Segundos. En
lenguaje C/C++/C#, sera Horas:: NroHora]], pues 2048 es '.'2 <eHeva<Illo a
na 11" Minutos:::: NroHora&Ox07fl'>5, pues ahora slo nos mteresa los
nme;os menores o iguales a 2047 (07FFh, en hexadecimal) pero divididos
entre 32 o sea "2 elevado a la 5", Y finalmente Segundos == (NroHoras&
Ox001F)*2, ya que ahora solo nos interesa los nmeros menores o iguales
. que 31 (001Fh, en hexadecimal) pero multiplicados por 2.
Bytes 12 y 13: Almacenan el nmero que representa a la .fecha en la que se
cre el archivo, siempre en formato inverso, es decIr el menos
significativo es el nombrado como 12. De esta manera el numero que
representa la fecha ser: NroFecha == (byte 13)*256 + (byte 12) . .
Recordar( por el estudio sobre manipulacin de bits q.ue hIZO en el
Captulo 4, que los 2 bytes de NroFecha, con sus 16 bIts,
desde la derecha significan: los 5 primeros bits representan el dJa (0-32),
los 4 bits siguientes el mes (0-16), y los 7 bits restantes el ao (0-128). Para
toda la faulia IBM= PC, los aos se cuentan a partir de 1980, por lo cual
conociendo NroFecha podemos 9btener el da, mes y ao de la siguiente
forma:
Da = (NroFecha &Ox001F);
Mes = (NroFecha& Ox01EO) 5;
Ao = (NroFecha & OxFEOO) 9 + 1980;
Bytes 14, 15, 16 y 17: Estos bytes almacenan el o suma de
comprobacin (tambin llamado Cdigo de RedundanCIa Clcltca o
los cuales son una serie de bytes que se generan durante la compreslOn e
identifican al archivo en prevencin de alguna alteracin. Cuando .se intenta
descomprimir el archivo, se vuelve a calcular estos SI
diferentes de los almacenados, entonces el archivo compnmldo ha sufndo
alguna alteracin y no podr ser descomprimido.
Bytes 18, 19, 20 y 21: Guardan el tamao original del archiv.o .en
usando el almacenamiento inverso. De esta manera el tamao ongmal sera:
TamNormal = (Byte21)*256*256*256 + (Byte20)*256*256 + (Byte19)*256 + (Byte18)
o tambin: TamNormal = (Byte21)<<24 + (Byte20)16 + (Byte19)8 + (Byte18)
Bytes 22, 23, 24 y 25: Almacenan el tamao en bytes del archivo
compriudo en formato inverso, esto es:
TamComprim ,,;, (Byte25)*256*256*256 + (Byte24)*256*256 + (Byte23)*256 + (Byte22)
o tambin TamComprim = (Byte25)24 + (Byte24)16 + (Byte23)8 + (Byte22)
Csar Liza Avila. No mates la produccin intelectual. no copies ste libro.
.
-----l
Archivos 219
Byte 27: Almacena la longitud en bytes de la ruta yel nombre del archivo.
Byte 30 y siguientes: Guardan la ruta y el nombre del archivo.
Bytes despus del nombre del archivo: Inmediatamente despus del
nombre del archivo, se encuentra el contenido del archivo, pero
I
compriudo.
EL DIRECTORIO
Es una zona muy similar a la DATA, pero sin los datos comprimidos,
adems contienen algunos bytes adicionales.
Leyendo esta zona, podemos obtener rpidamente el listado de todos los
archivos comprimidos, lo cual es realizado por nuestro programa. Para cada
archivo comprimido, existe una estructura como la mostrada en la figura
si uiente, ubicados una a continuacin de otra.
El CONTROL
Bytes O a 3: Se inician con los caracteres P y K, seguidos por los ASCII 05
Y 06 que confirman el inicio del Control.
Bytes 8 y 9: Indican el nmero de archivos comprimidos contenidos en el
archivo ZIP, como siempre en almacenauento inverso.
Bytes 10 y 11: Contienen Una copia de los bytes 8 y 9. Esta redundancia se
coloca con fines de recuperacin.
Bytes 16, 17, 18 y 19: Contienen el byte de inicio del EL DIRECTORIO
del archivo comprimido, almacenado inversamente. El byte de inicio de EL
DIRECTORIO ser:
ByteInicio = (Byte 19)*256*256*256 + (Byte 18)*256*256+ (Byte 17)*256 + (Byte 16)
o tambin: ByteInicio = (Byte 19)24 + (Byte 18)16+ (Byte 17)8 + (Byte 16)
Este byte nos servir de punto de entrada a nuestro programa, pero antes de
mostrarlo, necesitamos conocer algunas nuevas funciones:
Csar Liza A vila. Mis libros son econmicos. no hay razn para copiarlos.
~ .
220 Algoritmos y su Codificacin en C++-. Volumen 2. Csar Liza A vila
Funcin fseek:
Sintaxis: int fseek(FILE *fichero, long in! desplazamiento, in! origen);
Ubica el cursor del fichero para leer o escribir en una posicin deseada.
Retoma cero si tuvo xito, y diferente de cero si hubo error.
Parmetros:
Puntero tipo FILE del fichero cuyo cursor de lectura/escritura
deseamos mover
el valor del desplazamiento
el punto desde el que se calcular el desplazamiento
El parmetro origen puede tener tres posibles valores:
SEEK_SET se desplaza desde el principio del fichero. El primer byte del
fichero tiene un desplazamiento cero.
SEEK_CUR el desplazamiento se cuenta desde la posicin actual del
cursor.
SEEK_END el desplazamiento se cuenta desde el final del fichero.
Funcin ften:
Sintaxis: long int ftell(FILE *fichero);
Nos da la posicin actual del cursor de lectura/escritura de un fichero
El valor de retomo ser la posicin actual, o -1 si hay algn error.
El parmetro de entrada es un puntero a una estructura FILE del fichero
cuya posicin deseemos.
El programa lo presentamos a continuacin, cada lnea est debidamente
comentada por lo que no necesita mayor explicacin.
Csar Liza Avila. No mates la produccin intelectual. no copies ste libro.
Archivos 221
Csar Liza A vi/a. Mis libros son econmicos, no hay razn para copiarlos.
222 Algoritmos y su Codificacin en C++. Volumen 2. Csar Liza A vi/a
c::t'''c:\fJO(uments: <11m '" -, '< .,,"]
Ingrese archIvo c:\z.zip El
MultMatrlces.exe 23/7/2005 2:5:26 192583 bytes 38089 bytes 94
MultMatrices. cpp 2317/2005 2: 9: 58 1493 bytes 531 bytes dc
a.txt 19/11/2005 2:57:4 18 bytes 18 bytes e55belde
Press any key to continue
Csar Liza Avila. No mates la produccin intelectual, no copies ste libro.
Archivos 223
Solucin:
El ingreso y salida de bajo nivel, est provisto en io.h, y en direct.h,
algunas de sus funciones las mostramos aqu.
Csar Liza Avila. Mis libros son econmicos, 110 hav razn para copiarlos .
224 )' su Codifi,'acn f!n C++, Volumen 2,
('sar Uza A vila
El programa lee una carpeta, y nos cambiarnos a ella mediante
3hdr( ), para luego poder listar cada entrada de este directorio.
En Iist.aDir( ), definimos una variable del tipo struct _finddata,
definida en o.h, puesto que para cada archivo tenemos un conjunto de
'propiedades a los cuales podemos acceder.
La funcin _ndfirst( ), obtiene el primer archivo cuyo nombre
cumpla con el patrn indicado, en este caso "*. *", todos los archivos; y
coloca sus datos a partir de la direccin de memoria indicada por el
segundo argumento, en nuestro caso &archivo. Esta funcin devuelve un
entero largo, que servir como manejador o handle (nuestra variable listo),
para las futuras referencias.
Si listo, es diferente de cero, significa que encontr algn archivo
con el patrn indicado, procediendo a mostrar sus datos. Si es un directorio
(archivo.attrib ==_A_SUBDlR), se indicar como <DIR>, luego se procede a
buscar el siguiente archivo que cumpla con el mismo patrn de la primera
bsqueda, ahora indicada por listo, mostrando su nombre y hasta no
encontrar ms archivos.
Aqu, slo mostramos el contenido de un directorio especfico, pero
es posible recorrer todos los archivos del disco, incluyendo todos sus
subdirectorios, para ello necesitar usar recursin, terna que es tratado
extensamente en mi libro Estructura de Datos con C++.
Csar Liza Avila, No mates la produccin intelectual, no copies ste libro.
.
Archivo:; 225
1. Lea un carcter y muestre todas las posiciones dentro del archivo en
las que se encuentra.
2. Lea un archivo y guarde la suma de verificacin en otro archivo. La
suma de verificacin (cltecksum) es una serie de bytes que
al archivo, existen diversos algoritmos, lo ms fcil, aunque no muy
recomendable, es sumar los UNICODE de cada carcter del archivo.
3. Lea 2 archivos y nalos hacia un tercer archivo.
4. Dos archivos parecen ser iguales. Encuentre los bytes que son
diferentes indicando su ubicacin dentro del archivo.
5. Cuntas lneas y espacios en blanco aparecen en un archivo de texto
determinado?
6. Busque todas las ocurrencias de una palabra dentro de un archivo.
7. Se desea esconder un mensaje corto dentro de un archivo (esta tcnica
se conoce en general como esteallografa). Para ello se elige el
siguiente algoritmo: lea el mensaje y coloque cada una de sus letras en
las posiciones dadas por los nmeros primos, el resto de posiciones
sern dadas por el contenido del archivo original. Escriba una funcin
que haga esto y otra que muestre el mensaje oculto. Por ejemplo si el
mensajefue "hola mundo", en e/archivo se almacenara como:
8. Una forma de encriptamiento muy utilizado es sustituir cada carcter
por otro. El programador puede definir una tabla que contenga el
carcter original y otra tabla que contenga el carcter por el cual se
va a sustituir. Escriba un programa que permita encriptar y
desencriptar un ARCHIVO por SUSTITUCION con una tabla de
equivalencia definida por el programador.
9. Un virus es identificado mediante una cadena caracterstica extrada
de su cdigo. Un antivirus inspecciona los ficheros en busca de
cadenas asociadas a virus. Escriba un programa que lea una serie de
cdigos ASCII correspondientes al cdigo viral y los busque en un
archivo.
Csar Liza Avda. Mis libros son econmicos, no hay razn para copiarlos.
226 Algoritmos y su Codificaci6n en C++o Volumen 2. Csar Liza A vilo
10. Cuntos caracteres de cada tipo hay en un archivo dado?
Sugerencia: defina un arreglo de 256 elementos, el subndice indicar
el valor ASCII del carcterleido
11. Escriba un programa que dado un archivo diga que software lo cre.
Su programa debe identificar al menos 5 formatos. Sugerencia: Lea
los primeros bytes del archivo y busque algo que identifique a todo el
conjunto de archivos creados con el mismo programa. Por ejemplo, los
archivos creados con WinZip empiezan con PK, todos los ejecutables
empiezan con MZ, ya que al salir el DOS 2.0 Mark Zbikowski le puso
su siglas a los ejecutables.
12. Cree un archivo que contenga una cabecera que ocupe 15 bytes. La
cabecera est formada de la siguiente manera: los 3 primeros para las
iniciales de la empresa que creo el software, los 2 siguientes para las
iniciales del software, los 2 siguientes la versin del software, los 4
siguientes el ao, los 2 siguientes el mes y finalmente los 2 siguientes el
da de lanzamiento. Luego de los 15 bytes aparecen los datos
almacenados. Lea un archivo cualquiera y verifique si tiene el formato
definido, en cuyo caso muestre su cabecera.
13. Un archivo en formato DBF (F oxPro, Visual F oxPro, Dbase, F oxBase,
Clipper, etc.) tiene una cabecera de 32 bytes (O al 31) al inicio del
archivo, que indica lo siguiente: "
Bytes con subndice 7, 6, 5 y 4: cantidad de registros de la tabla
Bytes con subndices 9 y 8: byte a partir del cual se inician los datos
Bytes con subndices 11 y JO: longitud del registro, incluyendo la
marca del borrado.
Escriba un programa que lea un archivo DBF y muestre la cantidad de
registros, el byte de inicio de los datos, la longitud de cada registro.
Recuerde que los nmeros se almacenan en formato inverso, tal como
se vio en el Problema 7.8.
14. Es costumbre que cada sistema tenga un archivo de usuarios, cada uno
de los cuales tiene un password. Sin embargo, dicho password no se
guarda en disco, sino que en su lugar se almacena un valor hash, o
similar. Cree un archivo que contenga los ID de usuario y la firma del
password (un hash, checksum o un CCV). Luego lea login y el
password y diga si es un usuario registrado.
15. El formato WAV de Microsoft para almacenar sonidos, tiene una
cabecera de 44 bytes y contiene el tipo y organizacin de las muestras
de sonido.
@ Csar Liza Avila. No mates la produccin intelectual, no copies ste libro.
+
Archivos 227
Bytes O, 1,2,3 contiene la palabra "RIFF"
Bytes 4, 5, 6 7 tamao total del archivo en bytes menos 8 (esto es
porque no incluye los primeros 8 bytes)
Bytes 8, 9, JO, 11, 12, 13, 14 y 15 contiene la palabra "WAVEJ1nt "
note que hay un espacio despus de la t.
Bytes 16,17,18 y 19 Formato para PCM vale 16
Bytes 20, 21 Fonnato para PCM vale 1
Bytes 22 y 23, si es 1 es mono, 2 es estreo.
Bytes 24, 25, 26 y 27, frecuencia de muestreo puede valer 11025,
22050 44100.
Bytes 28, 29, 30 y 31 indica el nmero de bytes por segundo que se
debe intercambiar con la tarjeta de sonido para una grabacin o
reproduccin.
Bytes 32 y 33, nmero de bytes por captura 1, 2 4.
Bytes 34 y 35, nmero de bits por muestra, 8 16
Bytes 36, 37, 38 y 39 contiene la palabra "data"
Bytes 40,41,42 y 43, nmero total de bytes que ocupan las muestras.
Lea un archivo WA Vy muestre los datos de su cabecera
16. Escriba una funcin que grabe hacia un archivo los alumnos
aprobados y en otro los desaprobados (cdigo, apellido paterno,
apellido materno, promedio)
17. Escriba un programa que lea los datos de alumnos almacenados en un
archivo, los ordene alfabticamente (cdigo, apellido paterno, apellido
materno, promedio) y los guarde ordenados en otro archivo.
18. ~ e tiene un cdigo de libro char(5), un ttulo de libro char(30), y una
~ l s t a ~ ~ palabras clave char(70) que indican aquellas palabras que
Identifican al contenido de un libro. Cree un archivo con varios
registros y luego dada una palabra diga en que libros se encuentra.
19. Escri?a una funcin que elimine lgicamente un registro (cdigo,
apellldo paterno, apellido materno, estado J, de un archivo. Luego,
escriba una funcin que empaquete un archivo que almacena los
registros de n alumnos, Empaquetar significa crear un archivo con
todos aquellos alumnos que no han sido eliminados lgicamente.
Sugerencia: use el estado para indicar si esta o no eliminado.
20. Cree su propio formato que permita almacenar la definicin de la
estructura de registro (nombre del campo, tipo de dato, longitu.d, etc.),
luego lea n registros y gurdelos a un archivo usando suformato.
Csar Liza Avila. Mis libros son econmicos, no hay razn para copiarlos.
Acerca del Autor
Csar Liza Avila, es un reconocido Creador de Software, investigador
neto y difusor del conocimiento tcnico. Tiene doble forrnacin universitaria: Ing.
Industrial (UNT) e In9. de Computacin y Sistemas (UPAO), las cuales estudi
en forma simultnea, y sin convalidaciones, obteniendo en ambas meritorios
lugares. Debido a ello, es que combina los conocimientos adquiridos en ambas
carreras, en la mejora de la productividad de la organizacin mediante
herramientas automatizadas, trayendo como consecuencia la simplificacin de
procesos y el ahorro derivado de ellos.
Ha recibido varias distinciones, por haber ocupado los primeros puestos
en diversos concursos. As, obtuvo el 1er. Puesto en el examen de ingreso UNT,
en la Carrera Profesional de Ingeniera Industrial y el 3er. Puesto en el Cmputo
General entre ms de 17,000 postulantes" el 4to. Puesto en el examen de ingreso
Ing. de Computacin y Sistemas UPAO. Otras distinciones obtenidas son: 2do.
Puesto en el 11 DESAFIO DE BOLSA NIVEL REGIONAL, ("1990), 'ler. Puesto a
Nivel Regional del 11 DESAFIO NACIONAL DE BOLSA Y el 3er. Puesto a Nivel
Nacional en el mismo .concurso (1994). Adems en Octubre del 2001 recibi el
reconocimiento pblico del Colegio de Ingenieros del Per - Filial Trujillo, por su
destacada labor de investigacin y difusin del conocimiento tcnico.
Es un experto programador en C++, una muestra de ello son sus
programas publicados en la revista "Slo para Creadores", revista especializada
en difundir la creacin tcnica de software. En ella muestra la sencillez didctica de
su cdigo y su efectividad para realizar tareas que nos parecen tan misleriosas
como: reparar una Boa! Record, implementar esquemas de proteccin contra
copias, recuperar datos en discos duros que no tienen Boot, FAT o directorios,
visualizar archivos en diversos formatos como los ZIP, redefinicin de caracteres
en modo texto, entre algunos otros. Otros lenguajes en donde presenta gran
dominio son Assembler, FOXPRO, Pascal y Visual C#.
Es autor del .libro "El error del milenio", y de los programas 81082000
(escrito en eH), que verifica si una computadora es compatible con el ao 2000 y
SOL2000 (escrito en Assembler) que resuelve el problema de compatibilidad de
las computadoras respecto al ao 2000, y cuyos cdigos fuentes fueron incluidos
en el libro y publicados por la revista Soluciones del Diario Expreso, con el
objetivo de contribuir a un mejor conocimiento del problema y que la comunidad
informtica lo enfrente con xito. Este libro ha recibido elogiosos comentarios de
autoridades universitarias de Trujillo y de la Capital, mereciendo sendos artculos
en La Industria (Trujillo) , Diario Expreso (Lima), Diario OJO (Lima), entre otros .
L
Ha desarrollado sistemas de informacin en diversas instituciones tales
como: Escuela de Ingeniera Industrial y Sistemas-UNT, Carroceras Morillas,
Universidad Privada "Antenor Orrego", Municipalidad Distrital "El Porvenir",
Municipalidad Distrital Gran Chim - Cascas, Consorcio Pesquero Cal'Olina.
Asimismo, a realizado a sistemas de informacin en instituciones como
la Municipalidad Distrital "El Porvenir", e ITOS-SHELL No slo es un experto
en la construccin tcnica de sistemas de informacin, sino de software de
. propsito general como un utilitario para la verificacin la integridad de archivos
DBF (VERDBF.EXE) que es ms rpido y ms verstil que el FileFix de las
Utilidades Norton y el NPACK.EXE un software de compresin de datos utilizado
por el Sistema Compuleg de Editora Normas Legales, ambos programados en e
y Assembler.
Ha ocupado diversos cargos como Jefe de Sistemas del Convenio UNT-
MDP, responsable de Sistemas del Area Contable de la Universidad Privada
"Antenor Orrego", Director de Proyectos de Sistemas de Informacin en Mastersoft-
Per, Director de la revista Slo para Creadores. Se ha desempeado como
asistente de ctedra en los cursos de Software de Aplicacin I y Software de
Comunicacin en Universidad Privada "Antenor Orrego"; ha dictado los cursos
Lenguaje de Programacin y Manejadores de Base de Datos en la Unidad de
Tecnologa de la Informacin y de Sistemas UTISYS (Ex-Centro de Cmputo de
Ingeniera Industrial de la Universidad Nacional de Trujillo); asimismo, los cursos de
Anlisis y Diseo de Sistemas, y Lenguaje de Programacin 111, en el 1ST
ABACO-Trujillo; tambin, cursos como: Algoritmos, Tcnicas de
Programacin, Estructura de Datos Avanzados y Programacin Orientada a
Objetos en la Universidad Privada del Norte, entre muchos otros. Ha sido
expositor en ms de 30 eventos a nivel nacional destacando entre ellos el VII
CONEIS realizado en septiembre de 1999 en Cajamarca con el tema: Principios
d Construccin de Software y el Error del Milenio; y el '11m realizado
en agosto de 2000 en Trujillo, con el tema: Esquemas de Pro(eccn Contra
Copia. Tambin ha expuesto el Lenguaje Unificado de Modelado en diversas
ciudades como Trujillo, Chimbote, Chiclayo, entre otras.'
Actualmente, se dedica a la construccin de software a medida, a la
asesora en sistemas y a la difusin del conocimiento tcnico mediante artculos y
dictado de clases. Puede comunicarse con l a la siguiente direccin electrnica:
creadores@hotmail.com o visitar su pagina web: www.geoclties.com/cesaciz<l.
I
I
!
l
.... y SU CODIFICACION EN C++-.
Este libro nace con la idea de servir como texto introductorio a un curso de programacin.
Tiene caracterfsticas importantes dignas de resaltar que'lo diferencia de otros. Contiene
abundantes ejemplos divididos por temas en donde la complejidad va gradualmente en
aumento, con explicaciones detalladas de la
lgica utilizada, diagramas Nassi-Schneiderman
(N/S) y codificacin en C++. Sus 109 problemas
resueltos y 121 propuestos hace que esta obra
sea eminentemente prctica y por la manera
como est estructurado el libro podr detenerse
en cualquier momento, para reflexionar sobre lo
aprendido y tomar un merecido descanso con la
certeza que al retomar su lectura no habr
perdido la secuencia del. mismo.
Contenido:
1. La estructura secuencial
2. La estructura condicional simple
3. La estructura de seleccin mltiple
4. La estructura repetitiva mientras
5. La estructura repetitiva hacer mientras
6. La estructura repetitiva para
7. Arreglos unidimensionales
8, Funciones definidas por el usuario
ALGORITMOS Y SU CODIFICACION EN C++
Las Estructuras de Datos son un tema fundamental en la formacin de los estudiantes de
Ingeniera de Sistemas, Computacin e Informtica, y afines, pues nos dan un conocimiento
tcnico para elegir la mejor y ms eficiente forma de organizar nuestros datos para la solucin
de problemas de uso comn en prog;amacin. En
este libro encontrar ms de 85 ejemplos
completo:> 'de programas y ms de 140
ejercidos propuestos que sin duda, sern de
valiosa ayuda, tanto para los estudiantes como
de lo:; docenfes, y constituirn fuente inagotable
par3 la eld::eralJn d;; prctica:; y exmenes.
Toda:: aquella:> 'opc;ones de scftw3re .que usted
programador, siempre q!Jiso i:nplementar
son puestas a su alca,Ice y de manera en
estGcbra.
Conteaido:
1. Recursividad
2. Ordenamiento
3. Blsqueda
4. Listas Enlazadas
5. Pilas
6. Colas
7. Arboles Binarios de Bsqueda
Otras obras del Autor
MODELANDO CON UML. Principios '1 Apiicadcmes.
El Lenguaje Unificado de Modelado (UML) es un
lenguaje simblico para representar sistemas, Y es
de uso obligatorio a nivel mundial. Todos los
profesionales en Tecnologas de Informacin
utilizarlo Y dominarlo. Este libro le permltlra
aprender rpidamente los conceptos del y
sobre todo aplicarlos. A diferencia de otros libros
sobre el tema, aqu encontrar ms de 7ll ejemplos
desarrollados Y ms de 15 ejercicios propuestos que
le irn guiando en el aprendizaje del UMl.
Contenido:
1. Introduccin al UML
2. Diagramas de Casos de Uso
3. Diagramas de Clases
4. Diagramas de Secuencia
5. Diagramas de Colaboracin
6. Diagramas de Estado
7. DiagramasdeActividad
8. Diagramas de Componentes
9. Diagramas de Despliegue
EL ERROR DEL MILENIO
Este libro adems de contener una descripcin completa del Problema Informtico del Ao
2000, aporta con soluciones, incluyendo un diskette con 01 programa para verificar si su
computadora es compatible con el ao 2000, Y 02 programas para resolverlo, entregando el
CODIGO FUENTE de los programas. '
La gran cantidad de divertidas lustraciones Y el
lenguaje sencillo utilizado hacen amena su lectura,
siendo de sumo inters para cualquier persona que
est inmersa en el mundo moderno, pues es
imposible que no tome alguna accin respecto a
este problema, ya sea que tenga
en ;:;Iguna empresa o como un simple usuario.
Contenido;
1. Descripcin del Y21<.
2. Sistemas no informticos
3. Costos y aspectos jurdicos del Y2K
4. Queslamoshaciendo?
5. Problemas con el hardware
6. Problemas con el software
7. Tcnicas de solucin
8. Curiosidades del milenio.
Distribucin y Ventas
Ventas al por mayoH::
Sra. Serafina Pari de AqtH9nO
Av. Wilson # 1122. Telfono 4243986.
librera Nueva fErra
Jr. 195 (Frente a la UN!). Telfono 3813219. lima-Per.
Sra. Al'ltoi1lia Titl)
# 426 (Frente al Campo Ferial de Libros). Tlf. 4262280. lima-
CreaSoft
Av. Amrica Norte # 401. Telfono (044) 221363. Trujillo-Per.
Ventas al por menor:
A NIVEL NACIONAL:
UBUN
En sus tiendas de todo el Pen.
liMA:
Av. Wilson
En los puestos de venta libros de toda la Avenida
Puestos Frente a la UNI
En los puestos de venta de libros ubicados frente a la UNI
( .
TRUJILlO:
Librera El Retablo. Av. Espaa # 2116
Librera IDEAL (Stock). Jr. Orbegoso y'Francisco Pizarro #624.
CHIMBOTE: . .
Fer!a de Libros. Av. Pardo # 765y # 637. Telfono 327155
Ma!10lo. Av. Pardo # 673. 342991.
librerla UniVersitaria. Jr. Ellas Aguirre# 32B. Telfoilo 344713Z.
, CHICLAYO:
Feria de Libros. Elias Aguirre # 413
Librera Nuevo Mundo. .
Libreras de la Plazuela Elias Aguirre.
PIURA:
C&J Representacion:s. Centro Comercial Tres