0% encontró este documento útil (0 votos)
196 vistas70 páginas

Introducción a la Programación en C++

Este documento describe la versatilidad de los lenguajes C y C++. Ambos son lenguajes de programación de propósito general que pueden usarse para crear todo tipo de programas y aplicaciones, desde sistemas operativos hasta juegos. Aunque requieren más líneas de código que otros lenguajes de alto nivel, permiten crear programas compactos y rápidos gracias al uso de bibliotecas. C y C++ también tienen la ventaja de ser lenguajes portables, de código abierto y con una gran comunidad de desarrolladores. El documento luego

Cargado por

Anibal prado
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOC, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
196 vistas70 páginas

Introducción a la Programación en C++

Este documento describe la versatilidad de los lenguajes C y C++. Ambos son lenguajes de programación de propósito general que pueden usarse para crear todo tipo de programas y aplicaciones, desde sistemas operativos hasta juegos. Aunque requieren más líneas de código que otros lenguajes de alto nivel, permiten crear programas compactos y rápidos gracias al uso de bibliotecas. C y C++ también tienen la ventaja de ser lenguajes portables, de código abierto y con una gran comunidad de desarrolladores. El documento luego

Cargado por

Anibal prado
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOC, PDF, TXT o lee en línea desde Scribd

PROGRAMACIÓN EN C++

¿Por qué C++?


¿Qué clase de programas y aplicaciones se pueden crear usando C y C++?

La respuesta es muy sencilla: TODOS. (Introducción tomada de http://c.conclase.net/)

Tanto C como C++ son lenguajes de programación de propósito general. Todo puede programarse con
ellos, desde sistemas operativos y compiladores hasta aplicaciones de bases de datos y procesadores de
texto, pasando por juegos, aplicaciones a medida, etc.

Oirás y leerás mucho sobre este tema. Sobre todo diciendo que estos lenguajes son complicados y que
requieren páginas y páginas de código para hacer cosas que con otros lenguajes se hacen con pocas lí-
neas. Esto es una verdad a medias. Es cierto que un listado completo de un programa en C o C++ para
gestión de bases de datos (por poner un ejemplo) puede requerir varios miles de líneas de código, y que
su equivalente en Visual Basic sólo requiere unos pocos cientos. Pero detrás de cada línea de estos com-
piladores de alto nivel hay cientos de líneas de código en C, la mayor parte de estos compiladores están
respaldados por enormes bibliotecas escritas en C. Nada te impide a ti, como programador, usar biblio-
tecas, e incluso crear las tuyas propias.

Una de las propiedades de C y C++ es la reutilización del código en forma de bibliotecas de usuario.
Después de un tiempo trabajando, todos los programadores desarrollan sus propias bibliotecas para
aquellas cosas que hacen frecuentemente. Y además, raramente piensan en ello, se limitan a usarlas.

Además, los programas escritos en C o C++ tienen otras ventajas sobre el resto. Con la excepción del
ensamblador, generan los programas más compactos y rápidos. El código es transportable, es decir, un
programa ANSI en C o C++ podrá ejecutarse en cualquier máquina y bajo cualquier sistema operativo.
Y si es necesario, proporcionan un acceso a bajo nivel de hardware sólo igualado por el ensamblador.

Otra ventaja importante es que C tiene más de 30 años de vida, y C++ casi 20 y no parece que su uso
se debilite demasiado. No se trata de un lenguaje de moda, y probablemente a ambos les quede aún
mucha vida por delante. Sólo hay que pensar que sistemas operativos como Linux, Unix o incluso Win-
dows se escriben casi por completo en C.

Por último, existen varios compiladores de C y C++ gratuitos, o bajo la norma GNU, así como cientos de
bibliotecas de todo propósito y miles de programadores en todo el mundo, muchos de ellos dispuestos a
compartir su experiencia y conocimientos.

Los programas de ordenador

Es posible que usted nunca haya oído hablar de conceptos como compilación, ejecutables, etc. No se
trata de detallar aquí los mecanismos por los cuales un código escrito en un lenguaje de programación
se convierte en un programa que hace ciertas cosas en un ordenador. El tema es en sí mismo motivo de
libros. Sin embargo, sí que es interesante explicar cómo se obtiene un programa a partir de un código.

Para obtener un programa que se pueda ejecutar en un ordenador se necesita un código fuente, es de-
cir, un archivo de texto con las instrucciones. Este archivo suele tener la extensión cpp y es el que usted
tiene que escribir como programador. También son necesarios unos archivos de cabecera con la exten-
sión h; de éstos, algunos serán escritos por el programador, pero otros ya vienen con el compilador.
Con todos los archivos se realiza el proceso de compilación que da como resultado un archivo de exten-
sión obj.

El código que el programador escribe lo entienden las personas, pero no la máquina. El ordenador tiene
su propio lenguaje formado por unos y ceros, que es complicado para las personas. Entonces, qué se

Programación C++ Ing. Helmut Heinz Dehner Página 2 de 70


entiende por compilación. Pues simplemente la traducción de todas las instrucciones al idioma de la má -
quina. El programador se libera del complicado lenguaje de la máquina... y se concentra en el lenguaje
de programación mucho más cercano a la forma de pensar de los humanos.

Finalmente, antes de obtener el ejecutable es necesario un linkaje que enlaza el archivo obj con las li-
brerías que suministra el lenguaje. La mezcla del archivo obj con las librerías .lib conducen a un ejecuta-
ble exe. Este último archivo es el que se podrá ejecutar en la máquina.

Hoy en día, hay entornos de programación que realizan está labor en un conjunto integrado, posible-
mente usted trabaje con uno de ellos. En tal caso le remitimos al manual de instrucciones para compilar
y ejecutar un archivo. En general, de todas las funcionalidades que tienen esos entornos usted sólo va a
necesitar unas pocas; por lo tanto le aconsejamos que no pierda mucho el tiempo en aprender su mane-
jo hasta que realmente no necesite hacer cosas muy potentes.

Trabaje con un único archivo cpp y a lo sumo un archivo h, el resto lo pone todo el entorno, Construya y
ejecute las aplicaciones, no necesita nada más.

Esquema del proceso de compilación y linkado para obtener un ejecutable.

Consideraciones Generales
 C es lenguaje de “funciones”  por ejemplo la función “void main(void)”. Como función debe te-
ner uno o más argumentos. Puede ocurrir que ese argumento sea vacío.
 En C todas las funciones se escriben en minúsculas, salvo algunas excepciones.
 C hace distinción entre minúsculas y mayúsculas, de tal manera que el identificador Hola es dis -
tinto de hola, distinto de hOla, distinto de hoLa, etc.
 Toda instrucción termina con un punto y coma (;)
 C es un lenguaje de bloques. Dos o más instrucciones son un bloque que comienza con la apertu-
ra de una llave ({) y termina con el cierre de una llave (}).
 Se abre una llave… se cierra una llave, análogamente se abre un paréntesis… se cierra un parén -
tesis, etc.
 El Entorno Integrado de Desarrollo (EID) nos permite trabajar con “indentación”… se debe tra-
bajar en forma indentada
 Es de muy buena costumbre llenar de comentarios el código fuente
 Es responsabilidad del programador NO excederse en el rango máximo permitido para el tipo de
identificador declarado!!!!!! Por ejemplo, si declaro un int el valor máximo permitido es 32767.
 Deben inicializarse todos y cada uno de los acumuladores, porque el compilador NO los inicializa.
 Se deben declarar todas y cada una de los identificadores que se van a utilizar, así como su tipo.

Programación C++ Ing. Helmut Heinz Dehner Página 3 de 70


p

Un programa sencillo
La mejor manera de empezar el estudio de C++ es examinar un programa. Comenzaremos con el pro-
grama más simple que puede escribirse en C++: 1PRIMERO.CPP

#include <iostream.h>

void main(void)
{
cout <<"Esta es una línea de texto.";
}

La palabra "main" es muy importante, y debe aparecer una vez y sólo una en cualquier programa en
C++. Este es el punto de partida desde el cual el programa se ejecuta.
Siguiendo a la palabra "main", hay un par de paréntesis en la forma (), que le indican al compilador que
está ante una función.
Los signos de llave, conocidos como símbolos de agrupamiento, agrupan las declaraciones relaciona-
das, se usan para definir los límites del programa principal.
El punto y coma de final de línea es usado como mandato finalizador, por tanto el compilador asigna a
este caracter la función de indicar que la línea ya está completa.

La declaración #include
Esta declaración indica al compilador que incluya el contenido del archivo especificado al principio del
programa. En este caso, el compilador incluirá el contenido del archivo iostream.h. Los archivos que tie-
nen extensión h y se incluyen al principio (o cabecera) de los programas se llaman archivos de cabe-
cera.
Cada uno de los archivos de cabecera comprende definiciones que el compilador proporciona para dife-
rentes operaciones. Por ejemplo, hay archivos de cabecera para las operaciones matemáticas, para ope-

Programación C++ Ing. Helmut Heinz Dehner Página 4 de 70


raciones con archivos, y otros. Por ahora no nos preocuparemos mucho por los archivos de cabecera,
simplemente tengamos en cuenta que la declaración #include nos deja utilizarlos.

La consola
El instrumento más rudimentario de interacción es la consola, es decir, el teclado para permitir la inte-
racción hombre-máquina y la pantalla para la relación inversa. En la librería <iostream.h> hay definidos
cuatro elementos de interacción.
cout Salida por pantalla.
cin Entrada por el teclado.
cerr Salida de error por pantalla.
Los operadores « y », son los llamados operadores de inserción y de extracción respectivamente, sirven
para dirigir el flujo de datos.
La salida se realiza a través del operador « y consiste en insertar los datos en el stream, en particular se
convierte en salida por la pantalla. Lo mismo ocurre con la entrada, el operador » saca del stream el tipo
de dato necesario.

El operador cout
El operador cout muestra por pantalla lo que se encuentra entre comillas. Se utiliza con el doble signo
de menor que “<<“, llamado operador de inserción.
A continuación veremos un programa pequeño, pero que ilustra un concepto muy importante: 2SEGUN-

DO.CPP

#include <iostream.h>

void main(void)
{
cout <<"Esta es una línea de texto.\n";
cout <<"Y esta es otra ";
cout <<"línea de texto.\n\n";
cout <<"Esta es la tercera línea.";
}

El programa consta de cuatro declaraciones. Se ejecutan las líneas por orden de encuentro, por lo tanto
se ejecutará la línea superior en primer lugar, después la segunda, tras ésta la tercera y así sucesiva -
mente. El programa se ejecuta de arriba a abajo.

Cerca del fin de la primera línea aparece el llamado "caracter de corte: \ ". Se usa para indicar que le
sigue un caracter de control especial. En este caso, ese caracter es "n", que indica que se ejecutará una
nueva línea. Esta indicación hace que el cursor baje una línea y se coloque en la primera posición iz-
quierda de la pantalla. Se refiere normalmente a un retorno de carro. En cualquier parte del texto, don-
de se desee, puede acabar la línea y empezar otra nueva. Se puede cortar una palabra y mostrarla en-
tre dos líneas. El compilador considera la expresión "\n" como un solo caracter (caracter de corte+letra
n). Entonces, el primer cout muestra una línea de texto, y realiza un retorno de carro. La segunda línea
muestra una línea de texto, sin retorno de carro, porque la tercera efectúa 2 retornos de carro, resultan-
do una línea en blanco. Finalmente la cuarta línea muestra otra línea de texto y acaba el programa.

IDENTIFICADORES
Un identificador es una combinación de caracteres numéricos, alfanuméricos o letras, o algún número, o
un carácter subrayado “_”, lo usa una variable, o una función, o una definición de datos, etc. En el len -
guaje C++ debe tenerse en cuenta que mayúsculas y minúsculas definen identificadores distintos. Así,
el identificador “INDICE”, es distinto de “índice”, y también de “Índice”.

Programación C++ Ing. Helmut Heinz Dehner Página 5 de 70


Declaración de variables
Los programas usan variables para almacenar información. Dependiendo de la clase de valor que se
quiera guardar, tal como un número entero, una letra del alfabeto o un valor de punto flotante, diferirá
el tipo de la variable. La mayoría de los programas en C++ utilizarán los tipos de variables citados en
las siguientes tablas:
Tipos Básicos:
Tipo Ancho en Bit Ancho en Bytes Rango
char 8 1 0 a 255
int 16 2 -32768 a 32767
float 32 4 -3.4E-38 a 3.4E+38
double 64 8 -1.7E-308 a 1.7E+308
void 0 0 sin valor
Otros:
Tipo Ancho en Bit Ancho en Bytes Rango
signed char 8 1 -128 a 127
unsigned int 16 2 0 a 65535
long int 32 4 -2147483648 a 214.782.647
unsigned long int 32 4 0 a 4.294.967.295
unsigned short int 16 2 -32768 a 32767
Antes de que se pueda utilizar una variable hay que declararla, introducirla en el programa.
En la declaración se especifica el tipo de variable y su nombre.
Cuando se declara más de una variable del mismo tipo, C++ permite separar los nombres de las varia-
bles utilizando una coma.
Cada variable tiene un nombre único. Para que los programas sean más fáciles de leer y comprender de-
ben utilizarse nombres significativos para las variables.

Una vez declarada la variable se utiliza el operador de asignación (el signo igual) del C++ para asignar
un valor a una variable.
Cuando se declara una variable suele ser conveniente asignar el valor inicial de la misma. Para facilitar
las cosas, C++ permite asignar valores al mismo tiempo que se declaran las variables.
Después de asignar un valor a una variable, los programas pueden utilizar el valor de la misma haciendo
referencia simplemente a su nombre.
El siguiente programa, 3VARIABLE.CPP, asigna valores a dos variables y luego las exhibe en la panta-
lla utilizando el operador cout.
El operador de inserción (<<) comunica al sistema que lo sigue una variable o una constante.

#include <iostream.h>

void main(void)
{ /* Principio
del programa */

int edad; //Declaración de la variable


float salario = 451.75; //Declaración y asignación

edad=32; //Asignación del valor


cout <<"Edad del empleado: " << edad << " años ";
cout <<"\nSalario: $"<< salario << ".-";

// Fin del programa


}

COMO HACER COMENTARIOS


En el programa anterior vemos dos maneras de hacer comentarios en un programa, para hacerlo más
legible a otros. El compilador ignora estos comentarios.

Programación C++ Ing. Helmut Heinz Dehner Página 6 de 70


Una de las formas es utilizar la barra de división y el signo de estrella, en la forma /* para iniciar un
bloque de comentarios y la forma */ para finalizar el comentario.
También se utiliza la doble barra “//”, que inicia un comentario en cualquier parte de una línea y termina
automáticamente al final de ella. Este último método es el preferido para la definición de comentarios
porque es imposible comentar inadvertidamente fuera de varias líneas del programa. Esto podría ocurrir
al usar el otro método de anotación de comentarios en C++, al olvidar incluir el fin de anotación de un
comentario.
Se debe destacar que no deberían usarse los comentarios cuando el mismo sentido de la definición del
programa puede ser obtenido usando nombres significativos para variables, constantes y funciones, por
ello el programador debe seleccionar cuidadosamente los nombres de funciones y variables, esforzándo-
se por perfeccionar su propio código.

EJERCICIOS DE PROGRAMACIÓN:
1. Escribir un programa que visualice por pantalla su nombre completo.

2. Escribir otro que además muestre su dirección y número de teléfono, con una línea de espacio entre
los datos.

LIBRERIAS EN LENGUAJE C

#include <stdio.h>

clearerr fclose feof ferror fflush fgetc fgetpos


fgets fopen formato fprintf fputc fputs fread
freopen fscanf fseek fsetpos ftell fwrite getc
getchar gets perror printf putc putchar puts
remove rename rewind scanf setbuf setybuf sprintf
sscanf tmpfile tmpnam ungetc vfprintf vprintf vsprintf

#include <stdlib.h>

abort abs atexit atof atoi atol bsearch

calloc div exit free getenv labs ldiv

malloc mblen mbstowcs mbtowc qsort rand Realloc

srand strtod strtol strtoul system wctomb

#include <string.h>

memchr memcmp memcpy memmove memset strcat strchr

strcmp strcoll strcpy strcspn strerror strlen strmcat

strmcmp strmcpy strpbrk strrchr strspn strstr strtok

strxfrm

Programación C++ Ing. Helmut Heinz Dehner Página 7 de 70


#include <ctype.h>

tolower toupper

#include <locale.h>

localeconv setlocale

#include <math.h>

Acos Asin atan atan2 ceil cos cosh

Exp Fabs floor fmod frexp ldexp log

log10 modf pow sin sinh sqrt tan

tanh

#include <setjmp.h>

longjmp setjmp

#include <signal.h>

raise signal

#include <time.h>

asctime clock ctime difftime Gmtime localtime mktime

strftime time

Otras librerias que no tienen funciones asociadas. Pero tienen macros constantes y/o estructuras.

 #include <assert.h>

 #include <errno.h>

 #include <float.h>

 #include <limits.h>

Programación C++ Ing. Helmut Heinz Dehner Página 8 de 70


 #include <stdarg.h>

 #include <stddef.h>

RESUMEN DE LIBRERIAS

 assert.h Contiene una macro para el diagnóstico dentro de los programas.

 ctype.h Contiene varias funciones para comprobación de tipos y transformación de caracteres.

 errno.h Contiene varias macros usadas para informar de errores.

 limits.h Contienen varias macros que definen constantes para el tamaño de tipo enteros.

 float.h Contienen varias macros que definen constantes para el tamaño de tipo flotante.

 locale.h Contienen varias macros, funciones y tipos para unidades locales, como unidad monetaria,
tiempo, dígitos, etc.

 math.h Contiene una macro y varias funciones matemáticas.

 setjmp.h Contienen declaraciones que proporcionan una forma de evitar la secuencia normal de llamada
y regreso de funciones.

 signal.h Contiene un tipo, dos funciones y varias macros para manejar condiciones excepcionales que
aparecen durante la ejecución, tal como una señal de interrupción de una fuente externa o un error en
la ejecución.

 stdarg.h Contiene un tipo y tres macros que proporcionan recursos para recorrer una lista de argumentos
de función de tamaño y tipo desconocido.

 stddef.h Contiene varios tipos y macros que también están definidas en otras librerías, como size_t.

 stdio.h Contiene tipos, macros y funciones para la realización de tareas de E/S.

 stdlib.h Contiene tipos, macros y funciones para la conversión numérica, generación de números aleato-
rios, búsquedas y ordenación, gestión de memoria y tareas similares.

 string.h Contiene tipos, macros y funciones para la manipulación de cadenas de caracteres.

 time.h Contiene tipos, macros y funciones para la la manipulación de información sobre fechas y horas.

Tipos: char, int, float, long, long long, short, double, void.

Programación C++ Ing. Helmut Heinz Dehner Página 9 de 70


CADENAS DE FORMATO

d, i entero decimal con signo

o entero octal sin signo

u entero decimal sin signo

x entero hexadecimal sin signo (en minúsculas)

X entero hexadecimal sin signo (en mayúsculas)

f Coma flotante en la forma [-]dddd.dddd

e Coma flotante en la forma [-]d.dddd e[+/-]ddd

g Coma flotante según el valor

E Como e pero en mayúsculas

G Como g pero en mayúsculas

c un carácter

s cadena de caracteres terminada en '\0'

% imprime el carácter %

p puntero

SECUENCIA DE ESCAPE

\a Alerta

\b Espacio atrás

\f Salto de página

\n Salto de línea

Programación C++ Ing. Helmut Heinz Dehner Página 10 de 70


\r Retorno de carro

\t Tabulación horizontal

\v Tabulación vertical

\\ Barra invertida

\' Comilla simple

\" Comillas dobles

\OOO Visualiza un carácter cuyo código ASCII es OOO en octal

\xHHH Visualiza un carácter cuyo código ASCII es HHH en hexade-


cimal

Formateador Salida
%07i justificado a la derecha, 7 dígitos de largo, sin relleno
%.7i largo mínimo de 7 dígitos, justificado a la derecha, rellena con ceros
%8.2f tamaño total de 8 dígitos, con dos decimales
%.*f”',x,d) tamaño predeterminado,x numeros decimales
%*.*f”,x,y,d) tamaño igual a x, y numeros decimales
%s cadena terminada en null
%5s primeros cinco caracteres o delimitador
%.5s primeros cinco caracteres, sin tener en cuenta el delimitador
%20.5s primeros cinco caracteres, justificados a la derecha, con 20 caracteres de largo
%-20.5s primeros cinco caracteres, justificados a la izquierda, con 20 caracteres de largo

EL PROGRAMA TOMA DECISIONES

En ocasiones se desea que se ejecuten un conjunto de declaraciones si una condición es verdadera, y


otro grupo si la condición es falsa. Es decir, deseamos que el programa tome decisiones y responda de
acuerdo a ellas.
Para que el programa tome una decisión, generalmente realiza algún tipo de prueba, una comparación.
Para ello utilizará los llamados operadores relacionales:

Operador Relación
== ... igual a ...
!= ... distinto de ...
> ... mayor que ...
< ... menor que ...
>= ... mayor o igual que ...
<= ... menor o igual que ...

Programación C++ Ing. Helmut Heinz Dehner Página 11 de 70


! … NO

&& y
|| o

EL BUCLE WHILE
El lenguaje C++ tiene varias estructuras de control para bucles y bifurcaciones condicionales. Empeza-
remos por el bucle WHILE. Este bucle continuará ejecutándose mientras (while significa mientras, en
inglés) sea cierta la condición impuesta. Cuando esta condición no se cumpla, el bucle se parará. El
nombre en sí ya es una buena descripción.
Veamos un ejemplo del funcionamiento de este bucle en el programa 4WHILE.CPP

#include <iostream.h> // Este es un ejemplo del bucle "while"

void main(void)
{
int contador;

contador = 0;
while (contador < 6) {
cout <<"El valor del contador es " << contador << "\n";
contador = contador + 1;
}
}
Empezamos con un comentario y el nombre del programa. Tras esto procedemos a definir la variable
entera "contador" en el cuerpo del programa. La variable tiene como valor inicial 0. Y ahora, vamos al
bucle WHILE. La sintaxis es tal y como se describe ahora: la palabra reservada WHILE es seguida por
una expresión o por algo entre paréntesis, seguido a su vez por un mandato compuesto, encerrado en-
tre llaves. Tantas veces como sea cierta la condición, tantas veces se ejecutará este mandato. En este
caso, la variable contador irá incrementando su valor en 1 y, cuando alcance 6, el bucle dejará de ejecu-
tarse. El control del programa pasará a la primera instrucción tras el mandato o mandatos ejecutados
por el bucle.

Debemos destacar que:

1) Si la variable “contador” fuera mayor que 5, el bucle podría no ejecutarse jamás, (Ej: si empezara
con 6), ya que la comparación se realiza al iniciar el bucle.
2) Si la variable no se incrementa, el bucle no acabará de ejecutarse jamás.
3) Si el mandato dependiente del bucle es uno solo, no es necesario incluirlo entre llaves.

EL BUCLE DO-WHILE
Una variación del bucle WHILE se muestra en el programa 5DOWHILE.CPP

#include <iostream.h>

// Este es un ejemplo del bucle do-while

void main(void)
{
int i;

i = 0;
do {
cout <<"El valor de i es ahora " << i << "\n";
i = i + 1;
} while (i <= 5);
}
Programación C++ Ing. Helmut Heinz Dehner Página 12 de 70
Es casi idéntico al anterior, excepto en que el bucle comienza con la palabra reservada "DO", seguida
por un bloque de mandatos encerrados entre llaves, luego la palabra reservada WHILE y, finalmente la
expresión entre paréntesis. El bloque de comandos entre llaves se ejecutará mientras la condición en-
tre paréntesis se cumpla, Cuando la condición deje de ser cierta, el control pasará al primer mandato
tras el bloque de mandatos encerrados entre llaves.

Destacamos que:
1) Como la comprobación se realiza al final del bucle, el bloque de mandatos entre llaves se eje-
cutará al menos 1 vez.
2) Si “i” no se cambiara dentro del bucle, el programa se ejecutaría eternamente.
3) Igual que con el bucle WHILE, si el bloque de mandatos se reduce a uno, no son necesarias las lla-
ves.
Estos bucles pueden anidarse. Esto es, un bucle dentro de otro, y el número de anidamientos es ili-
mitado.

EL BUCLE FOR
El bucle for no es nada nuevo. Es una nueva manera de describir el bucle while. La estructura del bucle
for consiste en la palabra reservada for, seguida de determinado número de expresiones entre parénte-
sis. Estas expresiones son dos o tres campos separados por punto y coma.

#include <iostream.h>

// Este es un ejemplo de bucle for

void main(void)
{
int indice;

for(indice = 0;indice < 6;indice = indice + 1)


cout <<"El valor de indice es " <<indice<< "\n";
}

En nuestro ejemplo, 6BUCLEFOR.CPP, el primer campo contiene la expresión “indice= 0”, y es un


campo de inicialización. Algunas expresiones se ejecutan antes del primer paso, a través del bucle.
No hay límite para estas expresiones, pero un buen estilo de programación recomienda no excederse.
Varios mandatos de inicialización pueden ubicarse en este campo, separados por punto y coma.

El segundo campo, en este caso conteniendo "indice < 6", es el test que se hace al principio de
cada vuelta del bucle. Esta expresión se puede evaluar verdadera o falsa.

La expresión contenida en el 3er. campo se ejecuta cada vez que se ejecuta el bucle, esto no ocu-
rre hasta que todos los mandatos contenidos en el bucle se ejecutan en su totalidad. Este campo, al
igual que el primero, puede contener varios operandos separados por ;.

Siguiendo a la expresión for (), algún mandato simple, o un bloque que será ejecutado en el cuerpo del
bucle.

Los tres campos utilizados dentro del paréntesis podrían explicarse como:

for(indice = 0;indice < 6;indice = indice + 1)


Inicio Fin Incremento

Al igual que la estructura WHILE, la comparación se realiza al iniciar el bucle.

Programación C++ Ing. Helmut Heinz Dehner Página 13 de 70


EL CONDICIONAL IF
En el siguiente programa, 7IFELSE.CPP, vemos que hay un bucle for con un mandato que contiene 2
mandatos "if". Es un ejemplo de anidación. Debe quedar claro que en el ejemplo, cada if se ejecutará 10
veces.
#include <iostream.h> // Este es un ejemplo de los mandatos if-else

void main(void)
{
int dato;

for(dato = 0;dato < 10;dato = dato + 1) {

if (dato == 2)
cout <<"Dato es ahora igual a " <<dato<< "\n";

if (dato < 5)
cout <<"Dato es ahora " << dato << ", el cual es menor de 5\n";
else
cout <<"Dato es ahora " << dato << ", el cual es mayor de 4\n";

} // Fin del bucle


}

El condicional empieza con la palabra reservada if, seguida de una expresión entre paréntesis. Si la ex-
presión se evalúa y resulta cierta, el mandato simple que sigue a if se ejecutará, pero si es falsa, el con-
trol del programa pasará a la siguiente instrucción. En lugar del comando simple, podemos poner un
bloque de instrucciones encerrado por llaves.

La expresión “dato == 2", está simplemente preguntando si el valor de "dato" es igual a 2, es decir que
“==“ significa comparación, en cambio si la expresión fuera “=“ la función sería de asignación.

IF-ELSE
Este segundo IF es similar al primero, con la adición de una nueva palabra reservada, “else", seguida
del mandato cout. Esto, simplemente significa que si la expresión evaluada entre paréntesis resulta cier-
ta, la primera expresión es ejecutada. Caso contrario, las instrucciones después de else serán ejecuta-
das. Entonces, una de las expresiones se ejecuta siempre, al contrario del primer ejemplo, donde la ex-
presión o cumple o se ignora.

BREAK y CONTINUE
Veamos el programa 8BREAKCON.CPP

#include <iostream.h>

void main(void)
{
int xx;

for(xx = 5;xx < 15;xx = xx + 1){


if (xx == 8)
break;
cout <<"En el bucle break, xx es ahora " << xx << "\n"; }
for(xx = 5;xx < 15;xx = xx + 1){
if (xx == 8)
continue;
cout <<"En el bucle continue, xx es ahora " << xx << "\n"; }
}

Programación C++ Ing. Helmut Heinz Dehner Página 14 de 70


En el 1er. "for" hay un condicional que llama a una interrupción (break) si xx es igual a 8. Esta inte-
rrupción le sacará del bucle y continuará ejecutando los mandatos que haya después, dando por ter-
minado el bucle. Es un mandato muy útil cuando quiera abandonar un bucle, dependiendo del resulta-
do de una condición. En este caso, que xx sea igual a 8, el bucle finalizará y, el último valor aparecerá
por pantalla, es decir, el 7.

El siguiente bucle for contiene un comando continuo (continue), el cual no finaliza el bucle, pero
se desvía. Cuando xx alcance 8, en este caso, el programa saltará hasta el final del bucle y, continuará
ejecutando, ignorando el mandato cout, en este paso, cuando xx es 8, luego continuará normalmente el
bucle, en este caso, para xx igual a 9.

LA INSTRUCCIÓN SWITCH
Esta instrucción significa la elección de una posibilidad entre un abanico de varias. Empieza con la
palabra reservada "switch" seguida de una variable en paréntesis, la cual es la variable que determina
la opción adecuada por comparación. En el ejemplo, 9SWITCH.CPP, esta variable es "truck". Pueden
incluirse tantas posibilidades como sean necesarias, encerradas entre llaves, claro está. La palabra re -
servada "case" encabeza cada línea de opción, seguida por el valor de la variable. Si no se verifica
ninguna de las opciones de “case” se ejecutará la línea encabezada con default.
Este tipo de estructura también puede anidarse.

#include <iostream.h>

void main(void)
{
int dato;

for (dato = 3;dato < 13;dato = dato + 1) {

switch (dato) {
case 3 : cout << "El valor es tres \n";
break;
case 4 : cout << "El valor es cuatro\n";
break;
case 5 :
case 6 :
case 7 :
case 8 : cout << "El valor esta entre 5 y 8\n";
break;
case 11 : cout << "El valor es once\n";
break;

default : cout << "Es uno de los valores no definidos\n";


break;
} // fin del switch
} //fin del bucle for
}

EJERCICIOS DE PROGRAMACIÓN:

1. Escribir un programa que imprima 10 veces un nombre por pantalla. Hacer una versión para cada bu -
cle conocido. Definir cualquier variable cerca de su punto de uso.

2. Hacer un programa que cuente de 1 a 10, escriba cada número en la pantalla y que al lado del 3 y
del 7 escriba un comentario distinto para cada uno.

Programación C++ Ing. Helmut Heinz Dehner Página 15 de 70


ASIGNACIONES Y COMPARACIONES LÓGICAS

La función PRINTF()
Antes de analizar las asignaciones y comparaciones lógicas veremos una función similar al cout que se
utiliza en la programación en el lenguaje C. Tiene el propósito de visualizar algo en la pantalla, este algo
está dentro de unos paréntesis, rodeados a su vez por signos de comillas. Ej: printf (“Este texto
aparecerá por pantalla.\n”);
Como vemos, con la función printf se puede utilizar también el caracter de retorno de carro.

A continuación veremos el programa 10PRINTF.CPP en el que se utiliza esta función con diferentes ti-
pos de datos, modificando el formato de salida por pantalla.

#include <stdio.h>
void main(void)
{
int a; // tipo entero simple
long int b; // tipo entero expandido
short int c; // tipo entero comprimido
unsigned int d; // tipo entero sin signo
char e; // tipo caracter
float f; // tipo punto flotante
double g; // punto flotante doble precisión

a = 1023;
b = 2222;
c = 123;
d = 1234;
e = 'X';
f = 3.14159;
g = 3.1415926535898;

(20)printf("a = %d\n",a); // salida decimal


printf("a = %o\n",a); // salida octal
printf("a = %x\n",a); // salida hexadecimal
printf("b = %ld\n",b); // salida decimal long
printf("c = %d\n",c); // salida decimal short
printf("d = %u\n",d); // salida sin signo
printf("e = %c\n",e); // salida de caracter
printf("f = %f\n",f); // salida en flotante
printf("g = %f\n",g); // salida doble flotante
printf("\n");
printf("a = %d\n",a); // salida simple entera
printf("a = %7d\n",a); // usa un campo de 7 caracteres
printf("a = %-7d\n",a); // justif. izda. de 7 caracteres
printf("\n");
printf("f = %f\n",f); // salida simple float
printf("f = %12f\n",f); // usa un campo de 12 caracteres
printf("f = %12.3f\n",f); // usa 3 decimales
printf("f = %12.5f\n",f); // usa 5 decimales
printf("f = %-12.5f\n",f); // justificacion izquierda
}

Como se observa en la primer línea, el archivo de cabecera para utilizar la función printf no es el mismo
que para el cout. En este caso la biblioteca es stdio.h, que controla las operaciones de entrada y salida.
Después de declarar varios tipos de variables y asignarles un determinado valor, nos encontramos, a
partir de la línea 20, con declaraciones printf que utilizan el caracter %.

Programación C++ Ing. Helmut Heinz Dehner Página 16 de 70


Este caracter se utiliza con el printf para la visualización de una variable. Este signo señala el principio
de variables de distinto tipo. Por ejemplo, si el caracter que sigue a % es una letra d, nos indica que la
variable que a continuación aparece es de tipo decimal.
Todos los caracteres entre signos de comillas definen el patrón de los datos para ser mostrados por el
Po-
mandato y después de este patrón hay una coma seguida por la variable que quiere ser mostrada.
demos añadir más campos de salida y más variables entre las llaves para
imprimir más variables en el mandato, pero siempre debemos tener en
cuenta que el número de descriptores de campo y el número de va-
riables debe ser el mismo o se producirá un error.
Seguidamente, una lista de conversión de caracteres, y la forma de usarla con printf.
d: Notación decimal.
o: " octal.
x: " hexadecimal.
u: " sin signo.
c: " de caracter.
s: " de cadena.
f: " de punto flotante.

Cada caracter de los anteriores es precedido por un signo de porcentaje, indicando el tipo de conversión
de salida, y entre estos dos caracteres, puede incluirse cualquiera de los siguientes:
-: Justificación izquierda en este campo.
(n): Especificador de mínimo de caracteres por campo.
.: Para separar n de m. (n.m)
m): Dígitos significativos de la fracción flotante.
l: Indica un "long".

Formateador Salida
%07i justificado a la derecha, 7 dígitos de largo, sin relleno
%.7i largo mínimo de 7 dígitos, justificado a la derecha, rellena con ceros
%8.2f tamaño total de 8 dígitos, con dos decimales
%.*f”',x,d) tamaño predeterminado, x números decimales
%*.*f”,x,y,d) tamaño igual a x, y números decimales
%s cadena terminada en null
%5s primeros cinco caracteres o delimitador
%.5s primeros cinco caracteres, sin tener en cuenta el delimitador
%20.5s primeros cinco caracteres, justificados a la derecha, con 20 caracteres de largo
%-20.5s primeros cinco caracteres, justificados a la izquierda, con 20 caracteres de largo

MANDATOS DE ASIGNACIÓN DE ENTEROS


El programa 11ASIG_INT.CPP es un buen ejemplo de los mandatos de asignación:

#include <stdio.h>

void main(void)
{
int a,b,c;

a = 12;
b = 3;
c = a + b;
printf("a= %d| b= %d| c= %d\n\n",a,b,c);
Programación C++ Ing. Helmut Heinz Dehner Página 17 de 70
c = a - b;
printf("a= %d| b= %d| c= %d\n\n",a,b,c);
c = a * b;
printf("a= %d| b= %d| c= %d\n\n",a,b,c);
c = a / b;
printf("a= %d| b= %d| c= %d\n\n",a,b,c);
(17)c = a % b; // módulo o residuo
printf("a= %d| b= %d| c= %d\n\n",a,b,c);
(19)c = 12*a + b/2 - a*b*2/(a*c + b*2);
printf("a= %d| b= %d| c= %d\n\n",a,b,c);
(21)c = c/4+13*(a + b)/3 - a*b + 2*a*a;
printf("a= %d| b= %d| c= %d\n\n",a,b,c);
a = a + 1;
printf("a= %d| b= %d| c= %d\n\n",a,b,c);
b = b * 5;
printf("a= %d| b= %d| c= %d\n\n",a,b,c);

(28)a = b = c = 20; // asignación múltiple


printf("a= %d| b= %d| c= %d\n\n",a,b,c);
(30)a = b = c = 12*13/4;
printf("a= %d| b= %d| c= %d\n\n",a,b,c);
}

Tres variables se definen para su uso en el programa, y las demás son para ilustrar acerca de otros tipos
de asignación. Las dos primeras líneas asignan valores numéricos a “a” y a “b”, y las 4 siguientes líneas
ilustran el uso de las 5 funciones aritméticas básicas. En la línea 17 se utiliza el operador modular
(%) que da el resto de la división de a por b. Esto sólo puede ser aplicado a variables tipo int o char,
y sus extensiones, tales como long, short, etc. Siguiendo, en las líneas 19 y 21 se ilustra la manera de
combinar variables en algunas expresiones complejas, utilizando paréntesis.
En las líneas 28 y 30 se usa la asignación múltiple, construcción muy útil sobre todo cuando hay que
inicializar variables en grupo.

El operador cin
Este operador se utiliza para leer datos desde el teclado. Se usa con el llamado operador de extracción
(>>).
Con el operador cin pueden asignarse a las variables valores ingresados por el usuario.
Veamos como ejemplo el programa 12OPER_CIN.CPP:

#include <iostream.h>

void main(void)
{
int a;
float b;
char c;

cout << "Ingrese un valor entero: ";


cin >> a;

cout << "Ingrese un valor float: ";


cin >> b;

cout << "Ahora ingrese un caracter: ";


cin >> c;

cout << "\nLos datos ingresados son: ";


cout << "\n'a' = " << a;
cout << "\n'b' = " << b;

Programación C++ Ing. Helmut Heinz Dehner Página 18 de 70


cout << "\n'c' = " << c;

COMPARACIONES LÓGICAS
El programa 13COMPARAR.CPP contiene algunos ejemplos de comparaciones en C.

#include <iostream.h>

void main(void)
{
int x = 11,y = 11,z = 11;
char a = 40,b = 40,c = 40;
float r = 12.987,s = 12.987,t = 12.987;

// Primer grupo de mandatos comparadores

if (x == y) z = -13; // Esto asignará z = -13


if (x > z) a = 'A'; // Esto asignará a = 65
if (!(x > z)) a = 'B'; // Esto no cambiará nada
if (b <= c) r = 0.0; // Esto asignará r = 0.0
if (r != s) t = c/2; // Esto asignará t = 20

// Segundo grupo de mandatos comparadores

if (x = (r != s)) z = 1000; // Esto asignará x = algún número


// positivo y z = 1000
if (x = y) z = 222; // Esto asigna x = y, y z = 222
if (x != 0) z = 333; // Esto asigna z = 333
if (x) z = 444; // Esto asigna z = 444

// Tercer grupo de mandatos comparadores

x = y = z = 77;
if ((x == y) && (x == 77)) z = 33; // Esto asigna z = 33
if ((x > y) || (z > 12)) z = 22; // Esto asigna z = 22
if (x && y && z) z = 11; // Esto asigna z = 11
if ((x = 1) && (y = 2) && (z = 3)) r = 12.00;
// Esto asigna x = 1, y = 2, z = 3, r = 12.00
if ((x == 2) && (y = 3) && (z = 4)) r = 14.56; // Esto no cambia nada

// Cuarto grupo de comparadores

if (x == x); z = 27.345; // z siempre se cambia


if (x != x) z = 27.345; // Nadie cambia aquí
if (x = 0) z = 27.345; // Esto asigna x = 0, z sigue igual

Empezamos definiendo e inicializando nueve variables para usarlas en los mandatos comparadores.
El primer grupo de comparaciones representa el más simple, ya que sólo compara 2 variables. Cada va-
riable podría ser sustituida por una constante, y la comparación seguiría siendo válida, pero dos varia -
bles es el caso más frecuente. La primera comparación averigua si “x” e “y” son iguales, usando el doble
igual “==“ para esta comparación. La segunda comparación verifica si “x” es mayor de “z”.

La tercera introduce el operador NOT (!), el cual puede usarse para negar una comparación lógica ( !
(x>z) : que x no sea mayor que z). La cuarta comprueba que “b” sea menor o igual que “c”, y la última

Programación C++ Ing. Helmut Heinz Dehner Página 19 de 70


verifica que “r” y “s” no sean iguales (r != s). Tal como vimos anteriormente, si la comparación resulta
cierta, el mandato acompañante del if será ejecutado.

Las comparaciones del segundo grupo son más complicadas. Para comprender esto debemos entender
tan solo lo que significan verdadero y falso en lenguaje C. Falso está definido como valor 0, y verdade-
ro es definido como no cero. Cualquier variable entera o tipo char puede usarse para el resultado de
tipo verdadero/falso, o el resultado puede ser transformado en un valor entero o char.

Observemos primero la comparativa del segundo grupo de comparadores. La expresión “r!=s” será eva-
luada como cierta, teniendo en cuenta que “r” fue probablemente inicializada antes a 0.0, por tanto el
resultado será un no cero, tal vez un 1. Tengamos presente que cuando se evalúen dos variables float,
el resultado será siempre de tipo integer. Dado que no se le ha dado una variable para almacenar el re-
sultado de la comparación, lo hará produciendo directamente un entero. Finalmente, el resultado, 1 en
este caso, será asignado a “x”. Si hubiésemos usado el doble igual, el valor fantasma llamado 1, sería
comparado internamente con “x”, pero como hemos empleado el igual simple, el valor es asignado a
“x”, aunque el mandato esté entre paréntesis. Finalmente, dado que el resultado de la asignación entre
paréntesis es no cero, la expresión evaluada es cierta, y el valor 1000 es asignado a “z”. Por tanto, he-
mos conseguido 2 cosas: hemos asignado un nuevo valor a “x”, probablemente 1, y hemos destinado
1000 a “z”. Lo más importante a recordar es que valores verdadero/falso y muchas cosas más pueden
ser asignadas a este mandato condicional. El valor asignado a “x” es 1, pero distintos compiladores po-
drían asignar otros valores.
El ejemplo que proponemos servirá para aclarar conceptos. En él , “x” es asignado al valor de “y”, y
dado que el valor es 11, es no cero, lo cual es, por tanto, verdad. De este modo, a “z” se le asigna el
valor 222.

El tercer ejemplo del segundo grupo compara “x” y 0. Si el resultado es verdad, significa que “x” es no
cero, por tanto a “z” se le asigna el valor 333. El tercer ejemplo ilustra el mismo caso, ya que el resulta-
do de “x” es no cero. La comparación a cero no es actualmente necesaria, ya que el resultado de la mis-
ma es verdad. El tercer y cuarto ejemplo son idénticos.

CONCEPTOS ADICIONALES SOBRE COMPARACIÓN


El tercer grupo de comparaciones nos introducirá nuevos conceptos sobre comparaciones, tales como el
AND y el OR. Asignamos el valor 77 a tres variables enteras, simplemente para empezar otra vez con
valores definidos. La primera comparación del tercer grupo contiene el nuevo controlador “&&”, el cual
es el “AND“ lógico. El mandato en su totalidad lee si “x” es igual a “y” y si “x” es igual a 77, entonces el
resultado será verdad. Si es verdadera, la variable “z” toma el valor 33.
La siguiente comparación introduce el operador “¦¦”, el cual equivale a “OR”. El mandato verifica que si
“x” es mayor que “y” o que si “z” es mayor de 12, entonces el resultado es verdad. Dado que “z” es ma-
yor de 12, no importa que “x” sea mayor que “y” o no, porque sólo con que una condición sea cierta, ya
se cumple el mandato entero. La condición tiene resultado verdad, por lo cual asignamos el valor 22 a
“z”.

EVALUACIÓN LÓGICA
Cuando una expresión compuesta se evalúa, la evaluación se realiza de izquierda a derecha, y tan pron-
to como se cumple el resultado de la misma, se para. Nos referimos a “evaluación lógica” cuando em-
pleamos un AND y, uno de los términos evaluados da falso, la evaluación es discontinua, aunque los de -
más términos sean verdad, la condición en su totalidad resulta falso. Tratándose del OR, sólo con que
uno de los términos evaluados sea cierto, la condición ya se cumple ahí mismo, caso contrario del AND.
En caso de términos adicionales anidados, las reglas para su evaluación se describen en la sgte. página.

Yendo al siguiente ejemplo del tercer grupo, encontramos 3 variables simples, usadas en la parte condi -
cional de la comparación. Como todas las variables tienen valor no cero, todas son verdad, hay por tan-
to el “AND” de esas 3 variables, “r”, “s” y “t” son de tipo float, por lo cual no podrían ser usadas para
este propósito, pero pueden ser comparadas con cero, y el mismo tipo de expresión podría aplicárseles.

Continuando con el cuarto ejemplo del tercer grupo, encontramos 3 asignaciones en la parte compara-
dora del if. A las tres variables se les asignan nuevos valores, los cuales son no cero, por lo tanto produ -
cen un resultado verdad.
Programación C++ Ing. Helmut Heinz Dehner Página 20 de 70
El último ejemplo del tercer grupo contiene una pequeña trampa, pero como ya hemos hablado acerca
de esto, parte de la comparación evalúa falso. El resto de la comparación no es evaluada, porque es un
AND, que al dar falso en la primera comparación, ya la resuelve. Si el programa dependía del valor de
“y”, que había sido inicializada a 3, en la siguiente parte de la comparación cesará porque parará al en-
contrar el falso en el primer término. Por tanto, “z” no tomará valor 4, y la variable “r” no cambiará.

ÁREAS POTENCIALES DE PROBLEMAS


El último grupo de comparaciones ilustra tres posibilidades que pueden resultar algo confusas. Las tres
tienen como resultado el que “z” no tome el valor deseado, pero por diferentes motivos. En el primero,
la comparación evaluada resulta verdad pero el ; siguiente al segundo paréntesis termina la cláusula if y
el mandato implícito a “z” es ejecutado, siempre en el siguiente mandato. El if, por tanto, no tiene efec-
to por el punto y coma, que ignora el resto de la línea. El segundo mandato es más sencillo, porque “x”
siempre es igual a si mismo, por tanto la inigualdad jamás será cierta, y el mandato no hará nada, por
tanto es un esfuerzo inútil.
El último mandato siempre asignará 0 a “x”, y por tanto, la comparación siempre dará falso, no ejecu-
tando jamás la parte condicional del if.
El mandato condicional es extremadamente importante, y, debe ser minuciosamente estudiado, para es-
cribir buenos programas en C.

LA PARTE CRÍPTICA DEL C


Existen tres estructuras en C que no tienen sentido cuando se ven por primera vez, ya que no son intui-
tivas, pero al contrario, son extremadamente útiles para incrementar la eficiencia del código compilado y
las usan muchos programadores expertos en C.
El programa 14CRIPTICA.CPP es un ejemplo de 3 nuevas construcciones.

# include <iostream.h>

void main(void)
{
int x = 0,y = 2,z = 1025;
float a = 0.0,b = 3.14159,c = -37.234;

// incrementando
x = x + 1; // Incrementa x
x++; // Incrementa x
++x; // Incrementa x
z = y++; // z = 2, y = 3
z = ++y; // z = 4, y = 4

// decrementando
y = y - 1; // Decrementa y
y--; // Decrementa y
--y; // Decrementa y
y = 3;
z = y--; // z = 3, y = 2
z = --y; // z = 1, y = 1

// operador aritmético
a = a + 12; // Añade 12 a a
a += 12; // Añade 12 más a a
a *= 3.2; // Multiplica a por 3.2
a -= b; // Resta b a a
a /= 10.0; // Divide a entre 10.0

// expresión condicional
a = (b >= 3.0 ? 2.0 : 10.5 ); // Esta expresión

Programación C++ Ing. Helmut Heinz Dehner Página 21 de 70


if (b >= 3.0) // Y esta expresión
a = 2.0; // son idénticas, ambas
else // producen el mismo
a = 10.5; // resultado.

c = (a > b?a:b); // c tendrá el máximo de a o b


c = (a > b?b:a); // c tendrá el mínimo de a o b

En este programa algunas variables son definidas e inicializadas en el mismo mandato, para su uso pos-
terior.
El primer mandato ejecutable, simplemente suma 1 al valor de “x”. Los dos siguientes mandatos tam-
bién añaden 1 al valor de “x”, pero utilizando el operador de incremento de C++, un doble signo
más (++) antes o después de una variable, incrementa su valor en 1.
Si el signo está antes de la variable, es incrementada antes de su uso: z = ++y, incrementa “y” para
después asignar su valor a “z”.
Si el signo está después de la variable, ésta es usada e incrementada posteriormente: z = y++, asigna
a “z” el valor de “y”, luego incrementa esta última variable.

El siguiente grupo de mandatos ilustran el decremento en 1 de una variable, utilizando el operador de


decremento, el doble signo menos (--). Funciona igual que el incremento excepto, obviamente, en
que en este caso se resta 1 a la variable.

Otros operadores se usan para modificar una variable en algún valor constante. El primer mandato del
grupo del operador aritmético sencillamente suma 12 al valor de “a”. El segundo hace lo mismo, pero
utilizando la expresión “+=“. Algunas de las funciones aritméticas básicas, +, - ,*,/, pueden tratarse de
esta manera, poniendo la función deseada delante del signo igual, y eliminando la segunda referencia al
nombre de la variable. Nótese que la expresión a la derecha del operador aritmético puede ser expresión
válida.
Al igual que el incremento/decremento, el operador aritmético es una de las herramientas habituales de
un buen programador.

LA EXPRESIÓN CONDICIONAL
La expresión condicional es, al igual que los dos anteriores, un críptico. Consiste en 3 expresiones entre
paréntesis, separadas por un signo de interrogación y dos puntos. La expresión prioritaria en el interro-
gante es evaluada para determinar si es verdad o falso. Si es verdad, la expresión entre interrogantes y
dos puntos es evaluada y, si es “no verdad”, la expresión que sigue a los dos puntos se evalúa. El resul-
tado de la evaluación se usa en la asignación. El resultado final es idéntico que un if con else.
if else
a = (b >= 3.0 ? 2.0 : 10.5 ) Si b >=3.0 “a” será igual a 2.0 sino, “a” se igualará a 10.5

Esto viene ilustrado en el segundo ejemplo de este grupo. La expresión condicional tiene la ventaja aña -
dida de un código más compacto, el cual compilará la máquina en pocas instrucciones en el programa.
Las dos líneas finales del programa ejemplo ilustran una manera muy compacta de asignar la mayor de
2 variables, “a” o “b” a “c” y, de asignar la menor de esas variables a “c”.

Las palabras const y volatile


En el programa 15CONS_VOL.CPP vemos la utilización de estas nuevas palabras en C++.

#include <iostream.h>

void main(void)
{
(5) const int PRINCIPIO = 3; // El valor de PRINCIPIO no podrá cambiarse
const int FIN = 9; // El valor de FIN no podrá cambiarse
volatile int CENTRO = 6; // El valor de CENTRO podrá ser cambiado
Programación C++ Ing. Helmut Heinz Dehner Página 22 de 70
// por algo externo a este programa.
int indice; // Una variable normal de C

for (indice = PRINCIPIO ; indice < FIN ; indice++)


cout << "El valor del índice es " << indice << "\n";
}

La palabra const se usa para definir una constante.

En la línea 5 la constante es de tipo int (entero), se llama PRINCIPIO, y se le asigna el valor 3. El com-
pilador no permitirá que accidentalmente, o aún queriéndolo, se cambie el valor de PRINCIPIO porque
se ha declarado como constante. Si existiera una variable llamada PRINCIPIOS, el sistema no permitiría
que accidentalmente se cambiara el valor de PRINCIPIO. El compilador daría un mensaje de error, ya
que no está permitido cambiar el valor de una constante.

La palabra volatile indica que podrá cambiarse el valor de la variable así declarada. Aunque el valor de
una variable volátil puede ser cambiado por el programador, puede haber otro mecanismo para que el
valor pueda cambiarse, tal como por un procedimiento que ocasione su incremento. El compilador nece-
sita saber que este valor puede ser cambiado por alguna fuerza externa al avanzar el programa.

EL OPERADOR DE ALCANCE
El programa llamado 16OP_ALCAN.CPP ilustra otra construcción que es nueva en C++.
Esto permite acceso al índice declarado como variable global, (declarada antes del main) aunque hay
una variable local del mismo nombre dentro de la función principal.

El uso del doble dos puntos (::) antes del nombre de la variable, en las líneas 10, 12 y 15, indica que
estamos interesados en usar el índice global, definido en la línea 3, y no en el índice local definido en la
línea 7.

#include <iostream.h>

(3) int indice = 13;

void main(void)
{
(7) float indice = 3.1415;

cout << "El valor del índice local es " << indice << "\n";
(10) cout << "El valor del índice global es " << ::indice << "\n";

(12) ::indice = indice + 7; // 3 + 7 resultará en 10

cout << "El valor del índice local es " << indice << "\n";
(15) cout << "El valor del índice global es " << ::indice << "\n";

El uso de esta técnica permite acceso a la variable global para cualquier uso. Podría usarse en cálculos,
como un parámetro de función, o para cualquier otro propósito.
En la práctica realmente buena de un programador no se debe abusar de esto, porque podría hacer que
el código sea difícil de leer. Sería mejor usar un nombre diferente para cada variable, en vez de repetir
uno solo, pero esta construcción está disponible si se la necesita alguna vez.

DEFINICIÓN DE VARIABLES
Veamos a continuación el archivo 17VARDEF.CPP

#include <iostream.h>

Programación C++ Ing. Helmut Heinz Dehner Página 23 de 70


(3) int indice;

void main(void)
{
(7) int elemento;
(8) int &otro_elemento = elemento; // Un sinónimo para elemento

(10)elemento = indice + 14; //índice ha sido inicializado a cero y elemento toma su valor modificado
cout << "El elemento tiene el valor " << elemento << "\n";
elemento = 17;
cout << "El otro elemento tiene el valor " << otro_elemento << "\n";

(15)int mas_elementos = 13; //Esta no es una inicialización automática

cout << "Otro elemento tiene el valor " << mas_elementos << "\n";

(19)for (int contador = 3;contador < 8;contador++) {


cout << "El contador vale " << contador << "\n";
(21)char contador2 = contador + 65;
cout << "Contador2 tiene el valor " << contador2 << "\n";
}

(25)static unsigned estatico; //inicialización automática a cero


cout << "Estático vale " << estatico << "\n";
}
(28)
Las variables son automáticamente inicializadas a cero cuando se declaran. Los variables “indice”, en la
línea 3, y “estático”, en la línea 25 son, por lo tanto, automáticamente inicializadas a cero. Por supuesto,
todavía se pueden inicializar con algún otro valor si se desea. Las variables globales, como “indice”, se
llaman a veces externas.
La variable “elemento” en la línea 7, no contiene un valor válido. En la línea 10, se le asigna un valor
utilizando a “indice” (que vale cero) y se muestra por pantalla.

VARIABLE DE REFERENCIA
En la línea 8 se define a la variable “otro_elemento” como una variable de referencia, utilizando el sím-
bolo & (amperson).
La variable de referencia llega a ser un sinónimo para la variable “elemento”. Cambiando el valor de
“elemento” cambiará el valor de “otro_elemento” porque ambas son como una misma variable.
El sinónimo puede usarse para acceder al valor del variable con cualquier propósito. Se debe indicar que
una variable de referencia debe ser inicializada para hacer referencia a alguna otra va-
riable, de no ser así el compilador responderá con un error. Después de la inicialización, la variable no
puede cambiarse para hacer referencia a una variable diferente.
La variable de referencia no debería usarse muy frecuentemente, ya que puede conducir a confusiones
en el programa, pero puede utilizarse cuando el código es claro y fácil de comprender.

DECLARACIONES EJECUTABLES
En la línea 15 hay una declaración extraña, pero legal en C++. Es legal poner una declaración ejecuta-
ble en cualquier lugar del programa, incluso en una definición de variable.
En este caso, definimos la variable “mas_elementos” y la inicializamos con el valor 13.
Es muy importante que el variable se declare cerca de su punto de uso. Esto hace más fácil de ver qué
variable se usa para una determinada orden. Aunque tiene un alcance mucho más restringido.

Definición y declaración
Las palabras de definición y declaración se refieren a dos cosas diferentes en C++.

Programación C++ Ing. Helmut Heinz Dehner Página 24 de 70


Una declaración provee información al compilador sobre las características de un elemento tal como un
dato o una función, pero no define realmente ningún código para ser usado en la ejecución del progra-
ma. Es posible hacer tantas declaraciones como se desee sobre un mismo elemento.
Una definición, por otra parte, realmente define algo que existirá en el programa ejecutable, o algunas
variables útiles, o algún código ejecutable, y se requiere tener una y sólo una definición de cada ele -
mento en el programa.

En suma, una declaración introduce un nombre en el programa y una definición intro -


duce algunos códigos.
Cuando definimos las variables, declaramos sus nombres para el uso del compilador, y definimos una
ubicación de memoria para almacenar sus valores. Por lo tanto, cuando definimos una variable, la decla-
ramos y la definimos a la vez. (definir=ubicación de memoria para sus valores)(declarar= sus nombres
para uso del compilador)

Las variables En EL BUCLE for


Revisemos cuidadosamente el bucle definido en la línea 19.
Como puede verse, el índice se define en mismo bucle (“contador”). El alcance de este índice de bucle
va desde su declaración hasta el fin del programa.
A partir de allí, la variable está disponible, puede usarse para otro índice de bucle o para cualquier otro
propósito.
La variable nombrada “contador2” se declara e inicializa en cada paso por el bucle, porque se declara
dentro del bloque controlado por el for. Por lo tanto se declara e inicializa cinco veces. Tiene alcance úni-
camente dentro del bucle.
A la variable “contador2” se le asigna un valor numérico en la línea 21, pero cuando se imprime, apare -
ce como caracter. Esto es porque C++ tiene cuidado en usar el tipo correcto (contador2 fue declarado
como char).
Finalmente, la variable estática llamada “estático” se declara y se inicializa automáticamente a cero en
la línea 25. Su alcance va desde el punto de su declaración hasta el fin del bloque en que se declara, lí-
nea 28.

Salida Con formato FORMATO.CPP


//Salida con Formato
/*
Todas estas Funciones se encuentran en la Biblioteca "iomanip"

dec conversión a decimal


hex conversión a hexadecimal
oct conversión a octal
setprecision(int i) establece el número de dígitos significativos para un
valor. La precisión por defecto es seis. Si el valor es
real. La precisión se refiere al número de decimales.
setfill(int car) establece el carácter de relleno para las cadenas de caracteres. Por defecto es
el espacio en blanco.
setw(int n) establece el ancho mínimo del buffer, en caracteres, del
stream. Este valor por defecto es cero y significa que
sólo se insertarán (<<) los caracteres necesarios para
representar el valor. Si el ancho no es cero, se rellena
hasta n con el caracter de relleno.
ws extrae un espacio en blanco del principio del stream.
endl inserta un caracter '\n' y vacía el buffer del stream.
ends inserta un caracter '\0' para finalizar una cadena.
flush vacía el buffer del stream.
setiosflags(long fs)establece una lista de formato, combinados con el opera-
dor OR (|). Ver la función ios::flags.
resetiosflags(long fs) suprime una lista de flags de formato.

Los streams predefinidos proveen varias funciones miembro para el manejo de los datos. Algunas de es-
tas funciones son las siguientes:

Programación C++ Ing. Helmut Heinz Dehner Página 25 de 70


ios::flags(long flags) establece los flags de formato. El parámetro flags representa una lista de
alguno de los siguientes valores combinados con el operador OR (|).
ios::left justificación a la izquierda.
ios::right justificación a la derecha.
ios::scientific notación científica.
ios::fixed coma flotante en formato fijo.
ios::good() devuelve un valor distinto de cero si todos los bits de error, incluido el de fin de
fichero, están desactivados
ios::eof() devuelve un valor distinto de cero si se encuentra el fin de fichero (eof).
ios::bad() devuelve un valor distinto de cero si ocurre un error irrecuperable.
ios::fail() devuelve un valor distinto de cero si ocurre cualquier error excepto eof.
ios::clear(int st=0) si st es cero, desactiva todos los indicadores de error.
cout.flush() vacía el buffer en el de salida.
cin.get(char &c) extrae un carácter de la entrada estándar.

cin.getline(char *pc, int n, char d='\n')


extrae caracteres del stream hasta que dé una de las siguientes condiciones: se encontró el delimita-
dor d, se
han extraído n-1 caracteres, se encontró el final del fichero.

cin.ignore() extraer y descartar los caracteres hasta EOF inclusive.


*/
#include "stdafx.h"
#include <iostream>
#include <iomanip>

using namespace std;

//Ejemplo

void main(void)
{
float coef[] = { 5198, 3.21, 46.32, 506.5, 2002.38 };
char *prov[] = { "Córdoba", "Misiones", "Salta", "Chaco", "Corrientes" };

//Salida de los resultados alineados en columnas

cout << setiosflags(ios::fixed); //Formato Fijo


for (int i = 0; i<sizeof(coef) / sizeof(float); i++) //Divide cant. coef/Tam. Tip
cout << setiosflags(ios::left) //Justificación a la izquierda
<< setw(15) //Ancho para las cadenas caract
<< setfill('.') //Carácter de relleno
<< prov[i] //Escribe la provincia
<< resetiosflags(ios::left) //Suprime justificación
<< setw(10) //Ancho para las cantidades
<< setprecision(2) //Precisión de 2 decimales
<< coef[i] << endl; //escribe cantidad y '\n'
system("pause");

EJERCICIOS DE PROGRAMACIÓN
1. Escribir un programa que cuente de 1 a 12 Nº ingresados, que escriba el número en una columna, y
su cuadrado en otra contigua. Cuidar el formato de salida.

2. Escribir un programa que cuente de 1 a 12 Nº ingresados, escriba el número (n), y al lado el resulta -
do de dividir 1/n. Cálculo float de 5 dígitos (5 decimales).

3. Escribir un programa que cuente de 1 a 10 Nº ingresados, pero que sólo imprima los números com-
prendidos entre 32 y 39, uno en cada línea.

Programación C++ Ing. Helmut Heinz Dehner Página 26 de 70


4. Escribir un programa interactivo para leer una fecha con tres diferentes declaraciones cin. Imprimir
dicha fecha por pantalla. (error del tonto else)

5. Escribir un programa con unos valores constantes y con variables volátiles. Ver qué tipo de mensaje
de error da el compilador al intentar cambiar el valor de las constantes.

DEFINES Y MACROS

DEFINES Y MACROS: AYUDA A UNA PROGRAMACIÓN CLARA


A continuación vemos el primer ejemplo de algunas "defines" y "macros":
19DEFINE.C

#define START 0 /* Punto de comienzo del bucle */


#define ENDING 9 /* Punto de final del bucle */
#define MAX(A,B) ((A)>(B)?(A):(B)) /* Macro definitoria de Max */
#define MIN(A,B) ((A)>(B)?(B):(A)) /* Macro definitoria de Min */

void main(void)
{
int index,mn,mx;
int count = 5;

for (index = START;index <= ENDING;index++) {


mx = MAX(index,count);
mn = MIN(index,count);
printf("Max es %d y min es %d\n",mx,mn);
}
}

Observamos que las 4 primeras líneas de programa empiezan con la palabra "#define". Es la
manera de definir todos los "macros" y las "defines". Antes de empezar la compilación, el compilador
efectúa un paso de preprocesador para resolver todas las "defines". En el caso presente encontrará cada
sitio donde la combinación "START" aparezca y, simplemente la sustituirá por un 0, ya que esto es una
definición. El compilador nunca verá la palabra "START" en toda la compilación. Sólo encontrará ceros.
En este caso se utilizan las palabras "START", "ENDING", etc. Pero pueden utilizarse las que se
quiera, como "INICIO", "FIN", etc.
En el caso de un programa pequeño, como este, no tiene importancia lo que se use, pero imagí -
nese un programa de 2000 líneas y 27 referencias a START. Sería totalmente distinto. Si necesitara
cambiar todos los STARTS del programa por un nuevo número, no habría dificultad en hacerlo con un
"#define", pero más complicado sería cambiar todas las referencias manualmente, y realmente desas-
troso si se deja un par de referencias.
De la misma manera, el preprocesador encontrará todas las apariciones de la palabra "ENDING",
y las cambiará por 9, y el compilador operará en esa línea sin saber que hubo un "ENDING".
Es una buena costumbre en programación el usar mayúsculas para constantes simbólicas, como
"START" y "ENDING", y usar minúsculas para las variables. Per puede usarse el método que se prefiera,
es a gusto de cada uno.

¿ESTO ES ÚTIL?
Cuando en adelante tratemos sobre entrada/salida, necesitaremos alguna manera de conocer el
fin de fichero, en un fichero de entrada. Dado que diferentes compiladores usan distintos valores numé-
ricos para esto, a pesar de que lo más usual es usar 0 o -1, escribiremos un programa con "define" para
definir el EOF(fin de fichero) para nuestro compilador.
Si tras un tiempo cambiamos de intérprete C, será cuestión de modificar la define de acuerdo con
el nuevo compilador. Fin de fichero es otro de los indicadores no universales.
Esto tendrá sentido en temas posteriores.

Programación C++ Ing. Helmut Heinz Dehner Página 27 de 70


¿QUÉ ES UN MACRO?
Un macro no es más que otro define, pero dado que es capaz, o al menos susceptible de reali-
zar decisiones lógicas, o funciones matemáticas, tiene un nombre único.
Consideremos la tercera línea del programa como un ejemplo de macro. En este caso, si alguna
vez el preprocesador encuentra la palabra "MAX" seguida de un grupo de paréntesis, esperará a encon-
trar dos términos entre paréntesis, y realizará una sustitución de los términos en la segunda definición.
Entonces, el primer termino reemplazará cada "A" en la segunda definición, y el segundo término susti-
tuirá cada "B" en la segunda definición. Cuando encontramos la línea 12 del programa, "index" será sus -
tituido por cada "A", y "count" lo será por cada "B". Recordando la estructura críptica, estudiada ante -
riormente, revelaremos que "mx" recibirá el máximo valor de "index" o "count". De una manera pareci-
da, el macro "MIN" resultará en "mn", recibiendo el mínimo valor de "index" o "count". Los resultados
aparecen por pantalla. Hay bastantes paréntesis extra en la definición del macro, pero no sobran, son
esenciales.

UN MACRO INCORRECTO
El siguiente es un ejemplo mejor de macro:
20MACRO.C

#define WRONG(A) A*A*A /* Macro incorrecto para el cubo */


#define CUBE(A) (A)*(A)*(A) /* Macro correcto para el cubo */
#define SQUR(A) (A)*(A) /* Macro correcto para el cuadrado */
#define START 1
#define STOP 9

void main(void)
{
int i,offset;

offset = 5;
for (i = START;i <= STOP;i++) {
printf("El cuadrado de %3d es %4d, y su cubo es %6d\n",
i+offset,SQUR(i+offset),CUBE(i+offset));
printf("El incorrecto de %3d es %6d\n",i+offset,WRONG(i+offset));
}
}

La primera línea define un macro de nombre "WRONG", que sirve para obtener el cubo de "A", y
de hecho lo hace en algunos casos, aunque fracasando estrepitosamente en otros. El segundo macro,
llamado "CUBE" obtiene el cubo en todos los casos.
Consideremos el programa en si, donde el CUBE de i+offset es calculado. Si i es 1, lo cual es la
primera vez, buscaremos el cubo de 1+5+6, el cual es 216. Cuando usamos "CUBE" agrupamos valores
como estos: (1+5)*(1+5)*(1+5) = 6*6*6 =216. Como siempre, si usamos WRONG, los agruparemos
así: 1+5*1+5*1+5 = 1+5+5+5 = 16, lo cual es una respuesta incorrecta. Los paréntesis son básicos
para operar con variables agrupadas. Debe ver bien clara la diferencia entre "CUBE" y "WRONG". Los
valores correctos e incorrectos de cubo y cuadrado aparecen por pantalla para su inspección.
El resto del programa es simple, y no necesita comentarios.

EJERCICIOS DE PROGRAMACIÓN:

1-. Escribir un programa que cuente de 7 a -5 hacia atrás. Usar #define con mandatos para establecer
los límites. Por supuesto, se necesitará una variable decrementadora para la tercera parte del bucle
"for".

# define INICIO 7
# define FIN -5

Programación C++ Ing. Helmut Heinz Dehner Página 28 de 70


void main(void)
{
int n;

for(n=INICIO;n>=FIN;n--){
printf("\n %d ",n); }
}

TRABAJO PRÁCTICO DE ESTRUCTURAS DE CONTROL

1) Escribir un programa que permita la entrada de dos números y muestre su suma.


2) Ídem anterior, pero con “N” números.
3) Ingresar “N” números y encontrar el mayor y el menor. Además la posición de ingreso.
4) Escribir un programa para calcular el factorial de un número. (Debe trabajarse con reales dobles).
5) Escribir un programa para ingresar una serie de valores (termina con –1) de ventas y los suma divi -
didos en cuatro categorías:

Valores
< 1000
1000 – 2000
2001 – 3000
> 3000
6) Cuatro enteros entre 0 y 100 representan las puntuaciones de un estudiante de un curso de informá-
tica. Escribir un programa para encontrar la media de estas puntuaciones y visualizar una tabla de
notas de acuerdo al siguiente cuadro:
Media Puntuación
90 – 100 A
80 – 89 B
70 –79 C
60 – 69 D
0 – 59 E
7) La fuerza de atracción entre dos masas, m1 y m2, separadas por una distancia d, está dada por la
fórmula:

donde G es la constante de gravitación universal

Escribir un programa que lea la masa de dos cuerpos y la distancia entre ellos y a continuación ob-
tenga la fuerza gravitacional entre ella.
8) La famosa ecuación de Einstein para conversión de una masa m en energía viene dada por la fórmu-
la:

E = m * c2 c es la velocidad de la luz = 2.997925 x 1010 m/seg

Escribir un programa que lea una masa en gramos y obtenga la cantidad de energía producida cuan-
do la masa se convierte en energía.
9) La relación entre los lados (a,b) de un triángulo rectángulo y la hipotenusa (h) viene dada por la fór-
mula:

a2 + b2 = h2
Escribir un programa que lea la longitud de los lados y calcule la hipotenusa.
10) El área de un triángulo cuyos lados son a, b y c se puede calcular por la fórmula:

Programación C++ Ing. Helmut Heinz Dehner Página 29 de 70


#include <math.h> sqrt(p*…)

Escribir un programa que lea las longitudes de los tres lados de un triángulo y calcule el área del
triángulo.
11) Determinar la media de una lista indefinida de números positivos, terminados con un número ne -
gativo.
12) Dado el número de un mes y si el año es o no bisiesto, deducir el número de días del mes. Un
año es bisiesto si es múltiplo de 4(cuatro), salvo que sea principio de siglo, en cuyo caso NO es bi-
siesto, con la excepción de los que son múltiplos de 400(cuatrocientos).
13) Sumar los números enteros de 1 a 100 mediante:
a) estructura while;
b) estructura do while;
c) estructura for.
14) Determinar la media de una lista de números positivos terminada con un número no positivo des-
pués del ú1timo número válido.
15) Imprimir todos los números primos entre 2 y 1.000 inclusive.
16) Se desea leer las calificaciones de una clase de informática y contar el número total de aprobados
(7 o mayor que 7).
17) Leer las notas de una clase de Informática y deducir todas aquellas que sean NOTABLES ( >= 7 y
< 9).
18) Leer 100 números. Determinar la media de los números positivos y la media de los números ne-
gativos.
19) Un comercio dispone de dos tipos de artículos en fichas correspondientes a diversas sucursales
con los siguientes campos (que se ingresan por teclado):

a) código del artículo A o B,


b) precio unitario del artículo,
c) número de artículos.

i) La última ficha del archivo de artículos tiene un código de articulo, una letra X. Se pide:

(1) el número de artículos existentes de cada categoría,


(2) el importe total de los artículos de cada categoría.
20) Una estación climática proporciona un par de temperaturas diarias (máxima, mínima) (no es po-
sible que alguna o ambas temperaturas sea 9 grados). La pareja fin de temperaturas es 0,0. Se pide
determinar el número de días. cuyas temperaturas se han proporcionado, las medias máxima y míni-
ma, el número de errores -temperaturas de 0°- y el porcentaje que representaban.

21) Calcular:

a) Para N que es un entero leído por teclado.


b) Hasta que N sea tal que xn/n! < E (por ejemplo, E = 10-4).
22) Realizar un algoritmo que escriba los N primeros números de la serie de Fibonacci.

NOTA: La serie de Fibonacci es 1, 1, 2, 3, 4, 8, 13 y se genera de acuerdo a la ley siguiente:

Fibonacci (1) = 1
Fibonacci (2) = 1
Fibonacci (3) = 2 = Fibonacci(2) + Fibonacci(l)
Fibonacci (4) = 3 = Fibonacci(2) + Fibonacci(3)

Fibonacci(N para N > 1) = Fibonacci(N- 1) + Fibonacci(N- 2)

Programación C++ Ing. Helmut Heinz Dehner Página 30 de 70


Calcular el enésimo término de la serie de Fibonacci definida por:

A1 = 1 A2 = 1 A3 = 1 + 1 = A1 + A2 An = An-1 + An-2 (n>=3)


#en un año, cuantos hijos tiene una pareja de conejitos?
#cuanto tiempo necesito para tener n conejitos?
23) Se pretende leer todos los empleados de una empresa situados en un archivo empresa y a la ter -
minación de la lectura del archivo se debe visualizar un mensaje «existen trabajadores mayores de
65 años en un número de ...» y el número de t trabajadores mayores de 65 años.
24) Un capital C está situado a un tipo de interés R, al término de cuántos años se doblará?
25) Los empleados de una fábrica trabajan en dos turnos, diurno y nocturno. Se desea calcular el jor-
nal diario de acuerdo con los siguientes puntos:

a) la tarifa de las horas diurnas es de 500 pesetas,


b) la tarifa de las horas nocturnas es de 800 pesetas,
c) caso de ser domingo, la tarifa se incrementará en 200 pesetas el turno diurno y 300 pesetas el
turno nocturno.
26) Averiguar si dados dos números leídos del teclado, uno es divisor de otro.
27) Se introduce la hora del día en horas, minutos y segundos. Se desea escribir la hora correspon-
diente al siguiente segundo.
28) Se desea conocer una serie de datos de una empresa con 50 empleados: a) ¿Cuántos empleados
ganan más de 300.000 pesetas al mes (salarios altos); b) entre 100.000 y 300.000 pesetas (salarios
medios), y c) menos de 100.000 pesetas (salarios bajos y empleados a tiempo parcial)?
29) Imprimir una tabla de multiplicar como

1 2 3 4 ... 15
** ** ** ** ** **
1* 1 2 3 4 ... 15
2* 2 4 6 8 ... 30
3* 3 6 9 12 ... 45
4* 4 8 12 16 ... 60

15* 15 30 45 60 ... 225


30) Dado un entero positivo n(> T), comprobar si es primo o compuesto.

FUNCIONES EN C++

Al incrementarse el tamaño y la complejidad de los programas, es muy recomendable dividirlos en par-


tes más pequeñas llamadas funciones. Cada función ejecuta una tarea específica. Cuando el programa
necesita ejecutar la tarea llama a la función, proporcionándole la información que pudiera necesitar para
realizar su procesamiento.

Creación y uso de las primeras funciones


Cada función que se crea dentro de los programas debe tener un nombre único y, como en el caso de
los nombres de variables, el nombre de la función debe corresponder a la operación que realiza, para
hacer el programa más comprensible. Por ejemplo, si una función realizará el cálculo de promedios, su
nombre podría ser calculo_de_promedios, o algo similar.
Una función de C++ es semejante en estructura al programa main que se ha estado utilizando:

tipo_ retorno nombre_función (lista_de_parámetros) Cabecera de la función


{
declaraciones_de_variables;
declaraciones;
}

Luego, en el programa principal, se llamará a la función escribiendo su nombre seguido por paréntesis:
nombre_función(); Si la función necesita parámetros , éstos estarán dentro del paréntesis, separados
por comas.

Programación C++ Ing. Helmut Heinz Dehner Página 31 de 70


Después que se termina de ejecutar la última declaración de la función, la ejecución del programa conti-
núa en la primera declaración que sigue a la llamada de función.
Veamos un programa ejemplo: 21FUNCION.CPP

#include "stdafx.h"
#include <iostream>

using namespace std;

void mayor_y_menor(int a, int b, int c)


{
int menor = a;
int mayor = a;

if (b > mayor) mayor = b;


if (b < menor) menor = b;
if (c > mayor) mayor = c;
if (c < menor) menor = c;

cout << "\n\nEl n"<<char(163)<<"mero MAYOR es: " << mayor;


cout << "\nEl n" << char(163) << "mero MENOR es: " << menor;
}

void main(void)
{
cout << "Ahora se llamar"<<char(160)<<" a la funci"<<char(162)<<"n \n";
mayor_y_menor(5, 2, 3);
mayor_y_menor(500, 0, -500);
mayor_y_menor(101, 101, 101);
cout << "\n\nYa se retorn" << char(162) << " al programa principal.\n";
system("pause");
}

Como vemos en la línea 3, la función “mayor_y_menor” es de tipo void (nulo), esto significa que la
función no devolverá un valor al programa. Pero, como lo indican las declaraciones dentro del parénte-
sis, la función espera que el programa sí le pase información, en este caso, esperará tres valores de tipo
int.
En las líneas 20 a 22 vemos los llamados a la función, cada uno especifica los valores que envía a la
misma, todos enteros. Si se tratara de pasar a la función un valor de tipo diferente al especificado, el
compilador generará un error.
En el programa anterior vemos que los tres parámetros son de tipo int, pero no es necesario que todos
los parámetros de una función sean del mismo tipo, pudiendo ser uno de tipo int, otro char, o float, etc.

Veamos cómo la función puede devolver un resultado al programa en el archivo llamado 22FUN-
CION2.CPP:

#include "stdafx.h"
#include <iostream>

using namespace std;

int sumar_valores(int a, int b)


{
int resultado = a + b;

return (resultado);
}

Programación C++ Ing. Helmut Heinz Dehner Página 32 de 70


float promedio(int a, int b)
{
return (sumar_valores(a,b) / 2.0);
}

void main(void)
{
int x, y;

cout << "El programa le pedir"<<char(160)<<" que ingrese dos n"<<char(163)<<"meros enteros. ";
cout << "\n\nIngrese el primer n" << char(163) << "mero: ";
cin >> x;
cout << "\nIngrese el segundo n" << char(163) << "mero: ";
cin >> y;
cout << "\n\nLa suma de los n" << char(163) << "meros es : " << sumar_valores(x, y);
cout << "\nEl promedio es: " << promedio(x, y)<<endl;
system("pause");
}
En este programa se han declarado dos funciones, la primera devolverá al programa un valor de tipo int
y la segunda uno del tipo float. (Líneas 3 y 11).
Estas funciones utilizan la declaración return (retornar, volver) para devolver o producir un valor (Lí-
neas 7 y 13). Cuando el programa encuentra esta declaración, devuelve o produce el valor especificado
y termina la ejecución de la función, volviendo el control al programa.
Los llamados a las funciones se producen en las líneas 27 y 28, utilizando como parámetros los valores
que el mismo usuario ingresa (“x” e “y”), es decir que los parámetros pueden ser tanto constantes como
variables.

En la declaración de la primer función se utilizaron más líneas que las necesarias, si deseamos simplifi-
car el código del programa, las mismas podrían escribirse de la siguiente manera:
int sumar_valores(int a, int b)
{
return (a+b);
}

De esta manera se ha declarado la segunda función, sin necesidad de declarar una variable extra.

LOS PROTOTIPOS
Examinemos el archivo 23PROTIPO1.CPP

#include "stdafx.h"
#include <iostream>

using namespace std;

void relleno(int alas, float pies, char ojos);

void main(void)
{
int brazo = 2;
float pie = 1000.0;
char ojo = 66;

relleno(3, 12.0, 'A');


relleno(brazo, pie, ojo);
system("pause");
}

void relleno(int alas, float pies, char ojos)


{
cout << "Hay " << alas << " alas." << "\n";

Programación C++ Ing. Helmut Heinz Dehner Página 33 de 70


cout << "Hay " << pies << " pies." << "\n";
cout << "Hay " << (int)ojos << " ojos. " <<ojos<< "\n\n";
}

Un ejemplo útil… imprimir tabla de valores ASCII:

#include "stdafx.h"
#include <iostream>
#include <iomanip>

using namespace std;

void relleno(char caracter);

void main(void)
{
int i;
for (i = 32; i <= 127; i++)
relleno(i);
cout << endl;
system("pause");
}

void relleno(char caracter)


{
cout <<setw(5)<< int(caracter) << " = " << caracter<<" ";
}

Un prototipo es un modelo limitado de una entidad más completa que vendrá luego. En este caso, la
función “relleno” es la entidad completa que vendrá luego y el prototipo se ilustra en la línea 3. El pro-
totipo proporciona información sobre el tipo devuelto o producido por la función, así como sobre sus pa-
rámetros. Se utiliza para verificar los llamados a la función, ya que controla el número y el tipo de los
parámetros, comprobando si son los apropiados. En nuestro ejemplo, cada llamado a la función llamada
“relleno()” debe tener exactamente tres parámetros o el compilador dará un mensaje de error.
Además del número correcto de parámetros, los tipos deben ser compatibles o el compilador emitirá un
mensaje de error. El aviso sobre el que trabaja el compilador se ve en las líneas 11 y 12, la comproba-
ción de tipo puede hacerse en base al prototipo de la línea 3 aunque la función misma no está definida
aún.

Si el prototipo no es dado, el número de parámetros no se verificará, ni los tipos de los parámetros. Aún
cuando se tiene el número equivocado de parámetros, se conseguirá una compilación y vinculación apa -
rentemente buenas, pero el programa puede hacer algunas cosas extrañas cuando se ejecute. jaja

Para escribir el prototipo, simplemente se copia la cabecera de la función al comenzar el programa y se


añade un punto y coma al final como una señal al compilador de que ésta no es una función sino un pro-
totipo. Los nombres de las variables dadas en el prototipo son optativos y actúan meramente como co-
mentarios al lector del programa, ya que ellos son completamente ignorados por el recopilador. Si se
reemplaza la variable “alas” en la línea 3 con cualquier otro nombre no habría ninguna diferencia en la
compilación.

Aunque deseamos usar el tipo char para “ojos” en la función, queremos usarlo más bien como un núme-
ro y no como un caracter.

El entero en la línea 19 requiere que se exija la impresión del valor numérico como un caracter ASCII. El
próximo ejemplo de programa es similar pero sin el int.

LOS TIPOS COMPATIBLES


Un tipo compatible es cualquier tipo simple que puede convertirse a otro en una manera significativa.
Por ejemplo, si se usó un entero como el parámetro real y la función esperaba un tipo float como pará-

Programación C++ Ing. Helmut Heinz Dehner Página 34 de 70


metro formal, el sistema hará la conversión automáticamente. También se puede cambiar un float a
char, o un char a int. Aunque hay reglas definitivas de conversión que se deben seguir.
Si una función espera un parámetro entero, y se le proporciona uno real, la conversión no se realiza por-
que los valores son completamente diferentes.
La compatibilidad de tipos discutida anteriormente en este manual se aplica igualmente a la compatibili-
dad de tipos cuando se hacen llamados a una función. Además, el tipo especificado como el tipo de re-
greso debe ser compatible con el regreso esperado en la declaración de llamada, o el recopilador emitirá
una advertencia.

¿COMO TRABAJA UN PROTOTIPO?


Esta es una oportunidad para tratar prototipos y ver cómo trabajan y qué tipos de mensajes de error se
producen cuando se hacen cosas equivocadas. Cambiemos los parámetros reales en la línea 11 para leer
(12.2, 13, 12345) y ver qué dice el compilador sobre este cambio. Probablemente no dirá nada porque
son todos compatibles.
Si se cambian los valores por (12.0, 13), el compilador emitirá una advertencia o error porque no hay
argumentos suficientes.

También debería producirse un mensaje de error si se cambia uno de los parámetros en la línea 12 es -
cribiendo un signo amperson frente a uno de los nombres de las variables. Finalmente, cambiando la
primera palabra en la línea 3 entre void e int se puede ver otro mensaje de error. En la línea 15 se re -
querirá que la función concuerde con un prototipo, pero el compilador no lo encontrará.

UN POCO MAS SOBRE PROTOTIPOS


Veamos el ejemplo de programa llamado 24PROTIPO2.CPP

#include "stdafx.h"
#include <iostream>

using namespace std;

void relleno(int, float, char);

void main(void)
{
int brazo = 2;
float pie = 1000.0;
char ojo = 65;

relleno(3, 12.0, 67);


relleno(brazo, pie, ojo);
system("pause");
}

void relleno(int alas, // Número de alas


float pies, // Número de pies
char ojos) // Número de ojos
{
cout << "Hay " << alas << " alas." << "\n";
cout << "Hay " << pies << " pies." << "\n";
cout << "Hay " << int(ojos) << " ojos." << "\n\n";
}

Este programa es idéntico al primero, con excepción de unos pequeños cambios.


Los nombres de las variables se han omitido en el prototipo en la línea 3 solamente como una ilustración
de que ellos se interpretan como comentarios por el compilador de C++.
La cabecera de la función tiene un formato diferente para permitir un comentario al final de los paráme-
tros reales. Esto debería hacer la cabecera de función un poco más explicativa. Sin embargo, debemos
recordar que los comentarios no deberían usarse, reemplazándolos con una selección cuidadosa de los
nombres de variables.

Programación C++ Ing. Helmut Heinz Dehner Página 35 de 70


Algo útil:

#include "stdafx.h"
#include <iostream>
#include <iomanip>

using namespace std;

void relleno(int);

void main(void)
{
int j,i;
for (j = 32,i=1; j < 255; j++,i++)
{
relleno(j);
if (!(i % 9)) i = 0, cout << endl;
}

cout << endl;


system("pause");
}

void relleno(int n)
{
cout << setw(4)<< n << " = " << char(n)<<" | ";
}

¿QUE COSTO TIENE UN PROTOTIPO?


El prototipo no cuesta absolutamente nada en lo que concierne a la velocidad o tiempo de ejecución, ya
que demora una cantidad insignificante de tiempo en la comprobación que el compilador debe hacer.
El único precio que se debe pagar para usar un prototipo es el tamaño extra de los archivos de fuente
de los mismos, y el tiempo extra que el compilador tarda en leer los prototipos durante el proceso de
compilación, pero ambos costos son insignificantes.

PASE POR REFERENCIA


Examinemos el archivo 25PASREF.CPP para un ejemplo de un pase por referencia:

#include "stdafx.h"
#include <iostream>

using namespace std;

void violin(int, int &);

void main(void)
{
int cont = 7, ind = 12;

cout << "Los valores originales son: ";


printf("%3i %3i %x %x\n", cont, ind, &cont, &ind);

violin(cont, ind);

cout << "Los valores cuando retorno al main son ";


printf("%3d %3d\n", cont, ind);
system("pause");
}

void violin(int in1, int &in2)


{
Programación C++ Ing. Helmut Heinz Dehner Página 36 de 70
in1 = in1 + 100;
in2 = in2 + 100;
cout << "Los valores dentro de la funcion son ";
printf("%3i %3i %x %x\n", in1, in2, &in1, &in2);
}

Un ejemplo práctico:

#include "stdafx.h"
#include <iostream>

using namespace std;

void car_pol(float &x, float &y);


void pol_car(float &r, float &a);
void menu(void);

void main(void)
{
menu();
//system("pause");
}

void menu(void)
{
int opc;
float p, q;
for (;;)
{
cout << "\n\n1 - Cartesiana a Polar\n"
<< "2 - Polar a Cartesiana\n\n"
<< "0 - Salir\n\n"
<< "Ingrese opci" << char(162) << "n: ";
cin >> opc;
switch (opc)
{
case 0: break;
case 1: cout << "Ingrese x: ";
cin >> p;
cout << "Ingrese y: ";
cin >> q;
car_pol(p, q);
cout << "Las coordenadas polares R = " << p << "\tA = " << q << endl;
break;
case 2: cout << "Ingrese R: ";
cin >> p;
cout << "Ingrese A: ";
cin >> q;
pol_car(p, q);
cout << "Las coordenadas cartesianas X = " << p << "\tY = " << q << endl;
break;
default:
cout << "\n\nNo es correcta\n\n";
break;
}
if (!opc) break;
}
}
void car_pol(float &x, float &y)
{
float aux = sqrt(pow(x, 2) + pow(y, 2));
y = atan(x / y);

Programación C++ Ing. Helmut Heinz Dehner Página 37 de 70


x = aux;
}
void pol_car(float &r, float &a)
{
float aux = r*sin(a);
a = r*cos(a);
r = aux;
}

Otra variante:

#include "stdafx.h"
#include <iostream>
#include <iomanip>

using namespace std;

void car_pol(float &, float &);


void pol_car(float &, float &);

void main(void)
{
int opc;
float p, q;
do
{
system("cls");
cout << "1 - Cartesiana a Polar\n"
<< "2 - Polar a Cartesiana\n\n"
<< "0 - Finalizar\n\n"
<< "elija alternativa: ";
cin >> opc;
switch (opc)
{
case 0: break;
case 1: cout << "Ingrese el valor de X: ";
cin >> p;
cout << "Ingrese el valor de Y: ";
cin >> q;
car_pol(p, q); //en p retorna el valor del ángulo y en q retorna el valor de r1
cout << "\n\nLas coordenadas polares correspondientes son " << char(237) << " = "
<< setprecision(15) << p << "\t r = " << setprecision(15) << q << endl;
break;
case 2: cout << "Ingrese el valor del " << char(160) << "ngulo " << char(237) << ": ";
cin >> q;
cout << "Ingrese el valor del vector (R1): ";
cin >> p;
pol_car(p, q);// en p retorna el valor de X y en q retorna el valor de Y
cout << "\n\nLas coordenadas correspondientes son X = "
<< setprecision(15) << p << "\t Y = " << setprecision(15) << q << endl;
break;
default:
cout << "\n\nAlternativa NO disponible\n";
break;
}
if (opc) system("pause");
} while (opc);

}
void car_pol(float &ro, float &r1) //ro --> x; r1 --> y
{
float a = sqrt(pow(ro, 2) + pow(r1, 2));//este sería r1
ro = atan(ro / r1);

Programación C++ Ing. Helmut Heinz Dehner Página 38 de 70


r1 = a;
}
void pol_car(float &x, float &y) //x --> r1; y --> ro
{
float a = x*sin(y); //este sería y
x = x*cos(y);
y = a;
}

Por predefinición, cuando los programas introducen un parámetro a una función, C++ hace una copia
del valor de este parámetro y lo pone dentro de un lugar de memoria temporal llamado pila. Entonces la
función utiliza una copia del valor. Cuando se termina de ejecutar la función, C++ descarta el contenido
de la pila y cualquier cambio que la función haya hecho a la copia.
Para cambiar el valor de un parámetro, la función debe saber la dirección de memoria del parámetro. El
operador de dirección & se utiliza en los programas para indicarle a la función cuál es la dirección del
parámetro para que pueda realizar los cambios deseados.

Este procedimiento es un pase por referencia, permite el pasaje de una variable a una función y retor-
nar los cambios hechos en la función al programa principal.
Observemos el prototipo en la línea 4, donde la segunda variable tiene un signo & delante del nombre
de la variable. Este signo indica al compilador que esa variable actuará como un puntero (indicador) a la
variable real del programa principal que se usará en la función.
En la función misma, en las líneas 21 a 24, la variable “in2” se usa como cualquier otra, pero pasándola
desde el programa principal a la función, no usa una copia de ella. En efecto, el nombre “in2” es un si-
nónimo para la variable “ind” en el programa principal, hace referencia a ella. En cambio, la otra varia -
ble llamada “in1” se trata como cualquier otra variable normal en C.

Cuando el programa se compila y ejecuta, se observa que la variable “in1” cambia en la función pero
vuelve a su valor original cuando se retorna al programa principal (sigue valiendo 7). Sin embargo, la
segunda variable “in2”, cambia en la función y el nuevo valor se refleja en la variable del programa prin-
cipal (su valor cambia de 12 a 112), lo que se puede ver cuando los valores se imprimen por pantalla
(línea 16).

Si se prefiere omitir los nombres de variables en los prototipos, se escribiría el prototipo como se indica
a continuación: void violín (int, int&);

PARÁMETROS POR DEFECTO


Veamos el programa 26PARAMET.CPP como un ejemplo del uso de parámetros por defecto:

#include "stdafx.h"
#include <iostream>
#include <stdio.h>

using namespace std;

int volume(int largo, int ancho = 2, int alto = 3);

void main(void)
{
int x = 10, y = 12, z = 15;

cout << " Algunos datos de la caja son " << volumen(x, y, z) << "\n";
cout << " Algunos datos de la caja son " << volumen(x, y) << "\n";
cout << " Algunos datos de la caja son " << volumen(x) << "\n";

cout << " Algunos datos de la caja son ";


cout << volumen(x, 7) << "\n";
cout << " Algunos datos de la caja son ";
cout << volumen(5, 5, 5) << "\n";

}
Programación C++ Ing. Helmut Heinz Dehner Página 39 de 70
int volumen(int largo, int ancho, int alto)
{
printf("%4d %4d %4d ", largo, ancho, alto);
return largo * ancho * alto;
}

Este programa realmente se ve extraño ya que contiene algunos valores por defecto para los paráme-
tros en el prototipo, pero faltan valores muy útiles como veremos luego.

Este prototipo dice que el primer parámetro llamado “largo” debe darse para cada llamado de esta fun-
ción porque no fue proporcionado ningún valor por defecto.
El segundo parámetro llamado “ancho”, sin embargo, no requiere que se especifique para cada llamado,
ya que si no es especificado, se usará el valor 2 para la variable “ancho” dentro de la función. Asimismo,
el tercer parámetro es optativo, y si no es especificado, el valor 3 se usará para la “altura” dentro de la
función.

En la línea 10 de este programa se especifican los tres parámetros, así que no hay nada de particular en
este llamado a la función.
Sin embargo, en la línea 11, se especifican solamente dos valores, por lo tanto se usará el valor por de-
fecto para el tercer parámetro y el sistema trabajará como si se hubiera llamado a la función con volu-
men(x, y, 3), ya que el valor por defecto para el tercer parámetro es 3. En la línea 12, se especifica úni-
camente un parámetro, que se usará para el primer parámetro formal, y faltarán los otros dos. El siste-
ma considerará el llamado como volumen (x, 2, 3).

Notaremos que la salida por pantalla de estas tres de líneas se revierte. Esto se explicará luego.

Hay unas reglas que deben ser obvias pero serán revisadas de cualquier manera. Una vez que a un pa-
rámetro se le da un valor por defecto o de autoselección en la lista de parámetros formales, todos los
restantes deben tener también valores de autoselección. No es posible dejar hoyos en medio de la lista,
únicamente los valores anteriores pueden faltar. Por supuesto, los valores especificados deben ser de los
tipos correctos o se emitirá un error de compilación. Los valores por defecto pueden darse en el prototi-
po o en la cabecera de función, pero no en ambos.
Si ellos se dan en ambos lugares, el compilador debe usar solamente el valor por defecto, pero debe ve -
rificar cuidadosamente que ambos valores sean idénticos. Esto podría complicar un programa ya muy
complicado, por lo que se recomienda que los valores por defecto se declaren en el prototipo y no en la
función.

¿POR QUÉ SE INVIERTE LA SALIDA?


Cuando el compilador encuentra una declaración cout, la línea completa de código se repasa inicialmen-
te desde la derecha. Pero cuando se evalúa cualquier función, los datos se analizan de izquierda a dere -
cha.
Por lo tanto en la línea 10, volumen () se evalúa y se muestra primero. Luego las declaraciones del cout
se muestran de izquierda a derecha , apareciendo a continuación "Algunos datos de la caja son". Final-
mente, el resultado que es devuelto por volumen() aparece al final de la impresión.
Esta impresión no es la que intuitivamente se esperaría, pero así funciona C++.
Las líneas 14 a 17 son parecidas a cualquiera de las líneas de 10 a 12, pero están separadas en dos de -
claraciones que hacen que la impresión aparezca en el orden esperado.

NUMERO VARIABLE DE ARGUMENTOS


El programa 27VARARGS.CPP es una ilustración del uso de un número variable de argumentos en un
llamado a función. El compilador para ayuda comprobando cuidadosamente cuántos parámetros se usan
en los llamados de función y comprobando también los tipos de estos parámetros.

#include <iostream.h>
#include <stdarg.h>

// Declaración de una función con un parámetro requerido


(5)
Programación C++ Ing. Helmut Heinz Dehner Página 40 de 70
void mostrar_var(int numero, ...);

void main(void)
{
int ind = 5;
int uno = 1, dos = 2;

mostrar_var(uno, ind);
mostrar_var(3, ind, ind + dos, ind + uno);
mostrar_var(dos, 7, 3);
}
void mostrar_var(int numero, ...)
{
va_list param_pt;

va_start(param_pt,numero); // Llamada a la macro

cout << "Los parámetros son ";


for (int ind = 0 ; ind < numero ; ind++)
cout << va_arg(param_pt,int) << " "; // Extracción de un parámetro
cout << "\n";
va_end(param_pt); // Se cierra la macro
}

En ciertas ocasiones, podemos desear escribir una función que usa un número variable de parámetros.
La función printf () es un ejemplo de esto. EL ANSI - C tiene una serie de tres macros disponibles en el
archivo "stdarg.h" para permitir el uso de un número variable de argumentos. Estas macros están dispo-
nibles también para el uso con C++, pero necesitamos eliminar de alguna manera la comprobación de
tipos que hace C++ con todas las funciones. Los tres puntos ilustrados en la línea 5 harán esto para no-
sotros. Este prototipo dice que se requiere un único argumento de tipo int como el primer parámetro,
entonces el compilador no hará ninguna comprobación adicional de tipos.
Es evidente que el programa principal consiste en tres de llamados a la función, cada uno con un núme -
ro diferente de parámetros, y el sistema no hace diferencias en los tipos utilizados. Mientras el primer
parámetro sea de tipo int, el sistema compilará y ejecutará el programa sin problemas. Por supuesto el
compilador no comprueba los tipos que estén más allá del primer parámetro. El programador debe ase-
gurarse de que usa los tipos de parámetros adecuados.
En este programa, simplemente se muestran los números por pantalla para ilustrar que son manejados
adecuadamente.
Por supuesto, debemos tener en cuenta que el usar un número variable de argumentos en
un llamado de función puede conducir a obscurecer el código y debe usarse muy poco en un programa,
pero esta posibilidad existe y puede usarse si es necesario.

SOBRECARGA DE FUNCIONES
En C++, dos o más funciones pueden compartir el mismo nombre, siempre y cuando sus declaraciones
de parámetros sean diferentes.
El proceso por el cual varias funciones pueden compartir el mismo nombre se denomina sobrecarga
(overload) de funciones. De estas funciones se dice que están sobrecargadas.
El programa 28SOB_FUNC.CPP es un ejemplo de funciones sobrecargadas, que es una de las claves de
la programación orientada a objetos.

#include "stdafx.h"
#include <iostream>

using namespace std;

int relleno(const int); // Cuadrado de un número


int relleno(float); // Triple de un float y retorna int
float relleno(const float, float); // Promedio de dos float

Programación C++ Ing. Helmut Heinz Dehner Página 41 de 70


void main(void)
{
int ind = 8;
float longitud = 14.33;
float altura = 34.33;

cout << "El cuadrado de "<< ind<<" es " << relleno(ind) << "\n";
cout << "El cuadrado de "<< 2*ind<<" es " << relleno(2 * ind) << "\n";
cout << "El triple de la longitud es " << relleno(longitud) << "\n";
cout << "El triple de la altura es " << relleno(altura) << "\n";
cout << "El promedio es " << relleno(longitud, altura) << "\n";
system("pause");
}
int relleno(const int valor) // Cuadrado de un número
{
return valor * valor;
}

int relleno(float valor) // Triple de un float y retorna int


{
return (int)(3.0 * valor);
}

// Promedio de dos float


float relleno(const float in1, float in2)
{
return (in1 + in2) / 2.0;
}

En este programa ejemplo hay tres funciones, además de la función principal, y las tres tienen el mismo
nombre. La primer pregunta es probablemente "¿Qué función se ejecutará cuando se llame a relleno
() ?" .
La respuesta es que se ejecutará la función que tenga el número correcto de parámetros formales y que
sean del tipo especificado.
Si se llama a la función relleno () con una variable o valor entero como su parámetro real, la función co -
menzará en la línea 22. Si el único parámetro real es de tipo float, la función que comenzará en la línea
27, y si se especifican dos float, la función comenzará en la línea 33.
Es importante destacar que el tipo de regreso no es usado para determinar qué función se llamará. So -
lamente los parámetros formales se usan para determinarlo.

La palabra clave overload usada en la línea 3 sólo es requerida en la versión 1.2 de C++. La versión 2.0
y posteriores de C++ no la requieren, pero permiten usarla opcionalmente a fin de que el código sea
compatible con otros compiladores.

La selección de que función se llamará realmente no resta tiempo de ejecución ni compilación. Si se pu -


sieran nombres diferentes a cada una de las funciones sobrecargadas, no habría ninguna diferencia en la
velocidad o tamaño de ejecución del programa resultante.

El uso del operador const en algunas de las cabeceras y prototipos de función impide que el programa -
dor cambie accidentalmente el parámetro formal dentro de la función. En funciones tan cortas como és -
tas no hay problema. En una función más importante que se modifica ocasionalmente, se podría olvidar
fácilmente la intención original del uso de un valor e intentar cambiarlo durante la depuración del pro -
grama.

RECURSIVIDAD
En C, las funciones pueden llamarse a sí mismas. Si una expresión en el cuerpo de una función llama a
la propia función, se dice que ésta es recursiva. La recursividad es el proceso de definir algo en términos
de sí mismo y a veces se llama definición circular.
Los ejemplos de recursividad abundan.

Programación C++ Ing. Helmut Heinz Dehner Página 42 de 70


Para que en lenguaje de computadora sea recursivo, una función debe ser capaz de llamarse a sí
misma.

Se dice que una función es recursiva cuando se define en función de si misma.

No todas la funciones pueden llamarse a sí mismas, sino que deben estar diseñadas especialmente para
que sean recursivas, de otro modo podrían conducir a bucles infinitos, o a que el programa termine
inadecuadamente.

Tampoco todos los lenguajes de programación permiten usar recursividad.

C++ permite la recursividad. Cada vez que se llama a una función, se crea un juego de variables
locales, de este modo, si la función hace una llamada a si misma, se guardan sus variables y
parámetros, usando la pila, y la nueva instancia de la función trabajará con su propia copia de las
variables locales. Cuando esta segunda instancia de la función retorna, recupera las variables y los
parámetros de la pila y continua la ejecución en el punto en que había sido llamada.

Por ejemplo:

Podríamos crear una función recursiva para calcular el factorial de un número entero.

El factorial se simboliza como n!, se lee como "n factorial", y la definición es:

n! = n * (n-1) * (n-2) *... * 1

Hay algunas limitaciones:

 No es posible calcular el factorial de números negativos, no está definido.


 El factorial de cero es 1.

De modo que una función bien hecha para cálculo de factoriales debería incluir un control para esos
casos:

Ejemplo 1

#include "stdafx.h"
#include <iostream>
#include <iomanip>

using namespace std;

double factorial(unsigned long int n);

void main(void)
{
unsigned long int i;
cout << "Ingrese el n"<<char(163)<<"mero a calcular el factorial: ";
cin >> i;
cout << "\nEl factorial de " << i << " = " << setiosflags(ios::scientific)<<setprecision(12)
<< factorial(i)<<endl;
system("pause");
}

/* Función recursiva para cálculo de factoriales */


double factorial(unsigned long int n)
{
if (n < 0) return 0;
else if (n > 1) return n*factorial(n - 1); /* Recursividad */
Programación C++ Ing. Helmut Heinz Dehner Página 43 de 70
return 1; /* Condición de terminación, n == 1 */
}

Veamos paso a paso, lo que pasa cuando se ejecuta esta función, por ejemplo: factorial(4):

1ª Instancia
n=4
n>1
salida  4 * factorial(3) (Guarda el valor de n = 4)

2a Instancia
n>1
salida  3*factorial(2) (Guarda el valor de n = 3)

3a Instancia
n>1
salida  2*factorial(1) (Guarda el valor de n = 2)

4a Instancia
n == 1  retorna 1

3a Instancia
(recupera n=2 de la pila) retorna 1*2=2

2a instancia
(recupera n=3 de la pila) retorna 2*3=6

1a instancia
(recupera n=4 de la pila) retorna 6*4=24
Valor de retorno  24

Aunque la función factorial es un buen ejemplo para demostrar cómo funciona una función recursiva, la
recursividad no es un buen modo de resolver esta función, que sería más sencilla y rápida con un simple
bucle for.

La recursividad consume muchos recursos de memoria y tiempo de ejecución, y se debe aplicar a


funciones que realmente le saquen partido.

La principal ventaja de las funciones recursivas es que se pueden usar para crear versiones de algoritmo
más claras y más sencillas. Por ejemplo, la ordenación rápida (quicksort) es difícil implementar en forma
iterativa. Además, algunos problemas, especialmente los problemas relacionados con la inteligencia
artificial parece que tienden ellos mismos hacia soluciones recursivas. Por último, algunas personas
parecen pensar más fácilmente de forma recursiva que de forma iterativa.
Cuando se escriben funciones recursivas, se debe tener una sentencia if en algún sitio que fuerce a la
función a volver sin que se ejecute la llamada recursiva. Si no se hace así, la función nunca devolverá el
control una vez que se le ha llamado. Es un error muy común el escribir funciones recursivas sin un if.

Ejemplo 2
#include "stdafx.h"
#include <iostream>

using namespace std;

int MCD1(int a, int b);


int MCD2(int a, int b);

Programación C++ Ing. Helmut Heinz Dehner Página 44 de 70


void main(void)
{
int x, y;
do
{
cout << endl << endl << "Ingrese un valor (0 = FIN): ";
cin >> x;
if (x)
{
cout << "Ingrese otro valor: ";
cin >> y;
cout << endl << "El MCD1 de " << x << " y " << y << " = " << MCD1(x, y)
<< endl << "El MCD2 de " << x << " y " << y << " = " << MCD2(x, y)<<endl;
system("pause");
}
} while (x);
}

int MCD1(int a, int b)


{
if (b) MCD1(b, a%b);
else
return(a);
}

int MCD2(int a, int b)


{
if (a - b) MCD2(b, (a>b ? a - b : b - a));
else
return(b);
}

Ejemplo 3
/*visualizar las permutaciones de n elementos.*/
#include <iostream>
//using namespace std;

/* Prototipo de función */
void Permutaciones(char *, int l=0);

void main(void)
{
char palabra[] = "ABC";

Permutaciones(palabra);

cin.get();
}

void Permutaciones(char * cad, int l) {


char c; /* variable auxiliar para intercambio */
int i, j; /* variables para bucles */
int n = strlen(cad);

for(i = 0; i < n-l; i++) {


if(n-l > 2) Permutaciones(cad, l+1);
else cout << cad << ", ";
/* Intercambio de posiciones */
c = cad[l];

Programación C++ Ing. Helmut Heinz Dehner Página 45 de 70


cad[l] = cad[l+i+1];
cad[l+i+1] = c;
if(l+i == n-1) {
for(j = l; j < n; j++) cad[j] = cad[j+1];
cad[n] = 0;
}
}
}

EJERCICIOS DE PROGRAMACIÓN
1. Cambiar el tipo de “alas” a float en el prototipo de PROTIPO1.CPP para que disienta con la defini-
ción de función para ver si ocurre un error de compilación.

2. Cambiar la definición de función en PROTIPO1.CPP para acordar con el prototipo cambiado. Compi-
lar y ejecutar el programa sin cambiar los llamados en líneas 11 y 12. Explicar los resultados.

3. En PARAMET.CPP, quitar el valor por defecto para “alto” en el prototipo para ver qué tipo de error
de compilación se produce.

4. En SOB_FUNC.CPP, cambiar los nombres de las tres de funciones para que cada una tenga un nom-
bre único. Comparar el tamaño del archivo ejecutable resultante con el que dio el programa original.

TRABAJO PRÁCTICO DE FUNCIONES


1. Diseñar una función que calcule la media de tres números leídos del teclado y poner un ejemplo
de su aplicación.
2. Diseñar la función FACTORIAL que calcule el factorial de un número entero en el rango 100 a
300.
3. Diseñar un algoritmo para calcular el máximo común divisor de cuatro números basado en un
subalgoritmo función mcd (máximo común divisor de dos números).
4. Diseñar un procedimiento que realice el intercambio de valores de dos variables A y B.
5. Diseñar una función que encuentre el mayor de dos números enteros.
6. Diseñar una función que calcule xn, para x, variable real y n variable entera.
7. Diseñar un procedimiento que acepte un número de mes, un número de día y un número de año
y los visualice en el formato

dd/mm/aa

Por ejemplo, los valores 19,09,1987 se visualizarán como

19/9/97

y para los valores 3, 9 y 1905

3/9/05

8. Realizar dos funciones que realicen la conversión de coordenadas polares (r, ) a coordenadas
cartesianas (x, y) math.h

X = r * cos () (función X)

Y = r * sin () (función Y)

9. Escribir una función Salario que calcule los salarios de un trabajador para un número dado de ho-
ras trabajadas y un salario hora. Las horas que superen las 40 horas semanales se pagarán como
extras con un salario hora 1,5 veces el salario ordinario.
10. Escribir una función booleana Dígito que determine si un carácter es uno de los dígitos 0 al 9.
11. Escribir una función booleana Vocal que determine si un carácter es una vocal.
Programación C++ Ing. Helmut Heinz Dehner Página 46 de 70
12. Escribir una función que tenga un argumento de tipo entero y que devuelva la letra P si el núme-
ro es positivo, y la letra N si es cero o negativo.
13. Escribir una función lógica de dos argumentos enteros, que devuelva true si uno divide al otro y
false en caso contrario.
14. Escribir una función que convierta una temperatura dada en grados Celsius a grados Fahrenheit.
La fórmula de conversión es:

15. Escribir una función Redondeo que acepte un valor real Cantidad y un valor entero Decimales y
devuelva el valor de Cantidad redondeado al número especificado de Decimales. Por ejemplo, Re-
dondeo (20.563,2) devuelve el valor 20.56, y Redondeo (20.563,1) devuelve 20.6.
16. Escribir un programa que permita al usuario elegir el cálculo del área de cualquiera de las figuras
geométricas: círculo, cuadrado, rectángulo o triángulo, mediante funciones sobrecargadas.

ARREGLOS Y CADENAS

Como ya sabemos, los programas almacenan información en las variables. Hasta ahora, las variables
utilizadas sólo guardaban un valor. Sin embargo, en muchos casos los programas necesitarán guardar
muchos valores al mismo tiempo, tales como 50 calificaciones, 100 nombres de archivo o 1000 títulos
de libros. Cuando los programas necesitan almacenar muchos valores definen un arreglo. Es decir que
un arreglo es una variable capaz de guardar uno o más valores.

Cómo declarar una variable arreglo


Al igual que las variables que se han utilizado hasta este momento, un arreglo debe tener un tipo (como
int, char o float) y un nombre. Además, habrá que especificar el número de valores que almacenará.
Todos los valores que se almacenen en un arreglo deben ser del mismo tipo.
La siguiente declaración crea un arreglo llamado “calificaciones” que puede contener 100 calificaciones
de exámenes expresadas como números enteros: int calificaciones [100];
Cuando el compilador encuentra la declaración de variable, asignará la suficiente memoria para que con-
tenga 100 valores del tipo int. Cada valor es un elemento del arreglo.

Cómo utilizar los elementos de un arreglo


Veamos el programa 30ARREGLO.CPP:

#include "stdafx.h"
#include <iostream>

using namespace std;

void main(void)
{
int valores[5]; // Declaración del arreglo

valores[0] = 100;
valores[1] = 200;
valores[2] = 300;
valores[3] = 400;
valores[4] = 500;

cout << "El arreglo contiene los siguientes valores: ";


cout << valores[0] << ' ' << valores[1] << ' ' <<
valores[2] << ' ' << valores[3] << ' ' << valores[4]<<endl;
system("pause");
}

En primer lugar se define un arreglo de tipo int llamado “valores”. Los corchetes "[]" definen una matriz
con subíndice, y en el caso del ejemplo, el 5 entre corchetes define 5 campos de datos, tipo int, todo
Programación C++ Ing. Helmut Heinz Dehner Página 47 de 70
ello definido como variable “valores”. En C, los subíndices empiezan desde 0, y se incrementan de
uno en 1 hasta el máximo valor, en este caso, 4. Tenemos, por tanto, 5 variables tipo int, denominadas:
“valores[0]”, “valores[1]”, hasta “valores[4]”.
Recordemos siempre que al partir de 0, los subíndices tienen como máximo valor una posición menos
que en su definición.

Cuando los programas utilizan arreglos, el procedimiento más común es utilizar una variable índice para
indicar a los elementos del arreglo. En el siguiente programa, 31ARREGLO2.CPP, se utiliza el índice
dentro de un bucle for, que inicia al índice “i” en 0. El bucle termina cuando “i” es mayor que 4 (el últi -
mo elemento del arreglo):

#include "stdafx.h"
#include <iostream>

using namespace std;

void main(void)
{
int valores[5]; // Declaración del arreglo
int i;

valores[0] = 100;
valores[1] = 200;
valores[2] = 300;
valores[3] = 400;
valores[4] = 500;

cout << "El arreglo contiene los siguientes valores: ";

for (i = 0; i<5; i++)


cout << valores[i] << ' ';
cout << endl;
system("pause");
}
Cada vez que el bucle for incrementa a la variable “i”, el programa imprime el siguiente elemento del
arreglo.

Inicializar un arreglo en la declaración


Como ya se ha visto, C++ permite inicializar las variables en el momento de su declaración. Lo mismo
puede hacerse con un arreglo, especificando los valores iniciales colocándolos entre llaves. Por ej: int
valores[5] = {100, 200, 300, 400, 500 };
Si no se especifica el tamaño de un arreglo que se inicializa en una declaración, C++ asignará la sufi -
ciente memoria para que contenga el número de valores especificados, por ejemplo, la siguiente decla-
ración crea un arreglo capaz de guardar cuatro valores enteros:
int numeros[ ] = {1, 2, 3, 4 };

Las funciones trabajan con arreglos


Una función puede inicializar al arreglo, operar con sus valores o mostrarlos por pantalla.
Para que la función trabaje con el arreglo se debe especificar su tipo, no necesariamente su tamaño.
Normalmente se pasará un parámetro que especifique el número de elementos que hay en el arreglo.
El programa 32ARR_FUN.CPP pasa los arreglos a la función “mostrar_arreglo”, que presenta los valo-
res por pantalla:

#include "stdafx.h"
#include <iostream>

using namespace std;

void mostrar_arreglo(int arreglo[], int nro_elementos)

Programación C++ Ing. Helmut Heinz Dehner Página 48 de 70


{
int i;
for (i = 0; i < nro_elementos; i++)
cout << arreglo[i] << ' ';
}

void main(void)
{

int nros_chicos[] = { 1, 2, 3, 4, 5 };
int nros_grandes[] = { 1000, 2000, 3000 };
mostrar_arreglo(nros_chicos, 5);
mostrar_arreglo(nros_grandes, 3);
cout << endl;
system("pause");
}
El programa anterior simplemente pasa el arreglo a la función por medio del nombre. El siguiente pro-
grama, 33TRAERARR.CPP, utiliza la función “traer_valores” para asignar tres valores al arreglo “nume-
ros”:

#include "stdafx.h"
#include <iostream>

using namespace std;

void traer_valores(int arreglo[], int nro_elementos)


{
int i;
for (i = 0; i < nro_elementos; i++)
{
cout << "Introducir valor " << i << " : ";
cin >> arreglo[i];
}
}

void main(void)
{

int numeros[3];
int i;

traer_valores(numeros, 3);
cout << "Los valores del arreglo son : ";

for (i = 0; i < 3; i++)


cout << numeros[i] << ' ';
cout << endl;
system("pause");

ARREGLOS MULTIDIMENSIONALES

Veamos el programa 34MULTIARR.CPP como un ejemplo del trabajo con arreglos multidimensionales
(matrices):

#include "stdafx.h"
#include <iostream>

using namespace std;

void main(void)

Programación C++ Ing. Helmut Heinz Dehner Página 49 de 70


{
int i, j;
int arr1[8][8];
int arr2[25][12];

for (i = 0; i < 8; i++)


for (j = 0; j < 8; j++)
arr1[i][j] = i * j; // Esto es una tabla de multiplicar

for (i = 0; i < 25; i++)


for (j = 0; j < 12; j++)
arr2[i][j] = i + j; // Esto es una tabla de sumar

arr1[2][6] = arr2[24][10] * 22;


arr1[2][2] = 5;
arr1[arr1[2][2]][arr1[2][2]] = 177; // esto es arr1[5][5] = 177;

for (i = 0; i < 8; i++) {


for (j = 0; j < 8; j++)
printf("%5d ", arr1[i][j]);
printf("\n"); // nueva línea para cada suma de i
}
system("pause");
}

La variable “arr1” es un arreglo de 8x8, que contiene 8 veces 8, o 64 elementos en total. El primer ele-
mento es “arr1[0][0]”, y el último “arr1[7][7]”. Otro arreglo, “arr2” es también de este tipo, pero no es
cuadrado, para que se vea que un arreglo multidimensionado no debe ser necesariamente cuadrado.
Ambos arreglos están rellenos con datos, que representan una tabla de multiplicar, y, una tabla de su -
mar, el otro.
Para ilustrar que elementos individuales pueden ser modificados, a uno de los elementos de “arr1” se le
asigna uno de los elementos de “arr2”, tras ser multiplicado por 22 (línea 18). En la siguiente línea, se
le asigna a “arr1[2][2]” el valor arbitrario 5, y se lo usa para el subíndice del siguiente mandato de asig -
nación. El tercer mandato de asignación es en realidad “arr1[5][5] = 177”, porque cada uno de los su -
bíndices contiene el valor 5. Esto sirve a título de ilustración de que cualquier expresión valida puede
usarse como subíndice, sólo debe cumplir 2 reglas, una es que debe ser un entero (aunque un "char"
numérico también valdría), y la otra es que debe estar en el límite del subíndice del arreglo, y no sobre-
pasarlo.
El contenido total de la matriz “arr1” se imprime por pantalla, en forma de cuadrado, con lo cual pode -
mos comprobar por los valores si el programa hace lo que imaginábamos.

¿Es posible recorrer una matriz con un solo bucle y el tamaño de la misma?
#include "stdafx.h"
#include <iostream>
#include <time.h> //Se utiliza para poder generar verdaderos números al azar
#include <iomanip>

#define N 10
#define M 4

using namespace std;

void main(void)
{
int mat[N][M];
int i;

srand(time(NULL)); //se utiliza para inicializar la semilla de azar. Si no se inicializa siem-


pre genera

Programación C++ Ing. Helmut Heinz Dehner Página 50 de 70


//la misma secuencia de números

for (i = 0; i < N*M; i++)


{
//cout << "Ingrese el valor de Mat(" << i / M << "," << i%M << "): ";
//cin >> mat[i / M][i%M];
mat[i / M][i%M] = (rand() % M - rand() % M) ; // rand() % M --> genera un número al
azar entre 0 y M - 1
}
cout << "\n\nLa matriz ingresada es:";
for (i = 0; i < N*M; i++)
{
if (!(i % M))cout << endl;
cout <<setw(3)<< mat[i / M][i%M] << "\t";
}
cout << endl;
system("pause");
}

Declaración de una cadena de caracteres


Las cadenas de caracteres almacenan información tal como nombres de archivos, títulos de libros, nom-
bres de empleados, y otras combinaciones de caracteres.
C++ guarda las cadenas de caracteres en un arreglo del tipo char que termina con un carácter nulo
(NULL), por lo tanto, para declarar una cadena de caracteres simplemente se declara un arreglo de tipo
char con los suficientes elementos como para contener los caracteres deseados. Por ejemplo, la siguien -
te declaración crea un nombre de variable de cadenas de caracteres “nombre_archivo” capaz de almace-
nar 13 caracteres (el carácter NULL es uno de estos 13): char nombre_archivo[13];
La diferencia principal entre las cadenas de caracteres y otros tipos de arreglos es cómo C++ indica el
final del arreglo.
Este final se representa utilizando un carácter NULL (NULO), que C++ representa con el carácter espe-
cial “\0”. Cuando se asignan caracteres a la cadena, se debe poner el carácter null después del último
elemento. Por ejemplo, el programa 35ALFABETO.CPP, asigna las letras de la A a la Z a la variable “al-
fabeto” utilizando un ciclo for:

#include "stdafx.h"
#include <iostream>

using namespace std;

void main(void)
{
char alfabeto[27]; // 26 letras más NULL
char letra;
int i;

for (letra = 'A', i = 0; letra <= 'Z'; letra++, i++)


alfabeto[i] = letra;

alfabeto[i] = 0;// NULL '\0' 0


cout << "Las letras son: " << alfabeto<<endl;
cout << endl;
for ( i = 0; i < 26; i++)
cout << alfabeto[i];
cout << "\n\n";
system("pause");
}
Como puede verse, en la línea 13, el programa asigna el carácter NULL a la cadena para indicar el últi-
mo carácter de la misma.
Cuando el operador cout presenta la cadena, muestra los caracteres hasta llegar al nulo.

Programación C++ Ing. Helmut Heinz Dehner Página 51 de 70


Veamos ahora el bucle for que aparece en la línea 10. Este bucle inicializa e incrementa dos variables.
Cuando un bucle for inicializa o incrementa más de una variable se separan las operaciones utilizando
una coma “,”.

En qué difiere ‘A’ de “A”


Al examinar los programas de C++ podemos ver caracteres contenidos dentro de apóstrofes (Ej: ‘A’) y
caracteres dentro de comillas (“A”). Un caracter que está entre apóstrofes es un caracter constante. El
compilador de C++ solamente asigna un byte de memoria para guardar un caracter constante. Sin em-
bargo, un caracter encerrado entre comillas contiene una cadena constante.
El caracter y un caracter nulo que asigna el compilador (el compilador asigna automáticamente el carac-
ter NULL a una cadena constante). Por lo tanto, el compilador asignará dos bytes para guardar esta ca-
dena.

Cómo inicializar una cadena de caracteres


Para inicializar una cadena de caracteres en la declaración, simplemente se especifica la cadena deseada
encerrándola entre comillas, ej: char titulo[40] = “Aprenda C++”;
Si el número de caracteres asignado a la cadena es menor que el tamaño del arreglo, la mayoría de los
compiladores del C++ asignarán caracteres NULL al resto de la cadena.
Como ya se ha visto para los arreglos, si no se especifica el tamaño de la cadena, el compilador de C++
asignará la suficiente memoria como para contener las letras especificadas, más el caracter NULL. Ej:
char titulo[] = “Aprenda C++”;

Cadenas y funciones
Como en el caso de cualquier arreglo, para trabajar con una cadena en una función, simplemente debe-
mos especificar el tipo de arreglo (char). No se tiene que especificar el tamaño de la cadena. Por ejem-
plo, en el programa 36SHOW_CAD.CPP, se utiliza la función “mostrar_cadena” para mostrar por pan-
talla una cadena de caracteres:

#include "stdafx.h"
#include <iostream>

using namespace std;

void mostrar_cadena(char cadena[])


{
cout << cadena;
}

void main(void)
{

mostrar_cadena("Cadena de caracteres: ");


mostrar_cadena("Una cadena es un arreglo de tipo char.");
cout << endl;
system("pause");
}

Como ya sabemos, C++ utiliza el caracter NULL para indicar el final de una cadena. A continuación ve -
remos el programa 37LONG_CAD.CPP, que contiene una función que busca el caracter NULL para de-
terminar el número de caracteres que contiene una cadena.
Cuando examinemos más programas C++ encontraremos que muchas funciones buscan en esta forma
el caracter NULL dentro de una cadena de caracteres.

#include "stdafx.h"
#include <iostream>

using namespace std;

Programación C++ Ing. Helmut Heinz Dehner Página 52 de 70


int long_cadena(char cadena[])
{
int i;
for (i = 0; cadena[i]; i++); // Establece un ciclo
// buscando el siguiente caracter

return(i); // Longitud de la cadena


}

void main(void)
{

char titulo[] = "Aprenda C++";


char capitulo[] = "Arreglos y Cadenas";

cout << "La cadena '" << titulo << "' contiene " <<
long_cadena(titulo) << " caracteres.\n";

cout << "La cadena '" << capitulo << "' contiene " <<
long_cadena(capitulo) << " caracteres.\n";

cout << "La cadena " << titulo << " contiene " << strlen(titulo) <<" caracteres.\n"
<< "La cadena " << capitulo << " contiene " << strlen(capitulo) << " caracteres.\n";
system("pause");
}

La biblioteca string.h
El archivo string.h contiene muchas funciones para manipular cadenas. Por ejemplo, la función strupr
convierte una cadena de caracteres a mayúsculas. De igual forma, la función strlwr convierte la cadena
a minúsculas. Mientras que strlen regresa el número de caracteres que hay en una cadena. El progra-
ma 38STRING.CPP ilustra el empleo de las dos primeras:

#include "stdafx.h"
#include <iostream>

using namespace std;

void main(void)
{
char titulo[] = "Aprenda C++";
char capitulo[] = "Arreglos y Cadenas";

cout << "May"<<char(163)<<"sculas: " << strupr(titulo);


cout << "\n\nMin" << char(163) << "sculas: " << strlwr(capitulo) << endl;
system("pause");
}

SUBRUTINAS DE CADENAS
Veamos otras funciones de la biblioteca string.h en el programa 39CADENAS.CPP:

#include "stdafx.h"
#include <iostream>

using namespace std;

void main(void)
{
char nombre1[12], nombre2[12], cadena[25];
char titulo[20];
Programación C++ Ing. Helmut Heinz Dehner Página 53 de 70
strcpy(nombre1, "Margarita"); //NO ES LICITO PONER nombre1 = "Margarita"
strcpy(nombre2, "Pedro");
strcpy(titulo, "Trabajando con cadenas");

printf("%s\n\n", titulo);
printf("Nombre 1 es %s\n", nombre1);
printf("Nombre 2 es %s\n", nombre2);

if (strcmp(nombre1, nombre2)>0) // devuelve 1 si nombre1 > nombre2


strcpy(cadena, nombre1);
else
strcpy(cadena, nombre2);

printf("El nombre mayor alfab%cticamente es %s\n",char(130), cadena);

strcpy(cadena, nombre1);
strcat(cadena, " y ");
strcat(cadena, nombre2);
printf("Ambos nombres son %s\ny la longitud de la cadena = %i\n", cadena, strlen(cadena));

system("pause");
}

Primero se definen 4 cadenas. Después, en la línea 10, se utiliza una función de nombre “strcpy”, fun-
ción de copia de cadenas. Copia una cadena a otra mientras no aparezca NULL en la cadena origen. Tras
la ejecución de este mandato, “nombre1” contendrá “Margarita” pero sin las dobles comillas, que son
sólo para el compilador (así sabe que estamos definiendo una cadena). De la misma forma, en la si-
guiente línea “Pedro” se copia en “nombre2”, y luego se copia “titulo”. Nótese que no es necesario para
la definición de cadena el que las dos cadenas (origen - destino) sean de la misma longitud, tan solo con
que destino sea igual a origen+NULL, ya vale.
En la línea 18 vemos la función “strcmp”, o función de comparación de cadenas. Devolverá 1 si la pri-
mera cadena es más larga que la segunda, 0 si las 2 tienen la misma longitud y los mismos caracteres,
y -1 si la primera cadena es menor que la segunda. Una de las cadenas, dependiendo del resultado se
copia en la variable “cadena”, y se imprime el nombre más largo alfabéticamente. No debería sorpren -
dernos que “Pedro” gane, ya que es alfabéticamente mayor, no importa su longitud. También hay que
señalar que el resultado varía influido por mayúsculas o minúsculas.

El mandato en la línea 26 tiene otra utilidad, "strcat" o función concatenadora de cadenas (“Suma” de
caracteres). Esta función simplemente añade los caracteres de una cadena al final de otra, tomando cui-
dado de eliminar el NULL intermedio. En este caso, “nombre1” es copiado en “cadena” en la línea ante -
rior, luego se concatenan los 2 blancos, y finalmente la combinación se concatena con “nombre2”. El re-
sultado se imprime, con los dos nombres en “cadena”.

/*
Hacer un programa para que el usuario introduzca dos nombres, sin espacios, y los ordene alfa-
béticamente
*/
#include "stdafx.h"
#include <iostream>

using namespace std;

void main(void)
{
char nombre1[30], nombre2[30];
cout << "Ingrese el 1er nombre: ";
cin >> nombre1;
cout << "Ingrese el 2do nombre: ";
cin >> nombre2;
if (!strcmp(nombre1, nombre2)) cout << "\nLos nombres son iguales\n";
Programación C++ Ing. Helmut Heinz Dehner Página 54 de 70
else
if (strcmp(nombre1,nombre2)>0)
cout << nombre2 << " esta antes que " << nombre1 << endl;
else
cout << nombre1 << " esta antes que " << nombre2 << endl;
system("pause");
}

EJERCICIOS DE PROGRAMACIÓN
1. Hacer un programa con 3 cadenas cortas, alrededor de 6 caracteres cada una, y usar “strcpy” para
copiarlas en “uno”, “dos” y “tres”. Concatenar las 3 cadenas en una, e imprimir el resultado 10 ve -
ces.

2-. Definir 2 arreglos de tipo entero, cada uno con 10 elementos, de nombres “arr1” y “arr2”. Usando
un bucle, rellenar con valores informales, y añadir elemento a elemento en otro arreglo, “arreglo”.
Finalmente, imprimir el resultado en una tabla con número de índice. Ejemplo:
1. 2 + 10 = 12
2. 4 + 20 = 24
3. 6 + 30 = 36
etc.

Advertencia: el comando de impresión puede tomar la siguiente forma:


printf("%4d %4d + %4d =%4d\n",indice,arr1[indice],arr2[indice],arreglo[indice];

TRABAJO PRÁCTICO DE ARREGLOS


1. Realizar un programa que nos permita calcular la desviación estándar (SIGMA) de una lista de N nú-
meros (N<=15). Sabiendo que:

2. Escribir un programa que visualice un cuadrado mágico de orden impar n, comprendido entre 3 y
11; el usuario elige el valor de n. Un cuadrado mágico se compone de números naturales comprendi-
dos entre 1 y n2. La suma de los números que figuran en cada línea, cada columna y cada diagonal
son idénticos. Un ejemplo es:
8 1 6
3 5 7
4 9 2
Un método de construcción del cuadrado consiste en situar el número 1 en el centro de la 1º línea, el
número siguiente en la casilla situada encima y a la derecha, y así sucesivamente. Es preciso consi-
derar que el cuadrado se cierra sobre sí mismo: la línea encima de la 1º es de hecho la última y la
columna a la derecha de la última es la primera. Sin embargo, cuando la posición del número caiga
en una casilla ocupada, se elige la casilla situada por debajo del número que acaba de ser situado.
3. Escribir un programa que efectúe la multiplicación de dos matrices A, B:

A  m * p elementos
B  p * n elementos

Matriz producto: C  m * n elementos, tal que:

4. Escribir el algoritmo que permita obtener el número de elementos positivos de una tabla.
5. Rellenar una matriz identidad de 4 por 4.
6. Leer una matriz de N por N elementos y calcular la suma de cada una de sus filas y columnas, dejan-

Programación C++ Ing. Helmut Heinz Dehner Página 55 de 70


do dichos resultados en dos vectores, uno de la suma de las filas y otro de las columnas.
7. Cálculo de la suma de todos los elementos de un vector, así como la media aritmética.
8. Calcular el número de elementos negativos, cero y positivos de un vector dado de sesenta elemen-
tos.
9. Calcular la suma de los elementos de la diagonal principal de una matriz cuatro por cuatro (4 x 4).
10.Se dispone de una tabla T de cincuenta números reales distintos de cero. Crear una nueva tabla en
la que todos sus elementos resulten de dividir los elementos de la tabla T por el elemento T [K] ,
siendo K un valor dado.
11.Se dispone de una lista (vector) de N elementos. Se desea diseñar un algoritmo que permita insertar
el valor x en el lugar k-ésimo de la mencionada lista.
12.Se desea realizar un algoritmo que permita controlar las reservas de plazas de un vuelo MADRID CA-
RACAS, de acuerdo con las siguientes normas de la compañía aérea:
a) Número de plazas del avión: 300.
b) Plazas numeradas de 1 a 100: fumadores.
c) Plazas numeradas de 101 a 300: no fumadores.
Se debe realizar la reserva a petición del pasajero y cerrar la reserva cuando no haya plazas libres o
el avión esté próximo a despegar. Como ampliación de este algoritmo, considere la opción de anula-
ciones imprevistas de reservas.
13.Cada alumno de una clase de licenciatura en Ciencias de la Computación tiene notas correspondien -
tes a ocho asignaturas diferentes, pudiendo no tener calificación en alguna asignatura. A cada asig-
natura le corresponde un determinado coeficiente.
a) Escribir un programa que permita calcular la media de cada alumno.
b) Modificar el programa para obtener las siguientes medias:
i) general de la clase,
ii) de la case en cada asignatura,
iii) porcentaje de faltas (no presentado a examen).
14.Se dispone de las notas de cuarenta alumnos. Cada uno de ellos puede tener una o varias notas. Es-
cribir un programa que permita obtener la media de cada alumno y la media de la clase a partir de la
entrada de las notas desde el terminal.
15.Una empresa tiene diez almacenes y necesita crear un programa que lea las ventas mensuales de
los diez almacenes, calcule la media de ventas y obtenga un listado de los almacenes cuyas ventas
mensuales son superiores a la media.
16.Se dispone de una lista de cien números enteros. Calcular su valor máximo y el orden que ocupa en
la tabla.
17.Un avión dispone de ciento ochenta plazas, de las cuales sesenta son de 'no fumador' y numeradas
de 1 a 60 y ciento ochenta plazas numeradas de 61 a 180. Diseñar un programa que permita hacer
la reserva de plazas del avión y se detenga media hora antes de la salida del avión, en cuyo momen-
to se abrirá la lista de espera.
18.Calcular las medias de las estaturas de una clase. Deducir cuántos son más altos que la media y
cuántos más bajos que dicha media.
19.Las notas de un colegio se tienen en una matriz de 30 x 5 elementos (30, número de alumnos; 5,
número de asignaturas). Se desea listar las notas de cada alumno y su media. Cada alumno tiene
como mínimo dos asignaturas y máximo cinco, aunque los alumnos no necesariamente todos tienen
que tener cinco materias.
20.Dado el nombre de una serie de estudiantes y las calificaciones obtenidas en un examen, calculare
imprimir la calificación media, así como cada calificación y la diferencia con la media.
21.Se introducen una serie de valores numéricos desde el teclado, siendo el valor final de entrada de
datos o centinela -99. Se desea calcular e imprimir el número de valores leídos, la suma y media de
los valores y una tabla que muestre cada valor leído y sus desviaciones de la media.
22.Se tiene una lista de N nombres de alumnos. Escribir un programa que solicite el nombre de un
alumno, busque en la lista (array) si el nombre está en la lista.
23.Escribir un programa que permita visualizar el triángulo de Pascal:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1

Programación C++ Ing. Helmut Heinz Dehner Página 56 de 70


1 6 15 20 15 6 1
En el triángulo de Pascal cada número es la suma de los dos números situados encima de él. Este
problema se debe resolver utilizando un array de una sola dimensión.
24.Hacer cero los elementos de la diagonal principal de una matriz de N x N.
25.Imprimir el orden de los elementos de la diagonal principal de una matriz de N x N que sean iguales
a cero.
26.Leer una matriz A(6,8). Determinar cuántos elementos positivos tiene y que posición ocupa el mayor
de ellos. Si hay varios iguales al mayor, indicar la posición de todos.
27.Leer un vector A(N) e imprimir el que se obtiene eliminando sus elementos nulos.
28.Ordenar en forma creciente un vector real A de N elementos.
29.Encontrar por búsqueda binaria un elemento K del arreglo ordenado A(N).
30.Intercalación. Dados los arreglos A y B, ordenados, combinarlos produciendo el C.

ESTRUCTURAS Y UNIONES

Enumeración de tipos

Examinemos el archivo 40ENUM.CPP como un ejemplo del uso de tipos de variables enumeradas.

#include "stdafx.h"
#include <iostream>

using namespace std;

int main()
{
enum TipoFigura { Cuadro, Triangulo, Circulo };
TipoFigura Figura; //Definimos Figura de tipo enumerado TipoFigura
Figura = Circulo;
switch (Figura) {
case Cuadro: cout << "Actividades para Cuadros"; break;
case Triangulo: cout << "Actividades para Triángulo"; break;
case Circulo: cout << "Actividades para C"<<char(161)<<"rculo"; break;
default: cout << "Función no implementada"; break;
}
//Revisamos el valor predeterminado que asigna el compilador a los enumeradores
cout << endl << endl << "Valor de Cuadro: " << Cuadro << endl;
cout << "Valor de Triangulo: " << Triangulo << endl;
cout << "Valor de Circulo: " << Circulo << endl;
system("pause");
}

Veamos otro ejemplo:


#include "stdafx.h"
#include <iostream>

using namespace std;

#define NUM_OPCIONES 5
void main(void)
{
enum { Nuevo, Abrir, Guardar, Cerrar, Salir };
char menu[][10] = { "Nuevo", "Abrir", "Guardar", "Cerrar", "Salir" };
char opcion;
int i, caso;
do
{
/* Visualizar menú y leer la opción */
printf("\nSeleccione una opci%cn:\n\n",char(162));

Programación C++ Ing. Helmut Heinz Dehner Página 57 de 70


for (i = 0; i<NUM_OPCIONES; i++)
printf("%s (%d) ", menu[i], i);
printf(" : ");
cin >> opcion;

/* Mostrar en pantalla la opción seleccionada */


caso = opcion - '0';
switch (caso)
{
case Nuevo: printf("\nSe ha seleccionado la opci%cn %s\n",char(162), menu[caso]);
break;
case Abrir: printf("\nSe ha seleccionado la opci%cn %s\n", char(162), menu[caso]);
break;
case Guardar: printf("\nSe ha seleccionado la opci%cn %s\n", char(162), menu[caso]);
break;
case Cerrar: printf("\nSe ha seleccionado la opci%cn %s\n", char(162), menu[caso]);
break;
case Salir: printf("\nSe ha seleccionado la opci%cn %s\n", char(162), menu[caso]);
break;
default: printf("\n\nOpci%cn incorrecta\n\n",char(162));
break;
}
} while (caso != Salir);
}

El uso paralelo de una enumeración y una lista de cadenas facilita notablemente la construcción del pro-
grama; además, se entiende claramente el sentido de las acciones desencadenadas por el programa
principal. Obsérvese que hemos recurrido a leer un carácter, aun cuando la opción es numérica. Una vez
leído el valor de opción, se traduce a un número restándole el valor de '0', de tal modo que el carácter
'0' se convierte en el número 0, el carácter '1' se convierte en el número 1, y así sucesivamente. De
este modo, no es preciso comparar opcion con '4' sino caso con Salir ... y el método debe funcionar
siempre, sin cambios. Obsérvese también que se capturan los posibles errores del usuario: si el valor de
caso no aparece en la lista de sentencias case, se ejecuta el default correspondiente. Esto tendrá impor-
tancia en aquellos programas en que la activación de una opción desencadene la lectura de datos a par -
tir del teclado.

¿QUÉ ES UNA ESTRUCTURA?


Estructura es un tipo de dato definido por el usuario. Nosotros tenemos la capacidad de definir
nuevos tipos de datos considerablemente más complejos que los tipos manejados hasta ahora. Una es-
tructura es una combinación de varios datos definidos previamente, incluyendo otras estructuras ya de-
finidas. Una definición fácil de entender sería: “Es un grupo de datos afines en una forma fácil de usar
para el programador o usuario del programa. La mejor forma de entender la estructura es viendo un
ejemplo:
41STRUCT1.C

#include "stdafx.h"
#include <iostream>

using namespace std;

struct fecha{
int d;
int m;
int a;
};

void main(void)
{

struct mi_estructura
{

Programación C++ Ing. Helmut Heinz Dehner Página 58 de 70


char initial; /* inicial del 2o.nombre */
//int age; /* edad */
//int grade; /* curso escolar */
int age, grade;
fecha d_n;
} ;

mi_estructura boy, girl;

boy.initial = 'R';
boy.age = 21;
boy.grade = 75;
/*boy.d_n.d = 15;
boy.d_n.m = 1;
boy.d_n.a = 2000;*/
cout << "Ingrese fecha de nacimiento dd mm aa: ";
cin >> boy.d_n.d >> boy.d_n.m >> boy.d_n.a;

girl.age = boy.age - 1; /* ella es un año menor */


girl.grade = 82;
girl.initial = 'H';

printf("%c tiene %d a%cos y un grado escolar de %d\n",


girl.initial, girl.age, char(164), girl.grade);

printf("%c tiene %d a%cos y un grado escolar de %d y nacio %i/%i/%i\n",


boy.initial, boy.age, char(164), boy.grade,boy.d_n.d,boy.d_n.m,boy.d_n.a);
system("pause");
}

Las estructuras pueden ser de carácter global, de manera que se utilizan en todo el programa. En
el ejemplo de arriba, fecha está definida como global, pero además, lo que se define es un tipo de dato
que se declara o utiliza en el main dentro de otra estructura. Si la estructura está declarada dentro de la
función, tiene validez solo para la función que lo define.
El programa empieza con la definición de una estructura. La palabra clave "struct" es precedida por al-
gunas variables simples entre llaves, las cuales son componentes de la estructura. Las variables lista-
das, de nombre "boy" y "girl" se definen por el tipo mi_estrucutra. De acuerdo con la definición dada an -
teriormente, "boy" es ahora una variable compuesta de 4 elementos, "initial", "age" , "grade" y fecha de
nacimiento. Cada uno de los campos está asociado a "boy" y, cada uno puede almacenar una variable
de su respectivo tipo. La variable "girl" es también una variable con 4 campos asociados con los mismos
nombres que para "boy", pero son variables distintas. Hemos definido por tanto, 8 variables.

UNA VARIABLE COMPUESTA


Examinemos la variable "boy más detenidamente. Como hemos dicho antes, cada uno de los 3
elementos de "boy" es una variable simple, y puede utilizarse en cualquier programa C, tal como se usa
una variable de ese tipo. Por ejemplo, "age" es una variable entera y, por tanto, puede servir en cual-
quier zona de programa que necesite una variable "int" en, por ejemplo, cálculos, contadores, operacio -
nes de E/S, etc. El único problema que tenemos es en cómo definir el uso de la variable simple "age", la
cual es parte componente de "boy". Usamos ambos nombres con un punto decimal entre ellos, con el
nombre de la estructura en primer lugar. Entonces, el nombre completo y correcto de la variable de es-
tructura "age" sería: “boy.age". Esta construcción puede usarse en cualquier parte del programa, en la
cual deseemos referirnos a la estructura "boy". Obviamente es del todo incorrecto utilizar un nombre sin
el otro, o sea, mencionar sólo el nombre de la estructura, o la variable a secas. Estaremos hablando de
expresiones vacías.

ASIGNANDO VALORES A LAS VARIABLES


De acuerdo con la definición anterior, podemos asignar valores a cada una de las 3 variables aso-
ciadas a "boy", y a cada uno de los 3 componentes de "girl". "boy.initial" es un valor tipo "char", porque

Programación C++ Ing. Helmut Heinz Dehner Página 59 de 70


fue asignado así a la estructura. Por tanto, contendrá un caracter: a "boy.initial" se le asigna el caracter
"R" de acuerdo con su definición.. Al resto de componentes de la estructura se les asigna valores de su
respectivo tipo. Finalmente, a los componentes de "girl" se les asigna valores distintos, en orden distin-
to, a fin de demostrar que el orden de asignación de valores a la estructura no afecta al funcionamiento
de ésta.

COMO USAR LOS DATOS RESULTANTES


Ahora que ya hemos dado valores a las seis variables, podemos hacer lo que queramos con ellas.
A fin de hacer este primer ejemplo lo más sencillo posible, sólo mostramos las variables por pantalla,
para ver si contienen algo. Los "printf" no tienen nada especial. El nombre compuesto de cada variable
es especificado, ya que es el único válido a la hora de referirse a ella.
Las estructuras constituyen un buen método para agrupar datos a fin de hacer más fácil la escri-
tura y la comprensión del programa.

ESTRUCTURA DE ARRAYS
42STRUCT2.C
#include "stdafx.h"
#include <iostream>

using namespace std;

void main(void)
{
struct {
char initial;
int age;
int grade;
} kids[12];

int index;

for (index = 0; index < 12; index++) {


kids[index].initial = 'A' + index;
kids[index].age = 16;
kids[index].grade = 84;
}

kids[3].age = kids[5].age = 17;


kids[2].grade = kids[6].grade = 92;
kids[4].grade = 57;

for (index = 0; index < 12; index++)


printf("%c tiene %d años y un grado escolar de %d\n",
kids[index].initial, kids[index].age,
kids[index].grade);
system("pause");
}

Contiene la misma definición de estructura que el anterior, excepto en que en este definimos un
array de 12 variables denominadas "kids" con 3 campos. Este programa contiene, por tanto, 12 veces 3,
o sea, 36 variables simples, cada una de las cuales puede almacenar un dato de acuerdo con su tipo.
También definimos una variable simple denominada "index", para su uso en un bucle.
Para asignar un valor a cada componente, empleamos un bucle "for", y a cada paso del bucle se
efectúa una asignación a cada uno de los 3 componentes. Un paso de bucle asigna todos los valores a
un "kid". Esto no sería muy útil en una situación real, para asignar datos, pero el bucle podría leer de un
fichero y almacenar esos valores en las variables adecuadas. Puede considerarse esto como el principio
de una base de datos, ya que así es.

Programación C++ Ing. Helmut Heinz Dehner Página 60 de 70


En las siguientes instrucciones del programa asignamos nuevos valores a algunos de los compo-
nentes, para mostrar el método utilizado para hacerlo.
Los últimos mandatos contienen un bucle "for" en el cual todos los valores generados aparecen
por pantalla en un formato claro.

ESTRUCTURAS ANIDADAS Y CON NOMBRE


Las estructuras vistas hasta ahora eran muy simples, aunque útiles. Es posible definir estructuras
conteniendo docenas y, a veces, cientos o miles de elementos. Sería una ventaja para el programador
no definir todos los elementos en un solo paso, sino hacerlo de forma estructurada, en árbol. Esto será
objeto del siguiente programa.
43NESTED.C
#include "stdafx.h"
#include <iostream>

using namespace std;

void main(void)
{
struct person {
char name[25];
int age;
char status; /* M = casado, S = soltero */
};

struct alldat {
int grade;
person descrip;
char lunch[25];
} student[53];

struct alldat teacher, sub;


teacher.grade = 94;
teacher.descrip.age = 34;
teacher.descrip.status = 'M';
strcpy(teacher.descrip.name, "Mary Smith");
strcpy(teacher.lunch, "Baloney sandwich");

sub.descrip.age = 87;
sub.descrip.status = 'M';
strcpy(sub.descrip.name, "Old Lady Brown");
sub.grade = 73;
strcpy(sub.lunch, "Yogurt and toast");

student[1].descrip.age = 15;
student[1].descrip.status = 'S';
strcpy(student[1].descrip.name, "Billy Boston");
strcpy(student[1].lunch, "Peanut Butter");
student[1].grade = 77;

student[7].descrip.age = 14;
student[12].grade = 87;
cout << "Estudiante = " << student[1].descrip.name << " edad = " << student[1].descrip.age <<
" come = " << student[1].lunch << endl;
system("pause");
}

La primera estructura contiene 3 elementos, pero no está seguida por ningún nombre de variable. No
hemos definido, por tanto variables sólo para la estructura, pero le hemos dado nombre, "person", al
principio de la estructura. Este nombre puede ser utilizado para referirse a la estructura, pero no para
ninguna variable de esta. Hemos creado un nuevo tipo de variable, que podemos manejar tan fácilmen-

Programación C++ Ing. Helmut Heinz Dehner Página 61 de 70


te como manejamos tipos "int", "char" o cualquier otro tipo existente en C. La única condición que con-
lleva es que este nuevo tipo debe ir siempre asociado a la palabra "struct".

La siguiente definición de estructura contiene 3 campos, con el campo central del tipo de la es -
tructura anterior, es decir "person". Esta variable se llama "descript". Por tanto, la nueva estructura
contiene 2 variables simples, "grade" y una cadena denominada "lunch[25]", y la estructura "descript".
Ya que "descript" contiene 3 variables, la nueva estructura contiene realmente 5 variables. A esta es -
tructura se le da otro nombre, "alldat" que además constituye un nuevo tipo de variable. Finalmente de-
finimos un array de 53 variables cada una con la estructura definida por "alldat" y cada una de nombre
"student". Hemos definido un total de 53 veces 5 variables, cada una de las cuales es capaz de almace-
nar un valor.
Ya que hemos creado un nuevo tipo de variable, usémoslo para definir 2 variables más. Las va -
riables "teacher" y "sub" se definen en el siguiente mandato como variables de tipo "alldat", por lo cual
cada variable contiene 5 campos que pueden almacenar datos.

En las 5 siguientes líneas de programa, asignaremos valores a cada uno de los campos de "tea -
cher". El primer campo es "grade" y se expresa igual que las otras estructuras ya estudiadas, porque no
es parte de una estructura anidadas. Para definir este campo, empezamos con la variable "teacher" a la
que añadimos el nombre de grupo "descript", y entonces debemos describir que fichero de la estructura
anidada deseamos, por lo que asignamos "age". "Teacher" viene dado de la misma forma que "Age",
pero a los 2 últimos campos se les ha asignado cadenas, usando "strcpy", función normalmente utilizada
para estos menesteres.
Los nombres de las variables en la función "strcpy" son todavía nombres de variables, aunque es-
tén compuestas de varias partes.
A la variable "sub" le son asignados valores sin sentido de muchas formas, pero en diferente or -
den, ya que no se precisa un orden determinado para hacer estas asignaciones. Finalmente, a un grupo
de variables "student", se les asignan valores, con propósitos ilustrativos y, el programa finaliza. Nin-
guno de los valores se muestra en la pantalla dado que ya lo hicimos con varios en los últimos ejemplos.

MÁS ACERCA DE LAS ESTRUCTURAS


Es posible seguir anidando estructuras. No existe límite para las estructuras en un programa, no
obstante recomendamos no utilizar más de 3 para no crear confusión al programador, ya que la máqui-
na se aclara perfectamente. Además, se pueden incluir tantas estructuras como se desee en un nivel de
estructura, como por ejemplo definiendo esta estructura superior a "alldat", y usando "alldat" como
complemento a "person". La estructura person podría ser incluida en "alldat" dos o tres veces más,
como se quiera, como punteros de "alldat".
Una estructura puede contener arrays u otras estructuras, las cuales en cambio, pueden contener
arrays, tipos simples u otras estructuras.

UNIONES, ¿QUÉ SON?


• Una unión es una variable que puede contener (en momentos diferentes) objetos de diferentes tipos y tama-
ños y,
• Las uniones proporcionan una forma de manipular diferentes clases de datos dentro de una sola área de al-
macenamiento, sin incluir en el programa ninguna información dependiente de la máquina
Explicado de manera simple, podríamos decir que las uniones le permiten ver los mismos datos
con diferentes tipos, o usar un mismo dato con distintos nombres.

44UNION1.C

#include "stdafx.h"
#include <iostream>

using namespace std;

void main(void)
{
union {
int value; /*primera parte de la unión*/

Programación C++ Ing. Helmut Heinz Dehner Página 62 de 70


struct {
char first; /*Estos dos valores son la segunda */
char second;
} half;
} number;

long index;

for (index = 12; index < 300000; index += 35231) {


number.value = index;
printf(" %15ld %6ld %6ld\n", number.value, number.half.first,
number.half.second);
}
system("pause");
}

En este ejemplo, tenemos 2 elementos para la unión, la primera parte es un entero, "value" el
cual está almacenado como una variable de 2 bits en algún lugar de la memoria del ordenador. El se-
gundo elemento está constituido por 2 variables tipo caracter, "first" y "second". Estas variables se al-
macenan en la misma localización que "value", porque esto es lo que hace una unión. Permite almace-
nar datos de diferentes tipo en un mismo espacio físico. En este caso, podría ponerse un entero en "va-
lue", y recobrarlo luego en dos mitades, ubicadas en "first" y "second". Esta técnica se utiliza habitual-
mente para empaquetar bytes de datos cuando, por ejemplo, se están combinando datos para ser utili -
zados en los registros del microprocesador.
El acceso a los elementos de la unión es muy parecido a hacerlo en una estructura.
Una nota adicional acerca del programa: cuando se ejecuta en la mayoría de compiladores, los
datos aparecerán por pantalla con dos "f" de guía, debido a la salida en formato hexadecimal de las va -
riables "int" y "char", y añadiendo el signo a la izquierda. Convirtiendo los datos de tipo "char" en "int"
antes de sacarlos por pantalla se podrían evitar las "f". Esto supone la definición de nuevos tipos de va-
riables enteras y la asignación de variables "char" a ellas.

OTRO EJEMPLO DE UNIÓN


Supongamos que se desea hacer una gran base de datos, incluyendo información de algunos ti-
pos de vehículos. Sería absurdo incluir el número de hélices de un coche, o el número de ruedas de un
barco. Para tener todos los datos correctos, necesitaríamos esos tipos de datos para cada clase de
vehículo. Para que la base de datos sea eficiente, necesitaría diferentes tipos de datos para cada vehícu-
lo, aunque algunos podrían ser comunes, y otros exclusivos. Esto es lo que hace el siguiente ejemplo:
definiremos una estructura completa, decidiremos cual de los varios tipos de datos pueden incluirse.
Empezaremos por el principio, e iremos desarrollando:

45UNION2.C

#include "stdafx.h"
#include <iostream>

#define AUTO 1
#define BOAT 2
#define PLANE 3
#define SHIP 4

using namespace std;

void main(void)
{
struct automobile { /* estructura de un automóvil */
int tires;
int fenders;
int doors;
};

Programación C++ Ing. Helmut Heinz Dehner Página 63 de 70


typedef struct { /* estructura de un barco o un avión */
int displacement;
char length;
} BOATDEF;

struct {
char vehicle; /* ¨que tipo de vehículo? */
int weight; /* vehículo pesado */
union { /* tipo de dato dependiente */
struct automobile car; /* parte 1 de la union */
BOATDEF boat; /* parte 2 de la union */
struct {
char engines;
int wingspan;
} airplane; /* parte 3 de la union */
BOATDEF ship; /* parte 4 de la union */
} vehicle_type;
int value; /* valor del vehículo (en dólares) */
char owner[32]; /* nombre de los dueños */
} ford, sun_fish, piper_cub; /* 3 variables estructura */

/* define algunos campos como ejemplo */

ford.vehicle = AUTO;
ford.weight = 2742; /* con el depósito lleno*/
ford.vehicle_type.car.tires = 5; /* incluyendo repuesto */
ford.vehicle_type.car.doors = 2;

sun_fish.value = 3742; /* trailer no incluido */


sun_fish.vehicle_type.boat.length = 20;

piper_cub.vehicle = PLANE;
piper_cub.vehicle_type.airplane.wingspan = 27;

if (ford.vehicle == AUTO) /* cual es en este caso */


printf("El ford tiene %d ruedas.\n", ford.vehicle_type.car.tires);

if (piper_cub.vehicle == AUTO) /* cual no es en este caso */


printf("El avion tiene %d ruedas.\n", piper_cub.vehicle_type.
car.tires);
system("pause");
}

Primero definimos algunas constantes con el "#define", y comenzamos el programa en si. Definimos una
estructura denominada "automobile", la cual contiene varios campos, con los que no debería existir con-
fusión. No definimos variables, por ahora.

TRABAJO PRÁCTICO DE ESTRUCTURAS


1) Leer dos puntos. P1 y P2 representados como una estructura. Calcular la longitud del segmento que
los une y la pendiente de la recta que pasa por dichos puntos.

P1 (x1,y1) P2 (x2,y2)

Y
2
Y2 – Y1
Y
X2 –
1
X X1 X
1 2

Programación C++ Ing. Helmut Heinz Dehner Página 64 de 70


2) Escribir un programa que acepte la hora del día en formato militar (0845) y encuentre la representa-
ción usual en horas y minutos y AM/PM (8:45 AM) o acepte el formato usual y encuentre la corres -
pondiente representación militar:

0100 se representa por 1:00 AM


3:45 PM se representa por 1545
3) Escribir una declaración de un registro para cuatro figuras geométricas: triángulo, rectángulo, cua-
drado, y círculo. Para el triángulo se deben almacenar las longitudes de sus tres lados; para el rec-
tángulo, la longitud y el ancho, para el cuadrado, su lado y para el círculo, su radio. A continuación,
escribir un programa que lea una de las letras T (Triángulo), R (Rectángulo), C (Cuadrado), X (Círcu-
lo), y los valores correspondientes y calcule sus superficies.

4) Un número complejo tiene la forma a + bi, donde a y b son números reales e i2 = -1. Las operacio-
nes básicas con números complejos son:
¡

Escribir un programa que lea dos números complejos y el símbolo correspondiente a la operación y

ejecute la operación indicada. Utilizar una estructura para representar números complejos y procedi-

mientos y/o funciones para realizar las operaciones.

5) Se dispone de un tipo de dato estructurado Tiempo que consta de tres campos: Horas, Minutos y Se-
gundos. Se desea diseñar un Procedimiento / Función que reciba como entrada la hora inicial desde
el comienzo de un experimento y el tiempo transcurrido en segundos y que devuelva como salida la
hora actual. Se debe suponer un reloj de 24 Horas.
6) Se declara un dato estructurado Complejo –dos campos– que representa a los números complejos
(a, bi) que tiene una parte real (a) y una parte imaginaria (bi). Se desea diseñar una serie de proce-
dimientos / funciones que realicen las siguientes tareas:
a) Inicializar a cero el número complejo (a, b) = (0,0).
b) Leer números complejos.
c) Escribir números complejos.
d) Sumar números complejos (a, bi) + (c, di) ) = (a + b), (c + d)i.
e) Restar números complejos (a, bi) - (c, di) ) = (a - b), (c - d)i.
f) Multiplicar complejos (a + bi) * (c + di) ) = (ac - bd), (ad + bc)i.
g) Parte real de un complejo, a.
h) Parte imaginaria de un complejo, bi.
i) Conjugado de un complejo a – bi.
j) Valor absoluto de un complejo.

Nota: Recuerde que i * i = i2 = -1 (i, el número imaginario: ).


7) Un array de una estructura contiene la descripción de personas a efectos estadísticos. Cada estructu-
ra tiene los campos: nombre, edad, sexo, altura, color de piel, color de ojos, nacionalidad y región.
Escribir un programa que lea y almacene datos en este array, ordene el array por orden alfabético
de nombres y visualice o imprima su contenido.

Programación C++ Ing. Helmut Heinz Dehner Página 65 de 70


8) El inventario de un almacén de artículos deportivos se desea guardar en un array estructurado. Ar-
tículos con los campos: nombre, número de código (seis dígitos), número de artículos y precio. Escri-
bir un procedimiento que lea y almacene el archivo de datos del inventario en un array de estructura
adecuada. El programa principal debe contemplar las siguientes opciones, que serán realizadas tam-
bién con procedimientos: impresión de todo el inventario, búsqueda de un articulo por número de
código, actualización semanal (altas y bajas de artículos), ordenaci6n alfabética por nombre y orde-
nación decreciente por número de articulo.
9) Se desea crear un array estructurado con los datos de los estudiantes en un determinado colegio.
Los campos de los registros son: nombre, código, sexo, edad, curso, notas de las asignaturas del
curso anterior. A continuación, escribir un programa que lea y escriba este array, así como las opcio-
nes: ordenar por orden alfabético de nombres. calcular la media de cada alumno y visualizar la lista
de alumnos por curso ordenados alfabéticamente por nombre.
10) Un médico almacena la siguiente información de sus pacientes: nombre, dirección. teléfono, fe-
cha última visita, si es o no privado (no tiene seguridad social), si tiene alergias, y un campo de ob-
servaciones. Se desea un programa con las siguientes opciones:
a) Introducción de registros interactivamente.
b) Imprimir en pantalla toda la información del paciente.
c) Dado un nombre de un paciente, encontrar la fecha de la última visita.
d) Listar todos los pacientes con alergias.
e) Listar alfabéticamente todos los pacientes privados.
f) Imprimir todo el listado completo de pacientes.

Índice

PROGRAMACIÓN EN C++----------------------------------------------------------------------------2

¿Por qué C++?---------------------------------------------------------------------------------------------------------------2


¿Qué clase de programas y aplicaciones se pueden crear usando C y C++?--------------------------------------2

Los programas de ordenador----------------------------------------------------------------------------------2

Consideraciones Generales-------------------------------------------------------------------------------------3

Un programa sencillo-----------------------------------------------------------------------------------------------4

La declaración #include------------------------------------------------------------------------------------------5

La consola-----------------------------------------------------------------------------------------------------------------5

El operador cout-------------------------------------------------------------------------------------------------------5

IDENTIFICADORES--------------------------------------------------------------------------------------------------6

Declaración de variables-----------------------------------------------------------------------------------------6

COMO HACER COMENTARIOS----------------------------------------------------------------------------------7

EJERCICIOS DE PROGRAMACIÓN:--------------------------------------------------------------------------7

LIBRERIAS EN LENGUAJE C-----------------------------------------------------------------------------------------7

RESUMEN DE LIBRERIAS---------------------------------------------------------------------------------------------8

CADENAS DE FORMATO-----------------------------------------------------------------------------------------------9
Programación C++ Ing. Helmut Heinz Dehner Página 66 de 70
SECUENCIA DE ESCAPE----------------------------------------------------------------------------------------------10

EL PROGRAMA TOMA DECISIONES-----------------------------------------------------------10

EL BUCLE WHILE-----------------------------------------------------------------------------------------------------11

EL BUCLE DO-WHILE----------------------------------------------------------------------------------------------11

EL BUCLE FOR---------------------------------------------------------------------------------------------------------12

EL CONDICIONAL IF-----------------------------------------------------------------------------------------------13

IF-ELSE--------------------------------------------------------------------------------------------------------------------13

BREAK y CONTINUE------------------------------------------------------------------------------------------------13

LA INSTRUCCIÓN SWITCH-------------------------------------------------------------------------------------14

EJERCICIOS DE PROGRAMACIÓN:------------------------------------------------------------------------14

ASIGNACIONES Y COMPARACIONES LÓGICAS----------------------------------------15

La función PRINTF()----------------------------------------------------------------------------------------------15

MANDATOS DE ASIGNACIÓN DE ENTEROS----------------------------------------------------------16

El operador cin--------------------------------------------------------------------------------------------------------17

COMPARACIONES LÓGICAS-----------------------------------------------------------------------------------18

CONCEPTOS ADICIONALES SOBRE COMPARACIÓN---------------------------------------------19

EVALUACIÓN LÓGICA---------------------------------------------------------------------------------------------19

ÁREAS POTENCIALES DE PROBLEMAS------------------------------------------------------------------20

LA PARTE CRÍPTICA DEL C------------------------------------------------------------------------------------20

LA EXPRESIÓN CONDICIONAL------------------------------------------------------------------------------21

Las palabras const y volatile---------------------------------------------------------------------------------21

EL OPERADOR DE ALCANCE-----------------------------------------------------------------------------------22

DEFINICIÓN DE VARIABLES----------------------------------------------------------------------------------23

VARIABLE DE REFERENCIA------------------------------------------------------------------------------------23

DECLARACIONES EJECUTABLES----------------------------------------------------------------------------24

Definición y declaración-----------------------------------------------------------------------------------------24

Programación C++ Ing. Helmut Heinz Dehner Página 67 de 70


Las variables En EL BUCLE for-------------------------------------------------------------------------------24

Salida Con formato FORMATO.CPP-----------------------------------------------------------------------24

}-------------------------------------------------------------------------------------------------------------------------------26

EJERCICIOS DE PROGRAMACIÓN--------------------------------------------------------------------------26

DEFINES Y MACROS-----------------------------------------------------------------------------------26

DEFINES Y MACROS: AYUDA A UNA PROGRAMACIÓN CLARA----------------------------26

¿ESTO ES ÚTIL?------------------------------------------------------------------------------------------------------27

¿QUÉ ES UN MACRO?----------------------------------------------------------------------------------------------27

UN MACRO INCORRECTO---------------------------------------------------------------------------------------27

EJERCICIOS DE PROGRAMACIÓN:------------------------------------------------------------28

TRABAJO PRÁCTICO DE ESTRUCTURAS DE CONTROL-----------------------------28

FUNCIONES EN C++-----------------------------------------------------------------------------------30

Creación y uso de las primeras funciones------------------------------------------------------------31

LOS PROTOTIPOS---------------------------------------------------------------------------------------------------32

LOS TIPOS COMPATIBLES--------------------------------------------------------------------------------------34

¿COMO TRABAJA UN PROTOTIPO?------------------------------------------------------------------------34

UN POCO MAS SOBRE PROTOTIPOS---------------------------------------------------------------------34

¿QUE COSTO TIENE UN PROTOTIPO?-------------------------------------------------------------------35

PASE POR REFERENCIA------------------------------------------------------------------------------------------35

PARÁMETROS POR DEFECTO---------------------------------------------------------------------------------38

¿POR QUÉ SE INVIERTE LA SALIDA?--------------------------------------------------------------------39

NUMERO VARIABLE DE ARGUMENTOS------------------------------------------------------------------40

SOBRECARGA DE FUNCIONES-------------------------------------------------------------------------------41

RECURSIVIDAD-------------------------------------------------------------------------------------------------------42
Ejemplo 1-----------------------------------------------------------------------------------------------------------------42
Ejemplo 2-----------------------------------------------------------------------------------------------------------------44
Ejemplo 3-----------------------------------------------------------------------------------------------------------------44

EJERCICIOS DE PROGRAMACIÓN--------------------------------------------------------------------------45
Programación C++ Ing. Helmut Heinz Dehner Página 68 de 70
TRABAJO PRÁCTICO DE FUNCIONES--------------------------------------------------------45

ARREGLOS Y CADENAS------------------------------------------------------------------------------46

Cómo declarar una variable arreglo---------------------------------------------------------------------46

Cómo utilizar los elementos de un arreglo-----------------------------------------------------------46

Inicializar un arreglo en la declaración----------------------------------------------------------------48

Las funciones trabajan con arreglos---------------------------------------------------------------------48

}-------------------------------------------------------------------------------------------------------------------------------49

ARREGLOS MULTIDIMENSIONALES----------------------------------------------------------------------49
¿Es posible recorrer una matriz con un solo bucle y el tamaño de la misma?-----------------------------------50

Declaración de una cadena de caracteres------------------------------------------------------------50

En qué difiere ‘A’ de “A”----------------------------------------------------------------------------------------51

Cómo inicializar una cadena de caracteres----------------------------------------------------------51

Cadenas y funciones----------------------------------------------------------------------------------------------51

La biblioteca string.h---------------------------------------------------------------------------------------------52

SUBRUTINAS DE CADENAS------------------------------------------------------------------------------------53

EJERCICIOS DE PROGRAMACIÓN--------------------------------------------------------------------------54

TRABAJO PRÁCTICO DE ARREGLOS----------------------------------------------------------54

ESTRUCTURAS Y UNIONES------------------------------------------------------------------------56

Enumeración de tipos--------------------------------------------------------------------------------------------56

¿QUÉ ES UNA ESTRUCTURA?---------------------------------------------------------------------------------56

UNA VARIABLE COMPUESTA----------------------------------------------------------------------------------57

ASIGNANDO VALORES A LAS VARIABLES------------------------------------------------------------57

COMO USAR LOS DATOS RESULTANTES---------------------------------------------------------------57

ESTRUCTURA DE ARRAYS--------------------------------------------------------------------------------------58

ESTRUCTURAS ANIDADAS Y CON NOMBRE----------------------------------------------------------58

MÁS ACERCA DE LAS ESTRUCTURAS---------------------------------------------------------------------60

UNIONES, ¿QUÉ SON?--------------------------------------------------------------------------------------------60

Programación C++ Ing. Helmut Heinz Dehner Página 69 de 70


OTRO EJEMPLO DE UNIÓN-------------------------------------------------------------------------------------61

TRABAJO PRÁCTICO DE ESTRUCTURAS---------------------------------------------------62

Programación C++ Ing. Helmut Heinz Dehner Página 70 de 70

También podría gustarte