Está en la página 1de 96

TALLER DE INFORMTICA

APUNTES

LENGUAJE C
- Ao 2010 UNIVERSIDAD NACIONAL DE MISIONES - FACULTAD DE INGENIERA
OBER MISIONES ARGENTINA

INDICE
PRLOGO. ................................................................................................................... - 1 CAPITULO 1. INTRODUCCIN. ............................................................................... - 2 Por qu usar C? ............................................................................................................ - 2 CAPITULO 2. LENGUAJE C. ..................................................................................... - 4 2.1. Operaciones bsicas de programacin.................................................................... - 4 2.1.1. Creacin del fichero fuente. ................................................................................ - 4 2.1.2. Creacin del fichero objeto. ................................................................................ - 4 2.1.3. Creacin del fichero ejecutable. .......................................................................... - 4 2.1.3.1. Uso de libreras................................................................................................. - 4 2.1.3.2. Ficheros ejecutables y enlazadores................................................................... - 5 2.2. Manejo de Errores. ................................................................................................. - 5 2.2.1. Errores de sintaxis. .............................................................................................. - 5 2.2.2. Warnings o Avisos. ............................................................................................. - 5 2.2.3. Errores de enlazado. ............................................................................................ - 6 2.2.4. Errores de ejecucin. ........................................................................................... - 6 2.2.5. Errores de diseo. ................................................................................................ - 6 CAPITULO 3. ESTRUCTURA DE UN PROGRAMA. .............................................. - 7 3.1. Directivas del preprocesador. ................................................................................. - 7 3.2. Declaracin de variables globales. ......................................................................... - 8 3.3. Prototipos de funciones. ......................................................................................... - 8 3.4. Declaracin de clases. ............................................................................................ - 8 3.5. Funcin main(). ...................................................................................................... - 8 3.6. Definicin de funciones.......................................................................................... - 8 3.7. Definicin de clases................................................................................................ - 8 CAPITULO 4. DATOS, VARIABLES Y CONSTANTES.......................................... - 9 4.1 Datos........................................................................................................................ - 9 4.2. Variables................................................................................................................. - 9 4.2.1. Identificadores. .................................................................................................. - 10 4.2.2. Declaracin de variables.................................................................................... - 10 4.2.2.1. Declaracin de una variable de tipo entero (integer)...................................... - 11 4.2.2.2. Declaracin de una variable de tipo punto flotante (float). ............................ - 11 4.2.2.3. Declaracin de una variable de tipo punto flotante doble precisin (double).- 11 4.2.2.4. Declaracin de una variable sin tipo (void).................................................... - 11 -1-

4.2.2.5. Declaracin de una variable de tipo enumerado (enum). ............................... - 11 4.2.2.6. Declaracin de una variable de tipo boleana (boolean).................................. - 12 4.2.3. Inicializacin de variables ................................................................................. - 12 4.2.4. Ejercicios sobre Variables ................................................................................. - 12 4.3. Constantes............................................................................................................. - 13 4.3.1. Normas para la notacin.................................................................................... - 13 4.3.1.1. Constantes "int". ............................................................................................. - 13 4.3.1.2. Constantes "long". .......................................................................................... - 14 4.3.1.3. Constantes "long long". .................................................................................. - 15 4.3.1.4. Constantes "unsigned".................................................................................... - 15 4.3.1.5. Constantes "unsigned long"............................................................................ - 15 4.3.1.6. Constantes "unsigned long long".................................................................... - 15 4.3.1.7. Constantes "float". .......................................................................................... - 16 4.3.1.8. Constantes "double". ...................................................................................... - 16 4.3.1.9. Constantes "long double". .............................................................................. - 16 4.3.1.10. Constantes "char". ........................................................................................ - 16 4.3.2. Recomendaciones en el uso de la notacin. ...................................................... - 16 4.3.2.1. Constantes enteras. ......................................................................................... - 16 4.3.2.2. Constantes punto flotante. .............................................................................. - 16 4.3.3 Constantes carcter. Comentario adicional. ....................................................... - 17 4.3.3.1. Cdigo ASCII. ................................................................................................ - 17 4.3.3.2. Carcter nulo. ................................................................................................. - 18 4.3.3.3. Carcter EOF. ................................................................................................. - 18 4.3.4. Ejercicios ........................................................................................................... - 19 CAPITULO 5. OPERADORES. ................................................................................. - 20 5.1. Operadores aritmticos. ........................................................................................ - 20 5.1.1. Operadores aritmticos unitarios. ...................................................................... - 20 5.1.1.1. Operadores '+' y '- ...................................................................................... - 20 5.1.1.2. Operadores '++' y '--'....................................................................................... - 20 5.1.2. Operadores aritmticos binarios. ....................................................................... - 21 5.2. Operadores relacionales........................................................................................ - 22 5.3. Operadores lgicos. .............................................................................................. - 22 5.3.1. Operador && o AND. ....................................................................................... - 22 5.3.2. Operador || u OR............................................................................................... - 23 5.3.3. Operador ! o NOT. ............................................................................................ - 23 5.4. Operadores de asignacin..................................................................................... - 23 5.5. Operador "sizeof". ................................................................................................ - 24 5.6. Operador condicional (?). ..................................................................................... - 24 5.7. Operador coma (,)................................................................................................. - 25 CAPITULO 6. EXPRESIONES.................................................................................. - 26 6.1. Expresiones aritmticas. ....................................................................................... - 26 6.1.1. Reglas de Precedencia. ...................................................................................... - 27 6.2. Expresiones lgicas. ............................................................................................. - 27 6.2.1. Expresiones comparativas. ................................................................................ - 28 6.2.1.1. Aplicacin en datos tipo carcter.................................................................... - 28 6.2.1.2. Aplicacin en datos tipo lgico. ..................................................................... - 28 6.2.1.3. Aplicacin en datos tipo punto flotante.......................................................... - 28 -2-

6.2.2. Expresiones lgicas. .......................................................................................... - 28 6.3. Ejercicios con operadores y expresiones .............................................................. - 29 CAPITULO 7. INSTRUCCIONES............................................................................. - 31 7.1. Bloques. ................................................................................................................ - 31 7.2. Expresiones........................................................................................................... - 32 7.2.1. Llamadas a funcin............................................................................................ - 32 7.2.2. Asignacin......................................................................................................... - 32 7.2.3. Nula. .................................................................................................................. - 32 7.3. Bucles. .................................................................................................................. - 32 7.3.1. Bucle "while"..................................................................................................... - 33 7.3.2. Bucle "do while"................................................................................................ - 33 7.3.3. Bucle "for"......................................................................................................... - 34 7.4. Etiquetas. .............................................................................................................. - 34 7.4.1. Etiquetas de identificacin................................................................................. - 34 7.4.2. Etiquetas "case" y "default"............................................................................... - 34 7.5. Sentencias de Seleccin........................................................................................ - 35 7.5.1. Sentencia "if...else"............................................................................................ - 35 7.5.2. Sentencia "switch"............................................................................................. - 35 7.6. Sentencias de salto................................................................................................ - 36 7.6.1. Sentencia de ruptura "break". ............................................................................ - 36 7.6.2. Sentencia continue". ........................................................................................ - 37 7.6.3. Sentencia de salto "goto"................................................................................... - 37 7.6.4. Sentencia de retorno "return". ........................................................................... - 37 7.6.5. Sobre las sentencias de salto y la programacin estructurada. .......................... - 38 7.7. Comentarios.......................................................................................................... - 38 7.8. Ejercicios con sentencias. ..................................................................................... - 39 CAPITULO 8. FUNCIONES. ..................................................................................... - 40 8.1. Declaracin de funcin. El Prototipo. .................................................................. - 40 8.1.1. Funciones extern y static. .................................................................................. - 41 8.2. Definicin de funcin. .......................................................................................... - 41 8.2.1. Tipo de almacenamiento.................................................................................... - 41 8.2.2. Tipo de valor de retorno. ................................................................................... - 41 8.2.3. Modificadores opcionales.................................................................................. - 41 8.2.4. Nombre de la funcin. ....................................................................................... - 42 8.2.5. Lista de parmetros............................................................................................ - 42 8.2.6. Cuerpo de funcin. ............................................................................................ - 42 8.3. Funcin main(). .................................................................................................... - 42 8.4. mbito de variables. ......................................................................................... - 43 8.4.1. Variables locales................................................................................................ - 43 8.4.2. Variables globales. ............................................................................................ - 43 8.5. Ejercicios. ............................................................................................................. - 44 CAPITULO 9. ARREGLOS. ...................................................................................... - 47 9.1. Cadena de caracteres. ........................................................................................... - 47 9.2. Arreglos. ............................................................................................................... - 48 9.2.1. Inicializacin de un arreglo. .............................................................................. - 49 9.2.2. Operadores utilizados con arreglos.................................................................... - 49 9.3. Algoritmos de ordenacin: mtodo de la burbuja. ............................................... - 50 -3-

9.4. Ejercicios: cadenas de caracteres.......................................................................... - 51 9.5. Ejercicios: arreglos. .............................................................................................. - 51 CAPITULO 10. PUNTEROS...................................................................................... - 54 10.1. Declaracin de punteros ..................................................................................... - 55 10.2. Obtener punteros a variables .............................................................................. - 56 10.3. Diferencia entre punteros y variables ................................................................. - 57 10.4. Correspondencia entre arrays y punteros............................................................ - 58 10.5. Operaciones con punteros................................................................................... - 58 10.5.1. Asignacin....................................................................................................... - 59 10.5.2. Operaciones aritmticas................................................................................... - 59 10.5.3. Comparacin entre punteros............................................................................ - 59 10.6. Punteros genricos.............................................................................................. - 60 10.7. Punteros a estructuras ......................................................................................... - 61 10.8. Ejemplos de uso de punteros .............................................................................. - 61 10.8.1. Ejemplo 1......................................................................................................... - 61 10.8.2. Ejemplo 2......................................................................................................... - 62 10.9. Variables dinmicas............................................................................................ - 63 10.10. Ejercicios .......................................................................................................... - 64 CAPITULO 11. ESTRUCTURAS. ............................................................................. - 66 11.1. Estructuras. ......................................................................................................... - 66 11.2. Funciones en el interior de estructuras ............................................................... - 67 11.3. Inicializacin de estructuras ............................................................................... - 69 11.4. Asignacin de estructuras................................................................................... - 69 11.5. Arrays de estructuras .......................................................................................... - 70 11.6. Estructuras anidadas ........................................................................................... - 71 11.7. Operador "sizeof" con estructuras ...................................................................... - 72 11.8. Campos de bits ................................................................................................... - 73 11.9. Punteros a estructuras ......................................................................................... - 75 11.9.1. Ejemplo Gestion dinmica de Memoria y Lista Enlazada simple................... - 76 11.9.2. Ejemplo Gestin dinmica de Memoria y Lista Enlazada Doble.................... - 77 11.10. Ejercicios .......................................................................................................... - 78 CAPITULO 12. MS OPERADORES. ..................................................................... - 82 12.1. Operadores de Referencia (&) e Indireccin (*) ................................................ - 82 12.2. Operadores . y -> ................................................................................................ - 82 12.3. Operador de preprocesador................................................................................. - 82 12.4. Operadores de manejo de memoria "new" y "delete" ........................................ - 82 12.4.1. Operador new .................................................................................................. - 83 12.4.1.1 Ejemplo Gestion dinmica de Memoria y Lista Enlazada Doble.................. - 83 12.4.2-Operador delete ................................................................................................ - 85 CAPITULO 13. PASAJE DE VALORES A FUNCIONES. ...................................... - 86 13.1. Parmetros por valor y parmetros por referencia.............................................. - 86 13.1.1. Referencias a variables .................................................................................... - 87 13.2. Paso de parmetros por referencia...................................................................... - 87 13.3. Punteros como parmetros de funciones ............................................................ - 89 13.4. Funciones que devuelven referencias ................................................................. - 90 13.5. Arrays como parmetros de funciones ............................................................... - 91 -

-4-

TALLER DE INFORMTICA

Prlogo

PRLOGO.
El objetivo de este apunte es proporcionar de una gua para aprender a programar bajo el Entorno
Grfico del Sistema Operativo Linux en Lenguaje C.
Para ello, luego de varios intentos y pruebas sobre las aplicaciones a utilizar en el mbito del
Software Libre, se opt por la Distribucin de Linux Ubuntu y, como interface de IDE (Integrated
Development Environment), el Anjuta. Este apunte est destinado a los alumnos de los cursos de
Taller de Informtica y Computacin de la Facultad de Ingeniera de Ober.
Como aclararacin se expone que el apunte fue realizado mediante la compilacin / edicin de
materiales extrados fundamentalmente de Internet. En algunos casos con modificaciones parciales
y, en otros, modificaciones totales. Otro aporte utilizado, sobre todo en la organizacin de los
temas, fue obtenido de Libros; finalmente, se utilizaron los ejemplos de guas y apuntes de las
Ctedras de aos anteriores. En conclusin, este apunte es el resultado del trabajo de muchas
personas, organizado de la manera ms apropiada para el dictado de las asignaturas mencionadas
y poder conseguir los objetivos propuestos en las mismas.
Los ejemplos de cdigo de este apunte fueron probados sobre:
gcc versin 4.0.3 (Ubuntu 4.0.3-1ubuntu5)
Ubuntu 6.06 LTS - la versin Dapper Drake - publicada en junio de 2006.
Anjuta 1.2.4a (http://anjuta.org/ )
El libro se divide en partes, la Parte 1 incluye los captulos que se desarrollan en la Materia Taller de
Informtica. La Parte 2 y 3 son los temas que conjuntamente con la Parte 1 deben ser vistos en la
Materia Computacin.
En los Apndices fueron dispuestos materiales que se considera pueden ser importantes como
consulta o complemento.
Imgenes utilizadas a lo largo del texto

-1-

TALLER DE INFORMTICA

CAPITULO 1. Introduccin

CAPITULO 1. INTRODUCCIN.
EL lenguaje C fue creado por Dennis Ritchie en los laboratorios de la Bell Telephone en 1972. El
mismo fue pensado para desarrollar un Sistema Operativo llamado UNIX. Este lenguaje es el
sucesor del lenguaje llamado B (de all el nombre C).
Debido a la flexibilidad y poder de programacin, se extendi rpidamente y empezaron a surgir
distintas versiones. Como consecuencia de esto nace un comit llamado ANSI (American National
Estndar Institute) el cul define lo que se conoce como Standard C o como Estndar ANSI C.

Por qu usar C?

Es poderoso y flexible: dadas las caractersticas del lenguaje, permite el desarrollo de


proyectos como sistemas operativos, procesadores de texto, hojas de clculo, etc.

Es un lenguaje comn: como est muy difundido su uso, existe una amplia variedad de
compiladores y accesorios tiles para el programador.

Es transportable: se puede correr en cualquier tipo de computadora, esta ventaja se ve


aumentada con el Estndar C.

Posee pocas palabras clave: la base sobre la cual est construida la funcionalidad del
lenguaje tiene pocas palabras claves.

Es modular: el cdigo puede y debe ser escrito en mdulos llamado funciones que pueden
ser utilizadas y re-utilizadas por otras aplicaciones o programas.

El lenguaje C++ es una versin mejorada del C, lo que significa que tiene todo lo que tiene
el Estndar C ms agregados para la Programacin Orientada a Objetos.

Que diferencia hay entre C y C++? C++ es sper conjunto de C, es decir que C es un
conjunto de C o C est contenido por C++.

El C++ incorpora nuevas caractersticas sin comprometer ninguna de las bondades del C,
entre las cosas que se agreg son el concepto de clases, herencia, funciones virtuales del
lenguaje Simula67 y sobrecarga de operadores del Algol68 (caractersticas que veremos en
detalle en el curso).

Quien cre y cuando el C++?


El C++ fue desarrollado por Bjarne Strousrup, en los laboratorio de Bell a principios de los 80, esto
es 10 aos despus que el Lenguaje C.
Son compatibles los programas de C con C++?
Uno de los grandes aciertos de C++, fue mantener la compatibilidad con C, de este modo cualquier
programa hecho en C puede ser considerado tambin como un programa de C++.
Hay un Estndar para el C++?
S. En forma resumida, el ANSI define un conjunto de reglas; cualquier compilador de C o de C++
debe cumplir esas reglas, si no, no puede considerarse un compilador de C o C++. Estas reglas
definen las caractersticas de un compilador en cuanto a palabras reservadas del lenguaje,
comportamiento de los elementos que lo componen, funciones externas que se incluyen, etc. Un
programa escrito en ANSI C o en ANSI C++, podr compilarse con cualquier compilador que

-2-

TALLER DE INFORMTICA

CAPITULO 1. Introduccin

cumpla la norma ANSI. Se puede considerar como una homologacin o etiqueta de calidad de un
compilador.
Hay caractersticas no estndares en C++?
Si, todos los compiladores incluyen, adems del ANSI, ciertas caractersticas no ANSI, por ejemplo
libreras para grficos. Pero mientras no usemos ninguna de esas caractersticas, sabremos que
nuestros programas son transportables, es
decir, que podrn ejecutarse en cualquier ordenador y con cualquier sistema operativo. Por eso el
desarrollo de un programa bajo, por ejemplo Dev C++ de Bloodshed, podra no compilarse bajo
Anjuta.

-3-

TALLER DE INFORMTICA

CAPITULO 2. Lenguaje C

CAPITULO 2. LENGUAJE C.
Para poder crear un programa en lenguaje C debemos realizar una serie de pasos que nos
permitirn pasar de nuestro programa escrito en cdigo fuente a nuestro archivo ejecutable.
El lenguaje C es compilado, esto significa que un programa compilador lee el cdigo fuente
completo escrito por el programador, lo convierte en cdigo objeto tambin conocido como cdigo
binario o cdigo mquina. Una vez compilado, el linker enlazar las libreras dentro de su cdigo
objeto y as obtendr, finalmente el programa ejecutable. Veamos en detalle cada uno de estos
conceptos.

2.1. Operaciones bsicas de programacin.


2.1.1. Creacin del fichero fuente.
Los programas en C y C++ se escriben con la ayuda de un editor de textos (pico vi) del mismo
modo que cualquier texto corriente.
Los ficheros que contienen programas en C o C++ en forma de texto se conocen como fichero
fuente, y el texto del programa que contiene se conoce como programa fuente.
El usuario siempre escribir programas fuentes y los guardaremos en ficheros fuentes.
Los programas fuente no pueden ejecutarse. Son ficheros de texto, pensados para que ser
comprendidos por los seres humanos, pero incomprensibles para los ordenadores.

2.1.2. Creacin del fichero objeto.


Para obtener un programa ejecutable hay que seguir algunos pasos.
El primer paso es compilar o traducir el programa fuente a su cdigo objeto equivalente. Este es el
trabajo que hacen los compiladores de C y C++.
Consiste en obtener un fichero equivalente a nuestro programa fuente comprensible para el
ordenador, este fichero se conoce como fichero objeto,
y su contenido como cdigo objeto.
Los compiladores son programas que leen un fichero de texto que contiene el programa fuente y
generan un fichero que contiene el cdigo objeto. El cdigo objeto no tiene ningn significado para
los seres humanos, al menos no directamente. Adems es diferente para cada ordenador y para
cada sistema operativo.
Por lo tanto, existen diferentes compiladores para diferentes sistemas operativos y para cada tipo

de ordenador.

Estas tareas las realizaremos, como mencionamos con anterioridad, con el IDE Anjuta, pero se
podran realizar en modo de consola, utilizando un compilador por ejemplo g++.

2.1.3. Creacin del fichero ejecutable.


2.1.3.1. Uso de libreras.
Junto con los compiladores de C y C++, se incluyen ciertos ficheros llamados libreras.
Las libreras contienen cdigo objeto de programas que permiten hacer cosas comunes como, por
ejemplo, leer desde el teclado, escribir en pantalla, manejar nmeros, realizar funciones
matemticas, etc.
Las libreras estn clasificadas por el tipo de trabajos que hacen, hay libreras de entrada y salida,
matemticas, de manejo de memoria, de manejo de textos, etc.
Hay un conjunto de libreras muy especiales, que se incluyen con todos los compiladores de C y de
C++. Son las libreras ANSI o estndar. Pero tambin hay libreras no estndar, y dentro de stas
hay libreras pblicas y comerciales. En este curso slo usaremos libreras ANSI.

-4-

TALLER DE INFORMTICA

CAPITULO 2. Lenguaje C

2.1.3.2. Ficheros ejecutables y enlazadores.


Cuando obtenemos el fichero objeto, an no hemos terminado el proceso.
El fichero objeto, a pesar de ser comprensible para el ordenador, no puede ser ejecutado.
Hay varias razones para eso:
1. Nuestros programas usaran, en general, funciones que estarn incluidas en libreras externas, ya
sean ANSI o no. Es necesario combinar nuestro fichero objeto con esas libreras para obtener un
ejecutable.
2. A menudo, nuestros programas estarn compuestos por varios ficheros fuente y, de cada uno de
ellos, se obtendr un fichero objeto. Es necesario unir, todos los ficheros objeto ms las libreras,
en un nico fichero ejecutable.
3. Hay que dar ciertas instrucciones al ordenador para que cargue en memoria el programa y los
datos y para que organice la memoria de modo que se disponga de una pila de tamao adecuado.
La pila es una zona de memoria que usa el programa para intercambiar datos con otros programas
o con otras partes del propio programa. Veremos esto con ms detalle durante el curso.
Existe un programa que hace todas estas cosas, se trata del "link", o enlazador.
El enlazador toma todos los ficheros objeto que componen nuestro programa, los combina con los
ficheros de librera que sea necesario y crea un fichero ejecutable.
Una vez terminada la fase de enlazado, ya podremos ejecutar nuestro programa.

2.2. Manejo de Errores.


Por supuesto, somos humanos, y por lo tanto nos equivocamos. Los errores de programacin
pueden clasificarse en varios tipos, dependiendo de la fase en que se presenten.
Pueden ser:

Errores de sintaxis.

Warnings o avisos.

Errores de enlazado.

Errores de ejecucin.

Errores de diseo.

2.2.1. Errores de sintaxis.


Los errores de sintaxis son errores en el programa fuente. Pueden deberse a palabras reservadas,
palabras mal escritas, expresiones errneas o incompletas, variables no definidas, etc.
Los errores de sintaxis se detectan en la fase de compilacin. El compilador, adems de generar el
cdigo objeto, nos dar una lista de errores de sintaxis. De hecho nos dar slo una cosa o la otra,
ya que si hay errores no es posible generar un cdigo objeto.

2.2.2. Warnings o Avisos.


Adems de errores, el compilador puede dar tambin Avisos o Warnings.
Los avisos son errores, pero no lo suficientemente graves como para impedir la generacin del
cdigo objeto. No obstante, es importante corregir estos avisos, ya que el compilador tiene que
decidir entre varias opciones, y sus decisiones no tienen por qu coincidir con lo que el

-5-

TALLER DE INFORMTICA

CAPITULO 2. Lenguaje C

programador pretende. Las decisiones se basan en las directivas que los creadores del compilador
decidieron durante su creacin.

2.2.3. Errores de enlazado.


El programa enlazador tambin puede encontrar errores que normalmente se refieren a funciones
que no estn definidas en ninguno de los ficheros objetos ni en las libreras. Puede que hayamos
olvidado incluir alguna librera, algn fichero objeto o que hayamos olvidado definir alguna funcin
o variable, o lo hayamos hecho mal.

2.2.4. Errores de ejecucin.


Aunque se haya obtenido un fichero ejecutable, es posible que se produzcan errores.
En el caso de los Errores de ejecucin normalmente no obtendremos mensajes de error, sino que
simplemente el programa terminar bruscamente. Estos errores son ms difciles de detectar y
corregir.
Existen programas auxiliares para buscar estos errores, son los llamados depuradores o debuggers.
Estos programas permiten detener la ejecucin de nuestros programas, inspeccionar variables y
ejecutar nuestro programa paso a paso. Esto resulta til para detectar excepciones, errores sutiles,
y fallos que se presentan dependiendo de circunstancias distintas.

2.2.5. Errores de diseo.


Finalmente los errores ms difciles de corregir y prevenir.
Si nos hemos equivocado al disear nuestro algoritmo, no habr ningn programa que pueda
ayudar al programador a corregir los errores de diseo. Contra estos errores slo cabe practicar,
pensar. Puede ayudar a solucionar este tipo de errores la opcin depurar que generalmente poseen
los compiladores del lenguaje C.

-6-

TALLER DE INFORMTICA

CAPITULO 3. Estructura de un programa

CAPITULO 3. ESTRUCTURA DE UN PROGRAMA.


Los programas de computadoras varan sustancialmente en cuanto al propsito, estilo y
complejidad. Pero la mayora debe: ingresar y almacenar datos, procesar los datos para almacenar
los resultados deseados y mostrar, almacenar o imprimir los resultados obtenidos.
Cada dato utilizado durante la ejecucin del programa deber ser descrito para que el compilador lo
reconozca, sepa cmo almacenarlo y recuperarlo; se deber reservar memoria para que pueda
almacenar la cantidad de datos necesarios.
Una vez almacenados los datos, stos debern procesarse. El proceso vara segn el propsito del
programa.
Finalmente, los datos procesados debern ponerse a disposicin del usuario. Cuando se utiliza el
lenguaje C para escribir un programa se debe tener en cuenta que:

Todos los programas poseen una funcin main() que indica el punto donde se inicia la
ejecucin. La ejecucin finaliza cuando se encuentra el final de main.
Debe declarar todas las variables antes de usarlas.

Las partes ms importantes de un programa en C son:

Directivas del pre-procesador: #include y #define.

Declaracin de variables globales.

Prototipos de funciones.

Declaracin de clases.

Funcin main.

Definicin de funciones.

Definicin de clases.

3.1. Directivas del preprocesador.


Las lneas que comienzan con el smbolo # son indicaciones para el compilador o directivas del

preprocesador.
Sintaxis:

#include <archivo.h>

La directiva include le indica al compilador que lea y compile el contenido del archivo con extensin
.h que contiene las descripciones de las funciones de librera utilizadas a lo largo del programa.
Por ejemplo:

#include <stdio.h>

Le indica al compilador que compile el contenido del archivo stdio.h.


Sintaxis:

#define nombre valor

La directiva define determina un reemplazo o sustitucin. La directiva le indica al compilador que


cada vez que en el programa aparezca nombre sea reemplazado por valor. Esta sentencia resulta
til cuando son programas largos y nombre se utiliza varias veces ya que, si cambia el valor de
nombre se debe modificar una sola vez al principio del programa.

-7-

TALLER DE INFORMTICA

CAPITULO 3. Estructura de un programa

Por ejemplo:

#define NUMERO 5.3

Le indica al compilador que cada vez que aparezca NMERO en el programa sea sustituido por 5.3.

3.2. Declaracin de variables globales.


Las expresiones que permiten realizar clculos dentro de los programas estn formadas por
variables, constantes y operadores.
Las variables se deben declarar antes de ser utilizadas en el programa, ya que el compilador debe
conocer qu tipo de dato es una variable antes de poder compilar cualquier sentencia que la use.
El lugar donde se declara una variable afecta mucho la manera en que otras partes del programa
pueden utilizarla.
Las reglas que determinan cmo se puede usar una variable basada en el lugar en que fue
declarada se llaman reglas de alcance del lenguaje.
Si la variable se declara en sta zona del programa, fuera de todas las funciones, incluyendo la
funcin main(), se denomina variable global y se puede utilizar en cualquier parte del programa.

3.3. Prototipos de funciones.


Antes de utilizar una funcin en el programa, sta se debe definir.
En esta porcin del programa se definen las funciones a utilizar indicando el nombre de la funcin,
el nmero y tipos de argumentos que utilizar durante la ejecucin. Finaliza cada sentencia con
punto y coma (;).
Esta definicin se realiza mediante los prototipos de funciones.

3.4. Declaracin de clases.


Lugar dentro de los programas donde se deben crear las nuevas clases, se les debe asignar un
nombre utilizando las sentencias struc, union o class de C++.

3.5. Funcin main().


Todos los programas escritos en C poseen una funcin llamada main(). Es la funcin que se
ejecuta en primer lugar cuando comienza a funcionar el programa. El programa posee una sola
funcin main().
En la siguiente lnea aparece una llave { que indica el grupo de instrucciones que definen lo que
suceder cuando se ejecute el programa.
Cada grupo de sentencias finaliza con una llave }.

3.6. Definicin de funciones.


Esta zona contiene el cdigo para cada funcin declarada. El encabezamiento de la definicin ser
exactamente igual a la declaracin, excepto que no finaliza con punto y coma (;).

3.7. Definicin de clases.


En esta parte del programa se deben definir los objetos o instancias de la clase declarada en la
zona 3.4.

-8-

TALLER DE INFORMTICA

CAPITULO 4. Datos, variables y constantes

CAPITULO 4. DATOS, VARIABLES Y CONSTANTES.


4.1 Datos.
Como se haba mencionado en el captulo 3, Cada dato utilizado durante la ejecucin del programa
deber ser descrito para que el compilador lo reconozca, sepa cmo almacenarlo y recuperarlo; se
deber reservar memoria para que pueda almacenar la cantidad de datos necesarios.
La declaracin de cada tem de datos consiste en indicar qu tipo de dato es y darle un nombre que
lo identifique.
En C hay tipos bsicos de datos: carcter (character), entero (integer), punto flotante (floating
point) y puntero (point); aunque, en cada versin del lenguaje, pueden aparecer ms o menos
tipos de datos.
Por ejemplo, en C slo existen cinco tipos fundamentales y los tipos enumerados, C++ aade un
sptimo tipo, el bool, y el resto de los tipos son derivados de ellos.
Los nmeros son los datos fundamentales utilizados por los programas de computadoras. El
contenido de la memoria consiste en nmeros binarios almacenados en grupos de 8 bits (1 byte) o
16 bits (2 bytes o 1 word). An cuando un programa de computadora trabaje con letras o grficos,
bsicamente est involucrando una serie de nmeros almacenados en memoria.
Los diferentes tipos de datos dependen, en realidad, de la cantidad de bytes que ocupen en
memoria.

Para obtener informacin ms detallada acerca de los tipos de datos, la cantidad de memoria
reservada remitirse al APENDICE Tipos de datos
Cuando se desea definir tems de datos que almacenen palabras (dos o ms caracteres) nos
encontramos ante el tipo de dato string o cadena de caracteres.
Por ejemplo:

`hola
Juan Prez

Este tipo de datos merece un desarrollo especial por ello se ver en el captulo 9 que estudia el
tema de arreglos.

4.2. Variables.
El tem de dato llamado variable, se refiere a un espacio de memoria cuyo contenido se modificar
de acuerdo a las circunstancias durante la ejecucin del programa.
Cada variable utilizada en el programa deber ser declarada antes de ser utilizada.
La declaracin de una variable le indica al lenguaje que se pretende utilizar una variable particular y
qu tipo de dato almacenar. La declaracin se forma por un tipo de dato seguido de uno o ms
nombres de variables.
La inicializacin de una variable significa asignarle al espacio de memoria reservado un valor
particular. Resulta conveniente realizarlo porque cuando se declara una variable, el espacio de
memoria reservado, podr contener cualquier valor.

-9-

TALLER DE INFORMTICA

CAPITULO 4. Datos, variables y constantes

4.2.1. Identificadores.
Un identificador es el nombre que permite identificar un espacio de memoria mediante un nombre
vlido para el lenguaje.
El lenguaje C es flexible pero posee ciertas reglas que debemos respetar cuando definimos
identificadores para las variables que utilizaremos en el programa.
Reglas para dar nombre a las variables:

Slo se pueden usar letras (maysculas o minsculas), nmeros y ciertos caracteres no


alfanumricos, como el '_', pero nunca un punto, coma, guin, comillas o smbolos
matemticos o interrogaciones.

El primer carcter no puede ser un nmero.

C y C++ distinguen entre maysculas y minsculas, de modo que los identificadores


nmero y Nmero son diferentes.

Los primeros 32 dgitos son significativos, esto significa que


La_cantidad_total_de_dinero_en_mi_cuenta y La_cantidad_total_de_dinero_en_mi_banco
sern consideradas como la misma variable.

4.2.2. Declaracin de variables.


Una caracterstica del C es la necesidad de la declaracin de las variables que se usarn en el
programa. Aunque esto resulta chocante para los que se aproximan al C desde otros lenguajes de
programacin, es en realidad una caracterstica muy importante y til de C, ya que ayuda a
conseguir cdigos ms compactos y eficaces, y contribuye a facilitar la depuracin, la deteccin y
correccin de errores.
Sintaxis:

[tipo] [lista_de_identificadores];

Tipo debe ser un tipo de datos vlido y lista_de_identificadores puede ser uno o ms identificadores
separados por coma (,). La declaracin de variables puede considerarse como una sentencia.
Desde este punto de vista, la declaracin terminar con un ";".
Por ejemplo:

int numero;
float promedio, final;
char letra;

Tambin es posible inicializar las variables dentro de la misma declaracin.


Por ejemplo:

int a = 1234;
bool seguir = true, encontrado;
char letra = k;

Se declarara las variables "a", "seguir", "encontrado" y letra; y adems se inicia los valores de
"a" en 1234, seguir en "true" y letra con k.

- 10 -

TALLER DE INFORMTICA

CAPITULO 4. Datos, variables y constantes

En C, contrariamente a lo que sucede con otros lenguajes de programacin, las variables no


inicializadas tienen un valor indeterminado, contienen lo que normalmente se denomina "basura",
tambin en esto hay excepciones como veremos ms adelante.

4.2.2.1. Declaracin de una variable de tipo entero (integer).


[signed |unsigned] [short | long | long long ] int <identificador o nombre>
[signed |unsigned] long long [ int ] <identificador o nombre>
[signed |unsigned] long [ int ] <identificador o nombre >
[signed |unsigned] short [ int ] <identificador o nombre >

4.2.2.2. Declaracin de una variable de tipo punto flotante (float).


float <identificador o nombre >

4.2.2.3. Declaracin de una variable de tipo punto flotante doble


precisin (double).
[long] double <identificador o nombre >

4.2.2.4. Declaracin de una variable sin tipo (void).


void <identificador o nombre >
Este es una variable especial que indica la ausencia de tipo. Se usa en funciones que no devuelven
ningn valor, tambin en funciones que no requieren parmetros, aunque este uso slo es
obligatorio en C, y opcional en C++, tambin se usar en la declaracin de punteros genricos.

4.2.2.5. Declaracin de una variable de tipo enumerado (enum).


enum [<identificador_de_enum>] { <nombre> [= <valor>], ...} [lista_de_variables];
Este tipo nos permite definir conjuntos de constantes, normalmente de tipo int, llamados datos de

tipo enumerado.

Las variables declaradas de este tipo slo podrn tomar valores entre los definidos.
El identificador de tipo es opcional, y nos permitir declarar ms variables del tipo enumerado en
otras partes del programa. La lista de variables tambin es opcional. Sin embargo, al menos uno de
los dos componentes opcionales debe aparecer en la definicin del tipo enumerado.
Varios identificadores pueden tomar el mismo valor, pero cada identificador slo puede usarse en
un tipo enumerado.
Por ejemplo:

enum tipo_horas {una=1, dos, tres, cuatro, cinco, seis, siete, ocho, nueve, diez, once,
doce, trece=1, catorce, quince, dieciseis, diecisiete, dieciocho, diecinueve, veinte,
veintiuna, veintids, veintitrs, veinticuatro =0};
En este caso, una y trece valen 1, dos y catorce valen 2, etc. Y veinticuatro vale 0. Como se ve en
el ejemplo, una vez se asigna un valor a un elemento de la lista, los siguientes toman valores
correlativos. Si no se asigna ningn valor, el primer elemento tomar el valor 0.

- 11 -

TALLER DE INFORMTICA

CAPITULO 4. Datos, variables y constantes

4.2.2.6. Declaracin de una variable de tipo boleana (boolean).


bool <identificador o nombre>
Las variables de este tipo slo pueden tomar dos valores "true" o "false". Sirven para evaluar
expresiones lgicas.
Este tipo de variables se puede usar para almacenar respuestas, por ejemplo: Posees carnet de
conducir? O para almacenar informaciones que slo pueden tomar dos valores, por ejemplo: qu
mano usas para escribir?
En estos casos debemos acuar una regla, en este ejemplo, podra ser:
diestro->"true", zurdo->"false".

4.2.3. Inicializacin de variables


En C se pueden asignar valores a la mayora de las variables a la vez que se las declara.
La inicializacin de una variable se realiza poniendo un signo igual y una constante despus del
identificador.
Sintaxis:

[tipo] [identificador = constante];

Por ejemplo:

char a = p; int num = 0;

4.2.4. Ejercicios sobre Variables


1)Cules de los siguientes son tipos vlidos de variables? Marcar la opcin correcta.
a) unsigned char
S
No
b) long char
S

No

c) unsigned float
S
No
d) double char
S
No
e) signed long
S
No
f) unsigned short
S
No
g) signed long int
S
No
h) long double
S
No

- 12 -

TALLER DE INFORMTICA

CAPITULO 4. Datos, variables y constantes

i) enum dia {lunes, martes, miercoles, jueves, viernes, sabado, domingo};


S
No
j) enum color {verde, naranja, rojo}; enum fruta {manzana, fresa, naranja, platano};
S
No
k) long bool
S

No

4.3. Constantes.
Las constantes son muy similares a las variables, con la diferencia que stas solo pueden tomar un
valor en el momento de la declaracin, luego cualquier intento de modificacin ser tomado como
un error por parte del compilador.
Las constantes se declaran del mismo modo que las variables, solamente se debe anteponer la
sentencia const antes del tipo de dato.
Por ejemplo:

const int mayor = 25;

4.3.1. Normas para la notacin.


Veremos las reglas que rigen la escritura de las constantes en C segn diversos sistemas de
numeracin y que uso tiene cada uno.
Por qu es necesaria la notacin?
En todos los casos, especificar el tipo de la constante tiene como objetivo evitar que se realicen
conversiones de tipo durante la ejecucin del programa, obligando al compilador a hacerlas durante
la fase de compilacin.
Por ejemplo:

float x = 0.0;
if(x <= 1.0f) x += 0.01f;

Si en el ejemplo hubiramos escrito "if(x <= 1)...", el compilador almacenara el 1 como un entero,
y durante la fase de ejecucin se convertir ese entero a float para poder compararlo con x, que es
float. Al poner "1.0" estamos diciendo al compilador que almacene esa constante como un valor en
coma flotante.
Lo mismo se aplica a las constantes long, unsigned y char.

4.3.1.1. Constantes "int".


En C se usan tres tipos de numeracin para la definicin de constantes numricas, el decimal, el
octal y el hexadecimal, segn se use la numeracin en base 10, 8 16, respectivamente.
Por ejemplo:

El nmero 127, se representar en:


notacin decimal como 127
octal como 0177
hexadecimal como 0x7f.

En notacin octal se usan slo los dgitos del '0' al '7'.


En la notacin hexadecimal se usan 16 smbolos, los dgitos del '0' al '9' tienen el mismo valor que
en decimal, para los otros seis smbolos se usan las letras de la 'A' a la 'F', indistintamente en

- 13 -

TALLER DE INFORMTICA

CAPITULO 4. Datos, variables y constantes

maysculas o minsculas. Sus valores son 10 para la 'A', 11 para la 'B', y sucesivamente, hasta 15
para la 'F'.
Segn el ejemplo el nmero 0x7f, donde "0x" es el prefijo que indica que se trata de un nmero en
notacin hexadecimal, sera el nmero 7F, es decir,
7F=7*16+15=127. Del mismo modo que el nmero 127 en notacin decimal sera,
1*10+2*10+7=127.
En octal se usa como prefijo el dgito 0. El nmero 0177 equivale a 0177=1*8+7*8+7=127.

Hay que tener mucho cuidado con las constantes numricas, en C y C++ no es el mismo nmero el
0123 que el 123, aunque pueda parecer otra cosa. El primero es un nmero octal y el segundo
decimal.
La ventaja de la numeracin hexadecimal es que los valores enteros requieren dos dgitos por cada
byte para su representacin. As un byte puede tomar valores hexadecimales entre 0x00 y 0xff, dos
bytes entre 0x0000 y 0xffff, etc. Adems, la conversin a binario es casi directa, cada dgito
hexadecimal se puede sustituir por cuatro bits, el '0x0' por '0000', el '0x1' por '0001', hasta el '0xf',
que equivale a '1111'. En el ejemplo el nmero 127, o 0x7f, sera en binario '01111111'.
Con la numeracin octal es anlogo, salvo que cada dgito agrupa tres bits.
As un byte se puede tomar valores octales entre 0000 y 0377, dos bytes entre 0000000 y
0177777, etc. Adems, la conversin a binario es casi directa, cada dgito octal se puede sustituir
por tres bits, el '0' por '000', el '1' por '001', hasta el '7', que equivale a '111'. En el ejemplo el
nmero 127, o 0177, sera en binario '01111111'.
De este modo, cuando trabajemos con operaciones de bits, nos resultar mucho ms sencillo
escribir valores constantes usando la notacin hexadecimal u octal.
Por ejemplo, resulta ms fcil predecir el resultado de la siguiente operacin:
Que:

A = 0xaa & 0x55;


A = 170 & 85;

En ambos casos el resultado es 0, pero en el primero resulta ms evidente, ya que 0xAA es en


binario 10101010 y 0x55 es 01010101, y la operacin "AND" entre ambos nmeros es 00000000,
es decir 0.
Ahora se propone al alumno intentarlo con los nmeros 170 y 85.-

4.3.1.2. Constantes "long".


Para trabajar con valores constantes "long" debemos usar el sufijo "L". Esto resulta conveniente,
sobre todo, al utilizar las constantes en expresiones condicionales y, por coherencia, tambin en
expresiones de asignacin.
Por ejemplo:

long x = 123L;
if(x == 0L) cout << "Valor nulo" << endl;

Puede suceder que el compilador nos seale un error cuando usemos constantes long sin aadir el
sufijo L.

- 14 -

TALLER DE INFORMTICA

CAPITULO 4. Datos, variables y constantes

Por ejemplo:

if(x == 1343890883) cout << "Nmero long int" << endl;

Esta sentencia har que el compilador emita un error ya que no puede usar un tamao mayor sin
una indicacin explcita.
Hay casos en los que los tipos "long" e "int" tienen el mismo tamao, en ese caso no se producir
error, pero no podemos predecir que nuestro programa se compilar en un tipo concreto de
compilador o plataforma.

4.3.1.3. Constantes "long long".


Para trabajar con valores constantes "long long" debemos usar el sufijo "LL", sobre todo cuando
esas constantes aparecen en expresiones condicionales o de asignacin.
Por ejemplo:

long long x = 16575476522787LL;


if(x == 1LL) cout << "Valor nulo" << endl;

Como cuando se utilizan constantes long, a menudo recibiremos errores del compilador cuando
usemos constantes long long sin aadir el sufijo LL.
Por ejemplo:

if(x == 16575476522787) cout << "Nmero long long" << endl;

Esta sentencia har que el compilador emita un error ya que no puede usar un tamao mayor sin
una indicacin explcita.

4.3.1.4. Constantes "unsigned".


Del mismo modo, cuando trabajamos con valores constantes "unsigned" debemos usar el sufijo "U"
para las mismas situaciones que hemos indicado para las constantes "long".
Por ejemplo:

unsigned int x = 123U;


if(x == 3124232U) cout << "Valor encontrado" << endl;

4.3.1.5. Constantes "unsigned long".


En una constante, es posible utilizar los modificadores "unsigned" y "long", en ese caso debemos
usar el sufijo "UL" para las mismas situaciones que hemos indicado para las constantes "long" y
"unsigned".
Por ejemplo:

unsigned long x = 123456UL;


if(x == 3124232UL) cout << "Valor encontrado" << endl;

4.3.1.6. Constantes "unsigned long long".


Tambin es posible combinar, en una constante, los modificadores "unsigned" y "long long", en ese
caso debemos usar el sufijo "ULL", para las mismas situaciones que hemos indicado para las
constantes "long long" y "unsigned".
Por ejemplo:

unsigned long long x = 123456534543ULL;


if(x == 3124232ULL) cout << "Valor encontrado" << endl;

- 15 -

TALLER DE INFORMTICA

CAPITULO 4. Datos, variables y constantes

4.3.1.7. Constantes "float".


Tambin existe una notacin especial para las constantes en punto flotante.
En este caso consiste en aadir ".0" a aquellas constantes que puedan interpretarse como enteras.
Si se usa el sufijo "f" se tratar de constantes en precisin sencilla, es decir "float".
Por ejemplo:

float x = 0.0;
if(x <= 1.0f) x += 0.01f;

4.3.1.8. Constantes "double".


Si no se usa el sufijo f, se tratar de constantes de precisin doble, es decir tipo "double".
Por ejemplo:

double x = 0.0;
if(x <= 1.0) x += 0.01;

4.3.1.9. Constantes "long double".


Si se usa el sufijo "l" se tratar de constantes en precisin mxima, es decir "long double".
Por ejemplo:

long double x = 0.0L;


if(x <= 1.0L) x += 0.01L;

4.3.1.10. Constantes "char".


Las constantes de tipo "char" se representan entre comillas sencillas, por ejemplo 'a', '8', 'F'.

4.3.2. Recomendaciones en el uso de la notacin.


4.3.2.1. Constantes enteras.
En general podemos combinar los prefijos "0" y "0x" con los sufijos "L", "U", y "UL". Aunque es
indiferente usar los sufijos en maysculas o minsculas, es preferible usar maysculas, sobre todo
con la "L", ya que la 'l' minscula puede confundirse con un uno '1'.

4.3.2.2. Constantes punto flotante.


Se recomienda aadir el .0, cuando la constante se pueda confundir con un entero.
Usar la notacin exponencial
Tambin podemos usar notacin exponencial, donde el formato exponencial consiste en un
nmero, llamado mantisa, que puede ser entero o con decimales, seguido de una letra 'e' o 'E' y
por ltimo, otro nmero (entero) que es el exponente de una potencia de base 10.
Por ejemplo:

double x = 10e4;
double y = 4.12e2;
double pi = 3.141592e0;

- 16 -

TALLER DE INFORMTICA

CAPITULO 4. Datos, variables y constantes

Los valores anteriores se representaran:

x = 10 x 104 = 100000
y = 4,12 x 102 = 412
pi = 3.141592 x 100 = 3.141592

Al igual que con los enteros, es indiferente usar los sufijos en maysculas o minsculas, pero es
preferible usar maysculas, sobre todo con la "L", ya que la 'l' minscula puede confundirse con un
uno '1'.

4.3.3 Constantes carcter. Comentario adicional.


Si has pensado que una constante char se representa con 'k', tal vez, despus de un rato te
preguntes cmo se representa la constante que consiste en una comilla sencilla?
Existen ciertos caracteres, entre los que se encuentra la comilla sencilla, que no pueden ser
representados con la norma general. Para eludir este problema existe cierto mecanismo, llamado
secuencias de escape. En el caso comentado, la comilla sencilla se define como '\', y la barra
descendente se define como '\\'.
Adems de estos caracteres especiales existen otros.

4.3.3.1. Cdigo ASCII.


El cdigo ASCII es el conjunto de caracteres que puede ser representado por el tipo "char", consta
de 128 o 256 caracteres.
El cdigo ASCII de 128 caracteres utiliza 7 bits, actualmente ha quedado prcticamente obsoleto ya
que no admite caracteres como la '' o la '' pero, an se usa en ciertos equipos antiguos donde el
octavo bit se usa como bit de paridad en las transmisiones serie.
El cdigo ASCII de 256 caracteres utiliza los 8 bits y, si recordamos, el tipo "char" tiene siempre un
byte (8 bits) y esto no es por casualidad.
En este conjunto existen, adems de los caracteres alfabticos, en maysculas y minsculas, los
numricos, los signos de puntuacin y los caracteres internacionales, ciertos caracteres no
imprimibles, como el retorno de lnea, el avance de lnea, etc.
Veremos estos caracteres y cmo se representan como secuencia de escape, en hexadecimal, el
nombre ANSI y el resultado o significado.

- 17 -

TALLER DE INFORMTICA

CAPITULO 4. Datos, variables y constantes

Los tres ltimos son realmente comodines para la representacin de cualquier carcter.
El \nnn sirve para la representacin en notacin octal. Para la notacin octal se usan tres dgitos.
Hay que tener en cuenta que, anlogamente a lo que sucede en la notacin hexadecimal, en octal
se agrupan los bits de tres en tres. Por lo tanto, para representar un carcter ASCII de 8 bits, se
necesitarn tres dgitos. En octal slo son vlidos los smbolos del '0' al '7'.
Segn el ejemplo anterior, para representar el carcter 127 en octal usaremos la cadena '\177', y
en hexadecimal '\x7f'. Tambin pueden asignarse nmeros decimales a variables de tipo char.
Por ejemplo:

char A;
A = 'a';
A = 97;
A = 0x61;
A = '\x61';
A = '\141';

En este ejemplo todas las asignaciones son equivalentes y vlidas.

#include <iostream>
using namespace std;
int main()
{char opc0='A'; //Ascii de A expresado como Caracter
char opc1=65 ; //Ascii de A expresado en Decimal
char opc2= 0101; //Ascii de A expresado en Octal
char opc3 = 0x41; //Ascii de A expresado en Hexadecimal
cout << opc0 <<endl;
cout << opc1 <<endl;
cout << opc2 <<endl;
cout << opc3 <<endl;
return 0;
}
La salida de este programa muestra por pantalla 4 veces la A.

4.3.3.2. Carcter nulo.


El carcter nulo se usa en C para indicar la terminacin de las cadenas de caracteres, por lo tanto
es muy til y de uso frecuente.
Para hacer referencia a l se usa frecuentemente su valor decimal, es decir char A = 0, aunque es
muy probable que lo encuentres en libros o en programas como '\000', es decir en notacin octal.

4.3.3.3. Carcter EOF.


EOF viene del ingls "End Of File", este carcter se usa en muchos ficheros como marcador de fin
de fichero, sobre todo en ficheros de texto. Aunque dependiendo del sistema operativo este
carcter puede cambiar, por ejemplo en MS-DOS es el carcter "0x1A", el compilador siempre lo
traduce y devuelve el carcter EOF cuando un fichero se termina.

- 18 -

TALLER DE INFORMTICA

CAPITULO 4. Datos, variables y constantes

4.3.4. Ejercicios
1) si debe almacenar el dato, qu tipo de constante debera utilizar en cada caso? Marcar la opcin
correcta.
a) '\x37'
1. char
2. long
3. int
4. float
b) 123UL
1. unsigned
2. int
3. long
4. unsigned long
c) 34.0
1.
2.
3.
4.

int
double
float
long

d) 6L
1.
2.
3.
4.

int
long
double
char

e) 67
1.
2.
3.
4.

char
unsigned
int
float

f) 0x139
1. char
2. unsigned
3. int
4. float
g) 0x134763df23LL
1.
2.
3.
4.

long
unsigned
int
long long

Para la creacin de identificadores en la escritura del cdigo fuente se recomienda ver APENDICE
ESTILOS DE NOTACIN.

- 19 -

TALLER DE INFORMTICA

CAPITULO 5. Operadores

CAPITULO 5. OPERADORES.
Los operadores son elementos que disparan ciertos clculos cuando son aplicados a variables o a
otros objetos en una expresin.
Un operador es un smbolo que le dice al compilador que realice manipulaciones matemticas o
lgicas especficas.
El lenguaje C tiene las siguientes clases de operadores: aritmticos, relacionales, lgicos y sobre
bits.
Hay varios tipos de operadores, clasificados segn el tipo de objetos sobre los que actan.
Los tipos de operadores que veremos son:

Operadores Aritmticos.

Operadores Relacionales.

Operadores Lgicos.

Operadores de Asignacin.

Operador sizeof.

Operador condicional.

Operador coma.

5.1. Operadores aritmticos.


Los operadores aritmticos se utilizan para crear expresiones matemticas.

5.1.1. Operadores aritmticos unitarios.


Los operadores aritmticos unitarios que utiliza el C son: '+', '-','++', '--'
Sintaxis:

+ <expresin>
- <expresin>
<variable> ++ /* post-incremento */
++ <variable> /* pre-incremento */
<variable>-- /* post-decremento */
-- <variable> /* pre-decremento */

5.1.1.1. Operadores '+' y '- .


Los operadores aritmticos unitarios '+' y '-' asignan valores positivos o negativos a la expresin a
la que se aplican.

5.1.1.2. Operadores '++' y '--'.


Los otros dos operadores unitarios '++' y '--' son un tanto especiales, ya que slo pueden trabajar
sobre variables, pues implican una asignacin.
El primero ('++') incrementa el valor del operando y el segundo ('--') lo decrementa, ambos en una
unidad.

- 20 -

TALLER DE INFORMTICA

CAPITULO 5. Operadores

Existen dos modalidades, dependiendo de que se use el operador en la forma de prefijo o de sufijo.
En su forma de prefijo, el operador es aplicado antes de que se evale el resto de la expresin; en
la forma de sufijo, se aplica despus de que se evale el resto de la expresin.
Por ejemplo:

en las siguientes expresiones "a" vale 100 y "b" vale 10:


c = a + ++b;

En este primer ejemplo primero se aplica el pre-incremento, y b valdr 11 a continuacin se evala


la expresin "a+b", que dar como resultado 111, y por ltimo se asignar este valor a c, que
valdr 111.
Por ejemplo:

c = a + b++;

En este segundo ejemplo primero se avala la expresin "a+b", que dar como resultado 110, y se
asignar este valor a c, que valdr 110.
Finalmente se aplica en post-incremento, y b valdr 11.
Los operadores unitarios sufijos (post-incremento y post-decremento) se evalan despus de que
se han evaluado el resto de las expresiones.
En el primer ejemplo primero se evala ++b, despus a+b y finalmente c=<resultado>.
En el segundo ejemplo, primero se evala a+b, despus c = <resultado> y finalmente b++.

Es muy importante no pensar o resolver las expresiones C como ecuaciones matemticas, NO SON
EXPRESIONES MATEMATICAS.
No veas estas expresiones como ecuaciones, NO SON ECUACIONES.

5.1.2. Operadores aritmticos binarios.


Los operadores binarios que utiliza el lenguaje C son: ' +', ' - ', ' * ', ' / ', % '
Sintaxis:

<expresin>
<expresin>
<expresin>
<expresin>
<expresin>

+ <expresin> /*Sintaxis de operador suma */


- <expresin> /* Sintaxis de operador resta */
* <expresin> /* Sintaxis de operador multiplicacin */
/ <expresin> /* Sintaxis de operador divisin */
% <expresin> /* Sintaxis de operador resto */

Evidentemente se trata de las conocidas operaciones aritmticas de suma, resta, multiplicacin y


divisin y los operadores se comportan como en cualquier lenguaje de computadoras.
Debemos tener en cuenta, por ejemplo, que el operador divisin ( / ) aplicado a un entero truncar
(perder) cualquier resto.
Por ejemplo:

10 / 3 ser igual a 3 para la divisin entera.

El operador mdulo '%', devuelve el resto de la divisin entera del primer operando entre el
segundo. Por esta razn no puede ser aplicado a operando en coma flotante (ya que al ser
nmeros de punto flotante no hay resto!!).

- 21 -

TALLER DE INFORMTICA

CAPITULO 5. Operadores

5.2. Operadores relacionales.


Los operadores relacionales permiten determinar las relaciones que un valor o cantidad puede
tener con otro.
Aqu resulta clave la idea de verdadero o falso. En C cualquier valor distinto de cero es verdadero, y
cero (0) es falso. As, las expresiones que utilizan operadores relacionales devolvern como
resultado 0 si es falsa y 1 si es verdadera la expresin.
A continuacin mostramos los operadores relacionales y su sintaxis:

En las expresiones, "E1 <operador_relacional> E2, los operandos (E1, E2) tienen algunas
restricciones, pero de momento nos conformaremos con que sean de tipo aritmtico. El resto de las
restricciones las veremos cuando conozcamos los punteros y los objetos.

Es un error frecuente utilizar el = en lugar del ==, observar que el = es para ASIGNAR; y el
== es para COMPROBAR LA IGUALDAD.

5.3. Operadores lgicos.


Los operadores lgicos conforman expresiones lgicas y se utilizan para determinar cmo se
presentan las relaciones entre las expresiones involucradas.
La siguiente tabla presenta los operadores lgicos y su sintaxis:

5.3.1. Operador && o AND.


El operador "&&" equivale al "AND" o "Y"; devuelve "true" slo si las dos expresiones evaluadas
son "true" o distintas de cero, en caso contrario devuelve "false" o cero. Si la primera expresin
evaluada es "false", la segunda no se evala.
Generalizando, con expresiones AND con ms de dos expresiones, la primera expresin falsa
interrumpe el proceso e impide que se contine la evaluacin del resto de las expresiones. Esto es
lo que se conoce como "cortocircuito", y es muy importante, como veremos posteriormente.
El operador && se usa segn la siguiente tabla de verdad, donde se representa true con 1 y
false con 0.

- 22 -

TALLER DE INFORMTICA

CAPITULO 5. Operadores

5.3.2. Operador || u OR.


El operador "||" equivale al "OR" u "O inclusivo"; devuelve "true" si cualquiera de las
expresiones evaluadas es "true" o distinta de cero, en caso contrario devuelve "false" o cero. Si la
primera expresin evaluada es "true", la segunda no se evala.
El operador || se usa segn la siguiente tabla de verdad, donde se representa l

5.3.3. Operador ! o NOT.


El operador "!" es equivalente al "NOT", o "NO", y devuelve "true" slo si la expresin evaluada es
"false" o cero; en caso contrario devuelve "false".
La expresin "!E" es equivalente a (0 == E).
El operador ! se usa segn la siguiente tabla de verdad, donde se representa true con 0 y false
con 1.

5.4. Operadores de asignacin.


La asignacin consiste en un nombre de variable, seguido de un signo igual y el valor a ser
asignado.
Por ejemplo: a = 14;
El operador asigna el valor de la izquierda (14) a la variable (a) que est a la derecha del operador
asignacin (=).
Existen varios operadores de asignacin, el ms evidente y el ms usado es el "=", pero no es el
nico.
Los operadores de asignacin y sus diferentes usos se describen a continuacin:

- 23 -

TALLER DE INFORMTICA

CAPITULO 5. Operadores

5.5. Operador "sizeof".


El operador sizeof es un operador del tiempo de compilacin.
Este operador tiene dos usos diferentes. Devuelve el tamao de la variable o tipo que est como
operando. Si el operador funciona sobre un tipo de dato, ste deber ir entre parntesis.
Sintaxis:

sizeof <expresin>
sizeof (nombre_de_tipo)

En ambos casos, el resultado es una constante entera que da el tamao en bytes del espacio de
memoria usada por el operando, que es determinado por su tipo.
El espacio reservado por cada tipo depende de la plataforma.
En el primer caso, el tipo del operando es determinado sin evaluar la expresin, y por lo tanto sin
efectos secundarios.
Por ejemplo:

si el operando es de tipo "char", el resultado es 1.

A pesar de su apariencia, sizeof() NO es una funcin, sino un OPERADOR.

5.6. Operador condicional (?).


El operador "?:", se trata de un operador ternario (es decir tiene TRES operandos)
Sintaxis:

<expresin lgica> ? <expresin> : <expresin>

En la expresin E1? E2:E3, primero se evala la expresin E1, si el valor es verdadero ("true"), se
evaluar la expresin E2 y E3 ser ignorada, si es falso ("false"), se evaluar E3 y E2 ser ignorada.
Hay ciertas limitaciones en cuanto al tipo de los argumentos:
E1 debe ser una expresin lgica.
E2 y E3 deben ser de tipo aritmtico.
E2 y E3 deben ser de estructuras o uniones compatibles.
E2 y E3 deben ser de tipo "void".
Por ejemplo:

max = (a >=b) ? a : b;

A la variable max se le asigna el mayor valor.

#define max (a,b) (((a) > (b)) ? (a) : (b))

De este ejemplo slo nos interesa la parte de la derecha. La interpretacin es: si "a" es mayor que
"b", se debe evaluar "a", en caso contrario evaluar "b", en resumen, evala siempre el mximo!!
- 24 -

TALLER DE INFORMTICA

CAPITULO 5. Operadores

5.7. Operador coma (,).


El operador coma se utiliza para encadenar diversas expresiones. Provoca una secuencia de
operaciones a realizar, se puede pensar como hacer esto y luego esto.
Tiene una doble funcin: separa elementos de una lista de argumentos de una funcin. puede ser
usado como separador en expresiones "de coma".
Ambas funciones pueden ser mezcladas, pero hay que aadir parntesis para resolver las
ambigedades y provocar errores, ya que el operador coma tiene precedencia ms baja, por
ejemplo, que el operador de asignacin.
Sintaxis:

E1, E2, ... , En

En una expresin "de coma", cada operando es evaluado como una expresin, pero los resultados
obtenidos se tienen en cuenta en la prxima evaluacin.
Por ejemplo:

x = (y=3,y+1);

En primer lugar asigna el valor 3 a la variable y, y despus asigna el valor 4 a la variable x.

- 25 -

TALLER DE INFORMTICA

CAPITULO 6. Expresiones

CAPITULO 6. EXPRESIONES.
La combinacin de variables, constantes definidas o nmeros con uno o ms operadores dan como
resultado un valor. Esta combinacin recibe el nombre de expresin.
Una expresin es, segn el diccionario, un "conjunto de trminos que representan una cantidad",
entre nosotros es cualquier conjunto de operadores y varios operando, que dan como resultado
una cantidad.
Operando es cada una de las cantidades, constantes, variables o expresiones que intervienen en
una expresin.
Existe una divisin, en los operadores, atendiendo al nmero de operando que afectan. Segn esta
clasificacin pueden ser unitarios, binarios o ternarios, los primeros afectan a un solo operando, los
segundos a dos y los ternarios como era de esperar a tres.
Las variables y constantes se pueden procesar utilizando operaciones y funciones adecuadas a sus
tipos.
Cada expresin toma un valor que se determina tomando los valores de las variables y constantes
implicadas y la ejecucin de las operaciones indicadas.
Las expresiones se pueden clasificar, segn los tipos de objetos que manipulan, en:

Aritmticas: cuyo resultado sera de tipo numrico.

Lgicas: cuyo resultado sera de tipo lgico.

Carcter: cuyo resultado sera de tipo carcter.

6.1. Expresiones aritmticas.


Una expresin aritmtica es un conjunto de variables y/o constantes unidas o relacionadas por
parntesis y operadores aritmticos.
Son anlogas a las frmulas matemticas. Las variables y constantes son numricas (enteras o
punto flotante) y las operaciones son aritmticas.
Por ejemplo:

sueldo = sueldo_base + 0.15 * monto_ventas


e = a*b*b / 3 + (a*a + b) / (b + c)

Cuando se utilizan expresiones aritmticas se debe tener en cuenta que:

Si en una operacin ambos operando son enteros, entonces el resultado de la operacin es


un entero.

Si en una operacin uno o ambos operando son reales, entonces el


operacin es un real.

El operador / produce un cociente entero si los dos operando son enteros. Esto significa
que se pierde la parte decimal si la divisin no es exacta. Esta es una consecuencia de la
nota 1.

El operador / produce un cociente float si uno o los dos operando son float. Esta es una
consecuencia de la nota 2.

Por ejemplo:

resultado

de

la

7 / 2 es igual a 3 y no 3.5 como lo es matemticamente. Esto debido a que 7 y 2 son


enteros y al dividir dos enteros se pierde la parte fraccionaria, no se redondea.
- 26 -

TALLER DE INFORMTICA

CAPITULO 6. Expresiones

En cambio:

7.0 / 2 es igual a 3.5 ya que si uno o los dos operando son reales, entonces el resultado
es real. En este caso 7.0 es real.

6.1.1. Reglas de Precedencia.


Las expresiones que tienen dos o ms operando requieren reglas matemticas que permitan
determinar el orden de las operaciones.
Las Reglas de Prioridad o Precedencia son las reglas matemticas que permiten determinar el orden
de las operaciones.
Son:

Las operaciones que estn encerradas entre parntesis se evalan primero. Si aparecen
varios parntesis anidados, se evalan primero los parntesis interiores.

En caso de coincidir varios operadores de igual prioridad, el orden se determina de


izquierda a derecha.

Las operaciones aritmticas dentro de una expresin suelen seguir el siguiente orden de
prioridad:

Para ms detalle sobre operadores y reglas de precedencia ver


APENDICE. Precedencia de Operadores.

6.2. Expresiones lgicas.


Una expresin lgica o booleana es un conjunto de variables y/o constantes unidas mediante
operadores lgicos y operadores relacionales.
Las expresiones lgicas se forman combinando constantes lgicas, variables lgicas y otras
expresiones lgicas, utilizando operadores lgicos y relacionales; y su valor siempre es verdadero o
falso.
Una expresin lgica solo puede tomar uno de dos valores: verdadero o falso.
Las expresiones lgicas son ampliamente utilizadas en las estructuras selectivas y las estructuras
repetitivas.

- 27 -

TALLER DE INFORMTICA

CAPITULO 6. Expresiones

6.2.1. Expresiones comparativas.


El formato general para las comparaciones es:

<Expresin1> operador de relacin <Expresin2>


y el resultado ser verdadero o falso.
Por Ejemplo:

Si A = 4 y B = 3
A > B da como resultado Verdadero
(A 2) < (B 4) da como resultado Falso.

Los operadores de relacin se pueden aplicar a los tipos de datos estndar: entero, punto flotante,
carcter lgico.

6.2.1.1. Aplicacin en datos tipo carcter.


La aplicacin en valores numricos es evidente; pero cuando deba comparar datos de tipo carcter,
se requiere de una secuencia de ordenacin de los caracteres, similar al orden creciente o
decreciente.
La ordenacin suele ser alfabtica y se recurre al cdigo normalizado ASCII, donde:
0 < 1 < 2 < 3 ....
A < B < C ....
a < b < c ....

6.2.1.2. Aplicacin en datos tipo lgico.


Cuando se utilizan los operadores de relacin con valores lgicos, Falso < Verdadero.
Por ejemplo:

Si tenemos la expresin Falso < Verdadero, dar como resultado


Verdadero

6.2.1.3. Aplicacin en datos tipo punto flotante.


Cuando se utilizan los operadores = <> en valores punto flotante, es importante recordar que
estos valores no se pueden almacenar exactamente, debido a la precisin aritmtica limitada de las
computadoras.
As, lo aconsejable es excluir a los valores punto flotante en este tipo de comparaciones.

6.2.2. Expresiones lgicas.


En las expresiones lgicas se pueden mezclar operadores de relacin y lgicos.
Por Ejemplo:

(1 < 5) and (5 < 10) da como resultado Verdadero.


(5 < 10) or (A < B) da como resultado Verdadero.

- 28 -

TALLER DE INFORMTICA

CAPITULO 6. Expresiones

Para ms detalle sobre operadores y reglas de precedencia ver APENDICE. Precedencia de


Operadores.
Al igual que en las expresiones aritmticas, los parntesis se podrn utilizar y tendrn prioridad
sobre cualquier operacin.
Por Ejemplo:

not 4 > 6 da como resultado ERROR, ya que el operador NOT no se aplica sobre
el 4.
not(4 > 6) da como resultado Verdadero

6.3. Ejercicios con operadores y expresiones


1) Suponiendo los siguientes valores iniciales para las variables: x = 2; y = 6; z = 9; r = 100;
s = 10; a = 15; b = 3; Cules son los valores correctos en cada expresin? Marcar la opcin
correcta.
a) x += 10;
12
10
11
b) s *=

c) r /=

b;
9
13
30

0;
infinito
1
error

d) y += x + 10;
8
12
18
e) z -=

a*b;
-36
-18
36

2) Usar expresiones equivalentes para las siguientes, usando operadores mixtos.


a) x =

10 + x - y;
x += 10-y
x -= y+10
x += 10+y

- 29 -

TALLER DE INFORMTICA
b) r =

100*r;
r *= 100*r
r *= 100
r += 100

c) y =

y/(10+x);
y /= 10*x
y /= 10 + y/x
y /= 10+x

d) z =

3 * x + 6;
z += 6
z *= 3
no es posible

CAPITULO 6. Expresiones

3) Evaluar las siguientes expresiones. Siendo:x = 10; y = 20; z = 30;


a) z =

x - y, t = z - y;
z=-10, t=-30
t=10
z=30, t=-30

b) (x < 10) && (y > 15)


true
false
c) (x <= z) || (z <= y)
true
false
d) !(x+y < z)
true
false
e) (x+y != z) && (1/(z-x-y) != 1)
true
false
error

- 30 -

TALLER DE INFORMTICA

CAPITULO 7. Instrucciones

CAPITULO 7. INSTRUCCIONES
El elemento que nos est faltando para poder comenzar a escribir nuestros propios programas son
las sentencias o instrucciones.
Un programa contiene las acciones o instrucciones que resolvern el problema. Las instrucciones
describen la secuencia de pasos con el que se quiere solucionar el problema planteado.
Existen instrucciones de diversos tipos que nos permitirn enfrentarnos a todas las situaciones
posibles en programacin.
Los tipos de sentencias son:
Bloques
Expresiones
Llamadas a funcin
Asignacin
Nula
Bucles
while
do while
for
Etiquetas
Etiquetas de identificacin
case
default
Seleccin
if...else
switch
Saltos

break
continue
goto
return

Veamos cada una de ellas.

7.1. Bloques.
Una sentencia compuesta o un bloque es un conjunto de sentencias, que puede estar vaca,
encerrada entre llaves " {} ".
Sintcticamente, un bloque se considera como una nica sentencia.
Tambin se usa en variables compuestas, como veremos en el captulo de variables II, y en la
definicin de cuerpo de funciones.
Los bloques pueden estar anidados hasta cualquier profundidad.

- 31 -

TALLER DE INFORMTICA

CAPITULO 7. Instrucciones

7.2. Expresiones.
Una expresin seguida de un punto y coma (;), forma una sentencia de expresin.
La forma en que el compilador ejecuta una sentencia de este tipo es evaluando la expresin.
Cualquier efecto derivado de esta evaluacin se completar antes de ejecutar la siguiente
sentencia.
Sintaxis:

<expresin>;

7.2.1. Llamadas a funcin.


La sentencia de llamada a funcin es la manera de ejecutar las funciones que se definen en otras
partes del programa o en el exterior de ste, ya sea una librera estndar o particular.
La llamada a funcin se forma con el nombre de la funcin, una lista de parmetros entre
parntesis y un ";".

7.2.2. Asignacin.
Una instruccin de asignacin consiste en dar a una variable el valor de una expresin, el valor de
otra variable o el valor de una constante.
La sentencia de asignacin se utiliza para almacenar valores a variables o constantes.
Es una operacin que sita un valor determinado en una posicin de memoria.
Sintaxis:

<variable> <operador de asignacin> <expresin>;

La expresin de la derecha es evaluada y el valor obtenido es asignado a la variable o constante de


la izquierda. El tipo de asignacin depender del operador utilizado, estos operadores ya los vimos
en el captulo anterior.
En la parte izquierda de la asignacin se pone el nombre de la variable que se quiere modificar. La
parte derecha contiene una expresin que le dar el nuevo valor a la variable, y por lo tanto debe
tener el mismo tipo que la variable.

7.2.3. Nula.
La sentencia nula consiste en un nico ";". Sirve para usarla en los casos en los que el compilador
espera que aparezca una sentencia, pero en realidad no pretendemos hacer nada. Veremos
ejemplos de esto cuando lleguemos a los bucles.

7.3. Bucles.
Un bucle es la estructura de control que permite la repeticin de una serie determinada de
sentencias. Es importante tener en cuenta cuntas veces se repite el bucle y cul es el cuerpo del
bucle.
El cuerpo del bucle lo constituyen la serie de sentencias que pueden ser de cualquier tipo
(secuencial, de decisin o repetitivo) las cuales sern repetidas n veces, pudiendo ser n conocido o
desconocido. Cuando n es desconocido, el nmero de veces que debe repetirse el cuerpo del bucle
estar condicionado por una expresin lgica.
Un bucle no es ms que una serie de instrucciones que se repiten.

- 32 -

TALLER DE INFORMTICA

CAPITULO 7. Instrucciones

A la hora de utilizar un bucle, sea del tipo que sea, debemos ir con cuidado y pensar cuando debe
acabar ya que si no tuviramos en cuenta esto podramos entrar en un bucle sin fin, iramos
repitiendo las mismas lneas teniendo que abortar la aplicacin, para poder finalizar la ejecucin del
programa.
Por esto, es de suma importancia que pensemos, antes de hacer nada, en qu momento, cmo,
dnde y por qu debe acabar el bucle.

7.3.1. Bucle "while".


Es la sentencia de bucle ms sencilla, y sin embargo es tremendamente potente.
Sintaxis:

while (<condicin>) <sentencia/s>;

La sentencia o el grupo de sentencias es ejecutado repetidamente mientras la condicin sea


verdadera, ("while" en ingls significa "mientras").
Si no se especifica condicin se asume que es "true", y el bucle se ejecutar indefinidamente.
Si la primera vez que se evala la condicin resulta falsa, la/s sentencia/s no se ejecutarn ninguna
vez.
Por ejemplo:

while (x < 100) x = x + 1;


Se incrementar el valor de x mientras x sea menor que 100.

Este ejemplo puede escribirse, usando el C con propiedad y elegancia, de un modo ms compacto:

while (x++ < 100);


Aqu vemos el uso de una sentencia nula, observa que el bucle simplemente se repite, y la
sentencia ejecutada es ";", es decir, nada.

7.3.2. Bucle "do while".


Esta sentencia va un paso ms all que el "while".
Sintaxis:

do <sentencia/s> while(<condicin>);

La/s sentencia/s es ejecutada repetidamente mientras la condicin resulte verdadera.


Si no se especifica condicin se asume que es "true", y el bucle se ejecutar indefinidamente.
A diferencia del bucle "while", la evaluacin se realiza despus de ejecutar la sentencia, de modo
que se ejecutar al menos una vez.
Por ejemplo:

do
x = x + 1;
while (x < 100);

Se incrementar el valor de x hasta que x valga 100.

- 33 -

TALLER DE INFORMTICA

CAPITULO 7. Instrucciones

7.3.3. Bucle "for".


Por ltimo, el bucle "for", es el ms elaborado.
Sintaxis:

for ( [<inicializacin>]; [<condicin>] ; [<incremento>] )


<sentencia/s>

La/s sentencia/s es ejecutada repetidamente hasta que la evaluacin de la condicin resulte falsa.
Antes de la primera iteracin se ejecutar la iniciacin del bucle, que puede ser una expresin o
una declaracin.
En este apartado se iniciarn las variables usadas en el bucle. Estas variables pueden ser
declaradas en este punto, pero en ese caso tendrn validez slo dentro del bucle "for".
Despus de cada iteracin se ejecutar el incremento de las variables del bucle.
Todas las expresiones son opcionales, si no se especifica la condicin se asume que es verdadera.
Por ejemplo:

for (int i = 0; i < 100; i = i + 1);

Como las expresiones son opcionales, podemos simular bucles "while":

for(;i < 100;) i = i +1;


for(;i++ < 100;);
O bucles infinitos:

for(;;);

7.4. Etiquetas.
Los programas C y C++ se ejecutan secuencialmente, aunque esta secuencia puede ser
interrumpida de varias maneras.
Las etiquetas son la forma en que se indica al compilador en qu puntos ser reanudada la
ejecucin de un programa cuando haya una ruptura del orden secuencial.

7.4.1. Etiquetas de identificacin.


Las etiquetas de identificacin sirven como puntos de entrada para la sentencia de salto "goto".
Sintaxis:

<identificador>: <sentencia>

Estas etiquetas tienen el mbito restringido a la funcin dentro de la cual estn definidas.
Veremos su uso con ms detalle al analizar la sentencia "goto".

7.4.2. Etiquetas "case" y "default".


Estas etiquetas se circunscriben al mbito de la sentencia "switch", y se ver su uso cuando
estudiemos ese apartado.
Sintaxis:

switch(<variable>)
{
case <expresin_constante>: [<sentencias>][break;]
...
[default: [<sentencias>]]
}

- 34 -

TALLER DE INFORMTICA

CAPITULO 7. Instrucciones

7.5. Sentencias de Seleccin.


Las sentencias de seleccin permiten controlar el flujo del programa, seleccionando distintas
sentencias en funcin de diferentes valores.

7.5.1. Sentencia "if...else".


Implementa la ejecucin condicional de una sentencia.
Sintaxis:

if (<condicin>) <sentencia1>;
if (<condicin>) <sentencia1>; else <sentencia2>;

Si la condicin es "true" se ejecutar la sentencia1, si es "false" se ejecutar la sentencia2.


El "else" es opcional, y no pueden insertarse sentencias entre la sentencia1 y el "else".
Se pueden declarar variables dentro de la condicin.
Por ejemplo:

if ( int val = func(arg))...

En este caso, la variable "val" slo estar accesible dentro del mbito de la sentencia "if" y, si
existe, del "else".

7.5.2. Sentencia "switch".


Cuando se usa la sentencia switch el control se transfiere al punto etiquetado con el "case" cuya
expresin constante coincida con el valor de la variable del "switch".
A partir de ese punto todas las sentencias sern ejecutadas hasta el final del "switch", es decir
hasta llegar al "}". Esto es as porque las etiquetas slo marcan los puntos de entrada despus de
una ruptura de la secuencia de ejecucin, pero no marcan las salidas.
Esta caracterstica nos permite ejecutar las mismas sentencias para varias etiquetas distintas, y se
puede eludir usando la sentencia de ruptura "break" al final de las sentencias incluidas en cada
"case".
Si no se satisface ningn "case", el control parar a la siguiente sentencia despus de la etiqueta
"default". Esta etiqueta es opcional y si no aparece se abandonar el "switch".
No te preocupes, con un ejemplo se aclarar.
Sintaxis:

switch (<variable>)
{
case <expresin_constante>: [<sentencias>] [break;]
...
[default : [<sentencia>]]
}

Por ejemplo:

switch(letra)
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
EsVocal = true;

- 35 -

TALLER DE INFORMTICA

CAPITULO 7. Instrucciones

break;
default:
EsVocal = false;
}
En este ejemplo letra es una variable de tipo "char" y EsVocal de tipo "bool".
Si el valor de entrada en el "switch" corresponde a una vocal, EsVocal saldr con un valor
verdadero, en caso contrario, saldr con un valor falso.
El ejemplo ilustra el uso del "break", si letra es 'a', se cumple el primer "case", y la ejecucin
contina en la siguiente sentencia, ignorando el resto de los "case" hasta el "break".
Otro ejemplo:

Menor1 = Menor2 = Menor3 = Mayor3 = false;


switch (numero)
{
case 0:
Menor1 = true;
case 1:
Menor2 = true;
case 2:
Menor3 = true;
break;
default:
Mayor3 = true;
}
Veamos qu pasa en este ejemplo si nmero vale 1.
Directamente se reanuda la ejecucin en "case 1:", con lo cual Menor2 tomar el valor "true", lo
mismo pasar con Menor3.
Despus aparece el "break" y se abandona el "switch".

7.6. Sentencias de salto.


Las sentencias de salto permiten romper la ejecucin secuencial de un programa.

7.6.1. Sentencia de ruptura "break".


El uso de esta sentencia dentro de un bucle pasa el control a la primera sentencia despus de la
sentencia de bucle.
Un ejemplo de aplicacin es dentro de la sentencia "switch".
Sintaxis:

break

Ejemplo:

y = 0;
x = 0;
while (x < 1000)
{
if (y == 1000) break;
y++;
}
x = 1;
- 36 -

TALLER DE INFORMTICA

CAPITULO 7. Instrucciones

En este ejemplo el bucle no terminara nunca si no fuera por la lnea del "break", ya que x no
cambia.
Despus del "break" el programa continuara en la lnea "x = 1".

7.6.2. Sentencia continue".


El uso de la sentencia continue dentro de un bucle permite pasar el control al final de la sentencia
de bucle, justo al punto donde se evala la condicin para la permanencia en el bucle.
Sintaxis:

continue

Ejemplo:

y = 0;
x = 0;
while (x < 1000)
{
x++;
if (y >= 100) continue;
y++;
}

En este ejemplo la lnea "y++" slo se ejecutara mientras "y" sea menor que 100, en cualquier
otro caso el control pasa a la lnea "}", con lo que el bucle volvera a evaluarse.

7.6.3. Sentencia de salto "goto".


Con el uso de la sentencia goto el control del programa se transfiere directamente al punto
etiquetado con el identificador especificado.
El "goto" es un mecanismo que est en guerra permanente, y sin cuartel, con la programacin
estructurada.
El "goto" no se usa, se incluye aqu porque existe, pero siempre que se pueda debe ser eludido.
Existen otros mecanismos para hacer todo aquello que pueda realizarse con un "goto".
Sintaxis:

goto <identificador>

Ejemplo:

x = 0;
Bucle:
x++;
if (x < 1000) goto Bucle;

Este ejemplo emula el funcionamiento de un bucle "for" como el siguiente:

for(x = 0; x < 1000; x++);

7.6.4. Sentencia de retorno "return".


La sentencia return sale de la funcin donde se encuentra y devuelve el control a la rutina que la
llam, opcionalmente con un valor de retorno.
Sintaxis:

return [<expresin>]

- 37 -

TALLER DE INFORMTICA

CAPITULO 7. Instrucciones

Ejemplo:

int Paridad(int x)
{
if (x % 2) return 1;
return 0;
}

Este ejemplo ilustra la implementacin de una funcin que calcula la paridad de un parmetro. Si el
resto de dividir el parmetro entre 2 es distinto de cero, implica que el parmetro es impar, y la
funcin retorna con valor 1. El resto de la funcin no se ejecuta. Si por el contrario el resto de
dividir el parmetro entre 2 es cero, el parmetro ser un nmero par y la funcin retornar con
valor cero.

7.6.5. Sobre las sentencias de salto y la programacin estructurada.


En general, es una buena norma huir de las sentencias de salto. Lo dicho para la sentencia "goto"
es vlido en general para todas las sentencias de salto, salvo el "return" y el "break", este ltimo
tiene un poco ms de tolerancia, sobre todo en las sentencias "switch", donde resulta
imprescindible.

7.7. Comentarios.
Los comentarios ayudan a seguir el funcionamiento del programa durante la depuracin o en la
actualizacin del programa, adems de documentarlo.
No se trata propiamente de un tipo de sentencias, pero me parece que es el lugar adecuado para
introducir este concepto.
En C pueden introducirse comentarios en cualquier parte del programa, Los comentarios en C se
delimitan entre /* y */, cualquier cosa que escribamos en su interior ser ignorada por el
compilador, slo est prohibido su uso en el interior de palabras reservadas o en el interior de
identificadores.
Por ejemplo:

main(/*Sin argumentos*/void) est permitido


ma/*funcin*/in(void) es ilegal

La funcin de los comentarios es aclarar y documentar, no entorpecer el cdigo.


En C++ se ha incluido otro tipo de comentarios, que empiezan con //. Estos comentarios no tienen
marca de final, sino que terminan cuando termina la lnea.
Por ejemplo:

void main (void) // Esto es un comentario


{
}

Las llaves {} no forman parte del comentario.

- 38 -

TALLER DE INFORMTICA

CAPITULO 7. Instrucciones

7.8. Ejercicios con sentencias.


1) Mostrar los sucesivos valores de la variable x en los siguientes bucles:
a)

b)

c)

d)

e)

f)

int x=0;
while(x < 5) x += 2;

0,2,4,6
0,2,4
0,2,4,6,8

10
10,11
11

13,14
13,14,15
13

6,10,17
6,10,17,5
6,10,17,10,5

0,1,2,3,4,5,1,2,3,4,5,1
0,1,2,3,4,5,1,2,3,4,5
0,1,2,3,4,5,1,2,3,4,5,1,2

int x=10;
do x++; while(x < 10);

bool salir = false;


int x = 13;
while(!salir) {
x++;
salir = x%7;
}

int x = 6;
do {
switch(x%3) {
case 0: x=10; break;
case 1: x=17; break;
case 2: x=5; break;
}
} while(x != 5);

int x=0, y=0;


do {
if(x>4) { x %= 4; y++; }
else x++;
} while(y < 2);

int x=0, y=1;


while(y != 3) {
x++;
if(x<3) continue;
x=y; y++;
}

0,1,2,3,1,2,3,2,3
0,1,2,3,1,2,3,2
0,1,2,3,1,2,3,2,3,2

- 39 -

TALLER DE INFORMTICA

CAPITULO 8. Funciones

CAPITULO 8. FUNCIONES.
Las funciones son un conjunto de instrucciones que realizan una tarea especfica. En general toman
unos valores de entrada, llamados parmetros y proporcionan un valor de salida o valor de retorno;
aunque tanto unos como el otro pueden no existir.
Al igual que con las variables, las funciones pueden declararse y definirse.
Una declaracin es simplemente una presentacin.
Una definicin contiene las instrucciones con las que realizar su trabajo la funcin.

8.1. Declaracin de funcin. El Prototipo.


La declaracin de una funcin se realiza mediante una sentencia conocida con el nombre de
prototipo.
Un prototipo consiste en una definicin de la funcin sin cuerpo y terminado con un ";".
Sintaxis:

<tipo> func (<lista de declaracin de parmetros>);

Por ejemplo:

int Intervalo(int a, int b); /*Prototipo de la funcin Intervalo*/

El prototipo sirve para indicar al compilador los tipos de datos de retorno y los tipos de datos de los
parmetros que recibe la funcin, de modo que compruebe si son del tipo correcto cada vez que se
use esta funcin dentro del programa, o para hacer las conversiones de tipo cuando sea necesario.
Los nombres de los parmetros son opcionales, y se incluyen como documentacin y ayuda en la
interpretacin y comprensin del programa.
El ejemplo de prototipo anterior sera igualmente vlido y se podra poner como:

int Intervalo (int,int); /*Prototipo de la funcin Intervalo */


El prototipo del ejemplo indica que en algn lugar del programa se definir una funcin "Intervalo"
que admite dos parmetros de tipo "int" y que devolver un valor de tipo "int". No es necesario
escribir nombres para los parmetros, ya que el prototipo no los usa. En otro lugar del programa
habr una definicin completa de la funcin.

Normalmente se aconseja:
Copiar el prototipo de la funcin y pegar como una definicin eliminando el ; del final de lnea de
esta manera no se comenten errores.
PERO si hacemos esto utilizando la ltima forma de indicar el prototipo de la funcin (es decir sin
dar nombres a las variables) no sirve, ya que en la definicin de la funcin necesitamos dar un
nombre a la variable para poder usarla.
Las funciones se declaran como prototipos dentro del programa, o se incluyen estos prototipos
desde un fichero externo, (usando la directiva "#include")
La definicin de la funcin se hace ms adelante; lo habitual es hacerlo despus de la funcin
"main".
Los programas complejos se escriben normalmente usando varios ficheros fuente. Estos ficheros se
compilan separadamente y se enlazan juntos. Esto es una gran ventaja durante el desarrollo y

- 40 -

TALLER DE INFORMTICA

CAPITULO 8. Funciones

depuracin de grandes programas, ya que las modificaciones en un fichero fuente slo nos
obligarn a compilar ese fichero fuente, y no el resto, con el consiguiente ahorro de tiempo.
La definicin de las funciones puede hacerse dentro de los ficheros fuente o enlazarse desde
libreras precompiladas. La diferencia entre una declaracin y una definicin es que la definicin
posee un cuerpo de funcin.

En C++ es obligatorio el uso funciones prototipo, y aunque en C no lo es, resulta altamente


recomendable.

8.1.1. Funciones extern y static.


Hay funciones que son "extern" por defecto. Esto quiere decir que son accesibles desde cualquier
punto del programa, aunque se encuentren en otros ficheros fuente del mismo programa.
En contraposicin las funciones declaradas "static" slo son accesibles dentro del fichero fuente
donde se definen.

8.2. Definicin de funcin.


La definicin de una funcin se compone de las siguientes secciones, aunque pueden complicarse
en ciertos casos:

Tipo de almacenamiento

Tipo de valor de retorno

Modificadores opcionales

Nombre de la funcin

Lista de parmetros (entre parntesis)

Cuerpo de la funcin

8.2.1. Tipo de almacenamiento.


Opcionalmente, una palabra que especifique el tipo de almacenamiento, puede ser "extern" o
"static". Si no se especifica es "extern".

8.2.2. Tipo de valor de retorno.


El tipo del valor de retorno puede ser "void" si no necesitamos valor de retorno.
En C, si no se establece, por defecto ser "int", aunque en general se considera de mal gusto omitir
el tipo de valor de retorno.
En C++ es obligatorio indicar el tipo del valor de retorno.

8.2.3. Modificadores opcionales.


Los modificadores tienen un uso muy especfico, de momento no entraremos en este particular, lo
veremos en captulos posteriores.

- 41 -

TALLER DE INFORMTICA

CAPITULO 8. Funciones

8.2.4. Nombre de la funcin.


Para el nombre de la funcin, resulta muy til y recomendable, poner nombres que indiquen, lo
ms claramente posible, qu es lo que hace la funcin, y que permitan interpretar qu hace el
programa con slo leerlo.
Cuando se precisen varias palabras para conseguir este efecto existen varias reglas aplicables de
uso comn. Una consiste en separar cada palabra con un "_", la otra, que yo prefiero, consiste en
escribir la primera letra de cada palabra en mayscula y el resto en minsculas.
Por ejemplo, si hacemos una funcin que busque el nmero de telfono de una persona en una
base de datos, podramos llamarla "busca_telefono" o "BuscaTelefono".

8.2.5. Lista de parmetros.


Entre parntesis se deben incluir las declaraciones de parmetros separados por coma (,).
Los parmetros de una funcin son los valores de entrada (y en ocasiones tambin de salida).
Para la funcin se comportan exactamente igual que variables, y de hecho cada parmetro se
declara igual que una variable.
Una lista de parmetros es un conjunto de declaraciones de parmetros separados con comas.
Puede tratarse de una lista vaca.
En C es preferible usar la forma "func(void)" para listas de parmetros vacas.
En C++ este procedimiento se considera obsoleto, se usa simplemente "func()".

8.2.6. Cuerpo de funcin.


El cuerpo de funcin representa el cdigo que ser ejecutado cuando se llame a la funcin.
El cuerpo de la funcin se encierra entre llaves "{}"

8.3. Funcin main().


Una funcin muy especial es la funcin "main".
Se trata de la funcin de entrada, y debe existir SIEMPRE. Ser la funcin que tome el control
cuando se ejecute un programa en C.
Existen reglas para el uso de los valores de retorno y de los parmetros de la funcin "main", pero
de momento la usaremos como "int main()" o "int main(void)", con un entero como valor de
retorno y sin parmetros de entrada.
En Linux la funcin main() DEBER retornar un valor sino el compilador indicar un error.
Ejemplo de funcin:

/* Esta funcin devuelve el mayor de dos nmeros */


# include <iostream>
using namespace std;
/* Prototipo de funcin Mayor */
int Mayor (int a, int b);
int main()
/*variables locales x e y*/
{ int x,y;
cout << endl << "Ingrese un entero: ";
cin >> x;
cout << endl << "Ingrese otro entero: ";
cin >> y;
cout<< endl <<"El mayor valor es :" << Mayor(x,y)<< endl; /*Llamada*/
return 0;
}
int Mayor (int a, int b)
/* Definicin de funcin Mayor */
{ if (a >=b) return a;
else return b; }

- 42 -

TALLER DE INFORMTICA

CAPITULO 8. Funciones

8.4. mbito de variables.


Dependiendo de dnde se declaren las variables, podrn o no ser accesibles desde distintas partes
del programa.

8.4.1. Variables locales.


Las variables declaradas dentro de una funcin, y recuerda que "main" tambin es una funcin,
slo sern accesibles desde esa funcin. Esas variables son variables locales o de mbito local de
esa funcin.
Las variables declaradas dentro de un bucle, sern accesibles slo desde el propio bucle, sern de
mbito local del bucle.

8.4.2. Variables globales.


Las variables declaradas fuera de las funciones, normalmente antes de definir las funciones, en la
zona donde se declaran los prototipos, sern accesibles desde todas las funciones.
Diremos que esas variables sern globales o de mbito global.
Por ejemplo:

int EnteroGlobal;
// Declaracin de una variable global
int Funcion1(int a);
// Declaracin de un prototipo
int main()
{
int EnteroLocal;
// Declaracin de una variable local de main:
// Acceso a una variable local:
EnteroLocal = Funcion1(10);
EnteroGlobal = Funcion1(EnteroLocal); // Acceso a una valiable global:
return 0;
}
int Funcion1(int a)
{ char CaracterLocal; // Variable local de funcion1
// Desde aqu podemos acceder a EnteroGlobal, y tambin
//a CaracterLocal pero no a EnteroLocal
if (EnteroGlobal != 0)
//EnteroGlobal;
return a
else
return 0;
}

De modo que en cuanto a los mbitos locales tenemos varios niveles:

<tipo> funcion(parmetros)
{
<tipo> var;
for(<tipo> var;...)
...
return var;
}

// (1)

// (2)
// (3)

(1) los parmetros tienen mbito local a la funcin.


(2) las variables declaradas aqu, tambin.
(3) las declaradas en bucles, son locales al bucle.
Es una buena costumbre inicializar las variables locales.
Cuando se trate de variables estticas se inicializan automticamente a cero.

- 43 -

TALLER DE INFORMTICA

CAPITULO 8. Funciones

8.5. Ejercicios.
1-) En el ejemplo, qu mbito tiene cada una de las variables? Marcar la opcin correcta.

float s,i;
int main()
{
int x;
x=10;
for(int i=0; i<x; i++)
Mostrar(i);
i = 0.0;
while(x>0) {
i *= 10.3;
x--;
}
return 0;

a)

b)

c)

d)

2-)

La variable de tipo float s tiene mbito


global
local en main
local en bucle

La variable de tipo int i tiene mbito


global
local en main
local en bucle

La variable de tipo float i tiene mbito


global
local en main
local en bucle

La variable de tipo int x tiene mbito


global
local en main
local en bucle
Cules de los siguientes prototipos son vlidos?

a) Calcular(int, int, char r);


S
No
b) void Invertir(int, unsigned char)
S
No
c) void Aumentar(float valor);
S
No
d) float Negativo(float int);
S
No
e) int Menor(int, int, int);
S
No

- 44 -

TALLER DE INFORMTICA

CAPITULO 8. Funciones

f) char Menu(int opciones);


S
No
3-) Preguntas sobre la estructura de un programa. Marcar la opcin correcta.
a) Entre qu zonas haras las declaraciones de variables globales?
Antes de la zona de las directivas del preprocesador.
Entre la zona de las directivas del preprocesador y las declaraciones de prototipos.
Despus de la definicin de la funcin "main".
b) Qu aparecera normalmente justo despus de la definicin de la funcin "main"?
Las directivas del preprocesador.
Los prototipos de funciones.
Las definiciones de funciones.
4-) Identifique las siguientes partes de las funciones. Marcar la/s opcin/es correcta/s.

Encabezado o Definicin de la Funcin.


Cuerpo de la Funcin Enunciados de la Funcin.
Prototipo de la Funcin.
Argumentos de la Funcin.
Tipos de Argumentos de la Funcin.
Tipo de Argumento retornado por la Funcin.

5-) Escribir el cdigo fuente de un programa que contenga una funcin que reciba un entero y
devuelva P si es POSITIVO y N si es NEGATIVO.
6-) Escribir el cdigo fuente de un programa que desde main se llame a una funcin que recibe
dos argumentos enteros y devuelve un valor booleano, siendo TRUE si el mayor argumento es
divisible por el menor o FALSE si el mayor argumento no es divisible por el mayor.
7-) Escribir el cdigo fuente de un programa que desde main se llame a una funcin que recibe
como argumento dos nmeros reales, y retorna el menor que es mostrado en main.
8-) Escribir el cdigo fuente de un programa que desde main se llame a una funcin pasando como
argumento un valor entero, esta funcin calcula los coeficientes de la serie de Fibonacci hasta el
entero pasado; y retorna la suma de los trminos que se muestra desde main.

Ej: N=6 , la serie ser = 0 1 1 2 3 5. La suma mostrada en main ser S=12.

9-) Escribir el cdigo fuente de un programa que permita definir tres funciones, una que detecta si
un carcter es una Vocal , otra que detecta si es Consonante y otra si es un Dgito, todas devuelven
el valor TRUE o FALSE y desde main se debe indicar si el tipo de char ingresado es : vocal,
consonante dgito.
Se puede suponer en principio para simplificar que los caracteres ingresados son TODO minsculas.
Sugerencia: Mirar la tabla de caracteres ASCII.
10-) Escribir el cdigo fuente de un programa que desde main se llame a una funcin la cual recibe
un par de nmeros y retorna el resto de la divisin del mayor dividido el menor.
Sugerencia: usar el operador () ? : .
11-) Escribir el cdigo fuente de un programa que desde main se llame a una funcin que recibe
como argumento un nmero entero, calcula y muestra desde la misma funcin los divisores de ese
nmero retornando un valor TRUE, si el nmero no es primo y FALSE si es primo.
12-) Se dice que un nmero entero es perfecto, si la suma de sus divisores incluyendo el 1 es igual
a s mismo.
Ej: 6 = 3 + 2+ 1 , ver que 3,2,1 son divisores de 6.
Escribir una funcin que reciba un entero, y retorne TRUE para el caso de que el nmero sea un
entero perfecto.

- 45 -

TALLER DE INFORMTICA

CAPITULO 8. Funciones

13-) Escribir el cdigo fuente de un programa que desde main se llame a una funcin men que
no recibe ningn argumento y que retorne la opcin de men elegida, sta se mostrar desde
main. Los tems del men deberan ser por ej. 1,2,3,4 y 5 para salir, o A,B,.. y F para Finalizar.
Controlar que slo salga con la opcin indicada.
14-) Escribir el cdigo fuente de un programa que desde main se llame a una funcin men
(similar al ejercicio 13), las opciones del men sern:
1: Cargar un vector y luego presentar nuevamente el men, (todas las funciones refieren al vector)
2: Ordenar.
3:Buscar el mayor.
4:Calcular el promedio.
5:Salir.
Cada uno de estos puntos se debe realizar con una funcin. No usar variables globales. Usar pasaje
de valores a funciones por referencia para el caso de ordenar!!.
15-) Escribir el cdigo fuente de un programa que desde main llame a una funcin la cual itera (sin
hacer nada) mientras se introduzca la letra s y se detiene cuando se introduce la letra n.
Ver que s y n son MINUSCULAS!!.
16-) Escribir el cdigo fuente de un programa que desde main copie usado la funcin strcpy de
un string.
17-) Escriba una funcin que reciba la cantidad de elementos a acumular y retorne el valor
acumulado.

Ej: recibe 4, y luego se ingresan, dentro de la funcin cuatro nmeros, 1, 3, 3, 2 deber retornar a
main el total acumulado=9.
18-) Escriba una funcin que reciba la cantidad de elementos a promediar y retorne el promedio.

Ej: recibe 3, luego se ingresan, dentro de la funcin tres valores, 10, 5, 15 y deber retornar a
main el promedio=10.

- 46 -

TALLER DE INFORMTICA

CAPITULO 9. Arreglos

CAPITULO 9. ARREGLOS.
Un arreglo es un conjunto de elementos del mismo tipo agrupados en una sola variable. Es una
estructura de datos en la que se almacena una coleccin de datos del mismo tipo
Los arreglos poseen ciertas caractersticas particulares:

Cada posicin de almacenamiento en un arreglo es llamada un elemento del arreglo.

Para ingresar a un elemento en particular, utilizamos un ndice.

Tienen un nico nombre de variable, que representa todos los elementos, los cuales se
diferencian por un ndice o subndice.

Existen arreglos unidimensionales, bidimensionales y tridimensionales.

Fsicamente, un arreglo es un conjunto de localidades de memoria contiguas donde la


direccin ms baja corresponde al primer elemento y la direccin ms alta al ltimo.

En un arreglo de n elementos, stos ocuparan desde 0 hasta la n-1.

Por s mismo, el nombre del arreglo apunta a la direccin del primer elemento del arreglo.

9.1. Cadena de caracteres.


Antes de comenzar a desarrollar el tema de los arreglos o "arrays", veremos un caso especial de
ellos.
Se trata de las cadenas de caracteres o "strings" (en ingls).
Una cadena, en C, es un conjunto de caracteres, o valores de tipo "char", terminados con el
carcter nulo, es decir el valor numrico 0.
Internamente se almacenan en posiciones consecutivas de memoria.
Este tipo de estructuras recibe un tratamiento especial, y es de gran utilidad y de uso continuo.
Una cadena puede almacenar informaciones como nombres de personas, mensajes de error,
nmeros de telfono, etc.
Sintaxis para definir una variable tipo cadena:

char <identificador> [<longitud mxima>];


En este caso los corchetes no indican un valor opcional, sino que son realmente corchetes, por eso
estn en negrita.
Durante el tratamiento de variables tipo cadena tener en cuenta que:
Cuando se declara una cadena hay que tener en cuenta que tendremos que reservar una posicin
para almacenar el carcter nulo.
Por ejemplo:
Si queremos almacenar la cadena "HOLA", tendremos que declarar la cadena como:
char Saludo[5]; // Cuatro caracteres para "HOLA" y uno para '\000'.
Es posible hacer referencia a cada uno de los caracteres individuales que componen la cadena,
simplemente indicando la posicin.

- 47 -

TALLER DE INFORMTICA

CAPITULO 9. Arreglos

Por ejemplo:

Saludo[2]; //Hace referencia al 3 carcter de la cadena, la 'L'.

Los ndices tomarn valores empezando en el cero.


Por ejemplo:

Saludo[0]; //Hace referencia al 1 carcter de la cadena, la 'H'.

La asignacin directa slo est permitida cuando se hace junto con la declaracin.
Por ejemplo:

char Saludo[5];
Saludo = "HOLA"

Esta modalidad producir un error en el compilador, ya que una cadena definida de este modo se
considera una constante, como veremos en el captulo de "arrays" o arreglos.
La manera correcta de asignar una cadena es:

char Saludo[5];
Saludo[0] = 'H';
Saludo[1] = 'O';
Saludo[2] = 'L';
Saludo[3] = 'A';
Saludo[4] = '\000';

O bien:

char Saludo[5] = "HOLA";

Si parece un sistema engorroso, no te preocupes, en prximos captulos veremos


facilitarn la asignacin de cadenas.
Existen muchas funciones para el tratamiento de cadenas, como veremos,
compararlas, copiarlas, calcular su longitud, imprimirlas, visualizarlas, guardarlas
Adems, frecuentemente, nos encontraremos a nosotros mismos creando nuevas
bsicamente hacen un tratamiento de cadenas.

funciones que
que permiten
en disco, etc.
funciones que

9.2. Arreglos.
Empezaremos con los tipos de datos estructurados, los arrays.
Los arrays o arreglos permiten agrupar datos usando un mismo identificador.
Todos los elementos de un array son del mismo tipo, y para acceder a cada elemento se usan
subndices.
Sintaxis:

<tipo> <identificador>[<nm_elemen>][[<nm_elemen>]...];

Los valores para el nmero de elementos deben ser constantes, y se pueden usar tantas
dimensiones como queramos, limitado slo por la memoria disponible.
Cuando slo se usa una dimensin se suele hablar de listas o vectores, cuando se usan dos, de

tablas o matrices.

Ahora podemos ver que las cadenas de caracteres son un tipo especial de arrays. Se trata en
realidad de arrays de una dimensin de objetos de tipo char.
Los subndices son enteros, y pueden tomar valores desde 0 hasta <nmero de elementos>-1.

- 48 -

TALLER DE INFORMTICA

CAPITULO 9. Arreglos

Esto es muy importante, y hay que tener mucho cuidado.


Por ejemplo:

int Vector[10];

Crear un array con 10 elementos enteros; podremos acceder a los elementos Vector[0] a
Vector[9].
Como subndice podremos usar cualquier expresin entera.
En general C++ no verifica el mbito de los subndices. Si declaramos un array de 10 elementos,
no obtendremos errores al acceder al elemento 11.
Sin embargo, si asignamos valores a elementos fuera del mbito declarado, estaremos accediendo
a zonas de memoria que pueden pertenecer a otras variables o incluso al cdigo ejecutable de
nuestro programa, con consecuencias generalmente desastrosas.
Por ejemplo:

int Tabla[10][10];
char DimensionN[4][15][6][8][11];
...
DimensionN[3][11][0][4][6] = DimensionN[0][12][5][3][1];
Tabla[0][0] += Tabla[9][9];

Cada elemento de Tabla, desde Tabla[0][0] hasta Tabla[9][9] es un entero.


Del mismo modo, cada elemento de Dimensin N es un carcter.

9.2.1. Inicializacin de un arreglo.


Los arrays pueden ser inicializados junto con la declaracin.
Por ejemplo:

float R[10] = {2, 32, 4.6, 2, 1, 0.5, 3, 8, 0, 12};


float S[] = {2, 32, 4.6, 2, 1, 0.5, 3, 8, 0, 12};
int N[] = {1, 2, 3, 6};
int M[][3] = { 213, 32, 32, 32, 43, 32, 3, 43, 21};
char Mensaje[] = "Error de lectura";
char Saludo[] = {'H', 'o', 'l', 'a', 0};

En estos casos no es obligatorio especificar el tamao para la primera dimensin, como ocurre en
los ejemplos de las lneas 2, 3, 4, 5 y 6.
En estos casos la dimensin que queda indefinida se calcula a partir del nmero de elementos en la
lista de valores iniciales.
En el caso 2, el nmero de elementos es 10, ya que hay diez valores en la lista.
En el caso 3, ser 4.
En el caso 4, ser 3, ya que hay 9 valores, y la segunda dimensin es 3: 9/3=3.
Y en el caso 5, el nmero de elementos es 17, 16 caracteres ms el cero de fin de cadena.

9.2.2. Operadores utilizados con arreglos.


Ya hemos visto que se puede usar el operador de asignacin con arrays para asignar valores
iniciales.
El otro operador que tiene sentido con los arrays es sizeof.
Aplicado a un array, el operador sizeof devuelve el tamao de todo el array en bytes.
Podemos obtener el nmero de elementos dividiendo ese valor entre el tamao de uno de los
elementos.

- 49 -

TALLER DE INFORMTICA

CAPITULO 9. Arreglos

Por ejemplo:

#include <iostream>
using namespace std;
int main()
{
int array[231];
cout << "Nmero de elementos: " << sizeof(array)/sizeof(int) << endl;
cout << "Nmero de elementos: " << sizeof(array)/sizeof(array[0]) << endl;
cin.get();
return 0;
}

Las dos formas son vlidas, pero la segunda es, tal vez, ms general.

9.3. Algoritmos de ordenacin: mtodo de la burbuja.


Una operacin que se hace muy a menudo con los arrays, sobre todo con los de una dimensin, es
ordenar sus elementos.
Dedicaremos ms captulos a algoritmos de ordenacin, pero ahora veremos uno de los ms
usados, aunque no de los ms eficaces, se trata del mtodo de la burbuja.
Consiste en recorrer la lista de valores a ordenar y compararlos dos a dos.
Si los elementos estn bien ordenados, pasamos al siguiente par, si no lo estn los intercambiamos,
y pasamos al siguiente, hasta llegar al final de la lista.
El proceso completo se repite hasta que la lista est ordenada.
Veamos el mtodo utilizando un ejemplo:
Ordenar la siguiente lista de menor a mayor:
15 | 3 | 8 | 6 | 18 | 1
Empezamos comparando 15 y 3. Como estn mal ordenados los intercambiamos, la lista quedar:
3 | 15 | 8 | 6 |18 | 1
Tomamos el siguiente par de valores: 15 y 8, y volvemos a intercambiarlos, y seguimos el
proceso...
Cuando lleguemos al final la lista estar as:
3 | 8 | 6 |15| 1| 18
Empezamos la segunda pasada, pero ahora no es necesario recorrer toda la lista. Si observas vers
que el ltimo elemento est bien ordenado, siempre ser el mayor, por lo tanto no ser necesario
incluirlo en la segunda pasada.
Despus de la segunda pasada la lista quedar:
3 | 6 | 8 | 1| 15 |18
Ahora es el 15 el que ocupa su posicin final, la penltima, por lo tanto no ser necesario que entre
en las comparaciones para la siguiente pasada.
Las sucesivas pasadas dejarn la lista as:
3) 3 | 6 | 1| 8 | 15 | 18
4) 3 |1 | 6 | 8 | 15 | 18

- 50 -

TALLER DE INFORMTICA

CAPITULO 9. Arreglos

5) 1 | 3 | 6| 8 | 15 | 18

9.4. Ejercicios: cadenas de caracteres.


Teniendo en cuenta la asignacin que hemos hecho para la cadena Saludo, se muestran varias
versiones de una funcin que calcule la longitud de una cadena, cules de ellas funcionan y cules
no? Marcar la opcin correcta.
a)

int LongitudCadena(char cad[])


{
int l = 0;
while(cad[l]) l++;
return l;
}
S

No

b)

int LongitudCadena(char cad[])


{
int l;
for(l = 0; cad[l] != 0; l++);
return l;
}
S

No

c)

int LongitudCadena(char cad[])


{
int l = 0;
do {
l++;
} while(cad[l] != 0);
return l;
}
S

No

9.5. Ejercicios: arreglos.


1-) Hacer un programa que lea diez valores enteros en un array desde el teclado y calcule y
muestre: la suma, el valor promedio, el mayor y el menor.
2-) Hacer un programa que lea diez valores enteros en un array y los muestre en pantalla.
Despus ordenar de menor a mayor y vuelva a mostrar. Finalmente ordenar de mayor a menor y
los muestre por tercera vez. Para ordenar la lista usar una funcin que implemente el mtodo de la
burbuja y que tenga como parmetro de entrada el tipo de ordenacin, de mayor a menor o de
menor a mayor. Para el array usar una variable global.
3-) Hacer un programa que contenga una funcin con el prototipo
bool Incrementa (char numero[10]);.
La funcin debe incrementar el nmero pasado como parmetro en una cadena de caracteres de 9
dgitos. Si la cadena no contiene un nmero, debe devolver false, en caso contrario debe devolver
true, y la cadena debe contener el nmero incrementado. Si el nmero es "999999999", debe
devolver "0". Cadenas con nmeros de menos de 9 dgitos pueden contener ceros iniciales o no.

Ej: la funcin debe ser capaz de incrementar tanto la cadena "3423", como "00002323".
La funcin "main" llamar a la funcin Incrementar con diferentes cadenas.
- 51 -

TALLER DE INFORMTICA

CAPITULO 9. Arreglos

4-) Hacer un programa que contenga una funcin con el prototipo


bool Palindromo(char palabra[40]);.
La funcin debe devolver true si la palabra es un palndromo, y false si no lo es.
Una palabra es un palndromo si cuando se lee desde el final al principio es igual que leyendo
desde el principio, por ejemplo: "Otto", o con varias palabras "Anita lava la tina", "Dbale arroz a la
zorra el abad", La ruta nos aport otro paso natural.
En estos casos debemos ignorar los acentos y los espacios, pero no es necesario que tu funcin
haga eso, bastar con probar cadenas como "anitalavalatina", o "dabalearrozalazorraelabad".
La funcin no debe hacer distinciones entre maysculas y minsculas.
5-) Escribir el cdigo fuente de un programa que permita la carga de un string definido de no mas
de 20 caracteres e indique cuntos caracteres se tipearon.
Alternativa 1) suponer que no hay espacios en blanco, por ej. si se tipea asfhe<Enter>, debera
indicar 5 caracteres.
Alternativa 2) debera contar la cantidad caracteres ingresados incluidos los espacio en blanco, por
ej. Juan Jorge<Enter>, debera indicar 10 caracteres.
Resolucin Alternativa 2:

#include <iostream>
using namespace std;
int main()
{
int i=1;
char mensaje [21];
cout << " Ingrese un texto de no mas de 20 caracteres" << endl;
cin.getline (mensaje,21);
while (mensaje[i]!=0)i++;
cout <<endl <<"El arreglo tiene: " << i << " caracteres";
return 0;
}
6-) Escribir un cdigo de programa que llame desde main a una funcin pasando por referencia el
nombre de un array y desde esa funcin se mostrar por pantalla el array escrito de atrs para
adelante.

Ej: se ingresa desde main Juan Pablo y desde la funcin se deber mostrar: olbaP nauJ.
#include <iostream>
using namespace std;
int main()
{
int i=1;
char mensaje [21];
cout << " Ingrese un texto de no mas de 20 caracteres" << endl;
cin.getline (mensaje,21);
while (mensaje[i]!=0)i++;
cout <<endl <<"El arreglo tiene: " << i << " caracteres"<< endl;
while((i+1)!=0){cout << mensaje[i] ;--i;}
cout << endl;
return 0;
}

7-) Escribir el cdigo que permita la carga de un arreglo de dos dimensiones.


8-) Escribir el cdigo que permita cargar un vector y luego mostrar el mayor y menor elemento,
SIN ordenar.

- 52 -

TALLER DE INFORMTICA

CAPITULO 9. Arreglos

9-) Hacer un programa que cargue 25 valores enteros en un arreglo de 5 x 5, y luego muestre
primero la suma de cada fila y luego la suma de cada columna.
10-) Escribir el cdigo que permita cargar un vector y luego ordenar de mayor a menor.
11-) Escribir el cdigo que permita la carga de una arreglo de dos dimensiones de 3 x 3 y que
luego ordene todas las filas de mayor a menor.
12-) Escribir el cdigo que permita cargar un arreglo de 3 x 3 y que busque el menor elemento de
cada columna y muestre su valor y posicin (fila, columna).
13-) Escribir el cdigo que permita cargar un arreglo de 3 x 3, luego busque los elementos que se
repiten, y los muestre.

Ej: la salida sera: Elementos repetidos: 3 , 5, 12


Alternativa: indicar la cantidad de veces que se repiten cada nmero.
Ej: Elementos repetido 3 2 veces, 5 1 vez, 12 - 5 veces.

14-) Escribir el cdigo que permita cargar un arreglo de 10 elementos, primero se deber ingresar
la posicin y luego el valor. Se deber controlar que el ndice o posicin del arreglo no exceda al
valor mximo del arreglo.
Alternativa: Verificar si el elemento ya ha sido cargado.
15-) Escribir el cdigo que permita la carga de los 5 primeros elementos de un arreglo de 10
elementos y luego lo complete copiando el primero al ultimo lugar, el segundo al ante ultimo lugar.
Luego deber mostrar el arreglo cargado.

Ejemplo: se ingresa 1|3|5|2|4 el arreglo mostrado deber quedar:1|3|5|2|4|4|2|5|3|1

16-) Escribir el cdigo que permita cargar un arreglo de 3 x 3, pero que slo permita cargar los
elemento de la diagonal principal; el resto lo complete con ceros.
17-) Escribir el cdigo que permita cargar un arreglo de 3 x 3, pero que slo permita cargar los
elemento de la diagonal principal y el tringulo superior, luego deber completar el tringulo
inferior de manera de lograr una matriz simtrica.
Si se ingresan: 1, 2, 3, 7, 5 ,4.
Ej de matriz simtrica:
1
2
3

2
7
5

3
5
4

18-) Escribir el cdigo que permita cargar un arreglo de 3 x 3, y que luego cargue un vector
columna con el promedio de cada fila.
19-) Escribir el cdigo que permita cargar dos arreglos de 3 x 3 de nombre MatA y MatB y, que
luego, presente un men, como el siguiente:
1) Suma las Matrices MatA+MatB.
2) Resta las Matrices MatA-Matb.
3) Cargar MatA.
4) Cargar MatB.
5) Salir.

- 53 -

TALLER DE INFORMTICA

CAPITULO 10. Punteros

CAPITULO 10. PUNTEROS.


Los punteros proporcionan la mayor parte de la potencia al C y C++, y marcan la principal
diferencia con otros lenguajes de programacin.
Una buena comprensin y un buen dominio de los punteros pondrn en tus manos una
herramienta de gran potencia. Un conocimiento mediocre o incompleto te impedir desarrollar
programas eficaces.
Por eso le dedicaremos mucha atencin y mucho espacio a los punteros. Es muy importante
comprender bien cmo funcionan y cmo se usan.
Para entender qu es un puntero veremos primero cmo se almacenan los datos en un ordenador.
La memoria de un ordenador est compuesta por unidades bsicas llamadas bits. Cada bit slo
puede tomar dos valores, normalmente denominados alto y bajo, 1 y 0. Pero trabajar con bits no
es prctico, y por eso se agrupan.
Cada grupo de 8 bits forma un byte u octeto. En realidad el microprocesador, y por lo tanto nuestro
programa, slo puede manejar directamente bytes o grupos de dos o cuatro bytes. Para acceder a
los bits hay que acceder antes a los bytes. Y aqu llegamos al quid, cada byte tiene una direccin,
llamada normalmente direccin de memoria.
La unidad de informacin bsica es la palabra, dependiendo del tipo de microprocesador una
palabra puede estar compuesta por dos, cuatro, ocho o diecisis bytes. Hablaremos en estos casos
de plataformas de 16, 32, 64 128 bits. Se habla indistintamente de direcciones de memoria,
aunque las palabras sean de distinta longitud. Cada direccin de memoria contiene siempre un
byte. Lo que suceder cuando las palabras sean de 32 bits es que accederemos a posiciones de
memoria que sern mltiplos de 4.
Todo esto sucede en el interior de la mquina, y nos importa ms bien poco.
Podemos saber qu tipo de plataforma estamos usando averiguando el tamao del tipo int, y para
ello hay que usar el operador "sizeof()".
Por ejemplo:

cout << "Plataforma de " << 8*sizeof(int) << " bits";

Ahora veremos cmo funcionan los punteros.


Un puntero es un tipo especial de variable que contiene, ni ms ni menos que, una direccin de
memoria. Por supuesto, a partir de esa direccin de memoria puede haber cualquier tipo de objeto:
un char, un int, un float, un array, una estructura, una funcin u otro puntero. Seremos nosotros
los responsables de decidir ese contenido.
Intentemos ver con mayor claridad el funcionamiento de los punteros.
Podemos considerar la memoria del ordenador como un gran array, de modo que podemos acceder
a cada celda de memoria a travs de un ndice.
Podemos considerar que la primera posicin del array es la 0 celda[0].
Si usamos una variable para almacenar el ndice, por ejemplo, ndice=0, entonces celda[0] ==
celda[ndice]. Prescindiendo de la notacin de los arrays, el ndice se comporta exactamente igual
que un puntero.
El puntero ndice podra tener por ejemplo, el valor 3, en ese caso, *ndice tendra el valor 'valor3'.
Las celdas de memoria existirn independientemente del valor de ndice, o incluso de la existencia
de ndice, por lo tanto, la existencia del puntero no implica nada ms que eso, pero no que el valor
de la direccin que contiene sea un valor vlido de memoria.
Dentro del array de celdas de memoria existirn zonas que contendrn programas y datos, tanto
del usuario como del propio sistema operativo o de otros programas, el sistema operativo se
encarga de gestionar esa memoria, prohibiendo o protegiendo determinadas zonas.
El propio puntero, como variable que es, ocupar ciertas direcciones de memoria.

- 54 -

TALLER DE INFORMTICA

CAPITULO 10. Punteros

En principio, debemos asignar a un puntero, o bien la direccin de un objeto existente, o bien la de


uno creado explcitamente durante la ejecucin del programa. El sistema operativo suele controlar
la memoria, y no tiene por costumbre permitir el acceso al resto de la memoria.

10.1. Declaracin de punteros


Los punteros se declaran igual que el resto de las variables, pero precediendo el identificador con el
operador de indireccin, (*), que leeremos como "puntero a".
Sintaxis:

<tipo> *<identificador>;

Por ejemplo:

int *entero;
char *carcter;
struct stPunto *punto;

Los punteros siempre apuntan a un objeto de un tipo determinado, en el ejemplo, "entero" siempre
apuntar a un objeto de tipo "int".
La forma:

<tipo>* <identificador>;

con el (*) junto al tipo, en lugar de junto al identificador de variable, tambin est permitida.
Veamos algunos matices.
Por ejemplo:

int *entero;
equivale a:

int* entero;

Debes tener muy claro que "entero" es una variable del tipo "puntero a int", que "*entero" NO es
una variable de tipo "int".
Como pasa con todas las variables en C++, cuando se declaran slo se reserva espacio para
almacenarlas, pero no se asigna ningn valor inicial, el contenido de la variable permanecer sin
cambios, de modo que el valor inicial del puntero ser aleatorio e indeterminado. Debemos suponer
que contiene una direccin no vlida.
Si "entero" apunta a una variable de tipo "int", "*entero" ser el contenido de esa variable, pero no
olvides que "*entero" es un operador aplicado a una variable de tipo "puntero a int", es decir
"*entero" es una expresin, no una variable, que significa: el contenido a donde apunta el
puntero contenido de la direccin a la que apunta.

- 55 -

TALLER DE INFORMTICA

CAPITULO 10. Punteros

10.2. Obtener punteros a variables


Para averiguar la direccin de memoria de cualquier variable usaremos el operador de direccin
(&), que leeremos como "direccin de". Por supuesto, los tipos tienen que ser "compatibles", no
podemos almacenar la direccin de una variable de tipo "char" en un puntero de tipo "int".
Por ejemplo:

int A;
int *pA;
pA = &A;

Segn este ejemplo, pA es un puntero a int que apunta a la direccin donde se almacena el valor
del entero A. Trataremos de graficar lo visto hasta ahora.

Veamos como sera solicitando espacio o memoria de un modo dinmico para almacenar un entero,
es importante destacar que en este ejemplo SOLO SE USA EL PUNTERO, NO EXISTE NOMBRE
DE VARIABLE.

- 56 -

TALLER DE INFORMTICA

CAPITULO 10. Punteros

10.3. Diferencia entre punteros y variables


Declarar un puntero no crear un objeto. Por ejemplo: int *entero; no crea un objeto de tipo "int"
en memoria, slo crea una variable que puede contener una direccin de memoria. Se puede decir
que existe fsicamente la variable "entero", y tambin que esta variable puede contener la direccin
de un objeto de tipo "int".
Por ejemplo:

int A, B;
int *entero;
...
B = 213;
entero = &A;
*entero = 103;
B = *entero;
...

/* B vale 213 */
/* entero apunta a la direccin de la variable A */
/* equivale a la lnea A = 103; */
/* equivale a B = A; */

En este ejemplo vemos que "entero" puede apuntar a cualquier variable de tipo "int", y que
podemos hacer referencia al contenido de dichas variables usando el operador de indireccin (*).
Como todas las variables, los punteros tambin contienen "basura" cuando son declaradas. Es
costumbre dar valores iniciales nulos a los punteros que no apuntan a ningn sitio concreto:
entero = NULL;
caracter = NULL;
NULL es una constante, que est definida como cero en varios ficheros de cabecera, como "cstdio"
o "iostream", y normalmente vale 0.

- 57 -

TALLER DE INFORMTICA

CAPITULO 10. Punteros

10.4. Correspondencia entre arrays y punteros


Existe una equivalencia casi total entre arrays y punteros. Cuando declaramos un array estamos
haciendo varias cosas a la vez:

Declaramos un puntero del mismo tipo que los elementos del array, y que apunta al primer
elemento del array.
Reservamos memoria para todos los elementos del array. Los elementos de un array se
almacenan internamente en el ordenador en posiciones consecutivas de la memoria.

La principal diferencia entre un array y un puntero es que el nombre de un array es un puntero


constante, no podemos hacer que apunte a otra direccin de memoria. Adems, el compilador
asocia una zona de memoria para los elementos del array, cosa que no hace para los elementos
apuntados por un puntero autntico.
Por ejemplo:

int vector[10];
int *puntero;
puntero = vector;
*puntero++;
puntero++;

/* Equivale a puntero = &vector[0]; */


/* esto se lee como "direccin del primer de vector"*/
/* Equivale a vector[0]++; */
/* puntero equivale a &vector[1] */

Qu hace cada una de estas instrucciones?


La primera incrementa el contenido de la memoria apuntada por "puntero", que es vector[0].
La segunda incrementa el puntero, esto significa que apuntar a la posicin de memoria del
siguiente "int", pero no a la siguiente posicin de memoria.
El puntero no se incrementar en una unidad, como tal vez sera lgico esperar, sino en la longitud
de un "int". Anlogamente la operacin: puntero = puntero + 7;
No incrementar la direccin de memoria almacenada en "puntero" en siete posiciones, sino en
7*sizeof(int).
Por ejemplo:

struct stComplejo {
float real, imaginario;
} Complejo[10];
stComplejo *p;
p = Complejo;
/* Equivale a p = &Complejo[0]; */
p++;
/* p == &Complejo[1] */

En este caso, al incrementar p avanzaremos las posiciones de memoria necesarias para apuntar al
siguiente complejo del array "Complejo". Es decir avanzaremos sizeof(stComplejo) bytes.

10.5. Operaciones con punteros


Aunque no son muchas las operaciones que se pueden hacer con los punteros, cada una tiene sus
peculiaridades.

- 58 -

TALLER DE INFORMTICA

CAPITULO 10. Punteros

10.5.1. Asignacin
Ya hemos visto cmo asignar a un puntero la direccin de una variable.
Tambin podemos asignar un puntero a otro, esto har que los dos apunten a la misma posicin:

Por ejemplo:
int *q, *p;
int a;
q = &a;
p = q;

/* q apunta al contenido de a */
/* p apunta al mismo sitio, es decir, al contenido de a */

10.5.2. Operaciones aritmticas


Tambin hemos visto como afectan a los punteros las operaciones de suma con enteros.
Las restas con enteros operan de modo anlogo.
Pero, qu significan las operaciones de suma y resta entre punteros?
Por ejemplo:

int vector[10];
int *p, *q;
p = vector;
/* Equivale a p = &vector[0]; */
q = &vector[4];
/* apuntamos al 5 elemento */
cout << q-p << endl;

El resultado ser 4, que es la "distancia" entre ambos punteros.


Normalmente este tipo de operaciones slo tendr sentido entre punteros que apunten a elementos
del mismo array. La suma de punteros no est permitida.

10.5.3. Comparacin entre punteros


Comparar punteros puede tener sentido en la misma situacin en la que lo tiene restar punteros, es
decir, averiguar posiciones relativas entre punteros que apunten a elementos del mismo array.
Existe otra comparacin que se realiza muy frecuente con los punteros.
Para averiguar si estamos usando un puntero es corriente hacer la comparacin:
Sintaxis

if(NULL != p)
if(p)
if(NULL == p)
if(!p)

- 59 -

TALLER DE INFORMTICA

CAPITULO 10. Punteros

10.6. Punteros genricos


Es posible declarar punteros sin tipo concreto:
Sintaxis:

void *<identificador>;

Estos punteros pueden apuntar a objetos de cualquier tipo.


Por supuesto, tambin se puede emplear el "casting" con punteros.
Sintaxis:

(<tipo> *)<variable puntero>

Recordemos que el cambio o conversin de tipo de dato que se realiza de forma implcita en el
procesador cuando encuentra expresiones que contienen diferentes tipos de dato, pero podemos
hacerlo de una forma en que programador puede forzar un cambio de tipo de forma explcita. Este
cambio se llama cambio por promocin, o casting.
Por ejemplo:

#include <iostream>
using namespace std;
int main() {
char cadena[10] = "Hola";
char *c;
int *n;
//puntero a un entero
void *v;
c = cadena;
// c apunta a cadena
n = (int *)cadena;
// usa casting, n tambin apunta a cadena
v = (void *)cadena;
// v tambin
cout << "carcter: " << *c << endl;
cout << "entero: " << *n << endl;
cout << "float: " << *(float *)v << endl;
cin.get();
return 0;
}

El resultado ser:
Carcter: H
Entero: 1634496328
float: 2.72591e+20
Vemos que tanto "cadena" como los punteros "n", "c" y "v" apuntan a la misma direccin, pero
cada puntero tratar la informacin que encuentre all de modo diferente, para "c" es un carcter y
para "n" un entero. Para "v" no tiene tipo definido, pero podemos hacer "casting" con el tipo que
queramos, en este ejemplo con float.

El tipo de lnea del tercer "cout" es lo que suele asustar a los no iniciados en C y C++, y se parece
mucho a lo que se conoce como cdigo ofuscado. Parece como si en C casi cualquier expresin
pudiese compilar.

- 60 -

TALLER DE INFORMTICA

CAPITULO 10. Punteros

10.7. Punteros a estructuras


Los punteros tambin pueden apuntar a estructuras.
En este caso, para referirse a cada elemento de la estructura se usa el operador (->), en lugar del
(.).
Por ejemplo:

#include <iostream>
using namespace std;
struct stEstructura {
int a, b;
} estructura, *e;
int main()
{
estructura.a = 10;
estructura.b = 32;
e = &estructura;
cout << "variable" << endl;
cout << e->a << endl;
cout << e->b << endl;
cout << "puntero" << endl;
cout << estructura.a << endl;
cout << estructura.b << endl;
cin.get();
return 0;
}

10.8. Ejemplos de uso de punteros


10.8.1. Ejemplo 1
Primero un ejemplo que ilustra la diferencia entre un array y un puntero:

#include <iostream>
using namespace std;
int main() {
char cadena1[] = "Cadena 1";
char *cadena2 = "Cadena 2";
cout << cadena1 << endl;
cout << cadena2 << endl;
//cadena1++;
// Ilegal, cadena1 es constante
cadena2++;
// Legal, cadena2 es un puntero
cout << cadena1 << endl;
cout << cadena2 << endl;
cout << cadena1[1] << endl;
cout << cadena2[0] << endl;
cout << cadena1 + 2 << endl;
cout << cadena2 + 1 << endl;
cout << *(cadena1 + 2) << endl;
cout << *(cadena2 + 1) << endl;
cin.get();
return 0;
}

- 61 -

TALLER DE INFORMTICA

CAPITULO 10. Punteros

Aparentemente, y en la mayora de los casos, cadena1 y cadena2 son equivalentes, sin embargo
hay operaciones que estn prohibidas con los arrays, ya que son punteros constantes.

10.8.2. Ejemplo 2
#include <iostream>
using namespace std;
int main() {
char Mes[][11] = { "Enero", "Febrero", "Marzo", "Abril",
"Mayo", "Junio", "Julio", "Agosto",
"Septiembre", "Octubre", "Noviembre", "Diciembre"};
char *Mes2[] = { "Enero", "Febrero", "Marzo", "Abril",
"Mayo", "Junio", "Julio", "Agosto",
"Septiembre", "Octubre", "Noviembre", "Diciembre"};
cout << "Tamao de Mes: " << sizeof(Mes) << endl;
cout << "Tamao de Mes2: " << sizeof(Mes2) << endl;
cout << "Tamao de cadenas de Mes2: "
<< &Mes2[11][10]-Mes2[0] << endl;
cout << "Tamao de Mes2 + cadenas : "
<< sizeof(Mes2)+&Mes2[11][10]-Mes2[0] << endl;
cin.get();
return 0;
}
En este ejemplo declaramos un array "Mes" de dos dimensiones que almacena 12 cadenas de 11
caracteres, 11 es el tamao necesario para almacenar el mes ms largo (en caracteres):
"Septiembre".
Despus declaramos "Mes2" que es un array de punteros a char, para almacenar la misma
informacin. La ventaja de este segundo mtodo es que no necesitamos contar la longitud de las
cadenas para calcular el espacio que necesitamos, cada puntero de Mes2 es una cadena de la
longitud adecuada para almacenar cada mes.
Parece que el segundo sistema es ms econmico en cuanto al uso de memoria, pero hay que
tener en cuenta que adems de las cadenas tambin se almacenan los doce punteros.
El espacio necesario para almacenar los punteros lo dar la segunda lnea de la salida. Y el espacio
necesario para las cadenas lo dar la tercera lnea.
Si las diferencias de longitud entre las cadenas fueran mayores, el segundo sistema sera ms
eficiente en cuanto al uso de la memoria.

- 62 -

TALLER DE INFORMTICA

CAPITULO 10. Punteros

10.9. Variables dinmicas


Donde mayor potencia desarrolla los punteros es cuando se unen al concepto de memoria
dinmica.
Cuando se ejecuta un programa, el sistema operativo reserva una zona de memoria para el cdigo
o instrucciones del programa y otra para las variables que se usan durante la ejecucin. A menudo
estas zonas son la misma zona, es lomo la pila, que se usa, entre otras cosas, para intercambiar
datos entre funciones. El resto, la memoria que no se usa por nin que se llama memoria local.
Tambin hay otras zonas de memoria, cogn programa es lo que se conoce como "heap" o
montn. Cuando nuestro programa use memoria dinmica, normalmente usar memoria del
montn, y no se llama as porque sea de peor calidad, sino porque suele haber realmente un
montn de memoria de este tipo.
C++ dispone de dos operadores para acceder a la memoria dinmica, son "new" y "delete".
En C estas acciones se realizan mediante funciones de la librera estndar "stdio.h" que son maloc
(Memory Alocation) y free.

Hay una regla de oro cuando se usa memoria dinmica, toda la memoria que se reserve durante el
programa hay que liberarla antes de salir del programa. No seguir esta regla es una actitud muy
irresponsable, y en la mayor parte de los casos tiene consecuencias desastrosas. No se fen de lo
que diga el compilador, de que estas variables se liberan solas al terminar el programa, no siempre
es verdad. Veremos con mayor profundidad los operadores "new" y "delete" en otros captulos, por
ahora veremos un ejemplo.
Por ejemplo:

#include <iostream>
using namespace std;
int main() {
int *a;
char *b;
float *c;
struct stPunto {
float x,y;
} *d;
a = new int;
b = new char;
c = new float;
d = new stPunto;
*a = 10;
*b = 'a';
*c = 10.32;
d->x = 12; d->y = 15;
cout << "a = " << *a << endl;
cout << "b = " << *b << endl;
cout << "c = " << *c << endl;
cout << "d = (" << d->x << ", " << d->y << ")" << endl;
delete a;
delete b;
delete c;
delete d;
cin.get();
return 0; }
- 63 -

TALLER DE INFORMTICA

CAPITULO 10. Punteros

Y mucho cuidado!! Si pierdes un puntero a una variable reservada dinmicamente, no podrs


liberarla.
Por ejemplo:

int main()
{
int *a;
a = new int;
*a = 10;
a = new int;
*a = 20;
delete a;
return 0;
}

// variable dinmica
// nueva variable dinmica,
// se pierde el puntero a la anterior
// slo liberamos la ltima reservada

En este ejemplo vemos cmo es imposible liberar la primera reserva de memoria dinmica. Si no la
necesitbamos habra que liberarla antes de reservarla otra vez, y si la necesitamos, hay que
guardar su direccin, por ejemplo con otro puntero.

10.10. Ejercicios
1-) Escribir un programa con una funcin que calcule la longitud de una cadena de caracteres.
El nombre de la funcin ser LongitudCadena, debe devolver un "int", y como parmetro de
entrada debe tener un puntero a "char".
En "main" probar con distintos tipos de cadenas: arrays y punteros.
2-) Escribir un programa con una funcin que busque un carcter determinado en una cadena.
El nombre de la funcin ser BuscaCaracter, debe devolver un "int" con la posicin en que fue
encontrado el carcter, si no se encontr volver con -1.
Los parmetros de entrada sern una cadena caracteres.
3-) De qu tipo es cada una de las siguientes variables?
a) int*

a,b;
a puntero, b puntero
a puntero, b entero
a entero, b puntero
a entero, b entero

b) int *a,b;
a puntero, b puntero
a puntero, b entero
a entero, b puntero
a entero, b entero
c) int *a,*b;
a puntero, b puntero
a puntero, b entero
a entero, b puntero
a entero, b entero

- 64 -

TALLER DE INFORMTICA
d) int*

CAPITULO 10. Punteros

a,*b;
a puntero, b puntero
a puntero, b puntero doble
a entero, b puntero
a entero, b puntero doble

4-) Considerando las siguientes declaraciones y sentencias:


int array[]={1,2,3,4,5,6};
int *puntero;
puntero = array;
puntero++;
*puntero=*puntero+6;
puntero=puntero+3;
puntero=punteropuntero[2];
int x=punteroarray;
a) Cul es el valor de x? Marcar la opcin correcta.
1
2
3
4
b) Cual es el valor de array[1]? Marcar la opcin correcta.
2
4
6
8
5-) Cunta memoria ocupa un Puntero?
6-) La cantidad de memoria que ocupa el puntero depende del tipo de variable a la que apunta?

- 65 -

TALLER DE INFORMTICA

CAPITULO 11. Estructuras

CAPITULO 11. ESTRUCTURAS.


11.1. Estructuras.
Las estructuras son el segundo tipo de datos estructurados que veremos.
Las estructuras nos permiten agrupar varios datos, aunque sean de distinto tipo, que mantengan
algn tipo de relacin, permitiendo manipularlos todos juntos, con un mismo identificador, o por
separado.
Las estructuras son llamadas tambin muy a menudo registros, o en ingls "records". Y son
estructuras anlogas en muchos aspectos a los registros de bases de datos. Y siguiendo la misma
analoga, cada variable de una estructura se denomina a menudo campo, o "field".
Sintaxis:

struct [<identificador>] { [<tipo> <nombre_variable>[,<nombre_variable>,...]];


.
} [<variable_estructura>[,<variable_estructura>,...];

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


Las variables de estructura son variables declaradas del tipo de la estructura, y su inclusin tambin
es opcional. Sin bien, al menos uno de estos elementos debe existir, aunque ambos sean
opcionales.
En el interior de una estructura, entre las llaves, se pueden definir todos los elementos que
consideremos necesarios, del mismo modo que se declaran las variables.
Las estructuras pueden referenciarse completas, usando su nombre, como hacemos con las
variables que ya conocemos, y tambin se puede acceder a los elementos en el interior de la
estructura usando el operador de seleccin (.), un punto.
Tambin pueden declararse ms variables del tipo de estructura en cualquier parte del programa,
de la siguiente forma:

[struct] <identificador> <variable_estructura>


[,<variable_estructura>...];
En C++ la palabra "struct" es opcional en la declaracin de variables. En C es obligatorio usarla.
Por ejemplo:

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

Este ejemplo declara a Fulanito como una variable de tipo Persona. Para acceder al nombre de
Fulanito, por ejemplo para visualizarlo, usaremos la forma:

cout << Fulanito.Nombre;


IMPORTANTE:
Se buscar que las definiciones de la Estructuras sean GLOBALES, pero las instancias
LOCALES.

- 66 -

TALLER DE INFORMTICA

CAPITULO 11. Estructuras

11.2. Funciones en el interior de estructuras


C++, al contrario que C, permite incluir funciones en el interior de las estructuras. Normalmente
estas funciones tienen la misin de manipular los datos incluidos en la estructura.
Aunque esta caracterstica se usa casi exclusivamente con las clases, como veremos ms adelante,
tambin puede usarse en las estructuras.
Dos funciones muy particulares son las de inicializacin, o constructor, y el destructor. Veremos con
ms detalle estas funciones cuando asociemos las estructuras y los punteros. El constructor es una
funcin 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 operador "~".
Por ejemplo:
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(); // Declaracin del constructor
} Punto1, Punto2;
// Definicin del constructor, fuera de la estructura

Punto::Punto() {
x = 0;
y = 0;
}

Si no usramos un constructor, los valores de x e y para Punto1 y Punto2 estaran indeterminados,


contendran la "basura" que hubiese en la memoria asignada a estas estructuras durante la
ejecucin. Con las estructuras ste ser el caso ms habitual.

Para aquellos que usen un teclado espaol, el smbolo "~" se obtiene pulsando las teclas del
teclado numrico 1, 2, 6, mientras se mantiene pulsada la tecla ALT, ([ALT]+126).
Tambin mediante la combinacin [Atl Gr]+[4] (la tecla [4] de la zona de las letras, no del teclado
numrico).

Uso de espacios de trabajo


En C los espacios de trabajo reciben el nombre de namespace. Por defecto utilizamos el estndar
(std) pero podemos definir tantos como sean necesarios.
Supongamos que en un curso tenemos dos alumnos que se llaman Juan Perez, cuando debamos
llamarlos quin responder?
- 67 -

TALLER DE INFORMTICA

CAPITULO 11. Estructuras

Bueno eso es incierto, algo parecido sucede en el lenguaje C, donde se pueden definir tipos de
variables personales.
S, eso mismo podemos darle el nombre que queramos. Pero qu sucedera si queremos crear un
tipo de datos y tenemos la mala suerte que dentro de una librera que usamos ese tipo de dato ya
existe?
Es difcil saber si el nombre para el tipo de variables que queremos usar ya fue usado, en este caso
el compilador tirara un error y deberamos cambiar el nombre, para evitar esto se definen espacios
en los que se deben tener en cuenta determinados nombres. Sera algo parecido al ejemplo de
Juan Perez.
Esto se soluciona ubicando explcitamente a cada alumno en una comisin distinta.
Solo con fines didcticos veremos un cdigo en cual no compilara pero la idea es destacar la
referencia a distintos espacios de nombres.
Por ejemplo:

using namespace Ns1


{ int x; }
using namespace Ns2
{ int x; }
int main()
{
cout << endl <<" Ingrese el valor de x para el espacio de nombre Ns1: ";
cin >> Ns1:: x;
cout << endl <<" Ingrese el valor de x para el espacio de nombre Ns2: ";
cin >> Ns2:: x;
}

Mencionar aqu, slo a ttulo de informacin, que el constructor no tiene por qu ser nico. Se
pueden incluir varios constructores, pero veremos esto mucho mejor y con ms 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 captulos posteriores.
Tambin podemos incluir otras funciones, que se declaran y definen como las funciones que ya
conocemos, salvo que tienen restringido su mbito al interior de la estructura.
Por ejemplo:

#include <iostream>
using namespace std;
struct stPareja {
int A, B;
int LeeA() { return A;}
int LeeB() { return B;}
void GuardaA(int n) { A = n;}
void GuardaB(int n) { B = n;}
} Par;
int main()
{ Par.GuardaA(15);
Par.GuardaB(63);
cout << Par.LeeA() << endl;
cout << Par.LeeB() << endl;
cin.get();
return 0;
}

// Devuelve el valor de A
// Devuelve el valor de B
// Asigna un nuevo valor a A
// Asigna un nuevo valor a B

- 68 -

TALLER DE INFORMTICA

CAPITULO 11. Estructuras

En este ejemplo podemos ver cmo 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
algn tratamiento de los datos.
Por supuesto se pueden definir otras funciones y tambin constructores ms elaborados y
sobrecarga de operadores. Y en general, las estructuras admiten cualquiera de las caractersticas
de las clases, siendo en muchos aspectos equivalentes.
Veremos estas caractersticas cuando estudiemos las clases, y recordaremos cmo aplicarlas a las
estructuras.

11.3. Inicializacin de estructuras


De un modo parecido al que se inicializan los arrays, se pueden inicializar estructuras, tan slo hay
que tener cuidado con las estructuras anidadas.
Por ejemplo:

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.

11.4. Asignacin de estructuras


La asignacin de estructuras est permitida, pero slo entre variables del ismo tipo de estructura,
salvo que se usen constructores, y funciona como a intuicin dice que debe hacerlo.
Por ejemplo:

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

- 69 -

TALLER DE INFORMTICA

CAPITULO 11. Estructuras

La lnea:

Punto2 = Punto1;
equivale a:

Punto2.x = Punto1.x;
Punto2.y = Punto1.y;

11.5. Arrays de estructuras


La combinacin de las estructuras con los arrays proporciona una potente herramienta para el
almacenamiento y manipulacin de datos.
Por ejemplo:

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

Vemos en este ejemplo lo fcil que podemos declarar el array Plantilla que contiene los datos
relativos a doscientas personas.
Podemos acceder a los datos de cada uno de ellos:

cout << Plantilla[43].Direccion;

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

Plantilla[0] = Plantilla[99];
Veamos un ejemplo de un Array de instancias 2 dimensiones o dicho de otra manera una matriz de
instancias de una Estructura.

#include <iostream>
using namespace std;
struct prueba {int x; char nombre[11];};
int main()
{int i,j,k=1;
prueba datos[3][3];
//Instacia de Estructura de 2 dimensiones.
for ( i=0; i < 3; i++)
{
for (j=0; j < 3; j++)
{
datos[i][j].x=k;
cout<< endl << "Ingrese Nombre: " << endl;
cin.getline(datos[i][j].nombre,10);
//Permite ingresar hasta 10
k++;
}
}
for (i=0; i < 3; i++)
{ for (j=0; j < 3; j++)
{cout << datos[i][j].x <<" "<< datos[i][j].nombre <<endl;}
}
return 0;
}

- 70 -

TALLER DE INFORMTICA

CAPITULO 11. Estructuras

11.6. Estructuras anidadas


Tambin est permitido anidar estructuras, con lo cual se pueden conseguir superestructuras muy
elaboradas.
Por 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 prctica corriente definir estructuras dentro de estructuras, ya que resultan
tener un mbito local, y para acceder a ellas se necesita hacer referencia a la estructura ms
externa.
Por ejemplo para declarar una variable del tipo stNombre hay que utilizar el operador de acceso
(::):

stPersona::stNombre NombreAuxiliar;

Sin embargo para declarar una variable de tipo stDireccion basta con declararla:

stDireccion DireccionAuxiliar;

- 71 -

TALLER DE INFORMTICA

CAPITULO 11. Estructuras

11.7. Operador "sizeof" con estructuras


Cuando se aplica el operador sizeof a una estructura, el tamao obtenido no siempre coincide con
el tamao de la suma de sus campos.
Por ejemplo:

#include <iostream>
using namespace std;
struct A {
int x;
char a;
int y;
char b;
};
struct B {
int x;
int y;
char a;
char b;
};
int main()
{
cout << "Tamao de int: " << sizeof(int) << endl;
cout << "Tamao de char: " << sizeof(char) << endl;
cout << "Tamao de estructura A: " << sizeof(A) << endl;
cout << "Tamao de estructura B: " << sizeof(B) << endl;
cin.get();
return 0;
}

El resultado, usando Anjuta , es el siguiente:


Tamao
Tamao
Tamao
Tamao

de
de
de
de

int: 4
char: 1
estructura A: 16
estructura B: 12

Si hacemos las cuentas, en ambos casos el tamao de la estructura debera ser el mismo, es decir,
4+4+1+1=10 bytes. Sin embargo en el caso de la estructura A el tamao es 16 y en el de la
estructura B es 12, por qu?
La explicacin es algo denominado alineacin 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 slo se accede a posiciones de memoria mltiplos de 4, y el
compilador intenta alinear las variables con esas posiciones.
En el caso de variables "int" es fcil, ya que ocupan 4 bytes, pero con las variables "char" no, ya
que slo ocupan 1.
Cuando se accede a datos de menos de 4 bytes la alineacin no es tan importante. El rendimiento
se ve afectado sobre todo cuando hay que leer datos de cuatro bytes que no estn alineados.

- 72 -

TALLER DE INFORMTICA

CAPITULO 11. Estructuras

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 posicin mltiplo de 4, dejando 3 posiciones libres despus del
campo "a". Lo mismo pasa con el campo "b".

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 slo se desperdician los dos bytes sobrantes despus
de "b".

11.8. Campos de bits


Existe otro tipo de estructuras que consiste en empaquetar los campos de la estructura en el
interior de enteros, usando bloques o conjuntos de bits para cada campo.
Por ejemplo, una variable char contiene ocho bits, de modo que dentro de ella podremos
almacenar ocho campos de un bit, o cuatro de dos bits, o dos de tres y uno de dos, etc. En una
variable int de 16 bits podremos almacenar 16 bits, etc.
Debemos usar siempre valores de enteros sin signo, ya que el signo se almacena en un bit del
entero, el de mayor peso, y puede falsear los datos almacenados en la estructura.
Sintaxis:

struct [<nombre de la estructura>] {


unsigned <tipo_entero> <identificador>:<nm_de_bits>;
} [<lista_variables>];

Hay algunas limitaciones, por ejemplo, un campo de bits no puede ocupar dos variables distintas,
todos sus bits tienen que estar en el mismo valor entero.
Por ejemplo:

struct mapaBits {
unsigned char bit0:1;
unsigned char bit1:1;
unsigned char bit2:1;
unsigned char bit3:1;
unsigned char bit4:1;
unsigned char bit5:1;
unsigned char bit6:1;
unsigned char bit7:1;
};
struct mapaBits2 {
unsigned short int campo1:3;
unsigned short int campo2:4;
unsigned short int campo3:2;
unsigned short int campo4:1;
unsigned short int campo5:6;
};

- 73 -

TALLER DE INFORMTICA

CAPITULO 11. Estructuras

struct mapaBits3 {
unsigned char campo1:5;
unsigned char campo2:5;
};
En el primer caso se divide un valor char sin signo en ocho campos de un bit cada uno:

En el segundo caso dividimos un valor entero sin signo de diecisis bits en cinco campos de
distintas longitudes:

Los valores del campo5 estarn limitados entre 0 y 63, que son los nmeros que se pueden
codificar con seis bits. Del mismo modo, el campo4 slo puede valer 0 1, etc.

En este ejemplo vemos que como no es posible empaquetar el campo2 dentro del mismo char que
el campo1, se aade un segundo valor char, y se dejan sin usar los bits sobrantes.
Tambin es posible combinar campos de bits con campos normales.
Por ejemplo:

struct mapaBits2 {
int numero;
unsigned short int campo1:3;
unsigned short int campo2:4;
unsigned short int campo3:2;
unsigned short int campo4:1;
unsigned short int campo5:6;
float n;
};

Los campos de bits se tratan en general igual que cualquier otro de los campos de una estructura.
Se les puede asignar valores (dentro del rango que admitan), pueden usarse en condicionales,
imprimirse, etc.

- 74 -

TALLER DE INFORMTICA

CAPITULO 11. Estructuras

#include <iostream>
#include <cstdlib>
using namespace std;
struct mapaBits2 {
unsigned short int campo1:3;
unsigned short int campo2:4;
unsigned short int campo3:2;
unsigned short int campo4:1;
unsigned short int campo5:6;
};
int main()
{
mapaBits2 x;
x.campo2 = 12;
x.campo4 = 1;
cout << x.campo2 << endl;
cout << x.campo4 << endl;
cin.get();
return 0;
}
No es normal usar estas estructuras en programas, salvo cuando se relacionan con ciertos
dispositivos fsicos, por ejemplo, para configurar un puerto serie en MS-DOS se usa una estructura
empaquetada en un unsigned char, que indica los bits de datos, de parada, la paridad, etc, es
decir, todos los parmetros del puerto. En general, para programas que no requieran estas
estructuras, es mejor usar estructuras normales, ya que son mucho ms rpidas.
Otro motivo que puede decidirnos por estas estructuras es el ahorro de espacio, ya sea en disco o
en memoria. Si conocemos los lmites de los campos que queremos almacenar, y podemos
empaquetarlos en estructuras de mapas de bits podemos ahorrar mucho espacio.

11.9. Punteros a estructuras


Los punteros tambin pueden apuntar a estructuras y tambin pueden existir miembros de la
estructura que sean punteros.
En este caso, para referirse a cada elemento de la estructura se usa el operador (->), en lugar del
(.).
Suponiendo que el nombre del puntero es punt y el miembro de una estructura es dia y punt esta
inicializado a una instancia de esa estructura se podra acceder al miembro:

punt->dia
Por ejemplo:

struct stComplejo {
float real, imaginario;
} Complejo[10];
stComplejo *p;
p = Complejo;
p++;

/* Equivale a p = &Complejo[0]; */
/* p == &Complejo[1] */

En este caso, al incrementar p avanzaremos las posiciones de memoria necesarias para apuntar a
la siguiente instancia o conjuntos de variables del array de estructura llamado "Complejo" o si.
Es decir avanzaremos sizeof(stComplejo) bytes.

- 75 -

TALLER DE INFORMTICA

CAPITULO 11. Estructuras

Por ejemplo:

#include <iostream>
using namespace std;
struct stEstructura {
int a, b;
};
int main() {
stEstrucutra estructura, *e;
estructura.a = 10;
estructura.b = 32;
e = &estructura;
cout << "variable" << endl;
cout << e->a << endl;
cout << e->b << endl;
cout << "puntero" << endl;
cout << estructura.a << endl;
cout << estructura.b << endl;
cin.get();
return 0;
}

//La Estructura es Global !!


//Instancias Local !!
//accedo con el operador punto.

//accedo con el operado flecha ->

11.9.1. Ejemplo Gestion dinmica de Memoria y Lista Enlazada simple


Existen varias aplicaciones derivadas de incorporar un puntero como miembro de una estructura.
En particular mucho mas cuando el puntero apunta a una estructura del mismo tipo!! esto crea lo
que se conocen como listas Enlazadas Simples, Dobles , Circulares.. etc.
Veamos como son

/*Crear una lista simple de una cantidad de instancias a determinar en tiempo de


ejecucin o en forma dinmica de una estructura del siguiente tipo:
struct dato {int tel; int legajo; struct dato *pdato;};*/
//Crear una lista simple de 5 instancias
#include <iostream>
using namespace std;
struct dato {int tel; int legajo; struct dato *pdato;};
int main()
{
int i,cantidad_instancias;
struct dato *punterodato ;
cout<< " Ingrese un nro entero para definir la cantidad de
instancias"<< endl;
cin >> cantidad_instancias;
punterodato= new struct dato[cantidad_instancias];
for (i=0; i< cantidad_instancias ; i++)
{
cout << " Telefono: " << endl;
cin >> (punterodato+i)>
tel;
cout << " Legajo : " << endl;
cin >> (punterodato+i)>
legajo;
if(i==(cantidad_instancias1))(
punterodato+i)>
pdato=0;
- 76 -

TALLER DE INFORMTICA

CAPITULO 11. Estructuras

else (punterodato+i)>
pdato=(punterodato+i+1);
}
/*for (i=0; i< cantidad_instancias ; i++)
{
cout << punterodato>
tel;
cout << punterodato>
legajo;
punterodato++;
}*/
do
{
cout << punterodato << endl;
cout << punterodato>
tel<< endl;
cout << punterodato>
legajo <<endl;
cout << punterodato>
pdato << endl;
cout << endl << endl;
punterodato++;
}while (((punterodato1)
>
pdato)!=0);
return 0;
}
Este tipo de Lista se puede recorrer en un solo sentido desde el principio hacia el fin. Vemos otra
que no tiene este inconveniente.

11.9.2. Ejemplo Gestin dinmica de Memoria y Lista Enlazada Doble


Cargar una estructura doblemente enlazada del siguiente tipo:
struct dato {int tel; int legajo; struct dato *pprox; struct dato *pant;};

#include <iostream>
using namespace std;
struct dato {int tel; int legajo; struct dato *pprox; struct dato *pant;};
int main()
{
int i,cantidad_instancias;
struct dato *punterodato ;
cout<< " Ingrese un nro entero para definir la cantidad de
instancias"<< endl;
cin >> cantidad_instancias;
punterodato= new struct dato[cantidad_instancias];
for (i=0; i< cantidad_instancias ; i++)
{
cout << " Telefono: " << endl;
cin >> (punterodato+i)>
tel;
cout << " Legajo : " << endl;
- 77 -

TALLER DE INFORMTICA

CAPITULO 11. Estructuras

cin >> (punterodato+i)>


legajo;
if(i==0) (punterodato+i)>
pant=0;
else (punterodato+i)>
pant=(punterodato+i1);
if(i==(cantidad_instancias1))(
punterodato+i)>
pprox=0;
else (punterodato+i)>
pprox=(punterodato+i+1);
}
do
{
cout << " Direccion de esta instacia : ";cout << punterodato << endl;
cout << " Telefono : " << punterodato>
tel<< endl;
cout << " Legajo : ";cout << punterodato>
legajo <<endl;
cout << " Direccion de la insta. anterior: ";cout << punterodato>
pant<< endl;
cout << " Direccion de la insta. proxima: ";cout << punterodato>
pprox<< endl;
cout << endl << endl;
punterodato++;
}while (((punterodato1)
>
pprox)!=0);
return 0;
}
Este tipo de Lista se puede recorrer en ambos sentidos.

11.10. Ejercicios
Carga y muestra de Estructura de una sola Instancia
1-) Realizar un Programa en C que cargue una Estructura llamada Alumno de una sola instancia de
nombre Electronica del siguiente tipo: Nombre (char de 10 elementos), edad (entero), fecha de
nacimiento(arreglo de 3 enteros).
Luego de cargar esta estructura desde teclado deber mostrarla.
Carga y muestra de Estructura de 5 instancias
2-) Realizar un Programa en C que cargue una Estructura llamada Alumno de 5 instancias de
nombre Electronica del siguiente tipo: Nombre (char de 10 elementos), edad (entero), fecha de
nacimiento (arreglo de 3 enteros).
Luego de cargar esta estructura desde teclado deber mostrarla.
Carga y muestra de Estructura de 5 instancias usando puntero
3-) Realizar un Programa en C que cargue una Estructura llamada Alumno de 5 instancias de
nombre Electronica del siguiente tipo: Nombre (char de 10 elementos), edad (entero), fecha de
nacimiento(arreglo de 3 enteros).
Luego de cargar esta estructura desde teclado deber mostrarla. La carga y la muestra debern
realizarse usando punteros.

- 78 -

TALLER DE INFORMTICA

CAPITULO 11. Estructuras

Carga y muestra de Estructura de una sola instancia usando puntero a la estructura y funciones.
4-) Realizar un Programa en C que cargue una Estructura llamada Alumno de una sola instancia de
nombre Electronica del siguiente tipo: Nombre (char de 10 elementos), edad (entero), fecha de
nacimiento(arreglo de 3 enteros). La carga de la Instancia se deber hacer en una funcin llamada
carga que recibe como argumento un puntero a la Estructura. La muestra de la Instancia se deber
hacer en una funcin llamada muestra que recibe como argumento un puntero a la Estructura.
Carga y muestra de Estructura de 5 instancias usando puntero a la estructura y funciones.
5-) idem anterior pero para 5 instancias.
6-) Escribir un programa que almacene en un array los nombres y nmeros de telfono de 10
personas. El programa debe leer los datos introducidos por el usuario y guardarlos en memoria.
Despus debe ser capaz de buscar el nombre correspondiente a un nmero de telfono y el
telfono correspondiente a una persona. Ambas opciones deben se accesibles a travs de un men,
as como la opcin de salir del programa. El men debe tener esta forma, ms o menos:
a) Buscar por nombre
b) Buscar por nmero de telfono
c) Salir
Pulsa una opcin:
Nota: No olvides que para comparar cadenas se debe usar una funcin, no el operador ==.
7-) Para almacenar fechas podemos crear una estructura con tres campos: ano, mes y da. Los
das pueden tomar valores entre 1 y 31, los meses de 1 a 12 y los aos, dependiendo de la
aplicacin, pueden requerir distintos rangos de valores. Para este ejemplo consideraremos
suficientes 128 aos, entre 1960 y 2087. En ese caso el ao se obtiene sumando 1960 al valor de
ao. El ao 2003 se almacena como 43.
Usando estructuras, y ajustando los tipos de los campos, necesitamos un char para da, un char
para mes y otro para ao.
Disear una estructura anloga, llamada "fecha", pero usando campos de bits. Usar slo un entero
corto sin signo (unsigned short), es decir, un entero de 16 bits. Los nombres de los campos sern:
dia, mes y anno.
8-) Basndose en la estructura de bits del ejercicio anterior, escribir una funcin para mostrar
fechas: void Mostrar(fecha);. El formato debe ser:
"dd de mmmmmm de aaaa", donde dd es el da, mmmmmm el mes con letras, y aaaa el ao. Usar
un array para almacenar los nombres de los meses.
9-) Basndose en la estructura de bits del ejercicio anterior, escribir una funcin bool
ValidarFecha(fecha);, que verifique si la fecha entregada como parmetro es vlida. El mes tiene
que estar en el rango de 1 a 12, dependiendo del mes y del ao, el da debe estar entre 1 y 28, 29,
30 31.
El ao siempre ser vlido, ya que debe estar en el rango de 0 a 127.
Para validar los das usaremos un array int DiasMes[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30,
31};. Para el caso de que el mes sea febrero, crearemos otra funcin para calcular si un ao es o
no bisiesto: bool Bisiesto(int); Los aos bisiestos son los divisibles entre 4, al menos en el rango de
1960 a 2087 se cumple.
Nota: los aos bisiestos son cada cuatro aos, pero no cada 100, aunque s cada 400. Por ejemplo,
el ao 2000, es mltiplo de 4, por lo tanto debera haber sido bisiesto, pero tambin es mltiplo de
100, por lo tanto no debera serlo; aunque, como tambin es mltiplo de 400, finalmente lo fue.
10-) Seguimos con el tema de las fechas. Ahora escribir dos funciones ms.
La primera debe responder a este prototipo: int CompararFechas(fecha, fecha);. Debe comparar las
dos fechas suministradas y devolver 1 si la primera es mayor, -1 si la segunda es mayor y 0 si son
iguales. La otra funcin responder a este prototipo: int Diferencia(fecha, suministradas.

- 79 -

TALLER DE INFORMTICA

CAPITULO 11. Estructuras

11-) Supongamos la declaracin de la siguiente estructura:

struct ejemplo1 {
unsigned char c1:7;
unsigned char c2:6;
unsigned char c3:3;
unsigned char c4:4;
};:

a) Cuntos bytes ocupa esta estructura? Marcar la opcin correcta.


1
2
3
4
b) Y si en lugar de un "unsigned char" usamos un "unsigned short" de 16 bits?
1
2
3
4
c) Y si

en lugar de un "unsigned short" usamos un "unsigned int" de 32 bits?


1
2
3
4

12-) Tenemos la siguiente estructura:

struct A {
struct B {
int x,y;
float r;
} campoB;
float s;
struct {
int z;
float t;
} campoC;
} E;

Si tenemos la variable "E", indicar la forma correcta de acceder a las siguientes variables:
a) x
A.B.x
E.campoB.x
E.x
E.b.x
b) s
A.s
E.s
E.a.s
c) t
A.t
E.t
A.campoC.t
E.campoC.t

- 80 -

TALLER DE INFORMTICA

CAPITULO 11. Estructuras

13-) Considerando la siguiente declaracin:

struct A {
struct {
int x;
int y;
} campoB;
} *estructuraA;

a) Cmo se referenciara el campo x de la estructura A?


Estructura A.x
estructura A.campoB.x
estructura A.campoB->x
estructura A->campoB.x

- 81 -

TALLER DE INFORMTICA

CAPITULO 12. Ms operadores

CAPITULO 12. MS OPERADORES.


Veremos ahora ms detalladamente algunos operadores que ya hemos mencionado, y algunos
nuevos.

12.1. Operadores de Referencia (&) e Indireccin (*)


El operador de referencia (&) nos devuelve la direccin de memoria del operando.
Sintaxis:

&<expresin simple>

El operador de indireccin (*) considera a su operando como una direccin y devuelve su


contenido.
Sintaxis:

*<puntero>

Por ejemplo:

int A, *pA;
pA=&A;

Para este caso pA es un puntero, pero en el caso de que tengamos:

int a, b;
b=&a;

Vemos que b NO ES UN PUNTERO, en este caso se dice que b es un alias de o variable


referenciada, es decir es la misma variable con dos nombre distinto.

12.2. Operadores . y ->


El operador de seleccin (.) permite acceder a variables o campos dentro de una estructura.
Sintaxis:

<variable_estructura>.<nombre_de_variable>

El operador de seleccin de variables o campos se utiliza para estructuras referenciadas con


punteros. (->)
Sintaxis:

<puntero_a_estructura>-><nombre_de_variable>

12.3. Operador de preprocesador


El operador "#" sirve para dar rdenes o directivas al compilador. Por el momento este tema no
forma parte del Programa de la Materia.

12.4. Operadores de manejo de memoria "new" y "delete"


Veremos su uso en el captulo de punteros II y en mayor profundidad en el captulo de clases y en
operadores sobrecargados.

- 82 -

TALLER DE INFORMTICA

CAPITULO 12. Ms operadores

12.4.1. Operador new


El operador new sirve para reservar memoria dinmica.
Sintaxis:

[::]new [<emplazamiento>] <tipo> [(<inicializacin>)]


[::]new [<emplazamiento>] (<tipo>) [(<inicializacin>)]
[::]new [<emplazamiento>] <tipo>[<nmero_elementos>]
[::]new [<emplazamiento>] (<tipo>)[<nmero_elementos>]

El operador opcional :: est relacionado con la sobrecarga de operadores, de momento no lo


usaremos. Lo mismo se aplica a emplazamiento.
La inicializacin, si aparece, se usar para asignar valores iniciales a la memoria reservada con new,
pero no puede ser usada con arrays.
Las formas tercera y cuarta se usan para reservar memoria para arrays dinmicos. La memoria
reservada con new ser vlida hasta que se libere con delete o hasta el fin del programa, aunque
es aconsejable liberar siempre la memoria reservada con new usando delete. Se considera una
prctica muy sospechosa no hacerlo.
Si la reserva de memoria no tuvo xito, new devuelve un puntero nulo, NULL.

12.4.1.1 Ejemplo Gestion dinmica de Memoria y Lista Enlazada Doble


Cargar una estructura doblemente enlazada del siguiente tipo:

struct dato {int tel; int legajo; struct dato *pprox; struct dato *pant;}

recorrerla por teclado de manera que con P o p se pase a la proxima instancia y con A o a se pase
a la instancia anterior , con f o F se sale.

#include <iostream>
using namespace std;
void menu();
void recorre ( struct dato *p);
struct dato {int tel; int legajo; struct dato *pprox; struct dato *pant;};
int main()
{
int i,cantidad_instancias;
struct dato *punterodato ;
cout<< " Ingrese un nro entero para definir la cantidad de
instancias"<< endl;
cin >> cantidad_instancias;
// Solicito al sistema el espacio en memoria
punterodato= new struct dato[cantidad_instancias];
for (i=0; i< cantidad_instancias ; i++)
{
cout << " Telefono: " << endl;
cin >> (punterodato+i)>
tel;
cout << " Legajo : " << endl;
cin >> (punterodato+i)>
legajo;
if(i==0) (punterodato+i)>
pant=0;
else (punterodato+i)>
pant=(punterodato+i1);

- 83 -

TALLER DE INFORMTICA

CAPITULO 12. Ms operadores

if(i==(cantidad_instancias1))(
punterodato+i)>
pprox=0;
else (punterodato+i)>
pprox=(punterodato+i+1);
}
menu();
recorre (punterodato);
return 0;
}
void menu()
{
cout << " Para recorrer las instacias presione "<< endl;
cout << " presione P >
proxima A>
anterior F >
Finaliza";
}
void recorre(struct dato *p)
{ char opc;
do{
cin>> opc;
switch (opc)
{
case 'a':
case 'A':p=p>
pant;
cout << " Direccion de esta instacia : ";cout << p << endl;
cout << " Telefono : " << p>
tel<< endl;
cout << " Legajo : ";cout << p>
legajo <<endl;
cout << " Direccion de la insta. anterior: ";cout << p>
pant<< endl;
cout << " Direccion de la insta. proxima: ";cout << p>
pprox<< endl;
cout << endl << endl;
break;
case 'p':
case 'P':p=p>
pprox;
cout << " Direccion de esta instacia : ";cout << p << endl;
cout << " Telefono : " << p>
tel<< endl;
cout << " Legajo : ";cout << p>
legajo <<endl;
cout << " Direccion de la insta. anterior: ";cout << p>
pant<< endl;
cout << " Direccion de la insta. proxima: ";cout << p>
pprox<< endl;
cout << endl << endl;
break;
case 'f':

- 84 -

TALLER DE INFORMTICA

CAPITULO 12. Ms operadores

case 'F':cout << "Chau!";break;


defalut: cout << " Opcion no valida";break;
}
}while ( opc!='f' || opc!= 'F');
}

12.4.2-Operador delete
El operador delete se usa para liberar la memoria dinmica reservada con new.
Sintaxis:

[::]delete [<expresin>]
[::]delete [<expresin>]

La expresin ser normalmente un puntero, el operador delete[] se usa para liberar memoria de
arrays dinmicas. Es importante liberar siempre usando delete la memoria reservada con new.
Existe el peligro de prdida de memoria si se ignora esta regla. Cuando se usa el operador delete
con un puntero nulo, no se realiza ninguna accin. Esto permite usar el operador delete con
punteros sin necesidad de preguntar si es nulo antes.

Los operadores new y delete son propios de C++. En C se usan las funciones malloc y free para
reservar y liberar memoria dinmica y liberar un puntero nulo con free suele tener consecuencias
desastrosas.
Por ejemplo:

int main() {
char *c;
int *i = NULL;
float **f;
int n;
c = new char[123];
f = new float *[10]; (1)

// Cadena de 122 ms el nulo:


// Array de 10 punteros a flot a.
//Cada elemento del array es un array de 10 float
for(n = 0; n < 10; n++) f[n] = new float[10]; (2)
// f es un array de 10*10
f[0][0] = 10.32;
f[9][9] = 21.39;
c[0] = 'a';
c[1] = 0;
for(n = 0; n < 10; n++) delete[] f[n];
// liberar memoria dinmica
delete[] f;
delete[] c;
delete i;
return 0; }

f es un puntero que apunta a un puntero que a su vez apunta a un float. Un puntero puede
apuntar a cualquier tipo de variable, incluidos los propios punteros. Este ejemplo nos permite crear
arrays dinmicos de dos dimensiones. La lnea (1) crea un array de 10 punteros a float. La (2) crea
10 arrays de floats. El comportamiento final de f es el mismo que si lo hubiramos declarado como:
float f[10][10];

- 85 -

TALLER DE INFORMTICA

CAPITULO 13. Pasaje de valores a funciones

CAPITULO 13. PASAJE DE VALORES A FUNCIONES.


13.1. Parmetros por valor y parmetros por referencia.
Dediquemos algo ms de tiempo a las funciones.
Hasta ahora siempre hemos declarado los parmetros de nuestras funciones del mismo modo. Sin
embargo, ste no es el nico modo que existe para pasar parmetros. La forma en que hemos
declarado y pasado los parmetros de las funciones hasta ahora es la que normalmente se conoce
como "por valor". Esto quiere decir que cuando el control pasa a la funcin, los valores de los
parmetros en la llamada se copian a "variables" locales de la funcin, estas "variables" son de
hecho los propios parmetros, pero como hago si realmente queremos que los valores pasados se
modifiquen?, la respuesta a esto es pasar los valores por referencia.
Por ejemplo:

#include <iostream>
using namespace std;
int extremo_intervalo(int menor, int mayor);
int main() {
int a, b;
/*a y b locales de main */
cout << endl << "Ingrese el extremo de un intervalo: ";
cin >> a;
cout << endl << "Ingrese el extremo de un intervalo: ";
cin >> b;
cout << "a,b valen ->" << a << ", " << b << endl;
cout << "llamo a la funcion control pasando a y b y retorna: ";
if (extremo_intervalo(a, b)) cout << "Intercambiados !!";
else cout << "NO Intercambiados !!";
cout << endl;
/* llamo a la funcin */
cout << "a,b siguen valiendo ->" << a << ", " << b << endl;
return 0;
}

/* Esta funcin controla que el extermo inferior del intervalo sea menor o
igual que el extremo mayor */

int extremo_intervalo(int menor, int mayor)


{
int tmp;
if( menor <= mayor)
return 0;
/* retornado 0 no intercambia */
else
{tmp=menor;
menor=mayor;
/*intercambio los valores*/
mayor=tmp;}
return 1;
/* retorna 1 si intercambia */
}

Veamos como pasar valores a funciones pero que s puedan modificarlos.

- 86 -

TALLER DE INFORMTICA

CAPITULO 13. Pasaje de valores a funciones

13.1.1. Referencias a variables


Las referencias sirven para definir "alias" o nombres alternativos para una misma variable.
Para ello se usa el operador de referencia (&).
Por ejemplo:

&a

Aqu estaramos haciendo referencia a la direcin de memoria de la variable a, esta es la misma


dentro y fuera de cualquier funcin, aunque el nombre utilizado sea cualquiera.
Sintaxis:

<tipo> &<alias> = <variable de referencia>


<tipo> &<alias>

La primera forma es la que se usa para declarar variables de referencia, la asignacin es obligatoria
ya que no pueden definirse referencias indeterminadas. La segunda forma es la que se usa para
definir parmetros por referencia en funciones, en las que las asignaciones son implcitas.
Por ejemplo :

#include <iostream>
using namespace std;
int main() {
int a;
/* defino una variable */
int &r = a;
/* aca vemos que la direccin de la variable r es igual a la
de la varaible a => son lo mismo!! pero con otro nombre */
a = 10;
/* le doy un valor a a */
cout << " a vale ="<< a << endl;
cout << " el valor de de r es ="<< r << endl;
/*muestro el valor de r */
cin.get();
return 0;
}

En este ejemplo las variables a y r se refieren al mismo objeto, cualquier cambio en una de ellas se
produce en ambas. Para todos los efectos, son la misma variable.

13.2. Paso de parmetros por referencia


Si queremos que los cambios realizados en los parmetros dentro de la funcin se conserven al
retornar de la llamada, deberemos pasarlos por referencia. Esto se hace declarando los parmetros
de la funcin como referencias a variables.
Por ejemplo:

#include <iostream>
using namespace std;
int extremo_intervalo(int & menor, int & mayor);
/* ver que existe & */
int main() {
int a, b;
/*a y b locales de main */
cout << endl << "Ingreso el extremo de un intervalo: ";
cin >> a;
cout << endl << "Ingreso el otro extremo de un intervalo: ";
cin >> b;
cout << "a,b valen ->" << a << ", " << b << endl;
- 87 -

TALLER DE INFORMTICA

CAPITULO 13. Pasaje de valores a funciones

cout << "llamo a la funcion extremo_intervalo pasando a, b y retorna: ";


if (extremo_intervalo(a,b)) cout << "Intercambiados !!";
else cout << "NO Intercambiados !!";
cout << endl;
/* llamo a la funcin */
cout << "a,b valen ->" << a << ", " << b << endl;
return 0;
}

/* esta funcin controla que el extermo inferior del intervalo sea menor o igual
que el extremo mayor */

int extremo_intervalo(int &menor, int &mayor) /*recibe la direccin de las


variables */
{
int tmp;
if( menor <= mayor) return 0;
/* retornado 0 no intercambia */
else {
tmp=menor;
menor=mayor;
/*intercambio los valores*/
mayor=tmp;}
return 1;
/* retorna 1 si intercambia */
}

En este caso, las variables "a" y "b" tendrn valores distintos despus de llamar a la funcin.
Cualquier cambio que realicemos en los parmetros dentro de la funcin, se har tambin en las
variables referenciadas.

No podemos hacer llamadas a funciones con referencia a parmetros constantes.


Por ejemplo:

int extremo_intervalo(int & menor, int & mayor); /* prototipo */


extremo_intervalo(10 ,20 ); /* ERROR !!! MAL !!! */

- 88 -

TALLER DE INFORMTICA

CAPITULO 13. Pasaje de valores a funciones

13.3. Punteros como parmetros de funciones


Cuando pasamos un puntero como parmetro por valor de una funcin pasa lo mismo que con las
variables.
Dentro de la funcin trabajamos con una copia del puntero. Sin embargo, el objeto apuntado por el
puntero s ser el mismo, los cambios que hagamos en los objetos apuntados por el puntero se
conservarn al abandonar la funcin, pero no ser as con los cambios que hagamos al propio
puntero.
Por ejemplo:

#include <iostream>
using namespace std;
void funcion(int *q);
int main() {
int a;
int *p;
a = 100;
p = &a;
// Llamamos a funcion con un puntero funcion(p);
cout << "Variable a: " << a << endl;
cout << "Variable *p: " << *p << endl;
// Llamada a funcion con la direccin
de "a" (constante)
funcion(&a);
/*Sera Equivalente poner funcion(p) */
cout << "Variable a: " << a << endl;
cout << "Variable *p: " << *p << endl;
cin.get();
return 0;
}
void funcion(int *q) {
// Cambiamos el valor de la variable apuntada por el puntero
*q += 50;
q++;
/* vemos que cambio el valor de q, pero no tiene efecto */
}

Dentro de la funcin se modifica el valor apuntado por el puntero, y los cambios permanecen al
abandonar la funcin. Sin embargo, los cambios en el propio puntero son locales, y no se
conservan al regresar. Con este tipo de parmetro para funcin pasamos el puntero por valor.
Y cmo haramos para pasar un puntero por referencia?:

void funcion(int* &q); /*notar que no est * si no & !!*/


El operador de referencia siempre se pone junto al nombre de la variable.

- 89 -

TALLER DE INFORMTICA

CAPITULO 13. Pasaje de valores a funciones

13.4. Funciones que devuelven referencias


Como mencionamos, para devolver referencias desde una funcin, basta con declarar el valor de
retorno como una referencia.
Sintaxis:

<tipo> &<identificador_funcin>(<lista_parmetros>); /* notar que no est * si no & !! */

Esto nos permite trabajar con los elementos que nos pasan no con una copia.
Por ejemplo:

//La funcin mayor recibe un puntero a un array y dos indices para


// apuntar a una par de elementos del arreglo y retorna el mayor valor
// mas uno.
#include <iostream>
using namespace std;
int & mayor(int * , int , int); /* Prototipo de funcin */
int main()
{
int array [10] = {1, -3, 2, -1, 4, 5, 6, -7, 8, 9},a,b;
cout << "Ingrese un indice del vector enter 0 y 9" << endl;
cin >>a;
cout << "Ingrese un otro indice del vectot enter 0 y 9" << endl;
cin >>b;
cout << "El mayor valor es : "<< mayor( array, a,b ) << endl;
cin.get();
return 0;
}
int & mayor(int *vector , int y, int x)
{
return (++((vector[x]>=vector[y])?vector[x]:vector[y]));
}

Esta es una potente herramienta de la que disponemos, aunque ahora no se nos ocurra ninguna
aplicacin interesante.

- 90 -

TALLER DE INFORMTICA

CAPITULO 13. Pasaje de valores a funciones

13.5. Arrays como parmetros de funciones


Cuando pasamos un array como parmetro en realidad estamos pasando un puntero al primer
elemento del array, as que las modificaciones que hagamos en los elementos del array dentro de
la funcin sern validos al retornar.
Por ejemplo:

#include <iostream>
using namespace std;
#define TamanioArray 10
#include <iostream>
using namespace std;
int BuscaMenor(int x[]); //prototipo de la funcin
int main()
{
int arreglo[10];
for (int i=0; i < 10; i++)
{
cout << endl << "Ingrese un numero : " << endl;
cin >> arreglo[i];
cout << "El menor valor es: " << BuscaMenor(arreglo)<< endl;
}
return 0;
}
int BuscaMenor(int x[])
//defincin de la funcin
{
int menor=x[0];
// asigno como el menor al 1er elemento del array
for (int i=0; i < 10; i++)
if(x[i]< menor) menor=x[i];
return menor;
}

En este caso el array es de una dimensin, sin embargo, si slo pasamos el nombre del array de
ms de una dimensin no podremos acceder a los elementos del array mediante subndices, ya que
la funcin no tendr informacin sobre el tamao de cada dimensin.
Para tener acceso a arrays de ms de una dimensin dentro de la funcin se debe declarar el
parmetro como un array.

#include <iostream>
using namespace std;
#define N 3
#define M 3
void funcion(int [][M]);
int main() {
int Tabla[N][M]; // arreglo local Tabla;
for (int i=0; i < N; i++)for (int j=0; j<M ; j++)
{cout << "Ingrese un valor : " ;
cin >> Tabla[i][j];
}
funcion(Tabla);
//llamo a la funcion
for (int i=0; i < N; i++)for (int j=0; j<M ; j++)cout << Tabla[i][j] <<
" ";

- 91 -

TALLER DE INFORMTICA

CAPITULO 13. Pasaje de valores a funciones

return 0;
}
//Esta funcion solo cambia el valor de un elemento del arreglo
// pasado como referencia
void funcion(int arreglolocal[][M])
{
cout << "Ingrese un valor para cambiar el valor de
arreglolocal[1][1]" << endl;
cin >> arreglolocal [1][1] ;
}

Las estructuras tambin pueden ser pasadas por valor y por referencia.
Las reglas se les aplican igual que a los tipos fundamentales: las estructuras pasadas por valor no
conservarn sus cambios al retornar de la funcin. Las estructuras pasadas por referencia
conservarn los cambios que se les hagan al retornar de la funcin. Por el momento no
profundizaremos en esto.

- 92 -