SlideShare una empresa de Scribd logo
1 de 65
0
Manual de
Usuario
Laboratorio de Programación
Ingeniero Elsner Boanerge
González Ortega
ChristianAlexanderGarcía López
0
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................................................................................................................................................................. 37
Laboratorio de Programación 1
Manual de Usuario
1
Christian Alexander García López 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
1
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.
Laboratorio de Programación 1
Manual de Usuario
2
Christian Alexander García López 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
Constante
Aquellos 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
Laboratorio de Programación 1
Manual de Usuario
3
Christian Alexander García López 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 ENTERO
En 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
Laboratorio de Programación 1
Manual de Usuario
4
Christian Alexander García López 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 FLOTANTE
Un 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.
Laboratorio de Programación 1
Manual de Usuario
5
Christian Alexander García López 5
VARIABLES DE TIPO CARACTER
El 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
Laboratorio de Programación 1
Manual de Usuario
6
Christian Alexander García López 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 TIPOS
Cuando 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.
Laboratorio de Programación 1
Manual de Usuario
7
Christian Alexander García López 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.
Laboratorio de Programación 1
Manual de Usuario
8
Christian Alexander García López 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 :
Laboratorio de Programación 1
Manual de Usuario
9
Christian Alexander García López 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:
Laboratorio de Programación 1
Manual de Usuario
10
Christian Alexander García López 10
Como podemos observar el valor de y= 23.43, paso a ser una variable de tipo short con un nuevo
valor de: 23.
Laboratorio de Programación 1
Manual de Usuario
11
Christian Alexander García López 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:
Laboratorio de Programación 1
Manual de Usuario
12
Christian Alexander García López 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
Expresiones
Una 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.
Laboratorio de Programación 1
Manual de Usuario
13
Christian Alexander García López 13
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:
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 (*))
Laboratorio de Programación 1
Manual de Usuario
14
Christian Alexander García López 14
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.
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
Laboratorio de Programación 1
Manual de Usuario
15
Christian Alexander García López 15
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):
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
Laboratorio de Programación 1
Manual de Usuario
16
Christian Alexander García López 16
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];
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++
Laboratorio de Programación 1
Manual de Usuario
17
Christian Alexander García López 17
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++
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.
Laboratorio de Programación 1
Manual de Usuario
18
Christian Alexander García López 18
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;
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};
Laboratorio de Programación 1
Manual de Usuario
19
Christian Alexander García López 19
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
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 bidimensionales
Son 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.
Laboratorio de Programación 1
Manual de Usuario
20
Christian Alexander García López 20
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 7
0
1
2
3
Nota: todos los arreglos inician desde 0.
Laboratorio de Programación 1
Manual de Usuario
21
Christian Alexander García López 21
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.
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,
Laboratorio de Programación 1
Manual de Usuario
22
Christian Alexander García López 22
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.
 iostream:
Laboratorio de Programación 1
Manual de Usuario
23
Christian Alexander García López 23
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:
Laboratorio de Programación 1
Manual de Usuario
24
Christian Alexander García López 24
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.
Laboratorio de Programación 1
Manual de Usuario
25
Christian Alexander García López 25
¿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 std
Todas 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
Laboratorio de Programación 1
Manual de Usuario
26
Christian Alexander García López 26
una o varias librerías estándar de C++ es recomendable que declaremos el namespace std, para no
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++:
Laboratorio de Programación 1
Manual de Usuario
27
Christian Alexander García López 27
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.
#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.
Laboratorio de Programación 1
Manual de Usuario
28
Christian Alexander García López 28
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:
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;
Laboratorio de Programación 1
Manual de Usuario
29
Christian Alexander García López 29
Funciones en el interior de estructuras
C++, 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.
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 estructura
Punto::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.
Laboratorio de Programación 1
Manual de Usuario
30
Christian Alexander García López 30
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.
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 estructuras
De 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:
Laboratorio de Programación 1
Manual de Usuario
31
Christian Alexander García López 31
struct A {
int i;
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 estructuras
La 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.
Laboratorio de Programación 1
Manual de Usuario
32
Christian Alexander García López 32
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);
Laboratorio de Programación 1
Manual de Usuario
33
Christian Alexander García López 33
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 estructuras
La 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:
Laboratorio de Programación 1
Manual de Usuario
34
Christian Alexander García López 34
Plantilla[0] = Plantilla[99];
Estructuras anidadas
Tambié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
^
Laboratorio de Programación 1
Manual de Usuario
35
Christian Alexander García López 35
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.
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;
Laboratorio de Programación 1
Manual de Usuario
36
Christian Alexander García López 36
char a;
int y;
char b;
};
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: 4
Tamaño de char: 1
Tamaño de estructura A: 16
Tamañ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.
Laboratorio de Programación 1
Manual de Usuario
37
Christian Alexander García López 37
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.
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.
Laboratorio de Programación 1
Manual de Usuario
38
Christian Alexander García López 38
APERTURA Y CIERRE DE FICHEROS
Hasta 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
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 error
w Abre un fichero para escritura. Si el fichero no existe se crea, si el fichero existe se destruye y
se crea uno nuevo
a 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 binario
t 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:
Laboratorio de Programación 1
Manual de Usuario
39
Christian Alexander García López 39
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 FICHEROS
Para 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:
Laboratorio de Programación 1
Manual de Usuario
40
Christian Alexander García López 40
int i, v[3];
 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:
Laboratorio de Programación 1
Manual de Usuario
41
Christian Alexander García López 41
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);
Laboratorio de Programación 1
Manual de Usuario
42
Christian Alexander García López 42
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
Laboratorio de Programación 1
Manual de Usuario
43
Christian Alexander García López 43
#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.
Laboratorio de Programación 1
Manual de Usuario
44
Christian Alexander García López 44
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 escrituran");
Laboratorio de Programación 1
Manual de Usuario
45
Christian Alexander García López 45
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))
Laboratorio de Programación 1
Manual de Usuario
46
Christian Alexander García López 46
{ printf ("%d: %s: %cn" , 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.
Laboratorio de Programación 1
Manual de Usuario
47
Christian Alexander García López 47
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++.
Laboratorio de Programación 1
Manual de Usuario
48
Christian Alexander García López 48
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.
Laboratorio de Programación 1
Manual de Usuario
49
Christian Alexander García López 49
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 funciones
La 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.
Laboratorio de Programación 1
Manual de Usuario
50
Christian Alexander García López 50
Consejos acerca de return
Debes 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 funciones
Ejemplo 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.
Laboratorio de Programación 1
Manual de Usuario
51
Christian Alexander García López 51
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 }
Laboratorio de Programación 1
Manual de Usuario
52
Christian Alexander García López 52
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.
Procedimientos
Los 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.
Laboratorio de Programación 1
Manual de Usuario
53
Christian Alexander García López 53
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 funciones
En 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.
Laboratorio de Programación 1
Manual de Usuario
54
Christian Alexander García López 54
Ejercicios Resueltos en clases y propios
Uso del sizeof:
Área del Círculo
Laboratorio de Programación 1
Manual de Usuario
55
Christian Alexander García López 55
Estructura 1
Laboratorio de Programación 1
Manual de Usuario
56
Christian Alexander García López 56
Estructura 2
Laboratorio de Programación 1
Manual de Usuario
57
Christian Alexander García López 57
Matriz de Arreglo de 2x3 con funciones
Laboratorio de Programación 1
Manual de Usuario
58
Christian Alexander García López 58
Laboratorio de Programación 1
Manual de Usuario
59
Christian Alexander García López 59
Arreglo de Estructura
Laboratorio de Programación 1
Manual de Usuario
60
Christian Alexander García López 60
Arreglo Bidimensional
Laboratorio de Programación 1
Manual de Usuario
61
Christian Alexander García López 61
HORA Y FECHA DEL SISTEMA
Laboratorio de Programación 1
Manual de Usuario
62
Christian Alexander García López 62
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.

Más contenido relacionado

Destacado (7)

Electronica
ElectronicaElectronica
Electronica
 
LA REVOLUCION CIENTIFICA-TENCOLOGICO
LA REVOLUCION CIENTIFICA-TENCOLOGICOLA REVOLUCION CIENTIFICA-TENCOLOGICO
LA REVOLUCION CIENTIFICA-TENCOLOGICO
 
9. revolucion electronica informatica
9. revolucion electronica informatica9. revolucion electronica informatica
9. revolucion electronica informatica
 
Las tics en la educación melissa
Las tics en la educación melissaLas tics en la educación melissa
Las tics en la educación melissa
 
Tecnologias de la Informacion y la Comunicación (TIC'S)
Tecnologias de la Informacion y la Comunicación (TIC'S)Tecnologias de la Informacion y la Comunicación (TIC'S)
Tecnologias de la Informacion y la Comunicación (TIC'S)
 
Ntic´s características
Ntic´s  característicasNtic´s  características
Ntic´s características
 
Educacion electronica
Educacion electronicaEducacion electronica
Educacion electronica
 

Similar a Manual de usuario - christian García

Bash
BashBash
Bashjr480
 
ApuntesC++.pdf
ApuntesC++.pdfApuntesC++.pdf
ApuntesC++.pdfbilgrado01
 
Fjava
FjavaFjava
FjavaNumei
 
MANUAL DE LENGUAJE C
MANUAL DE LENGUAJE CMANUAL DE LENGUAJE C
MANUAL DE LENGUAJE Cclaudiocj7
 
Teoria de automatas y lenguajes formales
Teoria de automatas y lenguajes formalesTeoria de automatas y lenguajes formales
Teoria de automatas y lenguajes formalesUniversidad del Valle
 
Manal visual basic
Manal visual basicManal visual basic
Manal visual basicFredy Campos
 
Manual de Visual Basic para Excel
Manual de Visual Basic para ExcelManual de Visual Basic para Excel
Manual de Visual Basic para ExcelSaludsa
 
Estudio para la puesta en marcha de un robot scara adept three xl
Estudio para la puesta en marcha de un robot scara adept three xlEstudio para la puesta en marcha de un robot scara adept three xl
Estudio para la puesta en marcha de un robot scara adept three xlKloDgAr
 
Octave calculo numerico
Octave calculo numericoOctave calculo numerico
Octave calculo numericoLUIS COAQUIRA
 
Programacion en Phyton desde ce..........................ro
Programacion en Phyton desde ce..........................roProgramacion en Phyton desde ce..........................ro
Programacion en Phyton desde ce..........................roMa Florencia Ferrari
 
Sintaxis de PSeInt el da a entender todos los comandos del programa tambien a...
Sintaxis de PSeInt el da a entender todos los comandos del programa tambien a...Sintaxis de PSeInt el da a entender todos los comandos del programa tambien a...
Sintaxis de PSeInt el da a entender todos los comandos del programa tambien a...BerlyMachaca
 

Similar a Manual de usuario - christian García (20)

Curso de fortran
Curso de fortranCurso de fortran
Curso de fortran
 
Aprenda pascal
Aprenda pascalAprenda pascal
Aprenda pascal
 
Shell bash
Shell bashShell bash
Shell bash
 
Bash
BashBash
Bash
 
17 shell bash
17 shell bash17 shell bash
17 shell bash
 
Bashers
BashersBashers
Bashers
 
ApuntesC++.pdf
ApuntesC++.pdfApuntesC++.pdf
ApuntesC++.pdf
 
Curso de-fortran
Curso de-fortranCurso de-fortran
Curso de-fortran
 
Fjava
FjavaFjava
Fjava
 
MANUAL DE LENGUAJE C
MANUAL DE LENGUAJE CMANUAL DE LENGUAJE C
MANUAL DE LENGUAJE C
 
Teoria de automatas y lenguajes formales
Teoria de automatas y lenguajes formalesTeoria de automatas y lenguajes formales
Teoria de automatas y lenguajes formales
 
Manal visual basic
Manal visual basicManal visual basic
Manal visual basic
 
Manual de Visual Basic para Excel
Manual de Visual Basic para ExcelManual de Visual Basic para Excel
Manual de Visual Basic para Excel
 
Manual de programacion lenguaje en C
Manual de programacion lenguaje en CManual de programacion lenguaje en C
Manual de programacion lenguaje en C
 
Lenguaje c
Lenguaje cLenguaje c
Lenguaje c
 
Guia para java
Guia para javaGuia para java
Guia para java
 
Estudio para la puesta en marcha de un robot scara adept three xl
Estudio para la puesta en marcha de un robot scara adept three xlEstudio para la puesta en marcha de un robot scara adept three xl
Estudio para la puesta en marcha de un robot scara adept three xl
 
Octave calculo numerico
Octave calculo numericoOctave calculo numerico
Octave calculo numerico
 
Programacion en Phyton desde ce..........................ro
Programacion en Phyton desde ce..........................roProgramacion en Phyton desde ce..........................ro
Programacion en Phyton desde ce..........................ro
 
Sintaxis de PSeInt el da a entender todos los comandos del programa tambien a...
Sintaxis de PSeInt el da a entender todos los comandos del programa tambien a...Sintaxis de PSeInt el da a entender todos los comandos del programa tambien a...
Sintaxis de PSeInt el da a entender todos los comandos del programa tambien a...
 

Más de Estudiantes ISI_UCA (20)

Manual
ManualManual
Manual
 
Manual C/C++
Manual C/C++ Manual C/C++
Manual C/C++
 
Manual C/C++ Jason Martinez
Manual C/C++ Jason MartinezManual C/C++ Jason Martinez
Manual C/C++ Jason Martinez
 
Manual C-C++ Pablo
Manual C-C++ PabloManual C-C++ Pablo
Manual C-C++ Pablo
 
Manual programación
Manual programaciónManual programación
Manual programación
 
Manual C/C++ Carlos Diaz
Manual C/C++ Carlos Diaz Manual C/C++ Carlos Diaz
Manual C/C++ Carlos Diaz
 
Manual de usuario c
Manual de usuario  cManual de usuario  c
Manual de usuario c
 
Manual C/C++ Néstor Flores
Manual C/C++ Néstor FloresManual C/C++ Néstor Flores
Manual C/C++ Néstor Flores
 
Manual AGFV
Manual AGFVManual AGFV
Manual AGFV
 
Manual C / C++ Melvin
Manual C / C++ MelvinManual C / C++ Melvin
Manual C / C++ Melvin
 
Manual laboratorio de programación#1
Manual laboratorio de programación#1Manual laboratorio de programación#1
Manual laboratorio de programación#1
 
Manual de Programación c/c++ Ricky Bonilla
Manual de Programación c/c++ Ricky BonillaManual de Programación c/c++ Ricky Bonilla
Manual de Programación c/c++ Ricky Bonilla
 
Manual programación
Manual programaciónManual programación
Manual programación
 
Manual de usuario (C/C++)
Manual de usuario (C/C++)Manual de usuario (C/C++)
Manual de usuario (C/C++)
 
Manualito C/C++ - Leonardo Aquino
Manualito C/C++ - Leonardo AquinoManualito C/C++ - Leonardo Aquino
Manualito C/C++ - Leonardo Aquino
 
Manual de programación en C/C++
Manual de programación en C/C++Manual de programación en C/C++
Manual de programación en C/C++
 
Lenguaje de programacion en c
Lenguaje de programacion en cLenguaje de programacion en c
Lenguaje de programacion en c
 
Manual de c c++
Manual de c c++Manual de c c++
Manual de c c++
 
manualitoRodolfo
manualitoRodolfomanualitoRodolfo
manualitoRodolfo
 
Manual Francis Jarquin R
Manual Francis Jarquin RManual Francis Jarquin R
Manual Francis Jarquin R
 

Último

presentación del desensamble y ensamble del equipo de computo en base a las n...
presentación del desensamble y ensamble del equipo de computo en base a las n...presentación del desensamble y ensamble del equipo de computo en base a las n...
presentación del desensamble y ensamble del equipo de computo en base a las n...axelv9257
 
infor expo AVANCES TECNOLOGICOS DEL SIGLO 21.pptx
infor expo AVANCES TECNOLOGICOS DEL SIGLO 21.pptxinfor expo AVANCES TECNOLOGICOS DEL SIGLO 21.pptx
infor expo AVANCES TECNOLOGICOS DEL SIGLO 21.pptxgustavovasquezv56
 
Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21mariacbr99
 
Guia Basica para bachillerato de Circuitos Basicos
Guia Basica para bachillerato de Circuitos BasicosGuia Basica para bachillerato de Circuitos Basicos
Guia Basica para bachillerato de Circuitos BasicosJhonJairoRodriguezCe
 
Avances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estosAvances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estossgonzalezp1
 
Avances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanaAvances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanamcerpam
 
investigación de los Avances tecnológicos del siglo XXI
investigación de los Avances tecnológicos del siglo XXIinvestigación de los Avances tecnológicos del siglo XXI
investigación de los Avances tecnológicos del siglo XXIhmpuellon
 
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...JohnRamos830530
 
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptxEVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptxJorgeParada26
 
redes informaticas en una oficina administrativa
redes informaticas en una oficina administrativaredes informaticas en una oficina administrativa
redes informaticas en una oficina administrativanicho110
 
How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.FlorenciaCattelani
 
Buenos_Aires_Meetup_Redis_20240430_.pptx
Buenos_Aires_Meetup_Redis_20240430_.pptxBuenos_Aires_Meetup_Redis_20240430_.pptx
Buenos_Aires_Meetup_Redis_20240430_.pptxFederico Castellari
 
Generaciones de las Computadoras..pdf...
Generaciones de las Computadoras..pdf...Generaciones de las Computadoras..pdf...
Generaciones de las Computadoras..pdf...solanocortezluisalfr
 
presentacion_desamblado_de_una_computadora_base_a_las_normas_de_seguridad.pdf
presentacion_desamblado_de_una_computadora_base_a_las_normas_de_seguridad.pdfpresentacion_desamblado_de_una_computadora_base_a_las_normas_de_seguridad.pdf
presentacion_desamblado_de_una_computadora_base_a_las_normas_de_seguridad.pdfaxelv9257
 

Último (14)

presentación del desensamble y ensamble del equipo de computo en base a las n...
presentación del desensamble y ensamble del equipo de computo en base a las n...presentación del desensamble y ensamble del equipo de computo en base a las n...
presentación del desensamble y ensamble del equipo de computo en base a las n...
 
infor expo AVANCES TECNOLOGICOS DEL SIGLO 21.pptx
infor expo AVANCES TECNOLOGICOS DEL SIGLO 21.pptxinfor expo AVANCES TECNOLOGICOS DEL SIGLO 21.pptx
infor expo AVANCES TECNOLOGICOS DEL SIGLO 21.pptx
 
Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21
 
Guia Basica para bachillerato de Circuitos Basicos
Guia Basica para bachillerato de Circuitos BasicosGuia Basica para bachillerato de Circuitos Basicos
Guia Basica para bachillerato de Circuitos Basicos
 
Avances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estosAvances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estos
 
Avances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanaAvances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvana
 
investigación de los Avances tecnológicos del siglo XXI
investigación de los Avances tecnológicos del siglo XXIinvestigación de los Avances tecnológicos del siglo XXI
investigación de los Avances tecnológicos del siglo XXI
 
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
 
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptxEVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
 
redes informaticas en una oficina administrativa
redes informaticas en una oficina administrativaredes informaticas en una oficina administrativa
redes informaticas en una oficina administrativa
 
How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.
 
Buenos_Aires_Meetup_Redis_20240430_.pptx
Buenos_Aires_Meetup_Redis_20240430_.pptxBuenos_Aires_Meetup_Redis_20240430_.pptx
Buenos_Aires_Meetup_Redis_20240430_.pptx
 
Generaciones de las Computadoras..pdf...
Generaciones de las Computadoras..pdf...Generaciones de las Computadoras..pdf...
Generaciones de las Computadoras..pdf...
 
presentacion_desamblado_de_una_computadora_base_a_las_normas_de_seguridad.pdf
presentacion_desamblado_de_una_computadora_base_a_las_normas_de_seguridad.pdfpresentacion_desamblado_de_una_computadora_base_a_las_normas_de_seguridad.pdf
presentacion_desamblado_de_una_computadora_base_a_las_normas_de_seguridad.pdf
 

Manual de usuario - christian García

  • 1. 0 Manual de Usuario Laboratorio de Programación Ingeniero Elsner Boanerge González Ortega ChristianAlexanderGarcía López
  • 2. 0 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................................................................................................................................................................. 37
  • 3. Laboratorio de Programación 1 Manual de Usuario 1 Christian Alexander García López 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
  • 4. 1 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.
  • 5. Laboratorio de Programación 1 Manual de Usuario 2 Christian Alexander García López 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 Constante Aquellos 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
  • 6. Laboratorio de Programación 1 Manual de Usuario 3 Christian Alexander García López 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 ENTERO En 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
  • 7. Laboratorio de Programación 1 Manual de Usuario 4 Christian Alexander García López 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 FLOTANTE Un 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.
  • 8. Laboratorio de Programación 1 Manual de Usuario 5 Christian Alexander García López 5 VARIABLES DE TIPO CARACTER El 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
  • 9. Laboratorio de Programación 1 Manual de Usuario 6 Christian Alexander García López 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 TIPOS Cuando 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.
  • 10. Laboratorio de Programación 1 Manual de Usuario 7 Christian Alexander García López 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.
  • 11. Laboratorio de Programación 1 Manual de Usuario 8 Christian Alexander García López 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 :
  • 12. Laboratorio de Programación 1 Manual de Usuario 9 Christian Alexander García López 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:
  • 13. Laboratorio de Programación 1 Manual de Usuario 10 Christian Alexander García López 10 Como podemos observar el valor de y= 23.43, paso a ser una variable de tipo short con un nuevo valor de: 23.
  • 14. Laboratorio de Programación 1 Manual de Usuario 11 Christian Alexander García López 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:
  • 15. Laboratorio de Programación 1 Manual de Usuario 12 Christian Alexander García López 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 Expresiones Una 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.
  • 16. Laboratorio de Programación 1 Manual de Usuario 13 Christian Alexander García López 13 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: 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 (*))
  • 17. Laboratorio de Programación 1 Manual de Usuario 14 Christian Alexander García López 14 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. 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
  • 18. Laboratorio de Programación 1 Manual de Usuario 15 Christian Alexander García López 15 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): 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
  • 19. Laboratorio de Programación 1 Manual de Usuario 16 Christian Alexander García López 16 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]; 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++
  • 20. Laboratorio de Programación 1 Manual de Usuario 17 Christian Alexander García López 17 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++ 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.
  • 21. Laboratorio de Programación 1 Manual de Usuario 18 Christian Alexander García López 18 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; 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};
  • 22. Laboratorio de Programación 1 Manual de Usuario 19 Christian Alexander García López 19 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 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 bidimensionales Son 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.
  • 23. Laboratorio de Programación 1 Manual de Usuario 20 Christian Alexander García López 20 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 7 0 1 2 3 Nota: todos los arreglos inician desde 0.
  • 24. Laboratorio de Programación 1 Manual de Usuario 21 Christian Alexander García López 21 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. 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,
  • 25. Laboratorio de Programación 1 Manual de Usuario 22 Christian Alexander García López 22 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.  iostream:
  • 26. Laboratorio de Programación 1 Manual de Usuario 23 Christian Alexander García López 23 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:
  • 27. Laboratorio de Programación 1 Manual de Usuario 24 Christian Alexander García López 24 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.
  • 28. Laboratorio de Programación 1 Manual de Usuario 25 Christian Alexander García López 25 ¿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 std Todas 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
  • 29. Laboratorio de Programación 1 Manual de Usuario 26 Christian Alexander García López 26 una o varias librerías estándar de C++ es recomendable que declaremos el namespace std, para no 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++:
  • 30. Laboratorio de Programación 1 Manual de Usuario 27 Christian Alexander García López 27 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. #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.
  • 31. Laboratorio de Programación 1 Manual de Usuario 28 Christian Alexander García López 28 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: 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;
  • 32. Laboratorio de Programación 1 Manual de Usuario 29 Christian Alexander García López 29 Funciones en el interior de estructuras C++, 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. 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 estructura Punto::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.
  • 33. Laboratorio de Programación 1 Manual de Usuario 30 Christian Alexander García López 30 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. 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 estructuras De 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:
  • 34. Laboratorio de Programación 1 Manual de Usuario 31 Christian Alexander García López 31 struct A { int i; 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 estructuras La 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.
  • 35. Laboratorio de Programación 1 Manual de Usuario 32 Christian Alexander García López 32 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);
  • 36. Laboratorio de Programación 1 Manual de Usuario 33 Christian Alexander García López 33 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 estructuras La 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:
  • 37. Laboratorio de Programación 1 Manual de Usuario 34 Christian Alexander García López 34 Plantilla[0] = Plantilla[99]; Estructuras anidadas Tambié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 ^
  • 38. Laboratorio de Programación 1 Manual de Usuario 35 Christian Alexander García López 35 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. 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;
  • 39. Laboratorio de Programación 1 Manual de Usuario 36 Christian Alexander García López 36 char a; int y; char b; }; 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: 4 Tamaño de char: 1 Tamaño de estructura A: 16 Tamañ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.
  • 40. Laboratorio de Programación 1 Manual de Usuario 37 Christian Alexander García López 37 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. 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.
  • 41. Laboratorio de Programación 1 Manual de Usuario 38 Christian Alexander García López 38 APERTURA Y CIERRE DE FICHEROS Hasta 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 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 error w Abre un fichero para escritura. Si el fichero no existe se crea, si el fichero existe se destruye y se crea uno nuevo a 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 binario t 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:
  • 42. Laboratorio de Programación 1 Manual de Usuario 39 Christian Alexander García López 39 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 FICHEROS Para 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:
  • 43. Laboratorio de Programación 1 Manual de Usuario 40 Christian Alexander García López 40 int i, v[3];  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:
  • 44. Laboratorio de Programación 1 Manual de Usuario 41 Christian Alexander García López 41 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);
  • 45. Laboratorio de Programación 1 Manual de Usuario 42 Christian Alexander García López 42 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
  • 46. Laboratorio de Programación 1 Manual de Usuario 43 Christian Alexander García López 43 #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.
  • 47. Laboratorio de Programación 1 Manual de Usuario 44 Christian Alexander García López 44 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 escrituran");
  • 48. Laboratorio de Programación 1 Manual de Usuario 45 Christian Alexander García López 45 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))
  • 49. Laboratorio de Programación 1 Manual de Usuario 46 Christian Alexander García López 46 { printf ("%d: %s: %cn" , 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.
  • 50. Laboratorio de Programación 1 Manual de Usuario 47 Christian Alexander García López 47 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++.
  • 51. Laboratorio de Programación 1 Manual de Usuario 48 Christian Alexander García López 48 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.
  • 52. Laboratorio de Programación 1 Manual de Usuario 49 Christian Alexander García López 49 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 funciones La 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.
  • 53. Laboratorio de Programación 1 Manual de Usuario 50 Christian Alexander García López 50 Consejos acerca de return Debes 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 funciones Ejemplo 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.
  • 54. Laboratorio de Programación 1 Manual de Usuario 51 Christian Alexander García López 51 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 }
  • 55. Laboratorio de Programación 1 Manual de Usuario 52 Christian Alexander García López 52 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. Procedimientos Los 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.
  • 56. Laboratorio de Programación 1 Manual de Usuario 53 Christian Alexander García López 53 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 funciones En 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.
  • 57. Laboratorio de Programación 1 Manual de Usuario 54 Christian Alexander García López 54 Ejercicios Resueltos en clases y propios Uso del sizeof: Área del Círculo
  • 58. Laboratorio de Programación 1 Manual de Usuario 55 Christian Alexander García López 55 Estructura 1
  • 59. Laboratorio de Programación 1 Manual de Usuario 56 Christian Alexander García López 56 Estructura 2
  • 60. Laboratorio de Programación 1 Manual de Usuario 57 Christian Alexander García López 57 Matriz de Arreglo de 2x3 con funciones
  • 61. Laboratorio de Programación 1 Manual de Usuario 58 Christian Alexander García López 58
  • 62. Laboratorio de Programación 1 Manual de Usuario 59 Christian Alexander García López 59 Arreglo de Estructura
  • 63. Laboratorio de Programación 1 Manual de Usuario 60 Christian Alexander García López 60 Arreglo Bidimensional
  • 64. Laboratorio de Programación 1 Manual de Usuario 61 Christian Alexander García López 61 HORA Y FECHA DEL SISTEMA
  • 65. Laboratorio de Programación 1 Manual de Usuario 62 Christian Alexander García López 62 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.