PROGRAMACIÓN I EN C++ borland

79

description

PROGRAMACIÓN I EN C++ borland

Transcript of PROGRAMACIÓN I EN C++ borland

Page 1: PROGRAMACIÓN I EN C++ borland
Page 2: PROGRAMACIÓN I EN C++ borland

PROGRAMACIÓN EN C++PROGRAMACIÓN EN C++

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 decir, 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 extensió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 extensió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 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 librerías que suministra el lenguaje. La mezcla del archivo obj con las librerías .lib conducen a un ejecutable 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, posiblemente 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 manejo 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 “main()”. Como función debe tener 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 distinto

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 apertura 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éntesis,

etc.

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

Page 3: PROGRAMACIÓN I EN C++ borland

El Entorno Integrado de Desarrollo (EID) nos permite trabajar con “indentación”… se debe trabajar en forma indentada

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.

C, No inicializa los identificadores, por lo que es necesario que el programador los inicialice.

Un programa sencilloLa mejor manera de empezar el estudio de C++ es examinar un programa. Comenzaremos con el programa más simple que puede escribirse en C++: PRIMERO.CPP

#include <iostream.h>

main(){ 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 relacionadas, se usan para definir los límites del programa principal.

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

N

p

Page 4: PROGRAMACIÓN I EN C++ borland

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 #includeEsta 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 tienen extensión h y se incluyen al principio (o cabecera) de los programas se llaman archivos de cabecera. Cada uno de los archivos de cabecera comprende definiciones que el compilador proporciona para diferentes operaciones. Por ejemplo, hay archivos de cabecera para las operaciones matemáticas, para operaciones 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 consolaEl instrumento más rudimentario de interacción es la consola, es decir, el teclado para permitir la interacció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 coutEl 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: SEGUNDO.CPP

#include <iostream.h>

main(){ 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í sucesivamente. 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 izquierda de la pantalla. Se refiere normalmente a un retorno de carro. En cualquier parte del texto, donde se desee, puede acabar la línea y empezar otra nueva. Se puede cortar una palabra y mostrarla entre 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

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

Page 5: PROGRAMACIÓN I EN C++ borland

retornos de carro, resultando una línea en blanco. Finalmente la cuarta línea muestra otra línea de texto y acaba el programa.

IDENTIFICADORESUn identificador es una combinación de caracteres numéricos, alfanuméricos o letras, o algún número, o un caracter subrayado “_”, lo usa una variable, o una función, o una definición de datos, etc. En el lenguaje C++ debe tenerse en cuenta que mayúsculas y minúsculas definen identificadores distintos. Así, el identificador “INDICE”, es distinto de “indice”, y también de “Indice”.

Declaración de variablesLos 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 Rangochar 8 1 0 a 255int 16 2 -32768 a 32767

float 32 4 -3.4E-38 a 3.4E+38double 64 8 1.7E-308 a 1.7E+308void 0 0 sin valor

Otros:Tipo Ancho en Bit Ancho en Bytes Rango

signed char 8 1 -128 a 127unsigned int 16 2 0 a 65535

long int 32 4 -2147483648 a 214.782.647unsigned long int 32 4 0 a 4.294.967.295unsigned 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 variables utilizando una coma.Cada variable tiene un nombre único. Para que los programas sean más fáciles de leer y comprender deben 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, VARIABLE.CPP, asigna valores a dos variables y luego las exhibe en la pantalla utilizando el operador cout.El operador de inserción (<<) comunica al sistema que lo sigue una variable o una constante.

#include <iostream.h>

main(){ /* Principio

del programa */

int edad; //Declaración de la variable float salario = 451.75; //Declaración y asignación

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

Page 6: PROGRAMACIÓN I EN C++ borland

edad=32; //Asignación del valor cout <<"Edad del empleado: " << edad << " años "; cout <<"\nSalario: $"<< salario << ".-";

// Fin del programa}

COMO HACER COMENTARIOSEn el programa anterior vemos dos maneras de hacer comentarios en un programa, para hacerlo más legible a otros. El compilador ignora estos comentarios. 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ándose 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.

EELL PROGRAMAPROGRAMA TOMATOMA DECISIONESDECISIONES

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 ... ! … NO

&& y|| o

EL BUCLE WHILEEl lenguaje C++ tiene varias estructuras de control para bucles y bifurcaciones condicionales. Empezaremos 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.

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

Page 7: PROGRAMACIÓN I EN C++ borland

Veamos un ejemplo del funcionamiento de este bucle en el programa WHILE.CPP

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

main(){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 entre 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 ejecutarse. 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-WHILEUna variación del bucle WHILE se muestra en el programa DOWHILE.CPP

#include <iostream.h>

// Este es un ejemplo del bucle do-while

main(){int i;

i = 0; do { cout <<"El valor de i es ahora " << i << "\n"; i = i + 1; } while (i <= 5);}

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 entre 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 ejecutará al menos

1 vez.

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

Page 8: PROGRAMACIÓN I EN C++ borland

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 llaves. Estos bucles pueden anidarse. Esto es, un bucle dentro de otro, y el número de anidamientos es ilimitado.

EL BUCLE FOREl 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éntesis. Estas expresiones son dos o tres campos separados por punto y coma.

#include <iostream.h>

// Este es un ejemplo de bucle for

main(){int indice;

for(indice = 0;indice < 6;indice = indice + 1) cout <<"El valor de indice es " <<indice<< "\n";}

En nuestro ejemplo, BUCLEFOR.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 ocurre 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.

EL CONDICIONAL IFEn el siguiente programa, IFELSE.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

main(){int dato;

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

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

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

Page 9: PROGRAMACIÓN I EN C++ borland

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 expresión se evalúa y resulta cierta, el mandato simple que sigue a if se ejecutará, pero si es falsa, el control 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-ELSEEste 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 cierta, la primera expresión es ejecutada. Caso contrario, las instrucciones después de else serán ejecutadas. Entonces, una de las expresiones se ejecuta siempre, al contrario del primer ejemplo, donde la expresión o cumple o se ignora.

BREAK y CONTINUE Veamos el programa BREAKCON.CPP

#include <iostream.h>

main(){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"; }}

En el 1er. "for" hay un condicional que llama a una interrupción (break) si xx es igual a 8. Esta interrupción le sacará del bucle y continuará ejecutando los mandatos que haya después, dando por terminado el bucle. Es un mandato muy útil cuando quiera abandonar un bucle, dependiendo del resultado 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 SWITCHEsta 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, SWITCH.CPP, esta variable es "truck". Pueden incluirse tantas posibilidades

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

Page 10: PROGRAMACIÓN I EN C++ borland

como sean necesarias, encerradas entre llaves, claro está. La palabra reservada "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>

main(){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 bucle 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.

AASIGNACIONESSIGNACIONES YY C COMPARACIONESOMPARACIONES L LÓGICASÓ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 PRINTF.CPP en el que se utiliza esta función con diferentes tipos de datos, modificando el formato de salida por pantalla.

#include <stdio.h>main(){

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

Page 11: PROGRAMACIÓN I EN C++ borland

int a; // tipo entero simplelong int b; // tipo entero expandidoshort int c; // tipo entero comprimidounsigned int d; // tipo entero sin signochar e; // tipo caracterfloat f; // tipo punto flotantedouble g; // punto flotante doble precisión

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

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 %.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 mandato y después de este patrón hay una coma seguida por la variable que quiere ser mostrada. Podemos 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 variables 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.

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

(20)

Page 12: PROGRAMACIÓN I EN C++ borland

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".

MANDATOS DE ASIGNACIÓN DE ENTEROSEl programa ASIG_INT.CPP es un buen ejemplo de los mandatos de asignación:

#include <stdio.h>

main(){int a,b,c;

a = 12; b = 3; 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); c = a / b; printf("a= %d| b= %d| c= %d\n\n",a,b,c); c = a % b; // módulo o residuo printf("a= %d| b= %d| c= %d\n\n",a,b,c); c = 12*a + b/2 - a*b*2/(a*c + b*2); printf("a= %d| b= %d| c= %d\n\n",a,b,c); 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);

a = b = c = 20; // asignación múltiple printf("a= %d| b= %d| c= %d\n\n",a,b,c); 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.

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

(17)

(19)

(21)

(28)

(30)

Page 13: PROGRAMACIÓN I EN C++ borland

El operador cinEste 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 OPER_CIN.CPP:

#include <iostream.h>

main(){ 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; cout << "\n'c' = " << c;

}

COMPARACIONES LÓGICASEl programa COMPARAR.CPP contiene algunos ejemplos de comparaciones en C.

#include <iostream.h>

main() {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;

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

Page 14: PROGRAMACIÓN I EN C++ borland

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 variable podría ser sustituida por una constante, y la comparación seguiría siendo válida, pero dos variables 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 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 verdadero 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á evaluada 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 resultado 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, hemos 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 podrí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 resultado de “x” es no cero. La comparación a cero no es actualmente necesaria, ya que el resultado de la misma es verdad. El tercer y cuarto ejemplo son idénticos.

CONCEPTOS ADICIONALES SOBRE COMPARACIÓNEl 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

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

Page 15: PROGRAMACIÓN I EN C++ borland

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 mayor 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ÓGICACuando una expresión compuesta se evalúa, la evaluación se realiza de izquierda a derecha, y tan pronto como se cumple el resultado de la misma, se para. Nos referimos a “evaluación lógica” cuando empleamos un AND y, uno de los términos evaluados da falso, la evaluación es discontinua, aunque los demá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 condicional de la comparación. Como todas las variables tienen valor no cero, todas son verdad, hay por tanto 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 comparadora del if. A las tres variables se les asignan nuevos valores, los cuales son no cero, por lo tanto producen un resultado verdad.

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 encontrar el falso en el primer término. Por tanto, “z” no tomará valor 4, y la variable “r” no cambiará.

ÁREAS POTENCIALES DE PROBLEMASEl ú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 efecto 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 ejecutando jamás la parte condicional del if. El mandato condicional es extremadamente importante, y, debe ser minuciosamente estudiado, para escribir buenos programas en C.

LA PARTE CRÍPTICA DEL CExisten tres estructuras en C que no tienen sentido cuando se ven por primera vez, ya que no son intuitivas, pero al contrario, son extremadamente útiles para incrementar la eficiencia del código compilado y las usan muchos programadores expertos en C.El programa CRIPTICA.CPP es un ejemplo de 3 nuevas construcciones.

# include <iostream.h>

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

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

Page 16: PROGRAMACIÓN I EN C++ borland

// 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

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 posterior.El primer mandato ejecutable, simplemente suma 1 al valor de “x”. Los dos siguientes mandatos tambié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.

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

Page 17: PROGRAMACIÓN I EN C++ borland

LA EXPRESIÓN CONDICIONALLa 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 interrogante 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 resultado de la evaluación se usa en la asignación. El resultado final es idéntico que un if con 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ñadida 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 volatileEn el programa CONS_VOL.CPP vemos la utilización de estas nuevas palabras en C++.

#include <iostream.h>

main(){const int PRINCIPIO = 3; // El valor de PRINCIPIO no podrá cambiarseconst int FIN = 9; // El valor de FIN no podrá cambiarsevolatile int CENTRO = 6; // El valor de CENTRO podrá ser cambiado // 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 compilador 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 necesita saber que este valor puede ser cambiado por alguna fuerza externa al avanzar el programa.

EL OPERADOR DE ALCANCEEl programa llamado OP_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>

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

(5)

elseif

Page 18: PROGRAMACIÓN I EN C++ borland

int indice = 13;

main(){float indice = 3.1415;

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

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

cout << "El valor del índice local es " << indice << "\n"; 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 VARIABLESVeamos a continuación el archivo VARDEF.CPP

#include <iostream.h>

int indice;

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

elemento = indice + 14; //índice ha sido inicializado a cero cout << "El elemento tiene el valor " << elemento << "\n"; elemento = 17; cout << "El otro elemento tiene el valor " << otro_elemento << "\n";

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

cout << "Otro elemento tiene el valor " << mas_elementos << "\n"; for (int contador = 3;contador < 8;contador++) { cout << "El contador vale " << contador << "\n"; char contador2 = contador + 65; cout << "Contador2 tiene el valor " << contador2 << "\n"; } static unsigned estatico; //inicialización automática a cero

cout << "Estático vale " << estatico << "\n";}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.

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

(3)

(7)

(10)

(12)

(15)

(3)

(7)(8)

(10)

(15)

(19)

(21)

(25)

(28)

Page 19: PROGRAMACIÓN I EN C++ borland

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 REFERENCIAEn la línea 8 se define a la variable “otro_elemento” como una variable de referencia, utilizando el símbolo & (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 variable, 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 EJECUTABLESEn la línea 15 hay una declaración extraña, pero legal en C++. Es legal poner una declaración ejecutable 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ónLas palabras de definición y declaración se refieren a dos cosas diferentes en C++.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 programa. 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 elemento en el programa.

En suma, una declaración introduce un nombre en el programa y una definición introduce 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 declaramos y la definimos a la vez.

Las variables En EL BUCLE forRevisemos 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 únicamente dentro del bucle.A la variable “contador2” se le asigna un valor numérico en la línea 21, pero cuando se imprime, aparece 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//Salida con Formato/*

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

Page 20: PROGRAMACIÓN I EN C++ borland

Todas estas Funciones se encuentran en la Biblioteca "iomanip.h"

dec conversión a decimalhex conversión a hexadecimaloct conversión a octalsetprecision(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 estas funciones son las siguientes:

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 delimitador d, sehan extraído n-1 caracteres, se encontró el final del fichero.

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

*/

//Ejemplo

#include <iomanip.h>#include <iostream.h>#include <conio.h>

void main(){

float coef[]={5198,3.21,46.32,506.5,2002.38};

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

Page 21: PROGRAMACIÓN I EN C++ borland

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' getch();}

EJERCICIOS DE PROGRAMACIÓN1. 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 resultado 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 comprendidos entre 32 y 39, uno en cada línea.

4. Escribir un programa interactivo para leer una fecha con tres diferentes declaraciones cin. Imprimir dicha fecha por pantalla.

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.

DDEFINESEFINES YY M MACROSACROS

DEFINES Y MACROS: AYUDA A UNA PROGRAMACIÓN CLARAA continuación vemos el primer ejemplo de algunas "defines" y "macros":DEFINE.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 */

main(){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); }

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

Page 22: PROGRAMACIÓN I EN C++ borland

}

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 desastroso 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.

¿QUÉ ES UN MACRO?Un macro no es más que otro define , pero dado que es capaz, o al menos susceptible de realizar

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 encontrar 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 sustituirá cada "B" en la segunda definición. Cuando encontramos la línea 12 del programa, "index" será sustituido por cada "A", y "count" lo será por cada "B". Recordando la estructura críptica, estudiada anteriormente, revelaremos que "mx" recibirá el máximo valor de "index" o "count". De una manera parecida, 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 INCORRECTOEl siguiente es un ejemplo mejor de macro:

MACRO.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

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

Page 23: PROGRAMACIÓN I EN C++ borland

main(){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: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

main(){

int n;

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

}

TTRABAJORABAJO P PRÁCTICORÁCTICO DEDE E ESTRUCTURASSTRUCTURAS DEDE C CONTROLONTROL

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.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 divididos en cuatro categorías:

Valores< 1000

1000 – 20002001 – 3000

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

Page 24: PROGRAMACIÓN I EN C++ borland

> 30006) 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 A80 – 89 B70 –79 C60 – 69 D0 – 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 obtenga 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órmula:

E = c * m2 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 cuando 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órmula:

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:

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 negativo.12) Dado el nombre o número de un mes y si el año es o no bisiesto, deducir el número de días del mes.13) Sumar los números enteros de 1 a 100 mediante:

a) estructura repetir; b) estructura mientras; c) estructura desde.

14) Determinar la media de una lista de números positivos terminada con un número no positivo despué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 negativos.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 posible 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ínima, el número de errores -temperaturas de 0°- y el porcentaje que representaban.

21) Calcular:

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

Page 25: PROGRAMACIÓN I EN C++ borland

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) = 1Fibonacci (2) = 1Fibonacci (3) = 2 = Fibonacci(2) + Fibonacci(l)Fibonacci (4) = 3 = Fibonacci(2) + Fibonacci(3)

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

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

A1 = 1 A2 = 1 A3 = 1 + 1 = Al + A2 An = An-1 + An-2 (n>=3)23) Se pretende leer todos los empleados de una empresa situados en un archivo empresa y a la terminació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 jornal 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 correspondiente 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 ... 152* 2 4 6 8 ... 303* 3 6 9 12 ... 454* 4 8 12 16 ... 60

15* 15 30 45 60 ... 22530) Dado un entero positivo n(> T), comprobar si es primo o compuesto.

FUNCIONES FUNCIONES ENEN CC++++

Al incrementarse el tamaño y la complejidad de los programas, es muy recomendable dividirlos en partes 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 funcionesCada 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 estrado utilizando:

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

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

Page 26: PROGRAMACIÓN I EN C++ borland

{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.Después que se termina de ejecutar la última declaración de la función, la ejecución del programa continúa en la primera declaración que sigue a la llamada de función.Veamos un programa ejemplo: FUNCION.CPP

#include <iostream.h>

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úmero MAYOR es: " << mayor; cout << "\nEl número MENOR es: " << menor;}

main(){ cout << "Ahora se llamará a la funció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ó al programa principal.";}

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éntesis, 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 FUNCION2.CPP:

#include <iostream.h>

int sumar_valores(int a, int b){ int resultado = a + b;

return (resultado);}

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

(3)

(3)

(7)

(11)

(13)

(20)

(22)

Page 27: PROGRAMACIÓN I EN C++ borland

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

main(){ int x,y;

cout << "El programa le pedirá que ingrese dos números enteros. "; cout << "\n\nIngrese el primer número: "; cin >> x; cout << "\nIngrese el segundo número: "; cin >> y;

cout << "\n\nLa suma de los números es : " << sumar_valores(x,y); cout << "\nEl promedio es: " << promedio(x,y);}

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 simplificar 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 PROTOTIPOSExaminemos el archivo PROTIPO1.CPP

#include <iostream.h>

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

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

relleno(3, 12.0, 4); relleno(brazo, pie, ojo);}

void relleno(int alas, float pies, char ojos){ cout << "Hay " << alas << " alas." << "\n";

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

(27)(28)

(3)

(11)(12)

(15)

Page 28: PROGRAMACIÓN I EN C++ borland

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

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 prototipo proporciona información sobre el tipo devuelto o producido por la función, así como sobre sus pará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 comprobació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 aparentemente buenas, pero el programa puede hacer algunas cosas extrañas cuando se ejecute.

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 prototipo. Los nombres de las variables dadas en el prototipo son optativos y actúan meramente como comentarios 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úmero 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 COMPATIBLESUn 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á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 porque los valores son completamente diferentes.La compatibilidad de tipos discutida anteriormente en este manual se aplica igualmente a la compatibilidad de tipos cuando se hacen llamados a una función. Además, el tipo especificado como el tipo de regreso 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 escribiendo 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 requerirá que la función concuerde con un prototipo, pero el compilador no lo encontrará.

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

(19)

Page 29: PROGRAMACIÓN I EN C++ borland

UN POCO MAS SOBRE PROTOTIPOSVeamos el ejemplo de programa llamado PROTIPO2.CPP

#include <iostream.h>

void relleno(int, float, char);

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

relleno(3, 12.0, 67); relleno(brazo, pie, ojo);}

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 " << 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ámetros 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.

¿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 REFERENCIAExaminemos el archivo PASREF.CPP para un ejemplo de un pase por referencia:

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

void violin(int in1, int &in2);

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

cout << "Los valores son "; printf("%3d %3d\n", cont, ind);

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

(4)

Page 30: PROGRAMACIÓN I EN C++ borland

violin(cont, ind);

cout << "Los valores son "; printf("%3d %3d\n", cont, ind);}

void violin(int in1, int &in2){ in1 = in1 + 100; in2 = in2 + 100; cout << "Los valores son "; printf("%3d %3d\n", in1, in2);}

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 retornar 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 sinónimo para la variable “ind” en el programa principal, hace referencia a ella. En cambio, la otra variable 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 principal (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 DEFECTOVeamos el programa PARAMET.CPP como un ejemplo del uso de parámetros por defecto:

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

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

main(){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";

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

(16)

(21)

(24)

(10)(11)(12)

Page 31: PROGRAMACIÓN I EN C++ borland

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"; }

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ámetros 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 funció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 defecto para el tercer parámetro y el sistema trabajará como si se hubiera llamado a la función con volumen(x, y, 3), ya que el valor por defecto para el tercer parámetro es 3. En la línea 12, se especifica únicamente un parámetro, que se usará para el primer parámetro formal, y faltarán los otros dos. El sistema 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 pará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 prototipo 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 verificar 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 inicialmente desde la derecha. Pero cuando se evalúa cualquier función, los datos se analizan de izquierda a derecha.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". Finalmente, 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 declaraciones que hacen que la impresión aparezca en el orden esperado.

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

(14)(15)(16)(17)

Page 32: PROGRAMACIÓN I EN C++ borland

NUMERO VARIABLE DE ARGUMENTOSEl programa VARARGS.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 requeridovoid mostrar_var(int numero, ...);

main(){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 disponibles 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 nosotros. 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úmero 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 asegurarse 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 enun 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 FUNCIONESEn C++, dos o más funciones pueden compartir el mismo nombre, siempre y cuando sus declaraciones de parámetros sean diferentes.

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

(5)

Page 33: PROGRAMACIÓN I EN C++ borland

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 SOB_FUNC.CPP es un ejemplo de funciones sobrecargadas, que es una de las claves de la programación orientada a objetos.

#include <iostream.h>

overload relleno; // Esto es opcional

int relleno(const int); // Cuadrado de un númeroint relleno(float); // Triple de un float y retorna intfloat relleno(const float, float); // Promedio de dos float

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

cout << "El cuadrado de 12 es " << relleno(ind) << "\n"; cout << "El cuadrado de 24 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";}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 floatfloat 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 comenzará 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á. Solamente 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.

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

(3)

(22)

(27)

(33)

Page 34: PROGRAMACIÓN I EN C++ borland

La selección de que función se llamará realmente no resta tiempo de ejecución ni compilación. Si se pusieran 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 programador cambie accidentalmente el parámetro formal dentro de la función. En funciones tan cortas como éstas 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 programa.

RECURSIVIDADEn 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. Para que en lenguaje de computadora sea recursivo, una función debe ser capaz de llamarse a sí misma. Un sencillo ejemplo es la función fact(), que calcula el factorial de un entero. El factorial de un número N es el producto de todos los número entre 1 y N. Por ejemplo, el factorial de 3 es 1 x 2 x 3, ó 6. a continuación se muestra fact() y su equivalente iterativa en FACT.CPP:

Long unsigned int fact(int n) /* recursiva */{

long unsigned int resp;if(n==1) return(1);resp = fact(n--)*n;return (resp);

}

long unsigned int factiter(int n);{

long unsigned int t, resp;resp=1;for(t=1; t<n; t++)

resp = resp * t;return (resp);

}

La versión no recursiva de factiter() debe estar clara. Utiliza un bucle que empieza en 1 y termina en n y que progresivamente multiplica cada número por el producto móvil.La operación de la recursiva fact() es un poco más compleja. Cuando se llama a fact() con un argumento de 1, la función devuelve 1. En otro caso, devuelve el producto fact(n-1)*n. Para evaluar esta expresión se llama a fact() con n-1. Esto ocurre hasta que n es igual a 1 y las llamadas a la función empiezan a volver.Al calcular el factorial de 2, la primera llamada a fact() produce una segunda llamada con argumento de 1. Esta llamada devuelve 1, que se multiplica entonces por 2 (el valor original de n). La respuesta, entonces, es 2. (Puede encontrar interesante incluir sentencias cout en fact() para ver el nivel de cada llamada y cuales son las respuestas intermedias.)Cuando la función se llama a sí misma, se asigna un espacio en la pila para las nuevas variables locales y parámetros, y el código de la función se ejecuta con estas nuevas variables desde el principio. Una llamada recursiva no hace una nueva copia de la función. Sólo son nuevos los argumentos. Al volver de una llamada recursiva se recuperan de la pila las variables locales y los parámetros antiguos, y la ejecución se reanuda en el punto de la llamada a la función dentro de la función. Podría decirse que las funciones recursivas tienen un efecto “telescópico” que las lleva fura y dentro de sí mismas.

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

Page 35: PROGRAMACIÓN I EN C++ borland

La mayoría de las rutinas recursivas no minimizan significativamente el tamaño del código ni ahorran espacio de memoria. Además, las versiones recursivas de la mayoría de las rutinas se ejecutan un poco más despacio que sus versiones iterativas equivalentes, debido a las repetidas llamadas a la función. De hecho, muchas llamadas recursivas a una función pueden hacer que se desborde la pila. Debido a que el almacenamiento de los parámetros de la función y de las variables locales se hace en la pila y cada nueva llamada crea una copia de estas variables, es posible que la pila sobrescriba algún otro dato o la memoria del programa. Sin embargo, lo más probable es que no haya que preocuparse de esto, a menos que una función recursiva pierda el control.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 parece 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.

EJERCICIOS DE PROGRAMACIÓN1. Cambiar el tipo de “alas” a float en el prototipo de PROTIPO1.CPP para que disienta con la definició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. Compilar 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 nombre único. Comparar el tamaño del archivo ejecutable resultante con el que dio el programa original.

TTRABAJORABAJO P PRÁCTICORÁCTICO DEDE F FUNCIONESUNCIONES1. 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 1.0003. 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

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

Page 36: PROGRAMACIÓN I EN C++ borland

3/9/05

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

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

Y = r * sen () (función Y)

9. Escribir una función Salario que calcule los salarios de un trabajador para un número dado de horas 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.

12. Escribir una función que tenga un argumento de tipo entero y que devuelva la letra P si el número 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 dad 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, Redondeo (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.

ARREGLOSARREGLOS YY CADENASCADENAS

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 arregloAl 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 contenga 100 valores del tipo int. Cada valor es un elemento del arreglo.

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

Page 37: PROGRAMACIÓN I EN C++ borland

Cómo utilizar los elementos de un arregloVeamos el programa ARREGLO.CPP:

#include <iostream.h>

main(){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];

}

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 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, ARREGLO2.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 último elemento del arreglo):

#include <iostream.h>

main(){int valores[5]; // Declaración del arregloint 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] << ' ';

}

Cada vez que el bucle for incrementa a la variable “i”, el programa imprime el siguiente elemento del arreglo.

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

Page 38: PROGRAMACIÓN I EN C++ borland

Inicializar un arreglo en la declaraciónComo 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 suficiente memoria para que contenga el número de valores especificados, por ejemplo, la siguiente declaración crea un arreglo capaz de guardar cuatro valores enteros:

int numeros[ ] = {1, 2, 3, 4 };

Las funciones trabajan con arreglosUna 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 ARR_FUN.CPP pasa los arreglos a la función “mostrar_arreglo”, que presenta los valores por pantalla:

#include <iostream.h>

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

main(){

int nros_chicos[5] = {1, 2, 3, 4, 5};int nros_grandes[3] = {1000, 2000, 3000};

mostrar_arreglo(nros_chicos, 5);mostrar_arreglo(nros_grandes, 3);

}

El programa anterior simplemente pasa el arreglo a la función por medio del nombre. El siguiente programa, TRAERARR.CPP, utiliza la función “traer_valores” para asignar tres valores al arreglo “numeros”:

#include <iostream.h>

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

main(){

int numeros[3];int i;

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

Parámetro arreglo

Page 39: PROGRAMACIÓN I EN C++ borland

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

for (i=0; i < 3; i++) cout << numeros[i] << ' ';

}

ARREGLOS MULTIDIMENSIONALES

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

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

main(){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 }}

La variable “arr1” es un arreglo de 8x8, que contiene 8 veces 8, o 64 elementos en total. El primer elemento 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 sumar, 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 asignación. El tercer mandato de asignación es en realidad “arr1[5][5] = 177”, porque cada uno de los subí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 sobrepasarlo. El contenido total de la matriz “arr1” se imprime por pantalla, en forma de cuadrado, con lo cual podemos comprobar por los valores si el programa hace lo que imaginábamos.

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

(18)

Page 40: PROGRAMACIÓN I EN C++ borland

Declaración de una cadena de caracteresLas cadenas de caracteres almacenan información tal como nombres de archivos, títulos de libros, nombres de empleados, y otras combinaciones de caracteres. C++ guarda las cadenas de caracteres en un arreglo del tipo char que termina con un caracter 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 siguiente declaración crea un nombre de variable de cadenas de caracteres “nombre_archivo” capaz de almacenar 13 caracteres (el caracter 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 caracter NULL (NULO), que C++ representa con el caracter especial “ \0”. Cuando se asignan caracteres a la cadena, se debe poner el caracter null después del último elemento. Por ejemplo, el programa ALFABETO.CPP, asigna las letras de la A a la Z a la variable “alfabeto” utilizando un ciclo for:

#include <iostream.h>

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

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

alfabeto[i] = NULL;cout << "Las letras son: " << alfabeto;}

Como puede verse, en la línea 13, el programa asigna el caracter NULL a la cadena para indicar el último caracter de la misma.Cuando el operador cout presenta la cadena, muestra los caracteres hasta llegar al nulo.

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 embargo, 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 caracter NULL a una cadena constante). Por lo tanto, el compilador asignará dos bytes para guardar esta cadena.

Cómo inicializar una cadena de caracteresPara 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++”;

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

(10)

(13)

Page 41: PROGRAMACIÓN I EN C++ borland

Cadenas y funcionesComo en el caso de cualquier arreglo, para trabajar con una cadena en una función, simplemente debemos especificar el tipo de arreglo (char). No se tiene que especificar el tamaño de la cadena. Por ejemplo, en el programa SHOW_CAD.CPP, se utiliza la función “mostrar_cadena” para mostrar por pantalla una cadena de caracteres:#include <iostream.h>

void mostrar_cadena(char cadena[]){ cout << cadena;}

main(){

mostrar_cadena("Cadena de caracteres: ");mostrar_cadena("Una cadena es un arreglo de tipo char.");

}

Como ya sabemos, C++ utiliza el caracter NULL para indicar el final de una cadena. A continuación veremos el programa LONG_CAD.CPP, que contiene una función que busca el caracter NULL para determinar 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 <iostream.h>

int long_cadena(char cadena[]){ int i; for (i = 0; cadena[i] != '\0'; i++); // Establece un ciclo

// buscando el siguiente caracter

return(i); // Longitud de la cadena}

main(){

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.";

}

La biblioteca string.hEl 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 programa STRING.CPP ilustra el empleo de las dos primeras:

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

Page 42: PROGRAMACIÓN I EN C++ borland

#include <iostream.h>#include <string.h>

main(){

char titulo[] = "Aprenda C++";char capitulo[] = "Arreglos y Cadenas";

cout << "Mayúsculas: " << strupr(titulo);cout << "\n\nMinúsculas: " << strlwr(capitulo);

}

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

#include <iostream.h>#include <stdio.h>#include <string.h>

main(){char nombre1[12],nombre2[12],cadena[25];char titulo[20];

strcpy(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éticamente es %s\n",cadena);

strcpy(cadena,nombre1); strcat(cadena," "); strcat(cadena,nombre2); printf("Ambos nombres son %s\n",cadena);}

Primero se definen 4 cadenas. Después, en la línea 10, se utiliza una función de nombre “strcpy”, funció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 siguiente 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 primera 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 sorprendernos 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.

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

(10)

(18)

(26)

Page 43: PROGRAMACIÓN I EN C++ borland

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 cuidado de eliminar el NULL intermedio. En este caso, “nombre1” es copiado en “cadena” en la línea anterior, luego se concatenan los 2 blancos, y finalmente la combinación se concatena con “nombre2”. El resultado se imprime, con los dos nombres en “cadena”.

EJERCICIOS DE PROGRAMACIÓN1. 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 veces.

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 = 122. 4 + 20 = 243. 6 + 30 = 36etc.

Advertencia: el comando de impresión puede tomar la siguiente forma:printf("%4d %4d + %4d =%4d\n",indice,arr1[indice],arr2[indice],arreglo[indice];

TTRABAJORABAJO P PRÁCTICORÁCTICO DEDE A ARREGLOSRREGLOS1. 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 comprendidos 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 63 5 74 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 considerar 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 elementosB p * n elementos

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

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

Page 44: PROGRAMACIÓN I EN C++ borland

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 3 por 3 elementos y calcular la suma de cada una de sus

filas y columnas, dejando 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 elementos.

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 CARACAS, 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 anulaciones imprevistas de reservas.

13. Cada alumno de una clase de licenciatura en Ciencias de la Computación tiene notas correspondientes a ocho asignaturas diferentes, pudiendo no tener calificación en alguna asignatura. A cada asignatura 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. Escribir 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 momento se abrirá la lista de espera.

18. Calcular las medias de las estaturas de una clase. Deducir cuántos son

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

Page 45: PROGRAMACIÓN I EN C++ borland

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 11 2 1

1 3 3 11 4 6 4 1

1 5 10 10 5 11 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 cuantos 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.

EESTRUCTURASSTRUCTURAS YY U UNIONESNIONES

Enumeración de tipos

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

#include <iostream.h>

enum resultado {gana, pierde, ata, cancela};

main(){

Programación C++ Ing. Helmut Heinz Dehner Página 45 de 57(7)(8)

Page 46: PROGRAMACIÓN I EN C++ borland

resultado result;enum resultado omit = cancela;

for (result = gana;result <= cancela;result++) { if (result == omit) cout << "El juego ha sido cancelado\n"; else {

cout << "Se ha jugado "; if (result == gana) cout << "y nosotros ganamos!"; if (result == pierde) cout << "y nosotros perdimos."; cout << "\n"; } }}

En el programa ejemplo se usa la palabra enum en la línea 8, pero se la omite en la línea 7 para ilustrar que es optativo.

¿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 estructura es una combinación de varios datos definidos previamente, incluyendo otras estructuras ya definidas. 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: STRUCT1.C

main(){

struct { char initial; /* inicial del 2o.nombre */ int age; /* edad */ int grade; /* curso escolar */ } boy,girl;

boy.initial = 'R'; boy.age = 15; boy.grade = 75;

girl.age = boy.age - 1; /* ella es un año menor */ girl.grade = 82; girl.initial = 'H';

printf("%c tiene %d años y un grado escolar de %d\n", girl.initial, girl.age, girl.grade);

printf("%c tiene %d años y un grado escolar de %d\n", boy.initial, boy.age, boy.grade);}

El programa empieza con la definición de una estructura. La palabra clave "struct" es precedida por

algunas variables simples entre llaves, las cuales son componentes de la estructura . Después de la llave de cierre

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

Page 47: PROGRAMACIÓN I EN C++ borland

encontramos dos variables listadas, de nombre "boy" y "girl". De acuerdo con la definición dada anteriormente, "boy" es ahora una variable compuesta de 3 elementos, "initial", "age" y "grade". 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 3 campos asociados con los mismos nombres que para "boy", pero son variables distintas. Hemos definido por tanto, 6 variables.

UNA VARIABLE COMPUESTAExaminemos 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 cualquier zona de programa que necesite una variable "int" en, por ejemplo, cálculos, contadores, operaciones de E/S, etc. El único problema que tenemos es en como 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 estructura "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 VARIABLESDe acuerdo con la definición anterior, podemos asignar valores a cada una de las 3 variables asociadas a

"boy", y a cada uno de los 3 componentes de "girl". "boy.initial" es un valor tipo "char", porque 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 distinto, 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 RESULTANTESAhora 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 escritura y la comprensión del programa.

ESTRUCTURA DE ARRAYSSTRUCT2.C

main(){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;

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

Page 48: PROGRAMACIÓN I EN C++ borland

}

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);}

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.

En las siguientes instrucciones del programa asignamos nuevos valores a algunos de los componentes, 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 NOMBRELas 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.NESTED.C

#include <string.h>main(){ struct person { char name[25]; int age; char status; /* M = casado, S = soltero */ } ;

struct alldat { int grade; struct 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");

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

Page 49: PROGRAMACIÓN I EN C++ borland

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;}

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ácilmente como manejamos tipos "int", "char" o cualquier otro tipo existente en C. La única condición que conlleva 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 estructura 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 estructura se le da otro nombre, "alldat" que además constituye un nuevo tipo de variable. Finalmente definimos 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 almacenar un valor.

Ya que hemos creado un nuevo tipo de variable, usémoslo para definir 2 variables más. Las variables "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 "teacher". 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 estén compuestas de varias partes.

A la variable "sub" le son asignados valores sin sentido de muchas formas, pero en diferente orden, 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. Ninguno de los valores se muestra en la pantalla dado que ya lo hicimos con varios en los últimos ejemplos.

MÁS ACERCA DE LAS ESTRUCTURASEs 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áquina se aclara perfectamente. Además, se pueden incluir tantas estructuras como se desee en un nivel de estructura, como por

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

Page 50: PROGRAMACIÓN I EN C++ borland

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?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.

UNION1.C

main(){union {int value; /*primera parte de la unión*/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 ); } }

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 segundo elemento está constituido por 2 variables tipo caracter, "first" y "second". Estas variables se almacenan en la misma localización que "value", porque esto es lo que hace una unión. Permite almacenar datos de diferentes tipo en un mismo espacio físico. En este caso, podría ponerse un entero en "value", y recobrarlo luego en dos mitades, ubicadas en "first" y "second". Esta técnica se utiliza habitualmente para empaquetar bytes de datos cuando, por ejemplo, se están combinando datos para ser utilizados 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 variables "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 variables enteras y la asignación de variables "char" a ellas.

OTRO EJEMPLO DE UNIÓNSupongamos que se desea hacer una gran base de datos, incluyendo información de algunos tipos 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ículo, 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:

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

Page 51: PROGRAMACIÓN I EN C++ borland

UNION2.C

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

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

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 deposito 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 */

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

Page 52: PROGRAMACIÓN I EN C++ borland

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

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 confusión. No definimos variables, por ahora.

TTRABAJORABAJO P PRÁCTICORÁCTICO DEDE E ESTRUCTURASSTRUCTURAS1) 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)

2) Escribir un programa que acepte la hora del día en formato militar (0845) y encuentre la representación usual

en horas y minutos y AM/PM (8:45 AM) o acepte el formato usual y encuentre la correspondiente representación militar:

0100 se representa por 1:00 AM3:45 PM se representa por 1545

3) Escribir una declaración de un registro para cuatro figuras geométricas: triángulo, rectángulo, cuadrado, y círculo. Para el triángulo se deben almacenar las longitudes de sus tres lados; para el rectá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írculo), 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 operaciones básicas con números complejos son:

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

Page 53: PROGRAMACIÓN I EN C++ borland

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 procedimientos 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 Segundos. 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 procedimientos / 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 estructura 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.

8) El inventario de un almacén de artículos deportivos se desea guardar en un array estructurado. Artículos con los campos: nombre, número de código (seis dígitos), número de artículos y precio. Escribir 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 tambié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 ordenació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 opciones: 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, fecha última visita, si es o no privado (no tiene seguridad social), si tiene alergias, y un campo de observaciones. 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 C++ Ing. Helmut Heinz Dehner Página 53 de 57

Page 54: PROGRAMACIÓN I EN C++ borland

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

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

Consideraciones Generales------------------------------------------------------------------------------------------------2

Un programa sencillo-------------------------------------------------------------------------------------------------------3

La declaración #include---------------------------------------------------------------------------------------------------4

La consola---------------------------------------------------------------------------------------------------------------------4

El operador cout-------------------------------------------------------------------------------------------------------------4

IDENTIFICADORES------------------------------------------------------------------------------------------------------5

Declaración de variables---------------------------------------------------------------------------------------------------5

COMO HACER COMENTARIOS-------------------------------------------------------------------------------------6

EJERCICIOS DE PROGRAMACIÓN:--------------------------------------------------------------------------------6

EL PROGRAMA TOMA DECISIONES-------------------------------------------------------------------6

EL BUCLE WHILE--------------------------------------------------------------------------------------------------------6

EL BUCLE DO-WHILE---------------------------------------------------------------------------------------------------7

EL BUCLE FOR------------------------------------------------------------------------------------------------------------7

EL CONDICIONAL IF----------------------------------------------------------------------------------------------------8

IF-ELSE-----------------------------------------------------------------------------------------------------------------------9

BREAK y CONTINUE-----------------------------------------------------------------------------------------------------9

LA INSTRUCCIÓN SWITCH-------------------------------------------------------------------------------------------9

EJERCICIOS DE PROGRAMACIÓN:------------------------------------------------------------------------------10

ASIGNACIONES Y COMPARACIONES LÓGICAS------------------------------------------------10

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

MANDATOS DE ASIGNACIÓN DE ENTEROS------------------------------------------------------------------12

El operador cin-------------------------------------------------------------------------------------------------------------12

COMPARACIONES LÓGICAS---------------------------------------------------------------------------------------13

CONCEPTOS ADICIONALES SOBRE COMPARACIÓN-----------------------------------------------------14

EVALUACIÓN LÓGICA-----------------------------------------------------------------------------------------------15

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

Page 55: PROGRAMACIÓN I EN C++ borland

ÁREAS POTENCIALES DE PROBLEMAS------------------------------------------------------------------------15

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

LA EXPRESIÓN CONDICIONAL------------------------------------------------------------------------------------16

Las palabras const y volatile---------------------------------------------------------------------------------------------17

EL OPERADOR DE ALCANCE--------------------------------------------------------------------------------------17

DEFINICIÓN DE VARIABLES---------------------------------------------------------------------------------------18

VARIABLE DE REFERENCIA----------------------------------------------------------------------------------------18

DECLARACIONES EJECUTABLES--------------------------------------------------------------------------------19

Definición y declaración--------------------------------------------------------------------------------------------------19

Las variables En EL BUCLE for---------------------------------------------------------------------------------------19

Salida Con formato--------------------------------------------------------------------------------------------------------19

EJERCICIOS DE PROGRAMACIÓN-------------------------------------------------------------------------------21

DEFINES Y MACROS---------------------------------------------------------------------------------------21

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

¿ESTO ES ÚTIL?---------------------------------------------------------------------------------------------------------22

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

UN MACRO INCORRECTO-------------------------------------------------------------------------------------------22

EJERCICIOS DE PROGRAMACIÓN:------------------------------------------------------------------23

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

FUNCIONES EN C++---------------------------------------------------------------------------------------25

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

LOS PROTOTIPOS------------------------------------------------------------------------------------------------------27

LOS TIPOS COMPATIBLES------------------------------------------------------------------------------------------28

¿COMO TRABAJA UN PROTOTIPO?-----------------------------------------------------------------------------28

UN POCO MAS SOBRE PROTOTIPOS----------------------------------------------------------------------------28

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

PASE POR REFERENCIA----------------------------------------------------------------------------------------------29

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

Page 56: PROGRAMACIÓN I EN C++ borland

PARÁMETROS POR DEFECTO-------------------------------------------------------------------------------------30

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

NUMERO VARIABLE DE ARGUMENTOS-----------------------------------------------------------------------31

SOBRECARGA DE FUNCIONES------------------------------------------------------------------------------------32

RECURSIVIDAD----------------------------------------------------------------------------------------------------------34

EJERCICIOS DE PROGRAMACIÓN-------------------------------------------------------------------------------35

TRABAJO PRÁCTICO DE FUNCIONES--------------------------------------------------------------35

ARREGLOS Y CADENAS---------------------------------------------------------------------------------36

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

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

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

Las funciones trabajan con arreglos-----------------------------------------------------------------------------------38

ARREGLOS MULTIDIMENSIONALES----------------------------------------------------------------------------39

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

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

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

Cadenas y funciones-------------------------------------------------------------------------------------------------------40

La biblioteca string.h-----------------------------------------------------------------------------------------------------41

SUBRUTINAS DE CADENAS-----------------------------------------------------------------------------------------42

EJERCICIOS DE PROGRAMACIÓN-------------------------------------------------------------------------------42

TRABAJO PRÁCTICO DE ARREGLOS---------------------------------------------------------------43

ESTRUCTURAS Y UNIONES-----------------------------------------------------------------------------45

Enumeración de tipos-----------------------------------------------------------------------------------------------------45

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

UNA VARIABLE COMPUESTA--------------------------------------------------------------------------------------47

ASIGNANDO VALORES A LAS VARIABLES--------------------------------------------------------------------47

COMO USAR LOS DATOS RESULTANTES----------------------------------------------------------------------47

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

Page 57: PROGRAMACIÓN I EN C++ borland

ESTRUCTURA DE ARRAYS------------------------------------------------------------------------------------------47

ESTRUCTURAS ANIDADAS Y CON NOMBRE-----------------------------------------------------------------48

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

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

OTRO EJEMPLO DE UNIÓN-----------------------------------------------------------------------------------------50

Trabajo Práctico de Estructuras---------------------------------------------------------------------------52

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