Manual de usuario - christian García

64
0 Manual de Usuario Laboratorio de Programación Ingeniero Elsner Boanerge González Ortega Chrisan Alexander García López

Transcript of Manual de usuario - christian García

Page 1: Manual de usuario - christian García

0

Manual de Usuario

Laboratorio de Programación

Ingeniero Elsner Boanerge González Ortega

Christian Alexander García López

Page 2: Manual de usuario - christian García

Contenido Variables y Constante....................................................................................................................................1

Constante...................................................................................................................................................2

Tipos de Datos Y Expresiones.........................................................................................................................3

VARIABLES DEL TIPO ENTERO.....................................................................................................................3

VARIABLES DE NUMERO REAL O PUNTO FLOTANTE....................................................................................4

VARIABLES DE TIPO CARACTER...................................................................................................................5

CONVERSION AUTOMATICA DE TIPOS........................................................................................................6

ENCLAVAMIENTO DE CONVERSIONES (casting)...........................................................................................7

Expresiones..............................................................................................................................................12

Arrays, arreglos o vectores en C++. Uso, declaración y sintaxis de los vectores en C++..................................14

¿Cómo declarar un Array o Vector en C++?...............................................................................................16

¿Cómo inicializar un Array o Vector en C++?.............................................................................................17

Particularidades de los Arrays, arreglos o Vectores en C++........................................................................18

Arreglos bidimensionales..........................................................................................................................19

Bibliotecas o librerías en C++. Declaración y uso de librerías. #Include en C++..............................................21

¿Qué son exactamente las librerías?.........................................................................................................21

Sintaxis para declarar Librerías en C++......................................................................................................22

¿Cómo declarar una librería en C++?.........................................................................................................25

Acerca del namespace std.........................................................................................................................25

Estructura....................................................................................................................................................27

Funciones en el interior de estructuras.....................................................................................................29

Inicialización de estructuras......................................................................................................................30

Asignación de estructuras.........................................................................................................................31

Arrays de estructuras................................................................................................................................33

Estructuras anidadas................................................................................................................................34

Estructuras anónimas...............................................................................................................................34

Operador sizeof con estructuras...............................................................................................................35

Ficheros........................................................................................................................................................370

Page 3: Manual de usuario - christian García

1

Laboratorio de Programación 1Manual de Usuario

1

APERTURA Y CIERRE DE FICHEROS............................................................................................................38

fichero = fopen ( nombre-fichero, modo);.................................................................................................38

LECTURA Y ESCRITURA EN FICHEROS........................................................................................................39

Lectura y escritura formateada de texto ( fscanf – fprintf )........................................................................41

Lectura y escritura de caracteres ( fgetc – fputc ) y cadenas ( fgets – fputs )..............................................42

RECORRIDO DE UN FICHERO SECUENCIAL (feof)........................................................................................43

feof (fichero).............................................................................................................................................44

ACCESO DIRECTO A LOS DATOS (fseek).....................................................................................................46

Entrada y Salida (Printf, scanf, cout y cin).....................................................................................................47

Funciones, métodos y procedimientos..........................................................................................................48

Funciones:................................................................................................................................................48

Métodos:..................................................................................................................................................48

Procedimientos:.......................................................................................................................................49

Declarando funciones...............................................................................................................................49

Argumentos o parámetros........................................................................................................................49

Consejos acerca de return.........................................................................................................................50

Ejemplos de funciones..............................................................................................................................50

Procedimientos........................................................................................................................................52

Invocando funciones y procedimientos en C++.........................................................................................52

Detalles para invocar funciones................................................................................................................53

Ejemplos de uso de funciones...................................................................................................................53

Ejercicios Resueltos en clases y propios........................................................................................................54

Anexos.........................................................................................................................................................62

Christian Alexander García López

Page 4: Manual de usuario - christian García

Variables y Constante Una variable, en realidad, no es más que un nombre para identificar una (o varias) posiciones de memoria donde el programa guarda los distintos valores de una misma entidad. Un programa debe DEFINIR a todas las variables que utilizará, antes de comenzar a usarlas, a fin de indicarle al compilador de que tipo serán, y por lo tanto cuanta memoria debe destinar para albergar a cada una de ellas.

Dentro del Main() definí las variables de tipos enteros y con números enteros con el “int”, seguido de un identificador(nombre) de la misma. Para definir una variable debe tener en cuenta:

Darles nombre que tengan un significado que luego permita una fácil lectura del programa.

Los identificadores deben comenzar con una letra ó con el símbolo de subrayado "_" , pudiendo continuar con cualquier otro caractér alfanumérico ó el símbolo "_" .

El lenguaje C es sensible al tipo de letra usado; así tomará como variables distintas a una llamada "variable”, de otra escrita como "VARIABLE". Es una convención entre los programadores de C escribir los nombres de las variables y las funciones con minúsculas, reservando las mayúsculas para las constantes.

Los compiladores reservan determinados términos ó palabras claves (Keywords) para el uso sintáctico del lenguaje, tales como: asm, auto, break, case, char, do, for, etc. Si bien estas palabras están definidas para el ANSI C, los distintos compiladores extienden esta definición a OTROS términos, por lo que es aconsejable leer la tabla completa de palabras reservadas del compilador que se vaya a usar, para no utilizarlas en nombres de variables.

1

Page 5: Manual de usuario - christian García

2

Laboratorio de Programación 1Manual de Usuario

2

El compilador dará como error de "Definición incorrecta" a la definición de variables con nombres del tipo de:

5dias $variable primer-variable !variable Horas laborada

ConstanteAquellos valores que una vez compilado el programa no pueden ser cambiados , como por ejemplo los valores literales que hemos usado hasta ahora en las inicializaciones de las variables (100 , 3 , 'a' , '\n' ), suelen denominarse CONSTANTES .

Como dichas constantes son guardadas en memoria de la manera que al compilador le resulta más eficiente suelen aparecer ciertos efectos secundarios, a veces desconcertantes , ya que las mismas son afectadas por las reglas de RECONVERSION AUTOMATICA DE TIPO vista previamente.

A fin de tener control sobre el tipo de las constantes, se aplican las siguientes reglas:

Una variable expresada como entera (sin parte decimal) es tomada como tal salvo que se la siga de las letras F ó L (mayúsculas ó minúsculas) ejemplos :

1 : tomada como ENTERA

1F : tomada como FLOAT

1L : tomada como LONG DOUBLE

Una variable con parte decimal es tomada siempre como DOUBLE, salvo que se la siga de la letra F ó L

1.0 : tomada como DOUBLE

1.0F : tomada como FLOAT

1.0L : tomada como LONG FLOAT

Si en cualquiera de los casos anteriores agregamos la letra U ó u la constante queda calificada como UNSIGNED (consiguiendo mayor alcance) :

1u : tomada como UNSIGNED INT

1.0UL : tomada como UNSIGNED LONG DOUBLE

Christian Alexander García López

Page 6: Manual de usuario - christian García

3

Laboratorio de Programación 1Manual de Usuario

3

Una variable numérica que comienza con "0" es tomado como OCTAL asi : 012 equivale a 10 unidades decimales

Una variable numérica que comienza con "0x" ó "0X" es tomada como hexadecimal : 0x16 equivale a 22 unidades decimales y 0x1A a 26 unidades decimales.

Tipos de Datos Y Expresiones

VARIABLES DEL TIPO ENTEROEn el ejemplo anterior definimos a las variables como enteros (int).

De acuerdo a la cantidad de bytes que reserve el compilador para este tipo de variable, queda determinado el "alcance" ó máximo valor que puede adoptar la misma.

Debido a que el tipo int ocupa dos bytes su alcance queda restringido al rango entre -32.768 y +32.767 (incluyendo 0 ).

En caso de necesitar un rango más amplio, puede definirse la variable como "long int nombre_de_variable" ó en forma más abreviada "long nombre_de_variable"

Declarada de esta manera, nombre_de_variable puede alcanzar valores entre - 2.347.483.648 y +2.347.483.647.

A la inversa, si se quisiera un alcance menor al de int, podría definirse "short int " ó simplemente "short", aunque por lo general, los compiladores modernos asignan a este tipo el mismo alcance que "int".

Debido a que la norma ANSI C no establece taxativamente la cantidad de bytes que ocupa cada tipo de variable, sino tan sólo que un "long" no ocupe menos memoria que un "int" y este no ocupe menos que un "short",los alcances de los mismos pueden variar de compilador en compilador , por lo que sugerimos que confirme los valores dados en este parágrafo (correspondientes al compilador de Borland C++) con los otorgados por su compilador favorito.

Para variables de muy pequeño valor puede usarse el tipo "char" cuyo alcance está restringido a -128, +127 y por lo general ocupa un único byte.

Todos los tipos citados hasta ahora pueden alojar valores positivos ó negativos y, aunque es redundante, esto puede explicitarse agregando el calificador "signed" delante; por ejemplo:

signed int

signed long

Christian Alexander García López

Page 7: Manual de usuario - christian García

4

Laboratorio de Programación 1Manual de Usuario

4

signed long int

signed short

signed short int

signed char

Si en cambio, tenemos una variable que sólo puede adoptar valores positivos (como por ejemplo la edad de una persona ) podemos aumentar el alcance de cualquiera de los tipos , restringiéndolos a que sólo representen valores sin signo por medio del calificador "unsigned" . En la TABLA 1 se resume los alcances de distintos tipos de variables enteras

NOTA: Si se omite el calificador delante del tipo de la variable entera, éste se adopta por omisión (default) como "signed".

VARIABLES DE NUMERO REAL O PUNTO FLOTANTEUn número real ó de punto flotante es aquel que además de una parte entera, posee fracciones de la unidad. En nuestra convención numérica solemos escribirlos de la siguiente manera : 2,3456, lamentablemente los compiladores usan la convención del PUNTO decimal (en vez de la coma) . Así el numero Pi se escribirá : 3.14159 Otro formato de escritura, normalmente aceptado, es la notación científica. Por ejemplo podrá escribirse 2.345E+02, equivalente a 2.345 * 100 ó 234.5

De acuerdo a su alcance hay tres tipos de variables de punto flotante , las mismas están descriptas en la TABLA 2

Las variables de punto flotante son SIEMPRE con signo, y en el caso que el exponente sea positivo puede obviarse el signo del mismo.

Christian Alexander García López

Page 8: Manual de usuario - christian García

5

Laboratorio de Programación 1Manual de Usuario

5

VARIABLES DE TIPO CARACTEREl lenguaje C guarda los caracteres como números de 8 bits de acuerdo a la norma ASCII extendida , que asigna a cada caracter un número comprendido entre 0 y 255 ( un byte de 8 bits) Es común entonces que las variables que vayan a alojar caracteres sean definidas como:

char c ;

Sin embargo, también funciona de manera correcta definirla como

int c ;

Esta última opción desperdicia un poco más de memoria que la anterior ,pero en algunos casos particulares presenta ciertas ventajas . Pongamos por caso una función que lee un archivo de texto ubicado en un disco. Dicho archivo puede tener cualquier caracter ASCII de valor comprendido entre 0 y 255. Para que la función pueda avisarme que el archivo ha finalizado deberá enviar un número NO comprendido entre 0 y 255 ( por lo general se usa el -1 , denominado EOF, fin de archivo ó End Of File), en este caso dicho número no puede ser mantenido en una variable del tipo char, ya que esta sólo puede guardar entre 0 y 255 si se la define unsigned ó no podria mantener los caracteres comprendidos entre 128 y 255 si se la define signed (ver TABLA 1). El problema se obvia facilmente definiéndola como int.

Las variables del tipo caractér también pueden ser inicializadas en su definición, por ejemplo es válido escribir:

char c = 97 ;

para que c contenga el valor ASCII de la letra "a", sin embargo esto resulta algo engorroso , ya que obliga a recordar dichos códigos . Existe una manera más directa de asignar un caractér a una variable ; la siguiente inicialización es idéntica a la anterior :

char c = 'a' ;

Es decir que si delimitamos un caracter con comilla simple , el compilador entenderá que debe suplantarlo por su correspondiente código numérico .

Lamentablemente existen una serie de caracteres que no son imprimibles , en otras palabras que cuando editemos nuestro programa fuente (archivo de texto) nos resultará difícil de asignarlas a una

Christian Alexander García López

Page 9: Manual de usuario - christian García

6

Laboratorio de Programación 1Manual de Usuario

6

variable ya que el editor las toma como un COMANDO y no como un caracter . Un caso típico sería el de "nueva linea" ó ENTER .

Con el fin de tener acceso a los mismos es que aparecen ciertas secuencias de escape convencionales. Las mismas estan listadas en la TABLA y su uso es idéntico al de los caracteres normales , asi para resolver el caso de una asignación de "nueva linea " se escribirá:

char c = '\n' ; /* secuencia de

escape */

CONVERSION AUTOMATICA DE TIPOSCuando dos ó mas tipos de variables distintas se encuentran DENTRO de una misma operación ó expresión matemática , ocurre una conversión automática del tipo de las variables. En todo momento de realizarse una operación se aplica la siguiente secuencia de reglas de conversión (previamente a la realización de dicha operación):

1) Las variables del tipo char ó short se convierten en int

2) Las variables del tipo float se convierten en double

3) Si alguno de los operandos es de mayor precisión que los demás , estos se convierten al tipo de aquel y el resultado es del mismo tipo.

4) Si no se aplica la regla anterior y un operando es del tipo unsigned el otro se convierte en unsigned y el resultado es de este tipo.

Christian Alexander García López

Page 10: Manual de usuario - christian García

7

Laboratorio de Programación 1Manual de Usuario

7

Las reglas 1 a 3 no presentan problemas, sólo nos dicen que previamente a realizar alguna operación las variables son promovidas a su instancia superior. Esto no implica que se haya cambiado la cantidad de memoria que las aloja en forma permanente

Otro tipo de regla se aplica para la conversión en las asignaciones.

Si definimos los términos de una asignación como,"lvalue" a la variable a la izquierda del signo igual y "rvalue" a la expresión a la derecha del mismo, es decir:

"lvalue" = "rvalue" ;

Posteriormente al cálculo del resultado de "rvalue" (de acuerdo con las reglas antes descriptas), el tipo de este se iguala al del "lvalue". El resultado no se verá afectado si el tipo de "lvalue" es igual ó superior al del "rvalue", en caso contrario se efectuará un truncamiento ó redondeo, segun sea el caso.

Por ejemplo, el pasaje de float a int provoca el truncamiento de la parte fraccionaria, en cambio de double a float se hace por redondeo.

ENCLAVAMIENTO DE CONVERSIONES (casting)Las conversiones automáticas pueden ser controladas a gusto por el programador, imponiendo el tipo de variable al resultado de una operación. Supongamos por ejemplo tener:

double d , e , f = 2.33 ;

int i = 6 ;

e = f * i ;

d = (int) ( f * i ) ;

En la primer sentencia calculamos el valor del producto (f * i) , que según lo visto anteriormente nos dará un double de valor 13.98 , el que se ha asignado a e. Si en la variable d quisiéramos reservar sólo el valor entero de dicha operación bastará con anteponer, encerrado entre paréntesis, el tipo deseado. Así en d se almacenará el número 13.00.

Christian Alexander García López

Page 11: Manual de usuario - christian García

8

Laboratorio de Programación 1Manual de Usuario

8

También es factible aplicar la fijación de tipo a una variable, por ejemplo obtendremos el mismo resultado, si hacemos:

d = (int) f * i ;

En este caso hemos convertido a f en un entero (truncando sus decimales )

Los casting entre tipo de datos, que si se pueden ejecutar son:

Ejemplo 1:

En la conversión de Double a Short :

Christian Alexander García López

Page 12: Manual de usuario - christian García

9

Laboratorio de Programación 1Manual de Usuario

9

En la conversión: x=(short)y;

La ‘x’ recibirá el nuevo valor de la conversión. (short) es el tipo de dato al que lo queremos convertir ‘y’ es el valor del doublé que es 23.34

El resultado será de:

Christian Alexander García López

Page 13: Manual de usuario - christian García

10

Laboratorio de Programación 1Manual de Usuario

10

Como podemos observar el valor de y= 23.43, paso a ser una variable de tipo short con un nuevo valor de: 23.

Christian Alexander García López

Page 14: Manual de usuario - christian García

11

Laboratorio de Programación 1Manual de Usuario

11

Ejemplo 2:

En la conversión de Char a Short

En la conversión: caracter=(char)x;

‘caracter’ recibirá el nuevo valor de la conversión.

(char) es el tipo de dato al que lo queremos convertir

‘x’ es el valor del short que es 100

El resultado será de:

Christian Alexander García López

Page 15: Manual de usuario - christian García

12

Laboratorio de Programación 1Manual de Usuario

12

El programa no compila o no se ejecuta porque los tipos de variables son incompatibles.

Nota : Pero si en dado caso queremos convertir una variable de tipo char a entero. El programa si compilara, tu introduces la letra y el compilador te devuelvo como resultado el valor de esa letra es código ASCII

ExpresionesUna expresión es una combinación de operadores y operando de cuya evaluación se obtiene un valor. Los operando pueden ser nombres que denoten objetos variables o constantes, funciones, literales de cualquier tipo adecuado de acuerdo con los operadores u otras expresiones más simples. La evaluación de una expresión da lugar a un valor de algún tipo, una expresión se dice que es del tipo de su resultado.

¿Qué expresiones aritméticas existen en C?

De la evaluación de una expresión aritmética siempre se obtiene un valor de tipo entero o real. En lenguaje C existen algunos operadores que no se utilizan en pseudocódigo, y al revés. A continuación, se van a ver algunas similitudes y diferencias entre ambos lenguajes.

Figura - Comparación entre operadores aritméticos en pseudocódigo y en C.

Como se puede apreciar, existen tres diferencias importantes entre los operadores aritméticos en pseudocódigo y en lenguaje C:

1. El operador potencia (**) no existe en lenguaje C.2. En lenguaje C, sólo existe un operador de división (/).3. En lenguaje C, el operador módulo (mod) se escribe con el carácter porcentaje (%).

Ejemplo: A partir de las variables:

En pseudocódigo:

Christian Alexander García López

Page 16: Manual de usuario - christian García

13

Laboratorio de Programación 1Manual de Usuario

13

entero a = 4, b = 7, c = 2

En lenguaje C:

int a = 4, b = 7, c = 2;

podemos escribir, por ejemplo, la expresión:

En pseudocódigo:

-a * ( b mod c )

En lenguaje C:

-a * ( b % c )

De la evaluación de esta expresión se obtiene el valor

-4 (actúan en orden los operadores: (%), menos (-) y (*))

Las expresiones se evalúan de acuerdo con la precedencia de los operadores. Ante una secuencia de operadores de igual precedencia, la evaluación se realiza según el orden de escritura, de izquierda a derecha. El orden de evaluación puede modificarse usando paréntesis.

Arrays, arreglos o vectores en C++. Uso, declaración y sintaxis de los vectores en C++Un arreglo es un tipo de dato estructurado que almacena en una sola variable un conjunto limitado de datos

o elementos del mismo tipo. Asimismo, es un conjunto de localidades de memoria contiguas donde la direcciónmás baja corresponde al primer elemento y la dirección más alta al último. Por sí mismo, el nombre

del arreglo apunta a la dirección del primer elemento del arreglo. Los datos se llaman elementos del arreglo

y su posición se numera consecutivamente: 1, 2, 3…n. Un arreglo en lenguaje C inicia en la posición cero,

por lo tanto el i-ésimo elemento está en la posición i-1, es decir si el arreglo llamado a tiene n elementos, sus

nombres son a[0], a[1], ..., a[n-1]. El tipo de elementos almacenados en el arreglo puede ser cualquier tipo

de dato.

Christian Alexander García López

Page 17: Manual de usuario - christian García

14

Laboratorio de Programación 1Manual de Usuario

14

Para acceder a un elemento específico de un arreglo se usa un índice o subíndice.

Un arreglo se caracteriza por:

1. Ser una lista de un número finito de n elementos del mismo tipo.

2. Almacenar los elementos del arreglo en memoria contigua.

3. Tener un único nombre de variable que representa a todos los elementos y éstos se diferencian por un

índice o subíndice.

4. Acceder de manera directa o aleatoria a los elementos individuales del arreglo, por el nombre del arreglo

y el índice o subíndice.

Los arrays, arreglos o vectores forman parte de la amplia variedad de estructuras de datos que nos ofrece C++, siendo además una de las principales y más útiles estructuras que podremos tener como herramienta de programación. Los arrays, arreglos o vectores (como los quieras llamar), son utilizados para almacenar múltiples valores en una única variable. En un aspecto más profundo, los arrays, permiten almacenar muchos valores en posiciones de memoria continuas, lo cual permite acceder a un valor u otro de manera rápida y sencilla. Estos valores pueden ser números, letras o cualquier tipo de variable que deseemos incluso tipos de datos propios.

En múltiples ocasiones es necesario almacenar gran cantidad de información en una variable y a menudo sucede que no conocemos con exactitud la cantidad de datos que debemos almacenar, pero sabemos que sí sería más de uno, como por ejemplo almacenar las identificaciones de las personas ingresadas al sistema. Los arrays, arreglos o vectores son una estructura que nos permite solucionar este tipo de problemas.

Ejemplo de Arrays o Vectores en C++

Imaginemos que queremos crear un programa con el cual podamos de algún modo almacenar los títulos y los autores de diferentes libros. El usuario es el encargado de suministrar la información de cada libro, así entonces, dado que es el usuario quien lo hace, nosotros no tenemos manera alguna de saber cuántos libros va querer él ingresar por medio de nuestro programa. El caso principal es que queremos almacenar en la memoria el titulo y el autor de TODOS y cada uno de los libros. Entonces ¿cómo crees que podrías hacer esto? Con lo que sabemos hasta hora, se nos podrían ocurrir un par de cosas. Veamos:

Posible Solución 1: Sin usar vectores (errónea):

Christian Alexander García López

Page 18: Manual de usuario - christian García

15

Laboratorio de Programación 1Manual de Usuario

15

Podríamos pensar primero, "listo, está bien, es fácil, declaro una variable llamada titulo y otra autor, ambas de tipo string y se las pido al usuario", pues bien, esta solución digamos que nos permite almacenar la información del primer libro que el usuario ingrese, pero en cuanto desee ingresar otro libro ¿qué vamos a hacer?, si lo hacemos así, cuando el usuario ingrese la información para un nuevo libro, va a sobrescribir los valores anteriores y habremos perdido la información del primero, de manera que esta solución no es válida.

Posible Solución 2: Sin usar vectores o matrices (errónea):

Pensando un poco más en esto, se nos ocurre una forma de almacenar la información de cada libro, podríamos crear un par de variables distintas para cada libro. Pero de inmediato nos damos cuenta que si por ejemplo al usuario se le cruzara por la cabeza ingresa información para 10 libros tendríamos entonces ¡20 variables distintas!, 2 por cada libro, no es mucho, pero si se le ocurriera ingresar 1000 libros, ¿estarias dispuesto a declarar 2000 variables?. De modo que esta alternativa es incluso peor que la anterior y seguimos aún sin solucionar nuestro problema.

Posible Solución 3: Usando vectores o matrices (correcta):

Los arrays o los vectores han venido para ayudarnos en múltiples circunstancia similares a esta. Dado que un array, arreglo o vector es capaz de almacenar múltiples valores en una misma variable, tenemos el elemento perfecto para almacenar la información de todos los libros, podremos crear un vector de un tamaño cualquiera capaz de contener en sí los nombres de los autores y otro con los títulos de los libros o alternativamente podríamos crear una matriz de dos columnas que contenga en la primera columna los autores y en la segunda los títulos; ambas soluciones son válidas y vamos a ver ambas, usando vectores en esta sección y usando matrices en la sección de matrices.

Nota: En C++, a diferencia de algunos otros lenguajes de programación, los vectores y las matrices presentan un "inconveniente" con el tamaño. Es decir, no es posible crear de una manera sencilla un vector capaz de almacenar una cantidad de información indefinida, es necesario ingresar con antelación la cantidad de datos (tamaño) que el vector o la matriz tendrá…..

¿Cómo declarar un Array o Vector en C++?Para declarar un vector en C++, se deben seguir las mismas normas básicas que se siguen para declarar una variable cualquiera, con un pequeño cambio en la sintaxis. Para declarar un vector, arreglo o como lo quieras llamar, necesitaremos saber el tipo de los datos que irán al interior de este, es decir, serán número enteros, o numero decimales o cadenas de texto, etc. necesitamos también, como siempre, un nombre para el vector y un tamaño máximo. La sintaxis para declarar un vector en C++ es la siguiente:

tipo_de_dato nombre_del_vector[tamaño];

Christian Alexander García López

Page 19: Manual de usuario - christian García

16

Laboratorio de Programación 1Manual de Usuario

16

Para declarar un vector en C++, debemos definirle un tipo de los datos, sea entero, float, string, etc., debemos darle un nombre y al interior de los corchetes "[ ]" debemos poner el tamaño máximo que tendrá el vector, es decir la cantidad máxima de datos que podrá contener (recuerda que en C++ esto es necesario hacerlo). Veamos un ejemplo en el cual pondré la declaración de varios vectores de diferentes tipos y tamaños en C++

que representa cada línea del código anterior.

Línea 1: Esta línea contiene la declaración de un vector llamado my_vector1, el cual contendrá un máximo de 10 elementos de tipo entero.

Línea 2: Esta línea contiene la declaración de un vector llamado my_vector2, el cual contendrá un máximo de 25 elementos de tipo float.

Línea 3: Esta línea contiene la declaración de un vector llamado my_vector3, el cual contendrá un máximo de 500 elementos de tipo string.

Línea 4: Esta línea contiene la declaración de un vector llamado my_vector4, el cual contendrá un máximo de 1000 elementos de tipo booleano.

Línea 5: Esta línea contiene la declaración de un vector llamado my_vector5, el cual contendrá un máximo de 2 elementos de tipo char.

Ya que vimos cómo se declara un vector, vamos a ver cómo inicializarlo, es decir inicializar un vector en C++ o en otras palabras darle valores a un vector.

¿Cómo inicializar un Array o Vector en C++?En cuanto tenemos declarado un vector, es posible asignarle valores, evidentemente estos valores deben coincidir con el tipo de dato que le asignamos a dicho vector, no tendría sentido ingresar como valores de un vector cadenas de caracteres si el tipo de dato de dicho vector es numérico.

Formas distintas de inicializar un vector, todas son validas, ya es cuestión de nuestras necesidades y conocimientos determinar cuál es útil y en qué momento. Veamos entonces:

Forma 1 de declarar un Array o Vector en C++

Christian Alexander García López

Page 20: Manual de usuario - christian García

17

Laboratorio de Programación 1Manual de Usuario

17

string vector[5] = {"5", "hola", "2.7", "8,9", "adios"};

Aquí hemos declarado un vector de tipo string tamaño 5 y lo hemos inicializado con diferentes valores, es necesario notar que cada valor va entre comillas dobles "" puesto que son strings. El valor inicial corresponde a la casilla o índice 0 y tiene el valor de "5", el índice 1 el valor es "hola" y el índice 4 el valor es "adiós", es importante notar que el primer índice de n array o vector no es el UNO sino que es el CERO.

Forma 2 de declarar un Array o Vector en C++

int vector2[ ] = {1,2,3,4,10,9,80,70,19};

Aquí hemos declarado un vector de tipo int y no especificamos su tamaño, si el tamaño no se especifica entre los corchetes, el vector tendrá como tamaño el número de elementos incluidos en la llave, para este caso es 9.

Particularidades de los Arrays, arreglos o Vectores en C++Con C++, existen algunas particularidades, en cuanto a la declaración de vectores, que me parece importante destacara para que en momento de quizá caer en ellas comprender como podrían cambiar las cosas o básicamente en que consiste el error, veamos:

Particularidad 1 al momento de declarar o inicializar un Vector o Array en C++

int vector2[3];

vector2[3] = {1,5,10};

Dadas las características de C++, es fácil pensar que és factible crear o declarar un vector de un tamaño cualquiera y posteriormente inicializarlos de forma habitual como se muestra en este código, sin embargo hacer esto es un error, si declaramos un vector y no lo inicializamos inmediatamente, no es posible inicializarlo de la forma que hemos visto, es decir entre llaves cada valor, como en la línea 2 del código anterior. La única forma de inicializar el vector, o mejor dicho, darle valores a cada una de sus casillas, es hacerlo uno por uno, es decir darle un valor a la casilla cero a la uno y a la 2 (para un vector de tamaño 3). Por defecto, al declarar un vector sin ser inicializado, cada una de las casillas de este vector toma como valor el valor por defecto del tipo de variable, para el caso de los enteros (int) es -858993460. Así entonces para asignar valores a cada casilla lo hacemos así:

int vector2[3];

vector2[0] = 1;

vector2[1] = 3;

Christian Alexander García López

Page 21: Manual de usuario - christian García

18

Laboratorio de Programación 1Manual de Usuario

18

vector2[2] = 10;

Es importante notar en este código, que el número que va entre corchetes ya no indica tamaño (pues vector2 ya está declarado) sino que indica el índice o el numero de la casilla con la cual estaremos operando (recordemos que el primer índice es cero y no uno), en el código anterior, habíamos declarado un vector de tamaño 3, por lo cual debíamos asignar valores a los índices 0, 1 y 2.

Particularidad 2 al momento de declarar o inicializar un Vector o Array en C++

float vector3[5] = {10.5};

En C++ a la hora de inicializar un array, arreglo o Vector, estamos acostumbrados a que si inicializamos inmediatamente después de declarar el vector, debemos poner la misma cantidad de elementos al interior de las llaves de manera que corresponda con el tamaño del vector, pues bien, estos es lo más recomendable, sin embargo si ponemos una cantidad de elementos menor a la del tamaño real del vector, estamos queriendo decir que estos elementos toman los valores puestos entre las llaves y los demás serian cero, para el caso del código anterior el primer elemento (el del índice cero) va a tener un valor de 10.5 y los otros 4 elementos van a valer cero.

Ya tenemos claro cómo declarar un array o vector en C++, algunas características un tanto particulares de estos, sin embargo a un no sabemos cómo obtener los datos de un array, es decir una vez el array o vector este lleno con los elementos que queremos, como podemos obtener esa información y más aún, como obtener un valor específico dentro del array. Veámoslo:

Obtener el valor de una casilla específica en un array en C++

Es muy común el caso en el que tenemos un vector con una enorme cantidad de elementos, sin embargo de todos estos, solo nos interesa uno en especial y corremos con la suerte de saber cuál es su índice, sabiendo el índice de un elemento en un array es bastante sencillo obtener el valor de este:

float vector4[5] = {10.5, 5.1, 8.9, 10, 95.2}; //Array con 5 elementos

float numero5 = vector4[4]; //Para acceder al elemento 5, se usa el índice 4

float primerNumero = vector4[0]; //Para el primer elemento se usa el índice 0

Christian Alexander García López

Page 22: Manual de usuario - christian García

19

Laboratorio de Programación 1Manual de Usuario

19

Como podemos ver, para acceder a un valor específico conociendo el índice del elemento, solo basta con escribir dicho índice entre los corchetes "[ ]", recuerda que el índice comienza desde cero, así por lo tanto en un vector de 5 elementos (como el del ejemplo), el último elemento está en el índice 4 y el primer elemento del array en el índice 0.

Arreglos bidimensionalesSon arreglos con dos dimensiones, es decir tienen filas y columnas, los valores de la variable se llaman elementos, de la misma forma que en los arreglos unidimensionales y sus índices están compuesto por dos caracteres que indican posición. Para acceder a su elemento se debe poner su posición compuesta de los dos índices.

Por ejemplo para la matriz A y la posición en la fila 1 y la columna 2. Se debe poner A [1][2], denotándose que el primer índice indica la posición de la fila y el segundo la posición de la columna.

0 1 2 3 4 5 6 70123

Nota: todos los arreglos inician desde 0.

Christian Alexander García López

Page 23: Manual de usuario - christian García

20

Laboratorio de Programación 1Manual de Usuario

20

Bibliotecas o librerías en C++. Declaración y uso de librerías. #Include en C++

Junto con los compiladores de C y C++, se incluyen ciertos archivos llamados bibliotecas más comúnmente librerías. Las bibliotecas contienen el código objeto de muchos programas que permiten hacer cosas comunes, como leer el teclado, escribir en la pantalla, manejar números, realizar funciones matemáticas, etc.

Las bibliotecas están clasificadas por el tipo de trabajos que hacen, hay bibliotecas de entrada y salida, matemáticas, de manejo de memoria, de manejo de textos y como imaginarás existen muchísimas librerías disponibles y todas con una función específica.

Nota : Muchos personas consideran que el nombre adecuado es archivos de biblioteca, y están en lo correcto. Sin embargo, la mayoría llamamos a estos archivos librerías, y también me incluyo entre estos. El error proviene del nombre en inglés, que es library. Este término se traduce como biblioteca, y no como librería. De este modo a lo largo de esta sección las llamaré de cualquiera de las dos formas, para estar más claros.

Hay un conjunto de bibliotecas (o librerías) muy especiales, que se incluyen con todos los compiladores de C y de C++. Son las librerías (o bibliotecas) ANSI o estándar. También hay librerías que no son parte del estándar pero en esta sección sólo usaremos algunas bibliotecas (o librerías) ANSI.

Nota: Es muy útil las librerías, nos facilitan enormemente el trabajo de programar. Antes de hablar librerías y demás es necesario dominar algunos conceptos de fundamentación en general y otros temas importantes (ciclos, condicionales y demás) Ahora veamos algunas librerías y como es su sintaxis.

¿Qué son exactamente las librerías?En C++, se conoce como librerías (o bibliotecas) a cierto tipo de archivos que podemos importar o incluir en nuestro programa. Estos archivos contienen las especificaciones de diferentes funcionalidades ya construidas y utilizables que podremos agregar a nuestro programa, como por ejemplo leer del teclado o mostrar algo por pantalla entre muchas otras más.

Christian Alexander García López

Page 24: Manual de usuario - christian García

21

Laboratorio de Programación 1Manual de Usuario

21

Al poder incluir estas librerías con definiciones de diferentes funcionalidades podremos ahorrarnos gran cantidad de cosas, imaginemos por ejemplo que cada vez que necesitemos leer por teclado, debamos entonces crear una función que lo haga (algo realmente complejo), al poder contar con las librerías en C++, podremos hacer uso de una gran variedad de funciones que nos facilitaran la vida y aumentarán la modularidad de nuestros códigos.

Las librerías no son únicamente archivos externos creados por otros, también es posible crear nuestras propias librerías y utilizarlas en nuestros programas. Las librerías pueden tener varias extensiones diferentes, las más comunes son: .lib, .bpl, .a, .dll, .h y algunas más ya no tan comunes.

Nota: Las librearías son archivos (no siempre externos) que nos permiten llevar a cabo diferentes tareas sin necesidad de preocuparnos por cómo se hacen sino simplemente entender cómo usarlas. Las librearías en C++ permiten hacer nuestros programas más modulares y reutilizables, facilitando además crear programas con funcionalidades bastante complejas en unas pocas líneas de código.

Sintaxis para declarar Librerías en C++La declaración de librerías, tanto en C como en C++, se debe hacer al principio de todo nuestro código, antes de la declaración de cualquier función o línea de código, debemos indicarle al compilador que librerías usar, para el saber que términos estarán correctos en la escritura de nuestro código y cuáles no. La sintaxis es la siguiente: #include <nombre de la librería> o alternativamente #include "nombre de la librería". Cualquiera de las 2 formas es válida en C++ (no estoy seguro si en C sea válido), ten en cuenta que siempre el nombre de la librería debe ir entre " y " o entre < y >. En tu código puedes declarar todas las librerías que quieras aunque en realidad no tienen sentido declarar una librería que no vas a usar en tu programa, sin embargo no existe límite para esto.

A continuación algunas de las librerías de uso más común de C++ y que forman parte de las librerías estándar de este lenguaje.

fstream:

Flujos hacia/desde ficheros. Permite la manipulación de archivos desde el programar, tanto leer como escribir en ellos.

iosfwd:

Contiene declaraciones adelantadas de todas las plantillas de flujos y sus typedefs estándar. Por ejemplo ostream.

Christian Alexander García López

Page 25: Manual de usuario - christian García

22

Laboratorio de Programación 1Manual de Usuario

22

iostream:

Parte del a STL que contiene los algoritmos estándar, es quizá la más usada e importante (aunque no indispensable).

La biblioteca list:

Parte de la STL relativa a contenedores tipo list; listas doblemente enlazadas

math:

Contiene los prototipos de las funciones y otras definiciones para el uso y manipulación de funciones matemáticas.

memory:

Utilidades relativas a la gestión de memoria, incluyendo asignadores y punteros inteligentes (auto_ptr).

"auto_ptr" es una clase que conforma la librería memory y permite un fácil manejo de punteros y su destrucción automaticamente.

Biblioteca new:

Manejo de memoria dinámica

numeric:

Parte de la librería numérica de la STL relativa a operaciones numéricas.

ostream:

Algoritmos estándar para los flujos de salida.

queue:

Parte de la STL relativa a contenedores tipo queue (colas de objetos).

Librería stdio:

Contiene los prototipos de las funciones, macros, y tipos para manipular datos de entrada y salida.

Librería stdlib:

Contiene los prototipos de las funciones, macros, y tipos para utilidades de uso general.

string:

Christian Alexander García López

Page 26: Manual de usuario - christian García

23

Laboratorio de Programación 1Manual de Usuario

23

Parte de la STL relativa a contenedores tipo string; una generalización de las cadenas alfanuméricas para albergar cadenas de objetos. Muy útil para el fácil uso de las cadenas de caracteres, pues elimina muchas d elas dificultades que generan los char

typeinfo:

Mecanismo de identificación de tipos en tiempo de ejecución

vector:

Parte de la STL relativa a los contenedores tipo vector; una generalización de las matrices unidimensionales C/C++

forward_list

Esta librería es útil para implementar con gran facilidad listas enlazadas simples.

list

Permite implementar listas doblemente enlzadas (listas enlazadas dobles) facilmente.

iterator

Proporciona un conjunto de clases para iterar elementos.

regex

Proporciona fácil acceso al uso de expresiones regulares para la comparación de patrones.

thread

Útil para trabajar programación multihilos y crear múltiples hilos en nuestra aplicación.

Christian Alexander García López

Page 27: Manual de usuario - christian García

24

Laboratorio de Programación 1Manual de Usuario

24

¿Cómo declarar una librería en C++?Veamos a continuación como se haría la declaración de unas cuantas librerías conocidas, recuerda que ese pueden declarar todas las librerías necesarias y siempre debe hacerse al comienzo del código fuente

#include "iostream"

#include "string"

#include <math.h>

#include <conio.h>

using namespace std;

Con esto debió quedar claro, como declarar librerías C++ al interior de un código fuente. Lo único adicional, es la línea que dice using namespace std; esta línea nos ayuda a declarar un espacio de nombre que evita tener que usarlo cada que accedemos a alguna función específica de una librería. Teniendo este namespace declarado podemos llamar por ejemplo el comando cout >>, que pertenece a la librería iostream, sin embargo sin este namespace sería std::cout >>, imagina tener que hacer esto cada vez que uses algún comando o función de las librerías, sería bastante tedioso.

Acerca del namespace stdTodas las librerías estándar de C++ contienen una declaración del espacio de nombre std, es decir que todas las librerías que hacen parte del estándar de C++ colocan entidades dentro de este espacio de nombre.

Por esta razón cuando declaramos el uso del espacio de nombre std por medio de "using namespace std; ”, podemos evitar estar escribiendo std::cout o std::cin, etc en nuestro código.

El espacio de nombre std como tal no es una librería sino simplemente un namespace, por esta razón no reemplaza la declaración de las librerías del código, simplemente facilita la escritura de éste al momento de usar las entidades de las librerías estándar. Sin embargo si vamos a hacer uso de una o varias librerías estándar de C++ es recomendable que declaremos el namespace std, para no

Christian Alexander García López

Page 28: Manual de usuario - christian García

25

Laboratorio de Programación 1Manual de Usuario

25

tener que estar constantemente escribiendo cosas similares a las que puse hace unas líneas como std::cin o similares, dado que únicamente se puede acceder a la entidades de las librerías estándar por medio del espacio nombre std.

Muy bien, ahora veamos algunos ejemplos simples del uso de librerías o bibliotecas en C++

Ejemplo 1 de Librerías en C++:En el siguiente ejemplo veremos el uso de la librería stdlib.h que posee una gran variedad de funcionalidades, para este ejemplo usaremos la función rand que nos permite generar un número

aleatorio.#include <stdlib.h>

#include <iostream>

using namespace std;

int main ()

{

cout << ("Se va a generar un numero aleatorio ....\n");

cout << ("El numero generado es : ");

cout << rand(); //Se genera el número con rand y se muestra en pantalla

return 0;

}

En el anterior código hemos hecho uso de dos librerías: iostream y stdlib. La librería o biblioteca iostream, nos permitirá hacer uso del cin y el cout para obtener o imprimir valores por pantalla, respectivamente mientras stdlib nos dará acceso a la función rand que generará por nosotros un número cualquiera.

Ejemplo 2 de Librerías en C++:En el siguiente ejemplo veremos el uso de la librería string.h que nos permite básicamente crear y manipular muy fácilmente cadenas de caracteres.

Christian Alexander García López

Page 29: Manual de usuario - christian García

26

Laboratorio de Programación 1Manual de Usuario

26

#include <string.h>

#include <iostream>

using namespace std;

int main ()

{

cout << ("Hola! Por favor ingrese su nombre ....\n");

string cadena = "Hola "; //Se le da un valor inicial al string

string nombre; //Esta cadena contendrá el nombre

cin >> nombre; //Se lee el nombre

cadena = cadena + nombre; //Se juntan el saludo con el nombre usando "+"

cout << (cadena); //Se muestra el resultado final.

return 0;

}

Aquí hemos mostrado un mensaje solicitando el nombre al usuario y luego usando string, hemos creado un saludo que incluya el nombre del usuario. "Hola Juan".

Estructura Las estructuras son el segundo tipo de datos estructurados que veremos (valga la redundancia).

Al contrario que los arrays, las estructuras nos permiten agrupar varios datos, que mantengan algún tipo de relación, aunque sean de distinto tipo, permitiendo manipularlos todos juntos, usando un mismo identificador, o cada uno por separado.

Las estructuras son llamadas también muy a menudo registros, o en inglés records. Tienen muchos aspectos en común con los registros usados en bases de datos. Y siguiendo la misma analogía, cada objeto de una estructura se denomina a menudo campo, o field.

Sintaxis:

Christian Alexander García López

Page 30: Manual de usuario - christian García

27

Laboratorio de Programación 1Manual de Usuario

27

struct [<identificador>] { [<tipo> <nombre_objeto>[,<nombre_objeto>,...]];} [<objeto_estructura>[,<objeto_estructura>,...];

El identificador de la estructura es un nombre opcional para referirse a la estructura.

Los objetos de estructura son objetos declarados del tipo de la estructura, y su inclusión también es opcional. Sin bien, aún siendo ambos opcionales, al menos uno de estos elementos debe existir.

En el interior de una estructura, entre las llaves, se pueden definir todos los elementos que consideremos necesarios, del mismo modo que se declaran los objetos.

Las estructuras pueden referenciarse completas, usando su nombre, como hacemos con los objetos que ya conocemos, y también se puede acceder a los elementos definidos en el interior de la estructura, usando el operador de selección (.), un punto.

Una vez definida una estructura, es decir, si hemos especificado un nombre para ella, se puede usar igual que cualquier otro tipo de C++. Esto significa que se pueden declarar más objetos del tipo de estructura en cualquier parte del programa. Para ello usaremos la forma normal de declaración de objetos, es decir:

[struct] <identificador> <objeto_estructura> [,<objeto_estructura>...];

En C++ la palabra struct es opcional en la declaración de objetos, al contrario de lo que sucede en C, en el que es obligatorio usarla.

Ejemplo:

struct Persona { char Nombre[65]; char Direccion[65]; int AnyoNacimiento; } Fulanito;

Este ejemplo define la estructura Persona y declara a Fulanito como un objeto de ese tipo. Para acceder al nombre de Fulanito, por ejemplo para visualizarlo, usaremos la forma:

cout << Fulanito.Nombre;

Funciones en el interior de estructurasC++, permite incluir funciones en el interior de las estructuras. Normalmente estas funciones tienen la misión de manipular los datos incluidos en la estructura, y su uso está muy relacionado con la programación orientada a objetos.

Christian Alexander García López

Page 31: Manual de usuario - christian García

28

Laboratorio de Programación 1Manual de Usuario

28

Aunque esta característica se usa casi exclusivamente con las clases, como veremos más adelante, también puede usarse en las estructuras. De hecho, en C++, las diferencias entre estructuras y clases son muy tenues.

Dos funciones muy particulares son las de inicialización, o constructor, y el destructor. Veremos con más detalle estas funciones cuando asociemos las estructuras y los punteros.

El constructor es una función sin tipo de retorno y con el mismo nombre que la estructura. El destructor tiene la misma forma, salvo que el nombre va precedido el símbolo "~".

Nota: para aquellos que usen un teclado español, el símbolo "~" se obtiene pulsando las teclas del teclado numérico 1, 2, 6, mientras se mantiene pulsada la tecla ALT, ([ALT]+126). También mediante la combinación [Atl Gr]+[4] y un espacio (la tecla [4] de la zona de las letras, no del teclado numérico).

Veamos un ejemplo sencillo para ilustrar el uso de constructores:

Forma 1:

struct Punto { int x, y; Punto() {x = 0; y = 0;} // Constructor} Punto1, Punto2;

Forma 2:

struct Punto { int x, y; Punto(); // Declaración del constructor} Punto1, Punto2; // Definición del constructor, fuera de la estructuraPunto::Punto() { x = 0; y = 0; }

Si no usáramos un constructor, los valores de x e y para Punto1 y Punto2 estarían indeterminados, contendrían la "basura" que hubiese en la memoria asignada a estas estructuras durante la ejecución. Con las estructuras éste será el caso más habitual, ya que si necesitamos usar constructores para asignar valores iniciales, será mucho más lógico usar clases que estructuras.

Mencionar aquí, sólo a título de información, que el constructor no tiene por qué ser único. Se pueden definir varios constructores, pero veremos esto mucho mejor y con más detalle cuando veamos las clases.

Christian Alexander García López

Page 32: Manual de usuario - christian García

29

Laboratorio de Programación 1Manual de Usuario

29

Usando constructores nos aseguramos los valores iniciales para los elementos de la estructura. Veremos que esto puede ser una gran ventaja, sobre todo cuando combinemos estructuras con punteros, en capítulos posteriores.

También podemos incluir otras funciones, que se declaran y definen como las funciones que ya conocemos.

Otro ejemplo:

#include <iostream>using namespace std;

struct stPareja { int A, B; int LeeA() { return A;} // Devuelve el valor de A int LeeB() { return B;} // Devuelve el valor de B void GuardaA(int n) { A = n;} // Asigna un nuevo valor a A void GuardaB(int n) { B = n;} // Asigna un nuevo valor a B} Par; int main() { Par.GuardaA(15); Par.GuardaB(63); cout << Par.LeeA() << endl; cout << Par.LeeB() << endl; return 0; }

En este ejemplo podemos ver cómo se define una estructura con dos campos enteros, y dos funciones para modificar y leer sus valores. El ejemplo es muy simple, pero las funciones de guardar valores se pueden elaborar para que no permitan determinados valores, o para que hagan algún tratamiento de los datos.

Por supuesto se pueden definir otras funciones y también constructores más elaborados e incluso, redefinir operadores. Y en general, las estructuras admiten cualquiera de las características de las clases, siendo en muchos aspectos equivalentes.

Veremos estas características cuando estudiemos las clases, y recordaremos cómo aplicarlas a las estructuras.

Inicialización de estructurasDe un modo parecido al que se inicializan los arrays, se pueden inicializar estructuras, tan sólo hay que tener cuidado con las estructuras anidadas. Por ejemplo:

struct A { int i;

Christian Alexander García López

Page 33: Manual de usuario - christian García

30

Laboratorio de Programación 1Manual de Usuario

30

int j; int k;};

struct B { int x; struct C { char c; char d; } y; int z;};

A ejemploA = {10, 20, 30};B ejemploB = {10, {'a', 'b'}, 20};

Cada nueva estructura anidada deberá inicializarse usando la pareja correspondiente de llaves "{}", tantas veces como sea necesario.

Asignación de estructurasLa asignación de estructuras está permitida, pero sólo entre objetos del mismo tipo de estructura, (salvo que se usen constructores), y funciona como la intuición nos dice que debe hacerlo.

Veamos un ejemplo:

struct Punto { int x, y; Punto() {x = 0; y = 0;} } Punto1, Punto2; int main() { Punto1.x = 10; Punto1.y = 12; Punto2 = Punto1; }

La línea Punto2 = Punto1; equivale a Punto2.x = Punto1.x; Punto2.y = Punto1.y;.

Quizás te hayas quedado intrigado por el comentario anterior, que adelantaba que se pueden asignar estructuras diferentes, siempre que se usen losconstructores adecuados.

Esto, en realidad, se puede extender a cualquier tipo, no sólo a estructuras. Por ejemplo, definiendo el constructor adecuado, podemos asignar un entero a una estructura. Veamos cómo hacer esto.

Hasta ahora, los constructores que hemos visto no usaban argumentos, pero eso no significa que no puedan tenerlos.

Christian Alexander García López

Page 34: Manual de usuario - christian García

31

Laboratorio de Programación 1Manual de Usuario

31

Crearemos como ejemplo, una estructura para manejar números complejos. Un número complejo está compuesto por dos valores reales, el primero contiene lo que se llama la parte real y el segundo la parte imaginaria.

struct complejo { double real; double imaginario;};

Esta estructura es suficiente para muchas de las cosas que podemos hacer con números imaginarios, pero aprovechando que podemos crear funciones, podemos añadir algunas que hagan de una forma más directa cosas que de otro modo requieren añadir código externo.

Por ahora nos limitaremos a añadir unos cuantos constructores. El primero es el más lógico: un constructor por defecto:

struct complejo { complejo() { real=0; imaginario = 0; } double real; double imaginario;};

Este construtor se usará, por ejemplo, si declaramos un array:

complejo array[10];

El constructor por defecto será llamado para cada elemento del array, aunque no aparezca tal llamada en ningún punto del programa.

Otro constructor nos puede servir para asignar un valor a partir de dos números:

struct complejo { complejo() { real=0; imaginario = 0; } complejo(double r, double i) { real=r; imaginario = i; } double real; double imaginario;};

Mediante este constructor podemos asignar valores inciales en la declaración:

complejo c1(10.23, 213.22);

Christian Alexander García López

Page 35: Manual de usuario - christian García

32

Laboratorio de Programación 1Manual de Usuario

32

Los números reales se consideran un subconjunto de los imaginarios, en los que la parte imaginaria vale cero. Esto nos permite crear otro constructor que sólo admita un valor real:

struct complejo { complejo() { real=0; imaginario = 0; } complejo(double r, double i) { real=r; imaginario = i; } complejo(double r) { real=r; imaginario = 0; } double real; double imaginario;};

Este constructor nos permite, como en el caso anterior, inicializar un valor de un complejo en la declaración, pero también nos permite asignar un valor double a un complejo, y por el sistema de promoción automático, también podemos asignar valores enteros o en coma flotante:

complejo c1(19.232);complejo c2 = 1299.212;int x = 10;complejo c3 = x;

Este tipo de constructores se comportan como conversores de tipo, nada nos impide crear constructores con cualquier tipo de parámetro, y talesconstructores se podrán usar para convertir cualquier tipo al de nuestra estructura.

Arrays de estructurasLa combinación de las estructuras con los arrays proporciona una potente herramienta para el almacenamiento y manipulación de datos.

Ejemplo:

struct Persona { char Nombre[65]; char Direccion[65]; int AnyoNacimiento; } Plantilla[200];

Vemos en este ejemplo lo fácil que podemos declarar el array Plantilla que contiene los datos relativos a doscientas personas.

Podemos acceder a los datos de cada uno de ellos:

cout << Plantilla[43].Direccion;

O asignar los datos de un elemento de la plantilla a otro:

Plantilla[0] = Plantilla[99];

Christian Alexander García López

Page 36: Manual de usuario - christian García

33

Laboratorio de Programación 1Manual de Usuario

33

Estructuras anidadasTambién está permitido anidar estructuras, con lo cual se pueden conseguir superestructuras muy elaboradas.

Ejemplo:

struct stDireccion { char Calle[64]; int Portal; int Piso; char Puerta[3]; char CodigoPostal[6]; char Poblacion[32]; }; struct stPersona { struct stNombre { char Nombre[32]; char Apellidos[64]; } NombreCompleto; stDireccion Direccion; char Telefono[10]; };...

En general, no es una práctica corriente definir estructuras dentro de estructuras, ya que tienen un ámbito local, y para acceder a ellas se necesita hacer referencia a la estructura más externa.

Por ejemplo para declarar un objeto del tipo stNombre hay que utilizar el operador de acceso (::):

stPersona::stNombre NombreAuxiliar;

Sin embargo para declarar un objeto de tipo stDireccion basta con declararla:

stDireccion DireccionAuxiliar;

Estructuras anónimas^

Antes dijimos, al hablar sobre la sintaxis de las declaraciones de estructuras, que debe aparecer o bien el identificador de estructura, o bien declararse algún objeto de ese tipo en la declaración. Bien, eso no es del todo cierto. Hay situaciones donde se pueden omitir ambos identificadores.

Christian Alexander García López

Page 37: Manual de usuario - christian García

34

Laboratorio de Programación 1Manual de Usuario

34

Una estructura anónima es la que carece de identificador de tipo de estructura y de declaración de objetos del tipo de estructura.

Por ejemplo, veamos esta declaración:

struct stAnonima { struct { int x; int y; }; int z;};

Para acceder a los campos x o y se usa la misma forma que para el campo z:

stAnonima Anonima; Anonima.x = 0; Anonima.y = 0; Anonima.z = 0;

Pero, ¿cuál es la utilidad de esto?

Pues, la verdad, no mucha, al menos cuando se usa con estructuras. En el capítulo dedicado a las uniones veremos que sí puede resultar muy útil.

El método usado para declarar la estructura dentro de la estructura es la forma anónima, como verás no tiene identificador de tipo de estructura ni de campo. El único lugar donde es legal el uso de estructuras anónimas es en el interior de estructuras y uniones.

Operador sizeof con estructuras^Podemos usar el operador sizeof para calcular el espacio de memoria necesario para almacenar una estructura.

Sería lógico suponer que sumando el tamaño de cada elemento de una estructura, se podría calcular el tamaño de la estructura completa, pero no siempre es así. Por ejemplo:

#include <iostream>using namespace std; struct A { int x; char a; int y; char b;};

Christian Alexander García López

Page 38: Manual de usuario - christian García

35

Laboratorio de Programación 1Manual de Usuario

35

struct B { int x; int y; char a; char b;};

int main(){ cout << "Tamaño de int: " << sizeof(int) << endl; cout << "Tamaño de char: " << sizeof(char) << endl; cout << "Tamaño de estructura A: " << sizeof(A) << endl; cout << "Tamaño de estructura B: " << sizeof(B) << endl;

return 0;}

El resultado, usando Dev-C++, es el siguiente:

Tamaño de int: 4Tamaño de char: 1Tamaño de estructura A: 16Tamaño de estructura B: 12

Si hacemos las cuentas, en ambos casos el tamaño de la estructura debería ser el mismo, es decir, 4+4+1+1=10 bytes. Sin embargo en el caso de la estructuraA el tamaño es 16 y en el de la estructura B es 12, ¿por qué?

La explicación es algo denominado alineación de bytes (byte-aling). Para mejorar el rendimiento del procesador no se accede a todas las posiciones de memoria. En el caso de microprocesadores de 32 bits (4 bytes), es mejor si sólo se accede a posiciones de memoria múltiplos de cuatro, de modo que el compilador intenta alinear los objetos con esas posiciones.

En el caso de objetos int es fácil, ya que ocupan cuatro bytes, pero con los objetos char no, ya que sólo ocupan uno.

Cuando se accede a datos de menos de cuatro bytes la alineación no es tan importante. El rendimiento se ve afectado sobre todo cuando hay que leer datos de cuatro bytes que no estén alineados.

En el caso de la estructura A hemos intercalado campos int con char, de modo que el campo int y, se alinea a la siguiente posición múltiplo de cuatro, dejando tres posiciones libres después del campo a. Lo mismo pasa con el campo b.

Christian Alexander García López

Page 39: Manual de usuario - christian García

36

Laboratorio de Programación 1Manual de Usuario

36

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

x a vacío Y b vacío

En el caso de la estructura B hemos agrupado los campos de tipo char al final de la estructura, de modo que se aprovecha mejor el espacio, y sólo se desperdician los dos bytes sobrantes después de b.

0 1 2 3 4 5 6 7 8 9 10 11

x Y a b vacío

Ficheros Los ficheros, en contraposición con las estructuras de datos vistas hasta ahora (variables simples, vectores, registros, etc.), son estructuras de datos almacenadas en memoria secundaria. Para utilizar la información en memoria principal se emplea fundamentalmente la instrucción de asignación; sin embargo, para guardar o recuperar información de un fichero es necesario realizar una serie de operaciones que describiremos en este apartado. El formato de declaración de un fichero es el siguiente:

FILE * nom_ var_fich;

En otros lenguajes la declaración del fichero determina el tipo de datos que se van a almacenar en él. En C la filosofía es distinta, todos los ficheros almacenan bytes y es cuando se realiza la apertura y la escritura cuando se decide cómo y qué se almacena en el mismo; durante la declaración del fichero no se hace ninguna distinción sobre el tipo del mismo. En la operación de apertura se puede decidir si el fichero va a ser de texto o binario, los primeros sirven para almacenar caracteres, los segundos para almacenar cualquier tipo de dato. Si deseamos leer un fichero como el autoexec.bat utilizaremos un fichero de texto, si queremos leer y escribir registros (struct) usaremos un fichero binario.

APERTURA Y CIERRE DE FICHEROSHasta ahora, para obtener y almacenar datos de una estructura de datos bastaba con realizar asignaciones a la misma. Para utilizar los ficheros el procedimiento es distinto.

Antes de usar un fichero es necesario realizar una operación de apertura del mismo; posteriormente, si se desea almacenar datos en él hay que realizar una operación de escritura y si se quiere obtener datos de él es necesario hacer una operación de lectura. Cuando ya no se quiera utilizar el fichero se realiza una operación de cierre del mismo para liberar parte de la memoria

Christian Alexander García López

Page 40: Manual de usuario - christian García

37

Laboratorio de Programación 1Manual de Usuario

37

principal que pueda estar ocupando (aunque el fichero en sí está almacenado en memoria secundaria, mientras está abierto ocupa también memoria principal).

La instrucción más habitual para abrir un fichero es:

FILE * fichero;

fichero = fopen ( nombre-fichero, modo);La función fopen devuelve un puntero a un fichero que se asigna a una variable de tipo fichero. Si existe algún tipo de error al realizar la operación, por ejemplo, porque se desee abrir para leerlo y éste no exista, devuelve el valor NULL.

El nombre-fichero será una cadena de caracteres que contenga el nombre (y en su caso la ruta de acceso) del fichero tal y como aparece para el sistema operativo.

El modo es una cadena de caracteres que indica el tipo del fichero (texto o binario) y el uso que se va a hacer de él lectura, escritura, añadir datos al final, etc. Los modos disponibles son:

r Abre un fichero para lectura. Si el archivo no existe devuelve errorw Abre un fichero para escritura. Si el fichero no existe se crea, si el fichero existe se destruye y

se crea uno nuevoa Abre un fichero para añadir datos al final del mismo. Si no existe se crea+ Símbolo utilizado para abrir ell fichero para lectura y escritura.b El fichero es de tipo binariot El fichero es de tipo texto. Si no se pone ni b ni t el fichero es de texto. Los modos anteriores

se combinan para conseguir abrir el fichero en el modo adecuado.

Por ejemplo, para abrir un fichero binario ya existente para lectura y escritura el modo será "rb+ "; si el fichero no existe, o aun existiendo se desea crear, el modo será " wb+ ". Si deseamos añadir datos al final de un fichero de texto bastará con poner "a", etc.

La forma habitual de utilizar la instrucción fopen es dentro de una sentencia condicional que permita conocer si se ha producido o no error en la apertura, por ejemplo:

Christian Alexander García López

Page 41: Manual de usuario - christian García

38

Laboratorio de Programación 1Manual de Usuario

38

FlLE *fich;

if ((fich = fopen("nomfich.dat", "r")) == NULL)

{ /* control del error de apertura * /

printf ( " Error en la apertura. Es posible que el fichero no exista \n "); }

El resultado de fopen se almacena en la variable fich y después se compara fich con NULL para saber si se ha producido algún error. Toda la operación se puede realizar en la misma instrucción, tal y como aparece en el ejemplo.

Cuando se termine el tratamiento del fichero hay que cerrarlo; si la apertura se hizo con fopen el cierre se hará con fclose (fich);

Para utilizar las instrucciones de manejo de ficheros que veremos en esta unidad es necesario incluir la librería <stdio.h>

LECTURA Y ESCRITURA EN FICHEROSPara almacenar datos en un fichero es necesario realizar una operación de escritura, de igual forma que para obtener datos hay que efectuar una operación de lectura. En C existen muchas y variadas operaciones para leer y escribir en un fichero; entre ellas tenemos: fread -fwrite, fgetc -fputc, fgets - fputs, fscanf -fprintf

Es aconsejable utilizarlas por parejas; es decir, si se escribe con fwrite se debe leer con fread.

Lectura y escritura de bloques ( fread – fwrite )

Para leer y escribir en ficheros que no sean de texto las operaciones que se deben utilizar son fread y fwrite.

El formato de escritura en bloque es el siguiente:

fwrite (direcc_dato, tamaño_dato, numero_datos, punt_fichero);

Escribe tantos datos como indique número de datos en el fichero, tomando los datos a partir de la dirección del dato.

Los datos tienen que tener tantos bytes como especifique tamaño. La función fwrite devuelve el número de elementos escritos, este valor debe coincidir con número de datos.

Para calcular el tamaño en bytes de un dato o un tipo de dato se suele utilizar la función sizeof (dato) o sizeof (tipo-de-dato);

Por ejemplo:

int i, v[3];

Christian Alexander García López

Page 42: Manual de usuario - christian García

39

Laboratorio de Programación 1Manual de Usuario

39

sizeof (i) daría lo mismo que sizeof (int) sizeof (v) daría 3 veces el resultado de sizeof (V[1])

Por ejemplo:

FlLE *f;

int v[6], elem_escritos, num;

f = fopen (“datos.cht ", "wb ");

/* Para escribir los 3 últimos elementos de v (el 2, el 3 y el 4) */

elem-escritos = fwrite (&v[2], sizeof(int), 3, f );

/* Para escribir el primer elemento de v, valen las 2 instrucciones siguientes */

fwrite (v, sizeof (int), 1, f );

fwrite (&v[0], sizeof(int), 1, f );

/* Para escribir un entero valen las dos siguientes */

fwrite (&num, sizeof(int), 1, f);

fwrite (&num, sizeof(num), 1, f);

La sentencia de lectura de bloque es la siguiente:

fread (direcc_dato, tamaño_dato, numero_datos,punt_fichero);

Lee tantos datos como indique numero de datos del fichero, colocando los datos leídos a partir de la dirección del dato. Los datos tienen que tener tantos bytes como especifique tamaño del dato. La función fread devuelve el número de elementos leídos, y el valor devuelto debe coincidir con número de datos.

Ejemplos:

Christian Alexander García López

Page 43: Manual de usuario - christian García

40

Laboratorio de Programación 1Manual de Usuario

40

f = fopen (“datos.dat ", "rb ");

elem-escritos = fread (&v[2], sizeof(int), 3, f);

fread (v, sizeof(int), 1, f);

fread (&V[0], sizeof(int), 1, f);

fread (&num, sizeof(int), 1, f);

fread (&num, sizeof(num), 1, f);

Lectura y escritura formateada de texto ( fscanf – fprintf )Las instrucciones scanf y printf utilizadas normalmente para lecturas y escrituras de teclado y pantalla tienen sus correspondientes funciones para el manejo de ficheros: fscanf y fprintf. La única diferencia con las anteriores es la necesidad de dar como primer argumento el fichero en el que leemos o escribimos.

Para que lo escrito con fprintf pueda ser correctamente leído con fscanf es conveniente que el formato en el que se indican los tipos de datos que se van a leer o escribir sean similares para ambas instrucciones, que los tipos de datos estén separados, por ejemplo, por un blanco y que tengan un fin de línea al final.

Por ejemplo, los siguientes pares de instrucciones de lectura y escritura serían compatibles:

int num;

char car, cad [10] ;

FILE *f.

/* apertura del fichero */

.....

.....

fscanf (f, "%d %c %s ", &num, &car, cad);

fprintf ( f, "%d %c %s \n ", num, car, cad);

fscanf (f, "%s %c %d ", cad, &car, &num);

fprintf (f, "%s %c %d \n ", cad, car, num);

Christian Alexander García López

Page 44: Manual de usuario - christian García

41

Laboratorio de Programación 1Manual de Usuario

41

Lectura y escritura de caracteres ( fgetc – fputc ) y cadenas ( fgets – fputs )

Los formatos de las instrucciones de lectura y escritura de caracteres y cadenas son:

carácter_leido = fgetc (fichero);

fgetc lee un carácter del fichero, el carácter leído se almacenará en carácter leído. Cuando se llega al final del fichero devuelve EOF.

Fputc( car, fichero);

fputc escribe el carácter car en el fichero. Devuelve el carácter escrito o EOF en caso de error..

fgets (cadena_leida, num_caracteres, fichero);

Lee num_caracteres del fichero y los almacena en cadena_leida colocando el carácter de fin de cadena '\0' en la posición num_caracteres de la cadena leida.

Por ejemplo:

FlLE *f;

char cad[5];

fgets (cad, 5, f);

Almacena en cad la cadena " Buen " si se lee la línea " Buenas tardes " del fichero f. Si se realizan dos lecturas, en la segunda se almacena en cad la cadena “as t ".

fputs (cadena_escribir, fichero);

escribe la cadena en el fichero.

Por ejemplo:. fputs (cad, f);.

Ejemplo: Copiar un fichero de texto en otro

Christian Alexander García López

Page 45: Manual de usuario - christian García

42

Laboratorio de Programación 1Manual de Usuario

42

#include <stdio.h>

main ( )

{ FILE *fin *fout;

char c, x;

if (((fin = fopen(“DATOSIN.DAT", “rt")) == NULL) ||

((fout = fopen(“DATOSOUT.DAT" , “wt")) == NULL))

{ if (fout ! = NULL) fclose (fout) ;

if (fin ! = NULL) fclose (fin) ;

printf (“Error en la apertura de ficheros de salida \n” );

return 1;

}

c = fgetc(fin);

while (c != EOF)

{ x = fputc (c, fout);

if (x! = c) printf ("Error de escritura");

c = fgetc(fin);

}

fclose (fin);

fclose (fout);

return 0;

}

RECORRIDO DE UN FICHERO SECUENCIAL (feof)Las lecturas y escrituras en un fichero se realizan en la posición en la que se encuentra el puntero del fichero. Al abrir el fichero el puntero está antes del primer dato del mismo. Cada vez que se realiza una operación de lectura o escritura el puntero se mueve hasta apuntar al dato y después lo lee o escribe.

Christian Alexander García López

Page 46: Manual de usuario - christian García

43

Laboratorio de Programación 1Manual de Usuario

43

Por ejemplo, en un fichero f con dos datos (O y 1) al abrir el fichero tendríamos la siguiente situación:

Posición del puntero | puntero® | |

Datos | 0 | 1 | eof

Si realizamos la operación fread(&i, sizeof(int), 1, f); en la variable i tendremos almacenado el 0 y la situación después de la lectura será:

Posición del puntero | puntero® |

Datos | 0 | 1 | eof

Para leer todos los datos de un fichero basta con realizar lecturas sucesivas hasta que se lee el final del fichero. En un ejemplo anterior hemos visto cómo se puede detectar el final del fichero teniendo en cuenta el dato leído (leer hasta que fgetc( ) devuelva EOF). Esta operación es correcta, pero es más habitual utilizar una función de C que nos indica cuándo se ha leído el último dato:

feof (fichero)Devuelve un valor distinto de 0 cuando se ha alcanzado el final del fichero.

Ejemplo Escribir cinco registros en un fichero y leerlo posteriormente.

Solución:

#include<stdio.h>

struct t_reg {

int num;

char cad[10];

char car; };

int crear_fichero ()

{ FILE *fich;

int i, er_dev = 0;

struct t_reg r;

if ((fich = fopen(“fichreg.dat", “wb")) == NULL)

{ printf ("Error en apertura del fichero para escritura\n");

Christian Alexander García López

Page 47: Manual de usuario - christian García

44

Laboratorio de Programación 1Manual de Usuario

44

er_dev = 1;

}

else {

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

{ r.num = i;

r.car=’a’+1;

printf("Dé un nombre: ");

gets(r.cad);

fwrite(&r, sizeof(r), 1, fich);

}

fclose (fich);

}

return er_dev;

}

int Ieer_fichero ()

{ FILE *fich;

struct t-reg r;

int er_dev = 0;

if ((fich = fopen(“fichreg.dat", “rb")) == NULL)

{ printf ( “Error en apertura del fichero para lectura \n “ );

er_ dev = 1.

}

else

{ fread (&r, sizeof(r), 1, fich);

while (! feof(fich))

Christian Alexander García López

Page 48: Manual de usuario - christian García

45

Laboratorio de Programación 1Manual de Usuario

45

{ printf ("%d: %s: %c\n" , r.num, r.cad, r.car);

fread (&r, sizeof(r), 1, fich);

}

fclose (fich);

}

return er_dev;

}

int main(void)

{ int error;

error = crear_fichero();

if (!error) Ieer_fichero();

}

ACCESO DIRECTO A LOS DATOS (fseek)Cuando se lee un dato de un fichero y después el que está a continuación de él, y así sucesivamente, se dice que se está realizando una lectura secuencial del mismo. Cuando se puede acceder a cualquier dato de un fichero sin tener que pasar por anteriores se está realizando un acceso directo a los datos.

La función que permite situarse en un determinado dato del fichero es: fseek (fichero, posicion, origen);

Que coloca el puntero del fichero a tantos bytes del origen como indica posición contando a partir del origen señalado. Los orígenes posibles son:

SEEK_SET o 0 : principio del fichero.

SEEK_CUR o 1 : posición actual.

SEEK_END o 2 : final del fichero.

fseek devuelve 0 si no ha habido ningún error.

Christian Alexander García López

Page 49: Manual de usuario - christian García

46

Laboratorio de Programación 1Manual de Usuario

46

Por ejemplo, en un fichero que almacene números enteros la instrucción

fseek (f, 0, SEEK-SET); colocará el puntero al principio del fichero.

fseek (f, 3*sizeof(int), SEEK-CUR); colocará el puntero 3 posiciones más

allá de la posición actual del puntero.

Para saber cuál es la posición en la que está el puntero del fichero C. proporciona la función siguiente: ftell (fich);

Que devuelve la posición actual en bytes del puntero del fichero con respecto al principio del mismo.

Entrada y Salida (Printf, scanf, cout y cin) Toda la entrada y salida se realiza por medio de flujos, los cuales son secuencias de bytes. En operaciones de entrada, los bytes fluyen desde un dispositivo (por ejemlo, el teclado, el disco duro, una conexión de red) hacia la memoria principal. En operaciones de salida, los bytes fluyen desde la memoria principal hacia un dispositivo (por ejemplo, una pantalla, una impresora, un disco duro, una conexión de red, etcétera).

Cuando comienza la ejecución del programa, automáticamente se conectan tres flujos al programa. Por lo general, el flujo estándar de entrada se conecta al teclado y el flujo estándar de salida se conecta a la pantalla. A menudo, los sistemas operativos permiten redireccionar estos flujos hacia otros dispositivos. Un tercer flujo, el flujo estándar de error, se conecta a la pantalla. Los mensajes de error se arrojan al flujo estándar de error.

Las operaciones de E/S no forman parte del lenguaje C/C++, los programas interactúan con el entorno (memoria, teclado, mouse, impresora, pantalla, etc.) por medio de un conjunto de funciones diseñadas para proporcionar un sistema estándar de E/S a los programas. Se pretende que las funciones presenten una interfaz conveniente para la programación y reflejen las operaciones que proporcionan la mayoría de los sistemas operativos modernos.

Esta carencia de E/S predefinidas hace al lenguaje C/C++ más adaptable, dado que se conecta a librerías o bibliotecas para proporcionar las operaciones de entrada y salida de archivos y consola; tales librerías pertenecen al conjunto de la biblioteca estándar de ANSI C/C++ disponibles en cualquier compilador de C/C++.

Christian Alexander García López

Page 50: Manual de usuario - christian García

47

Laboratorio de Programación 1Manual de Usuario

47

Las funciones de librería de entrada estándar tienen dos tareas principales; la primera, establecer una interfaz de comunicación entre el programa y el dispositivo de entrada, desde el cual se leen datos en formato de texto; la segunda, convertir los datos leídos en un formato (char, char*, bool, int, float, double) adecuado para el tratamiento de los mismo por el programa. Las funciones de librería de salida estándar tienen dos tareas principales; la primera, establecer una interfaz de comunicación entre el programa y el dispositivo de salida, hacia el cual se envían datos en formato de texto; la segunda, convertir los datos del programa (char, char*, bool, int, float, double) a un formato adecuado para su representación en un dispositivo de salida.

Funciones, métodos y procedimientos

Las funciones son una herramienta indispensable para el programador, tanto las funciones creadas por él mismo como las que le son proporcionadas por otras librerías, cualquiera que sea el caso, las funciones permiten automatizar tareas repetitivas, encapsular el código que utilizamos, e incluso mejorar la seguridad, confiabilidad y estabilidad de nuestros programas. Dominar el uso de funciones es de gran importancia, permiten modularizar nuestro código, separarlo según las tareas que requerimos, por ejemplo una función para abrir, otra para cerrar, otra para actualizar, etc. básicamente una función en nuestro código debe contener la implementación de una utilidad de nuestra aplicación, es decir que por cada utilidad básica (abrir, cerrar, cargar, mover, etc.) sería adecuado tener al menos una función asociada a ésta.

Funciones:Las funciones son un conjunto de procedimiento encapsulados en un bloque, usualmente reciben parámetros, cuyos valores utilizan para efectuar operaciones y adicionalmente retornan un valor. Esta definición proviene de la definición de función matemática la cual posee un dominio y un rango, es decir un conjunto de valores que puede tomar y un conjunto de valores que puede retornar luego de cualquier operación.

Métodos:Los métodos y las funciones son funcionalmente idénticos, pero su diferencia radica en el contexto en el que existen. Un método también puede recibir valores, efectuar operaciones con estos y retornar valores, sin embargo en método está asociado a un objeto, básicamente un método es una función que pertenece a un objeto o clase, mientras que una función existe por sí sola, sin necesidad de un objeto para ser usada.

Christian Alexander García López

Page 51: Manual de usuario - christian García

48

Laboratorio de Programación 1Manual de Usuario

48

Procedimientos:Los procedimientos son básicamente lo un conjunto de instrucciones que se ejecutan sin retornar ningún valor, hay quienes dicen que un procedimiento no recibe valores o argumentos, sin embargo en la definición no hay nada que se lo impida. En el contexto de C++ un procedimiento es básicamente una función void que no nos obliga a utilizar una sentencia return.

Declarando funcionesLa sintaxis para declarar una función es muy simple, veamos:

tipo nombreFuncion ([tipo nombreArgumento,[tipo nombreArgumento]...])

{

/*

* Bloque de instrucciones

*/

return valor;

}

Recordemos que una función siempre retorna algo, por lo tanto es obligatorio declararle un tipo (el primer componente de la sintaxis anterior), luego debemos darle un nombre a dicha función, para poder identificarla y llamarla durante la ejecución, después al interior de paréntesis, podemos poner los argumentos o parámetros. Luego de la definición de la "firma" de la función, se define su funcionamiento entre llaves; todo lo que esté dentro de las llaves es parte del cuerpo de la función y éste se ejecuta hasta llegar a la instrucción return.

Argumentos o parámetros Una función o procedimiento pueden tener una cantidad cualquier de parámetros, es decir

pueden tener cero, uno, tres, diez, cien o más parámetros. Aunque habitualmente no suelen tener más de 4 o 5.

Si una función tiene más de un parámetro cada uno de ellos debe ir separado por una coma. Los argumentos de una función también tienen un tipo y un nombre que los identifica. El tipo

del argumento puede ser cualquiera y no tiene relación con el tipo de la función.

Christian Alexander García López

Page 52: Manual de usuario - christian García

49

Laboratorio de Programación 1Manual de Usuario

49

Consejos acerca de returnDebes tener en cuenta dos cosas importantes con la sentencia return:

Cualquier instrucción que se encuentre después de la ejecución de return NO será ejecutada. Es común encontrar funciones con múltiples sentencias return al interior de condicionales, pero una vez que el código ejecuta una sentencia return lo que haya de allí hacia abajo no se ejecutará.

El tipo del valor que se retorna en una función debe coincidir con el del tipo declarado a la función, es decir si se declara int, el valor retornado debe ser un número entero.

Ejemplos de funcionesEjemplo 1:

int funcionEntera()//Función sin parámetros

{

int suma = 5+5;

return suma; //Acá termina la ejecución de la función

return 5+5;//Este return nunca se ejecutará

//Intenta intercambiar la línea 3 con la 5

int x = 10; //Esta línea nunca se ejecutará

}

Como puedes ver es un ejemplo sencillo, si ejecutas esto, la función te retornará el valor de suma que es 10 (5+5). Las líneas posteriores no se ejecutarán nunca, aunque no generan error alguno, no tienen utilidad. Puedes notar que para este caso es lo mismo haber escrito return suma que escribir return 5+5. Ambas líneas funcionan equivalentemente.

Christian Alexander García López

Page 53: Manual de usuario - christian García

50

Laboratorio de Programación 1Manual de Usuario

50

Ejemplo 2:

char funcionChar(int n)//Función con un parámetro

{

if(n == 0)//Usamos el parámetro en la función

{

return 'a'; //Si n es cero retorna a

//Notar que de aquí para abajo no se ejecuta nada más

}

return 'x';//Este return sólo se ejecuta cuando n NO es cero

}

Aquí hicimos uso se múltiples sentencia return y aprovechamos la característica de que al ser ejecutadas finalizan inmediatamente la ejecución de la parte restante de la función. De este modo podemos asegurar que la función retornará 'a' únicamente cuando el valor del parámetro n sea cero y retornará un 'x' cuando dicho valor no sea cero.

Ejemplo 3:

bool funcionBool(int n, string mensaje)//Función con dos parámetros

{

if(n == 0)//Usamos el parámetro en la función

{

cout << mensaje;//Mostramos el mensaje

return 1; //Si n es cero retorna 1

return true;//Equivalente

}

return 0;//Este return sólo se ejecuta cuando n NO es cero

return false;//Equivalente }

Christian Alexander García López

Page 54: Manual de usuario - christian García

51

Laboratorio de Programación 1Manual de Usuario

51

Aquí ya tenemos una función que recibe dos parámetros, uno de ellos es usado en el condicional y el otro para mostrar su valor por pantalla con cout, esta vez retornamos valores booleanos 0 y 1, pudo ser true o false también.

ProcedimientosLos procedimientos son similares a las funciones, aunque más resumidos. Debido a que los procedimientos no retornan valores, no hacen uso de la sentencia return para devolver valores y no tienen tipo específico, solo void. Veamos un ejemplo:

Ejemplo de procedimientos

void procedimiento(int n, string nombre)

{

if(n == 0)

{

cout << "hola" << nombre;

return;

}

cout << "adios" << nombre;

}

De este ejemplo podemos ver que ya no se usa un tipo sino que se pone void, indicando que no retorna valores, también podemos ver que un procedimiento también puede recibir parámetros o argumentos.

Nota: Los procedimientos también pueden usar la sentencia return, pero no con un valor. En los procedimientos el return sólo se utiliza para finalizar allí la ejecución de la función.

Invocando funciones y procedimientos en C++Ya hemos visto cómo se crean y cómo se ejecutan las funciones en C++, ahora veamos cómo hacemos uso de ellas.

nombreFuncion([valor,[valor]...]);

Como puedes notar es bastante sencillo invocar o llamar funciones en C++ (de hecho en cualquier lenguaje actual), sólo necesitas el nombre de la función y enviarle el valor de los parámetros. Hay que hacer algunas salvedades respecto a esto.

Christian Alexander García López

Page 55: Manual de usuario - christian García

52

Laboratorio de Programación 1Manual de Usuario

52

Detalles para invocar funciones El nombre de la función debe coincidir exactamente al momento de invocarla. El orden de los parámetros y el tipo debe coincidir. Hay que ser cuidadosos al momento de

enviar los parámetros, debemos hacerlo en el mismo orden en el que fueron declarados y deben ser del mismo tipo (número, texto u otros).

Cada parámetro enviado también va separado por comas. Si una función no recibe parámetros, simplemente no ponemos nada al interior de los

paréntesis, pero SIEMPRE debemos poner los paréntesis. Invocar una función sigue siendo una sentencia habitual de C++, así que ésta debe finalizar

con ';' como siempre. El valor retornado por una función puede ser asignado a una variable del mismo tipo. Una función puede llamar a otra dentro de sí misma o incluso puede ser enviada como

parámetro a otra.

Ejemplos de uso de funcionesEn el siguiente código vamos a hacer un llamado a algunas de las funciones y al procedimiento, que declaramos anteriormente.

int main()

{

funcionEntera(); //Llamando a una función sin argumentos

bool respuesta = funcionBool(1, "hola"); //Asignando el valor retornado a una variable

procedimiento(0, "Juan");//Invocando el procedimiento

//Usando una función como parámetro

procedimiento(funcionBool(1, "hola"), "Juan");

return 0;

}

En el código anterior podemos ver cómo todas las funciones han sido invocadas al interior de la función main (la función principal), esto nos demuestra que podemos hacer uso de funciones al interior de otras. También vemos cómo se asigna el valor retornado por la función a la variable 'respuesta' y finalmente, antes del return, vemos cómo hemos usado el valor retornado por 'funcionBool' como parámetro del procedimiento.

Christian Alexander García López

Page 56: Manual de usuario - christian García

53

Laboratorio de Programación 1Manual de Usuario

53

Ejercicios Resueltos en clases y propios Uso del sizeof:

Área del Círculo

Christian Alexander García López

Page 57: Manual de usuario - christian García

54

Laboratorio de Programación 1Manual de Usuario

54

Estructura 1

Christian Alexander García López

Page 58: Manual de usuario - christian García

55

Laboratorio de Programación 1Manual de Usuario

55

Estructura 2

Christian Alexander García López

Page 59: Manual de usuario - christian García

56

Laboratorio de Programación 1Manual de Usuario

56

Matriz de Arreglo de 2x3 con funciones

Christian Alexander García López

Page 60: Manual de usuario - christian García

57

Laboratorio de Programación 1Manual de Usuario

57

Christian Alexander García López

Page 61: Manual de usuario - christian García

58

Laboratorio de Programación 1Manual de Usuario

58

Arreglo de Estructura

Christian Alexander García López

Page 62: Manual de usuario - christian García

59

Laboratorio de Programación 1Manual de Usuario

59

Arreglo Bidimensional

Christian Alexander García López

Page 63: Manual de usuario - christian García

60

Laboratorio de Programación 1Manual de Usuario

60

HORA Y FECHA DEL SISTEMA

Christian Alexander García López

Page 64: Manual de usuario - christian García

61

Laboratorio de Programación 1Manual de Usuario

61

Anexos No puse imágenes de anexo, porque trate que en el trayecto del Manual, ir poniendo ejemplos que había realizado. Para poder tener una mejor comprensión.

Christian Alexander García López