Você está na página 1de 70

Corporativo Internacional Universitario

Nombre: Edwin Gonzlez Castaeda

Profesor: Gabriel Flores Gonzlez

Materia:

Introduccin a la programacin Tema: Introduccin al lenguaje c Tipos de datos Manejo de operaciones y expresiones Estructura de control e interacciones Tipos estructurados Funciones.

1er Semestre

INDICE

Estructura general de un programa en C ..1 Entornos de programacin C....2 Tipos de Entornos de Programacin...3 Compilacin4 Ejecucin del programa .5 Tipos de datos6 Enteros.7 Flotantes..8 Caracteres y Cadenas en C9 Variables y Constantes en C10 Entrada y salida (E/S) <stdio.h>......11 Tipos de Operadores y Expresiones.12 Estructuras de control e iteraciones.13 Tipos Estructurados..14 Funciones.15 Bibliografa.......16

Estructura general de un programa en C

/* Comentarios de un parrafo completo comprendidos entre /*.....*/, sirven para aclarar qu el programa o una parte del programa */ // Comentarios de 1 sola lnea // Zona de ficheros de cabecera de las libreras # include <....... .h> // h de Head # include <....... .h> // Zona de prototipos de funciones int Potencia (int x,y) // Zona de variables globales int valor; float media_total; voidmain (void) // Prog. ppal. tpico de Turbo C { // llave de inicio del programa // codigo del programa ....... ....... // fin del programa } // Desarrollo del cdigo de las funciones anteriores

Entornos de programacin C
Suele decirse que los programadores de verdad trabajan con un simple editor de texto y un compilador. Aunque tambin existen programas que nos hacen la, en muchas ocasiones ardua, tarea de programar ms cmoda y sencilla. Veamos alguno de ellos. Dev-C++ es uno de estos programas, desarrollado por Bloodshed Software y sin una nueva versin desde 2005, nos ofrece un entorno cmodo para la realizacin de nuestros proyectos tanto en lenguaje C como en C++. Permite la incorporacin de aadidos y libreras que expandan las funcionalidades del programa y utiliza un compilador basado en GCC: Mingw. Es un programa sencillo, rpido e intuitivo de utilizar, adems incorpora un depurador para facilitar la optimizacin de nuestros cdigos. Code::Blocks es un programa similar a Dev-C++, no es tan sencillo de configurar como es el anteriormente citado, pero admite la posibilidad de aadir numerosos compiladores como Digital Mars, Microsoft Visual C++, Borland C++ o Watcom. Adems Code::Blocks incorpora, adems de la posibilidad de aadir diversas libreras, herramientas para la creacin de interfaces grficas de usuario. Para finalizar, Microsoft Visual C++ es un programa muy completo, orientado sobre todo al desarrollo de aplicaciones para Windows, ofrece herramientas para la programacin utilizando libreras de DirectX o de .Net Framework. Existe una versin de pago que ofrece funcionalidad para muchos ms lenguajes y numerosas herramientas ms y tambin existe una versin gratuita llamada Express.

Siguiendo la terminologa anterior, es el banco de trabajo del programador Da soporte a las actividades de la fase de codificacin (preparacin del cdigo y prueba de unidades) Los mismos productos sirven tambin para el diseo detallado y para las pruebas de integracin.

Se sita, por tanto, en la parte central del ciclo de desarrollo

Funciones de un Entorno de Programacin Como se ha dicho, la misin de un Entorno de Programacin es dar soporte a la preparacin de programas, es decir, a las actividades de codificacin y pruebas.

Las tareas esenciales de la fase de codificacin son: o Edicin (creacin y modificacin) del cdigo fuente o Proceso/ejecucin del programa Interpretacin directa (cdigo fuente) Compilacin (cdigo mquina) - montaje - ejecucin Compilacin (cdigo intermedio) - interpretacin Otras funciones: o Examinar (hojear) el cdigo fuente o Analizar consistencia, calidad, etc. o Ejecutar en modo depuracin o Ejecucin automtica de pruebas o Control de versiones o Generar documentacin, reformar cdigo o ... y otras muchas ms ...

Tipos de Entornos de Programacin


Un entorno de programacin puede estar concebido y organizado de maneras muy diferentes. A continuacin se mencionan algunas de ellas.

En las primeras etapas de la informtica la preparacin de programas se realizaba mediante una cadena de operaciones tales como la que se muestra en la figura para un lenguaje procesado mediante compilador. Cada una de las herramientas deba invocarse manualmente por separado. En estas condiciones no puede hablarse propiamente de un entorno de programacin

El editor es un editor de texto simple El compilador traduce cada fichero de cdigo fuente a cdigo objeto El montador (linker / builder / loader) combina varios ficheros objeto para generar un fichero ejecutable o El depurador maneja informacin en trminos de lenguaje de mquina Un entorno de programacin propiamente dicho combina herramientas como stas, mejoradas y mejor integradas. A veces se nombra con las siglas IDE (Integrated Development Environment). Los componentes cuya evolucin ha sido ms aparente son los que realizan la interaccin con el usuario: o El editor ya no es un simple editor de texto, sino que tiene una clara orientacin al lenguaje de programacin usado (reconoce y maneja determinados elementos sintcticos) o El depurador no presenta informacin en trminos del lenguaje de mquina, sino del lenguaje fuente o El editor est bien integrado con las dems herramientas (se posiciona directamente en los puntos del cdigo fuente en los que hay errores de compilacin, o que se estn ejecutando con el depurador en un momento dado. No es fcil establecer una clasificacin dentro de la variedad de entornos de programacin existentes. En algn momento se describieron las siguientes clases de entornos, no excluyentes: o Entornos centrados en un lenguaje o Entornos orientados a estructura o Entornos coleccin de herramientas
o o o

Compilacin

Existen muchos compiladores de C. El CC es el compilador estndar de Sun. El compilador GNU de C es GCC, el cual es bastante popular y esta disponible en varias plataformas. Existen tambin compiladores equivalentes de C++ los cuales usualmente son nombrados como CC. Por ejemplo, Sun provee CC y GNU GCC. El compilador de GNU es tambin denotado como g++. Existen otros compiladores menos comunes de C y C++. En general todos los compiladores mencionados operan esencialmente de la misma forma y comparten muchas opciones comunes en la lnea de opciones. Ms adelante se listan y se dan ejemplos de opciones comunes de los compiladores. Sin embargo, la mejor referencia de cada compilador es a travs de las pginas en lnea, del manual del sistema. Por ejemplo: man gcc. Para compilar el programa usaremos el comando gcc. El comando deber ser seguido por el nombre del programa en C que se quiere compilar. Un determinado nmero de opciones del compilador pueden ser indicadas tambin. Por el momento no haremos uso de estas opciones todava, se irn comentando algunas ms esenciales. Por lo tanto, el comando bsico de compilacin es: GCC- programa C donde programa C es el nombre del archivo. Si hay errores obvios en el programa (tales como palabras mal escritas, caracteres no tecleados u omisiones de punto y coma), el compilador se detendr y los reportar. Podra haber desde luego errores lgicos que el compilador no podr detectar. En el caso que esta fuera la situacin se le estar indicando a la computadora que haga las operaciones incorrectas. Cuando el compilador ha terminado con xito, la versin compilada, o el ejecutable, es dejado en un archivo llamado a.out, o si la opcin -o es usada con el compilador, el nombre despus de -o es el nombre del programa compilado. Se recomienda y es ms conveniente usar la opcin -o con el nombre del archivo ejecutable como se muestra a continuacin: GCC -o programa programa el cual pone el programa compilado en el archivo del programa sealado, en ste caso en programa, en vez del archivo a.out.

Ejecucin del programa


El siguiente estado es correr el programa ejecutable. Para correr un ejecutable en UNIX, simplemente se escribe el nombre del archivo que lo contiene, en este caso programa (o a.out). Con lo anterior, se ejecuta el programa, mostrando algn resultado en la pantalla. En ste estado, podra haber errores en tiempo de ejecucin (run-time errors), tales como divisin por cero, o bien, podran hacerse evidentes al ver que el programa no produce la salida correcta. Si lo anterior sucede, entonces se debe regresar a editar el archivo del programa, recompilarlo, y ejecutarlo nuevamente.

Estructuras
En C una estructura es una coleccin de variables que se referencian bajo el mismo nombre. Una estructura proporciona un medio conveniente para mantener junta informacin que se relaciona. Una definicin de estructura forma una plantilla que se puede usar para crear variables de estructura. Las variables que forman la estructura son llamados elementos estructurados. Generalmente, todos los elementos en la estructura estn relacionados lgicamente unos con otros. Por ejemplo, se puede representar una lista de nombres de correo en una estructura. Mediante la palabra clave struct se le indica al compilador que defina una plantilla de estructura. struct direc { char nombre[30]; char calle[40]; char ciudad[20]; char estado[3]; unsigned int codigo; }; Con el trozo de cdigo anterior no ha sido declarada ninguna variable, tan slo se ha definido el formato. Para declarar una variable, se har como sigue: struct direc info_direc; Se pueden declarar una o ms variables cuando se define una estructura entre ) y ;. Por ejemplo: struct direc { char nombre[30];

char calle[40]; char ciudad[20]; char estado[3]; unsigned int codigo; } info_direc, binfo, cinfo; observar que direc es una etiqueta para la estructura que sirve como una forma breve para futuras declaraciones. Como en este ltima declaracin se indican las variables con esta estructura, se puede omitir el nombre de la estructura tipo. Las estructuras pueden ser tambin preinicializadas en la declaracin: struct direc info_direc={"Vicente 2000","Dorado","MMX",12345}; Fernandez","Fantasia

Para referenciar o accesar un miembro (o campo) de una estructura, C proporciona el operador punto ., por ejemplo, para asignar a info_direc otro cdigo, lo hacemos como: info_direc.codigo=54321;

Tipos de datos
o

Los tipos de datos definen los mtodos de almacenamiento disponibles para representar informacin, junto con la manera en que dicha informacin ha de ser interpretada. Los tipos de datos son indispensables para la declaracin de variables. En C tenemos diferentes tipos de datos:

o o o

6. Tipos de datos (I) Tipo Bytes Desde Hasta void Es nulo (NULL) no retorna nada signed char 1 -128 127 unsigned char 1 0 255 signed short 2 -32768 32767 unsigned short 2 0 65535 signed int 2 -32768 32767

7. Tipos de datos (II) Tipo Bytes Desde Hasta unsigned int 2 0 65535 signed long 4 -2147483648 2147483647 unsigned long 4 0 4294967295 float 4 3,4x10 -38 3,4x10 38 double 8 1,7x10 -308 1,7x10 308 long double 10 3,4x10 -4932 3,4x10 4932

8. Nota sobre los tipos de datos: si omitimos las palabras signed o unsigned al declarar un tipo de dato, el compilador automticamente asume por default que es un tipo signed; es decir que si al declarar el tipo de dato simplemente colocamos, por ejemplo, int, entonces el compilador asumir que hemos declarado un signed int

9. Para declarar variables globales: //llamado a las cabeceras Tipo_dato1 variable1, variable2, , variablen; Tipo_dato2 variable3, variable4, , variablem; //declaracin de funciones{} Ejemplo: #include<stdio.h> char caracter; float iva,total_pagar,descuento; unsigned long pvc,tcd; void main(){ //instrucciones; ... } Estas variables van a servir en cualquier parte del programa

10. Para declarar variables locales: //llamado a las cabeceras //declaracin de una funcin{ Tipo_dato1 variable1, variable2, , variablen; Tipo_dato2 variable3, variable4, , variablem; } Ejemplo: #include<stdio.h> void main(){ int numero,edad,cantidad; float iva,total_pagar,descuento; unsigned long pvc,tcd; //instrucciones; ... } Estas variables van a servir solo en la funcin main()

11. Qu son las constantes? o Son aquellos valores que, una vez compilado el programa, no pueden ser cambiados. o Al definir las constantes, debemos tomar en cuenta las siguientes REGLAS DE CONVERSIN DE TIPOS DE DATOS: 12. o Reglas de conversin de tipos de datos I o Una constante entera (sin parte decimal) es tomada como tal, a menos que se la aadan las letras F L (maysculas minsculas) ejemplos : 1 : tomada como entera (int) 12f : tomada como flotante (float) 456L : tomada como doble larga (long double) o Una variable con parte decimal es tomada siempre como DOUBLE, salvo que se la siga de la letra F L 2.0 : tomada como doble (double) 3.56F : tomada como flotante (float) 1.007L : tomada como flotante larga (long float) 13.

o o

Reglas de conversin de tipos de datos II Si en cualquiera de los casos anteriores agregamos la letra U u la constante queda calificada como UNSIGNED: 86u : tomada como entera sin signo (unsigned int) 32.44632UL : tomada como doble larga sin signo (unsigned long double) Una variable numrica que comienza con &quot;0&quot; (cero) es tomado como OCTAL asi : 012 equivale a 10 unidades en numeracin decimal Una variable numrica que comienza con &quot;0x&quot; &quot;0X&quot; (cero equis) es tomada como HEXADECIMAL asi : 0x16 equivale a 22 unidades en numeracin decimal

14. Para declarar constantes: //llamado a las cabeceras #define constante1 valor1; #define constante2 valor2; //declaracin de una funcin{ } Ejemplo: #include<stdio.h> #define PI 3.141592 //constante double #define OCTAL 017 //constante octal #define FLOTANTE 14F //constante flotante Void main(){ //instrucciones; ... } Estas constantes sirven en cualquier parte del programa

15. Operadores Aritmticos en C Operador Nombre Ejemplo + Suma a+b - Resta a-b * Multiplicacin a*b / Divisin a/b % Residuo entero de la divisin a%b ++ Incremento en 1 a++ -- Decremento en 1 a

16. Operadores Relacionales en C Operador Nombre Ejemplo > Mayor que a>b < Menor que a<b >= Mayor o igual que a>=b <= Menor o igual que a<=b == Igual (Equivalente) a==b != Diferente (No es igual) a!=b

17. Operadores Lgicos en C Operador Nombre Ejemplo Devuelve cierto si: && Y (and) (exp1)&& (exp2) ambas son verdaderas || O (or) (exp1)|| (exp2) Una o ambas es verdadera ! No (not) !(exp1) Cambia el valor de la expresin

18. Notas sobre los Operadores en C

Los operadores aritmticos y relacionales pueden trabajar con variables o constantes de cualquier tipo numrico, como por ejemplo int, double, float, etc En los Operadores lgicos, exp1 y exp2 corresponden a EXPRESIONES LGICAS (Expresiones que pueden tomar los valores de verdadero o falso). Ejemplo: (7<2)||(4>3)

19. Caracteres de conversin ms usados de scanf(); y printf(); (I) Carcter Significado %c El dato es carcter %d El dato es entero %e El dato es valor en coma flotante %f El dato es valor en coma flotante %g El dato es valor en coma flotante %h El dato es entero corto

20. Caracteres de conversin ms usados de scanf(); y printf(); (II) Carcter Significado %i El dato es entero decimal, octal o hexadecimal %o El dato es octal %s El dato es cadena de caracteres, seguido de espacio en blanco y del carcter fin de lnea () %u El dato es entero decimal sin signo %x El dato es entero hexadecimal

21. Caracteres de conversin ms usados de scanf(); y printf(); (III) o Ejemplo: o int a,b; o char letra; o float area; o printf(%c ,%i, %f, %i,letra,a,area,b);

22. Secuencias de Escape (I) Carcter Cdigo Valor ASCII Campana (alerta) a 007 Retroceso (espacio atrs) 008 Tabulador horizontal 009 Nueva lnea 010 Tabulador vertical v 011 Nueva pgina f 012

23. Secuencias de Escape (II) Carcter Cdigo Valor ASCII Retorno de carro 013 Comillas () 034 Interrogacin (?) ? 039 Barra invertida 063 Fin de lnea 092 Nmero octal ooo 000

Enteros
Los enteros son el tipo de dato ms primitivo en C. Se usan para representar nmeros enteros. Pero siempre se pueden encontrar otras aplicaciones para los nmeros enteros. En general se pueden usar para representar cualquier variable discreta. Los tipos de datos enteros son: short, int, long y long long. Es decir que para el lenguaje C existen diferentes tamaos de nmeros enteros que, segn el compilador y la plataforma de hardware, pueden tener desde 1 byte hasta 8 bytes (para ms detalles busca en la referencia). Adems, el lenguaje C hace la distincin de si el entero es con signo o sin signo (signed o unsigned). La forma de declarar un entero es con uno de los tipos de datos que sean enteros segn el tamao que se quiera. En caso de que no se declare si es con signo o sin signo, se toma con signo. Algunos ejemplos de declaraciones de enteros: int a; unsignedint a; signedlong a; signedlonglong a =10000000; Todos los nmeros son representados en memoria mediante una cadena de bits. En el caso de los nmeros con signo, el bit ms significativo es el que se usa para representar el signo. La representacin de los nmeros negativos se realiza mediante el complemento a dos, que es una tcnica que permite operar con los nmeros negativos de forma lgica. Slo a modo de ejemplo, la representacin en memoria de un -8 en una variable de 2 bytes, entera, con signo sera la siguiente: 1111111111111000

Ntese que no se ha tenido en cuenta el endianness de la arquitectura.

Flotantes
Se denomina flotantes a los tipos de datos que representan a los nmeros reales, ya que utilizan un sistema de representacin basado en la tcnica de coma flotante, que permite operar con nmeros reales de diversas magnitudes, mediante un nmero decimal llamado mantisa y un exponente que indica el orden de magnitud. El tipo de dato flotante en lenguaje C slo tiene dos tamaos: el float y el double, que son 4 bytes y 8 bytes respectivamente. Se los puede utilizar tanto para representar nmeros decimales, como para representar nmeros enteros con un orden de magnitud muy grande. La forma de declarar una variable flotante es escribiendo en una lnea uno de los tipos de datos flotantes y a continuacin el nombre de la variable y tal vez algn valor que se les quiera dar. Algunos ejemplos: float a; double a =1e23; double a =3.1416; float a =4e-9; double a =-78; Hay que tener en cuenta que aunque los valores flotantes son ms convenientes para algunas aplicaciones, hay casos en los que se prefieren los enteros. Esto se debe a que los nmeros flotantes no necesariamente tienen soporte de hardware, en particular en las plataformas integradas. Una alternativa que se utiliza en estas situaciones es interpretar los enteros como decimales de forma que 150 se interprete como 1.5 y 2345 como 23.45. Para el caso de los flotantes de 4 bytes, se utiliza 1 bit para el signo, 8 bits para el exponente y 23 bits para el valor del nmero. El procedimiento para almacenar un nmero en una variable flotante es el siguiente: 1. Se convierte a binario la parte entera. 2. Se coloca el signo en el bit ms significativo de la misma manera que en los enteros (1 para el - y 0 para el +). 3. Se mueve la coma (en la representacin binaria de la parte entera) hasta que est a la derecha del primer uno y ste se descarta (el uno ms significativo). El valor del exponente ser el nmero de posiciones que se movi la coma. El exponente usa la representacin de un entero con complemento a dos. 4. Se convierte en binario la parte decimal del nmero. Esto usando el peso de los bits. el bit decimal ms significativo vale 1/2, el siguiente vale 1/4, el

otro 1/8, el otro 1/16 y as hasta completar lo que falta para los 23bits del valor. 5. Se concatena todo y ese es el valor flotante representado en memoria.

Caracteres
Los caracteres se representan utilizando el tipo char, que tiene slo 1 byte de tamao. Este tipo se utiliza para representar los 256 caracteres de la tabla de caracteres del sistema. El tipo char es tambin un tipo entero, ya que puede tomar valores de 0 a 255. En cuanto a la forma de declarar variables de tipo char es la misma forma que con los otros tipos. char a; char a ='s'; char a =48; Como puedes ver, se le puede asignar un nmero a una variable char, ya que se trata de un tipo entero. En algunas situaciones particulares se utiliza el tipo char para contadores, porque permite que ocupen slo un byte en memoria. Es importante notar que con la llegada de la codificacin UTF-8, los caracteres de los diversos idiomas pueden ocupar 1, 2, 3 o 4 bytes, de modo que el tipo char ya no alcanza para la representacin de todos los caracteres. Por ello, el estndar C99 introduce el tipo wchar que puede ocupar ms de 1 byte, segn sea necesario para la codificacin utilizada por el sistema.

Caracteres y Cadenas en C
1. Caracteres y Cadenas 2. Conceptos Bsicos o Caracteres Valor entero representado como caracter entre comillas simples. Por ejemplo: 'z' representa al valor entero de z Internamente se representa como un tipo de dato enumerado usando el cdigo ASCII ( cdigo estndar americano para el intercambio de informacin ). o Cadenas

Es un arreglo de caracteres que: Puede incluir letras, dgitos y caracteres especiales (*, /, $) Tiene un puntero al primer caracter Cuyo valor de la cadena es la direccin de memoria del primer elemento.

3.
o o

Los cdigos para los caracteres que representan dgitos del 0 al 9 son consecutivos. Las letras en el alfabeto estn divididos en dos rangos: uno para las maysculas (A-Z) y otro para las minsculas (a-z). Sin embargo dentro de cada rango los valores ASCII son consecutivos.

Propiedades Importantes del Cdigo ASCII 4. Constantes de Tipo Caracter o Es un estndar para referirse a un carcter especfico en C. o Para referirse al cdigo ASCII de la letra A, se especifica A , el cual es el 65. o Para referirse al cdigo del carcter 9, de forma similar, 9. CUIDADO: El referirse al carcter, no es lo mismo que referirse al valor entero. El 9 es diferente del 9. 5. Operaciones con Caracteres o Se puede: o Sumar un entero a un carcter o Restar un entero de un caracter o Restar un caracter de otro o Comparar dos caracteres entre s

CUIDADO: Al sumar o restar el resultado no debe salirse del rango de representacin ASCII 6. Manejo de Cadenas o Definicin Como un arreglo de caracteres o una variable de tipo char * char color[] = &quot;blue&quot;; char *colorPtr = &quot;blue&quot;; Recuerde que una cadena se representa como un arreglo de caracteres y termina con '' color tiene 5 elementos o Lectura Utilizando scanf

scanf(&quot;%s&quot;, cadena); Copia la entrada en el arreglo cadena[] No se necesita el & (porque una cadena es un puntero) Recuerde dejar espacio en el arreglo para el fin de cadena ' o Escritura Utilizando printf printf(%s,cadena); 7. Ejemplos o char RandomLetra(void) o { o return (RandomInteger (A, Z)); o } o bool esMayuscula (char ch) o { o return (ch >= A && ch <=Z); o }

bool esDigito (char ch) { return (ch >= 0 && ch <=9); } bool esMinuscula (char ch) { return (ch >= a && ch <=z); } 8. Interfaces tiles 9. La interfaz ctype.h o Contiene un gran nmero de funciones para determinar el tipo de carcter, entre las principales tenemos: o islower(ch) retorna TRUE si el carcter ch es minscula o isupper(ch) retorna TRUE si el carcter ch es mayscula o isalpha(ch) retorna TRUE si ch es un valor alfabtico o isdigit(ch) retorna TRUE si ch es un dgito o isalnum(ch) retorna TRUE si ch es un valor alfanumrico o ispunct(ch) retorna TRUE si ch es un smbolo de puntuacin o isspace(ch) retorna TRUE si ch es un carcter en blanco 10. ctype.h: Librera de manejo de caracteres 11. Stdlib.h: Librera de funciones de conversin o Convierte cadenas de dgitos a enteros y valores de punto flotante. 12. stdio.h 13. String.h: Librera de manipulacin de cadenas o Incluye funciones para: Manipular cadenas Bsqueda en cadenas Manejo de tokens Determine la longitud de cadenas 14. Funciones de comparacin de cadenas o int strcmp( const char *s1, const char *s2 ); Compara string s1 con s2 Retorna: Un nmero negativo si s1 < s2

Cero, si s1 == s2 Un nmero positivo si s1 > s2 o int strncmp(const char *s1,const char *s2,size_t n); Compara n caracteres de s1 en s2 Retorna valores como los anteriores 15. Funciones de Bsqueda

VARIABLES, Y CONSTANTES EN C
Qu es una Variable?

Es solo un nombre para identificar posiciones de memoria. Este nombre de la variable debe ser un identificador vlido. En las variables (posiciones de memoria) se guardan los datos usados por el programa durante su ejecucin. TODA variable debe ser DECLARADA antes de poder ser utilizada.

constante o funcin

Para que un identificador sea vlido debe: Iniciar con una letra del alfabeto ingls, o con el signo (_) No debe contener caracteres especiales, tales como @, $, # Despus de la primera letra puede contener ms letras del alfabeto ingls, nmeros, o el carcter (_) NO DEBE haber espacios en blanco en los identificadores C diferencia maysculas de minsculas, entonces no es lo mismo declarar la variable numero que Numero o NuMeRo Existen palabras propias del lenguaje (palabras reservadas) que no pueden ser usadas como identificadores ej: if, do

Tipos de variables

Variables globales: son las que se declaran despus del llamado a las cabeceras, pero antes de cualquier funcin, y son tiles para cualquier parte del programa. Variables locales: son las que se declaran dentro de una funcin, y solo sirven para ser usadas dentro de esa funcin.

Entrada y salida (E/S) <stdio.h>


En este captulo se vern varias formas de entrada y salida (E/S). Se han mencionado brevemente algunas formas y ahora se revisarn con un poco ms de detalle. Los programas que hagan uso de las funciones de la biblioteca de E/S deben incluir la cabecera, esto es: #include <stdio.h>

Reportando errores
En muchas ocasiones es til reportar los errores en un programa de C. La funcin de la biblioteca estndar perror es la indicada para hacerlo. Es usada conjuntamente con la variable errno y frecuentemente cuando se encuentra un error se desea terminar el programa antes. Adems se revisa la funcin exit() y errno, que en un sentido estricto no son parte de la biblioteca stdio.h, para ver como trabajan con perror.

Perror()
El prototipo de la funcion perror es: void perror(const char *s); La funcin perror() produce un mensaje que va a la salida estndar de errores, describiendo el ltimo error encontrado durante una llamada al sistema o a ciertas funciones de biblioteca. La cadena de caracteres s que se pasa como argumento, se muestra primero, luego un signo de dos puntos y un espacio en blanco; por ltimo, el mensaje y un salto de lnea. Para ser de ms utilidad, la cadena de caracteres pasada como argumento debera incluir el nombre de la funcin que incurri en el error. El cdigo del error se toma de la variable externa errno, que toma un valor cuando ocurre un error, pero no es puesta a cero en una llamada no errnea.

errno
A la variable especial del sistema errno algunas llamadas al sistema (y algunas funciones de biblioteca) le dan un valor entero, para indicar que ha habido un error. Esta variable esta definida en la cabecera #include <errno.h> y para ser usada dentro de un programa debe ser declarada de la siguiente forma: extern int errno; El valor slo es significativo cuando la llamada devolvi un error (usualmente -1), algunas veces una funcin tambin puede devolver -1 como valor vlido, por lo que se debe poner errno a cero antes de la llamada, para poder detectar posibles errores.

exit
La funcin exit tiene el siguiente prototipo de acuerdo a la cabecera #include <stdlib.h>: void exit(int status); La funcin produce la terminacn normal del programa y la devolucin de status al proceso padre o al sistema operativo. El valor de status es usado para indicar como ha terminado el programa: o sale con un valor EXIT_SUCCESS en una terminacin o sale con un valor EXIT_FAILURE en una terminacin Por lo tanto cuando se encuentre un error se llamar a la funcin como exit(EXIT_FAILURE) para terminar un programa con errores.

Flujos
Los flujos son una forma flexible y eficiente para leer y escribir datos. Existe una estructura interna de C, FILE, la cual representa a todas los flujos y esta definida en stdio.h. Por lo tanto simplemente se necesita referirse a la estructura para realizar entrada y salida de datos. Para usar los flujos entonces se debe declarar una variable o apuntador de este tipo en el programa. No se requiere conocer ms detalles acerca de la definicin.

Se debe abrir un flujo antes de realizar cualquier E/S, despus se puede accesar y entonces se cierra. El flujo de E/S usa un BUFFER, es decir, un pedazo fijo de rea temporal de la memoria (el buffer) es ledo o escrito a un archivo. Lo siguiente se muestra en la figura 17.1. Observar que el apuntador del archivo actualmente apunta a ste buffer.

Esto conduce a un uso eficiente de E/S pero se debe tener cuidado: los datos escritos a un buffer no aparecen en un archivo (o dispositivo) hasta que el buffer es escrito (con \n se puede hacer). Cualquier salida anormal del cdigo puede causar problemas.

Flujos predefinidos
En UNIX se tienen predefinidos 3 flujos (en stdio.h): stdin, stdout y stderr. Todas ellas usan texto como mtodo de E/S. Los flujos stdin y stdout pueden ser usadas con archivos, programas, dispositivos de E/S como el teclado, la consola, etc. El flujo stderr siempre va a la consola o la pantalla. La consola es el dispositivo predefinido para stdout y stderr. El teclado lo es para stdin. Los flujos predefinidos son automticamente abiertas.

Re direccionamiento
Lo siguiente no es parte de C, pero depende del sistema operativo. Se hace redireccionamiento desde la lnea de comandos con: >que redirecciona stdout a un archivo. Por lo tanto, si se tiene un programa llamado salida, que usualmente muestra en pantalla algo, entonces: salida> archivo_sal mandar la salida al archivo archivo_sal <redirecciona stdin desde un archivo a un programa.

Por lo tanto, si se espera entrada desde el teclado para un programa llamado entrada, se puede leer en forma similar la entrada desde un archivo. entrada< archivo_ent Con |entubamiento o pipe se coloca stdout de un programa en stdin de otro, prog1 | prog2 Por ejemplo, mandar la salida (usualmente a consola) de un programa directamente a la impresora out | lpr

E/S Basica
Hay un par de funciones que dan las facilidades bsicas de E/S. Quizs las ms comunes son: getchar() y putchar(). Estn definidas y son usadas como sigue:

int getchar(void) -- lee un caracter de stdin int putchar(char ch) -- escribe un caracter a stdout y regresa el caracter escrito.

main() { int ch; ch = getchar(); (void) putchar((char) ch); } Otras funciones relacionadas son: int getc(FILE *flujo); int putc(char ch, FILE *flujo);

E/S formateada
Se han visto ya algunos ejemplos de como C usa la E/S formateada. En esta seccin se revisarn con ms detalle.

printf
El prototipo de la funcin esta definido como: int printf( const char *formato, lista arg ...);

que muestra en stdout la lista de argumentos de acuerdo al formato especificado. La funcin devuelve el nmero de caracteres impresos. La cadena de formateo tiene dos tipos de objetos:

caracteres ordinarios -- estos son copiados a la salida. especificadores de conversin -- precedidos por % y listados en la tabla 16.1.

Entre el % y el caracter de formato se puede poner:


- signo menos para justificar a la izquierda. nmero entero para el ancho del campo. m.d en donde m es el ancho del campo, y d es la precisin de dgitos despus del punto decimal o el nmero de caracteres de una cadena.
Por lo tanto:

printf("%-2.3f\n",17.23478); la salida en pantalla ser: 17.235 y printf("VAT=17.5%%\n"); genera la siguiente salida: VAT=17.5%

scanf
La funcin esta definida como sigue: int scanf( const char *formato, lista arg ...); Lee de la entrada estndar (stdin) y coloca la entrada en la direccin de las variables indicadas en lista args. Regresa el nmero de caracteres ledos. La cadena de control de formateo es similar a la de printf. Importante: se requiere la direccin de la variable o un apuntador con scanf.

Por ejemplo: scanf("%d", &i); Para el caso de un arreglo o cadena slo se requiere el nombre del mismo para poder usar scanf ya que corresponde al inicio de la direccin de la cadena. char cadena[80]; scanf("%s",cadena);

Archivos
Los archivos son la forma ms comn de los flujos. Lo primero que se debe hacer es abrir el archivo. La funcin fopen() hace lo siguiente: FILE *fopen(const char *nomb, const char *modo); fopen regresa un apuntador a un FILE. En la cadena nomb se pone el nombre y la trayectoria del archivo que se desea accesar. La cadena modo controla el tipo de acceso. Si un archivo no puede ser accesado por alguna razn un apuntador NULL es devuelto. Los modos son:

``r'' lectura; ``w'' escritura; y ``a''

Para abrir un archivo se debe tener un flujo (apuntador tipo archivo) que apunte a la estructura FILE. Por lo tanto, para abrir un archivo denominado miarch.dat para lectura haremos algo como lo siguiente; FILE *flujo; /* Se declara un flujo */ flujo = fopen("miarch.dat","r"); es una buena prctica revisar si un archivo se pudo abrir correctamente if ( (flujo = fopen("miarch.dat","r")) == NULL ) { printf("No se pudo abrir %s\n","miarch.dat");

exit(1); } .....

Lectura y escritura de archivos


Las funciones fprintf y fscanf son comnmente empleadas para accesar archivos. int fprintf(FILE *flujo, const char *formato, args ... ); int fscanf(FILE *flujo, const char *formato, args ... ); Las funciones son similares a printf y scanf excepto que los datos son ledos desde el flujo, el cual deber ser abierto con fopen(). El apuntador al flujo es automticamente incrementado con todas las funciones de lectura y escritura. Por lo tanto, no se debe preocupar en hacer lo anterior.

char *cadena[80]; FILE *flujo; if ( (flujo = fopen( ... )) != NULL) fscanf(flujo,"%s",cadena); Otras funciones para archivos son: int getc(FILE *flujo) int putc(char ch, FILE *s) Estas son parecidas a getchar y putchar. getc esta definida como una macro del preprocesador en stdio.h. fgetc es una funcin de la biblioteca de C. Con ambas se consigue el mismo resultado. Para el volcado de los datos de los flujos a disco, o bien, para disasociar un flujo a un archivo, haciendo previamente un volcado, usar: int fflush(FILE *flujo); int fclose(FILE *flujo); Tambin se puede tener acceso a los flujos predeterminados con fprintf, etc. Por ejemplo: fprintf(stderr,"No se puede calcular!!\n"); fscanf(stdin,"%s",string); int fgetc(FILE *flujo) int fputc(char ch, FILE *s)

sprintf y sscanf
Son parecidas a fprintf y fscanf excepto que escriben/leen una cadena. int sprintf(char *cadena, char *formato, args ... ) int sscanf(char *cadena, cahr *formato, args ... ) Por ejemplo: float tanque_lleno = 47.0; float kilometros = 400; char km_por_litro[80]; /* litros */

sprintf( km_por_litro, "Kilometros por litro = %2.3f", kilometros/tanque_lleno);

Peticin del estado del flujo


Existen unas cuantas funciones tiles para conocer el estado de algn flujo y que tienen los prototipos siguientes: int feof(FILE *flujo); int ferror(FILE *flujo); void clearerr(FILE *flujo); int fileno(FILE *flujo);

feof() devuelve verdadero si el flujo indicado esta en el fin del archivo. Por lo tanto para leer un flujo, fp, lnea a lnea se podra hacer algo como: while ( !feof(fp) ) fscanf(fp,"%s",linea); ferror() inspecciona el indicador de error para el flujo indicado, regresando verdadero si un error ha ocurrido. clearerr() limpia los indicadores de fin-de-fichero y error para el flujo indicado. fileno() examina el argumento flujo y devuelve su descriptor de fichero, como un entero.

E/S de bajo nivel o sin almacenamiento intermedio


Esta forma de E/S es sin buffer -cada requerimiento de lectura/escritura genera un acceso al disco (o dispositivo) directamente para traer/poner un determinado nmero de bytes.

No hay facilidades de formateo -ya que se estn manipulando bytes de informacin. Lo anterior significa que se estan usando archivos binarios (y no de texto). En vez de manejar apuntadores de archivos, se emplea un manejador de archivo de bajo nivel o descriptor de archivo, el cual da un entero nico para identificar cada archivo. Para abrir un archivo usar: int open(char* nomb, int flag); que regresa un descriptor de archivo -1 si falla. flag controla el acceso al archivo y tiene los siguientes macros definidas en fcntl.h:

O_APPEND el archivo se abrir en modo de slo aadir O_CREAT si el archivo no existe, ser creado. O_EXCL abrir en forma exclusiva. O_RDONLY slo lectura O_RDWR lectura y escritura O_WRONLY slo escritura

para ver otras opciones usar man. La funcin: int creat(char* nomb, int perms); puede tambin ser usada para crear un archivo. Otras funciones son: int close(int fd); int read(int fd, char *buffer, unsigned longitud); int write(int fd, char *buffer, unsigned longitud); que pueden ser usadas para cerrar un archivo y leer/escribir un determinado nmero de bytes de la memoria/hacia un archivo en la localidad de memoria indicada por buffer. La funcin sizeof() es comnmente usada para indicar la longitud. Las funciones read y write regresan el nmero de bytes ledos/escritos o -1 si fallan.

Se tiene a continuacin dos aplicaciones que usan algunas de las funciones indicadas: #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> main(int argc, char **argv) {float buffer[]={23.34,2.34,1112.33}; int df; int bytes_esc; int num_flot; /* Primeramente se crea el archivo */ if ( (df = open(argv[1], O_CREAT, S_IRUSR | S_IWUSR) ) == -1) { /* Error, archivo no abierto */ perror("Archivo datos, apertura"); exit(1);} else printf("Descriptor de archivo %d\n",df); /* Despues se abre para solamente escribir */ if ( (df = open(argv[1], O_WRONLY) ) == -1) { /* Error, archivo no abierto */ perror("Archivo datos, apertura"); exit(1);} else

printf("Descriptor de archivo %d\n",df);

/* En primer lugar se escribe el numero de flotantes que seran escritos */ num_flot = 3; if ( (bytes_esc = write(df, &num_flot, sizeof(int)) ) == -1) { /* Error en la escritura */ perror("Archivo datos, escritura"); exit(1);} else printf("Escritos %d bytes\n",bytes_esc); /* Se escribe el arreglo de flotantes */ if ( (bytes_esc = write(df, buffer, num_flot*sizeof(float)) ) == -1) { /* Error en la escritura */ perror("Archivo datos, escritura");

exit(1);} else printf("Escritos %d bytes\n",bytes_esc); close(df);} Ejemplo de lectura del ejemplo anterior: /* Este programa lee una lista de flotantes de un archivo binario. */ /* El primer byte del archivo es un entero indicando cuantos */ /* flotantes hay en el archivo. Los flotantes estan despues del */ /* entero, el nombre del archivo se da en la linea de comandos. */ #include <stdio.h> #include <fcntl.h> main(int argc, char **argv) {float buffer[1000]; int fd; int bytes_leidos; int num_flot; if ( (fd = open(argv[1], O_RDONLY)) == -1) { /* Error, archivo no abierto */ perror("Archivo datos"); exit(1);} if ( (bytes_leidos = read(fd, &num_flot, sizeof(int))) == -1) { /* Error en la lectura */ exit(1);} if ( num_flot > 999 ) { /* arch muy grande */ exit(1); } if ( (bytes_leidos = read(fd, buffer, num_flot*sizeof(float))) == -1) { /* Error en la lectura */exit(1);}

Tipos de Operadores y Expresiones

Nombres de las variables Letra (Letra o Dgito)* -> 31 caracteres Las maysculas son diferentes de las minsculas Es prctica comn de C, denotar con - MAYUSCULAS las constantes - minsculas las variables Tipos

char int -> (CALIFICADORES: short, long, unsigned) float double Constantes Simblicas (Preprocesamiento) Ej. #define PI 3.14159265359 #define MAXLINE 1000 char line [MAXLINE+1] #define FORMFEED '\014' Variables constantes: Ej. const float pi=3.14159265359; Alfanumricas: Se evalan en tiempo de compilacin, no de ejecucin. Ejs. 3.14159265359 123.456e-7 0.12E3 '0' ->ASCII 48, EBCDIC 240 Declaraciones: Se pueden declarar varias variables en pocos renglones: int lower,upper,step; char c, line[1000]; Tambin se pueden escribir ms explicitamente, para agregar comentarios: int lower; /* algunos comentarios */ int upper; int step; char c; char line[1000]; Inicializacin de variables: char backslash='\\'; int i=0;

Operadores aritmticos: + - * / %(mdulo) Ej. (uso del mdulo) if (year%4==0 && year%100!=0 || year%400==0) es un ao bisiesto; else no lo es; Operadores relacionales y lgicos: >>= <= < == !=

El operador que convierte en 0 algo distinto de 0, y en 1, el cero, es !. Ej. if (!inword) if (inword==0) Conversiones de Tipos Se hacen conversiones automticas cuando tiene sentido. Ej. float + int -> float "char" e "int" se manejan indiscrimidamente. Ej. int atoi(char s[]) /* convierte s a int */ { int i,n; n=0; for (i=0; s[i]>='0' && s[i]<='9';++i) n=10*n+s[i]-'0'; return (n); } Conversin coaccionada "cast" Se puede forzar la conversin de un tipo en otro. El formato es: (nombre-de-tipo) expresin por ejemplo: sqrt( (double) n) Operadores de incremento y decremento si n=5, entonces x=n++; -> x=5 n=6 x=++n; -> x=6 n=6 Operadores lgicos para manejo de bits: & AND lgico | OR lgico ^ XOR lgico << desplazamiento a la izquierda >> desplazamiento a la derecha ~ complemento a uno (unario)

Ejs c = n & '\077'; x = x | MASK; x = x & ~'\077'; Ej. Funcin para tomar n bits a partir de la posicin p getbits(unsigned int x, p, n) {

return ((x>>(p+1-n)) & ~(~0 << n)); } Nota: (~0 << n) es 11..100..0 con n ceros a la derecha ~(~0 << n) es 00..011..1 con n unos a la derecha Operadores y expresiones de asignacin La expresin e1 op= e2 es idntico a e1 = e1 op e2 donde "op" es un operador como {],-,*,/,%,<<,>>,&,^,|} Por ejemplo: i=i+2; es idntico a i+=2; Expresiones condicionales Tienen el siguiente formato e1 ? e2 : e3; si e1 es verdadero se evala e2, si e1 es falso, se evala e3. z=(a>b) ? a : b; /* z=max(a,b) */ Precedencia y orden de evaluacin

OPERADOR ASOCIATIVIDAD
() [] -> . -> ! ~ ++ -- - (tipo) * & sizeof <* / % -> + - -> <<>> -> <<= >>= -> == != -> & -> ^ -> | -> && -> || -> ? : <= += -= etc <0 -> ASOCIATIVIDAD -> izquierda a derecha <- derecha a izquierda i=i+2 i+=2

Expresiones
En un programa, el tipo de un dato determina las operaciones que se pueden realizar con l. Por ejemplo, con los datos de tipo entero se pueden realizar operaciones aritmticas, tales como la suma, la resta o la multiplicacin. Ejemplo 1: Algunos ejemplos son: 111 + 6 (operacin suma) 19 - 72 (operacin resta) 24 * 3 (operacin multiplicacin) Todas las operaciones del ejemplo constan de dos operandos (constantes enteras) y un operador. La mayora de las veces es as, pero, tambin es posible realizar operaciones con distinto nmero de operadores y/u operandos. Ejemplo 2: Por ejemplo: 111 + 6 - 8 (tres operandos y dos operadores) -( ( +19 ) + 72 ) (dos operandos y tres operadores) -( -72 ) (un operando y dos operadores)

En las operaciones del ejemplo se puede observar que los caracteres ms (+) y menos (-) tienen dos usos: 1. Operadores suma y resta. 2. Signos de un nmero (tambin son operadores). Los operadores de signo ms (+) y menos (-) son operadores monarios, tambin llamados unarios, ya que, actan, solamente, sobre un operando. Los caracteresabrir parntesis "(" y cerrar parntesis ")" se utilizan para establecer la prioridad de los operadores, es decir, para establecer el orden en el que los operadores actan sobre los operandos. Un operador indica el tipo de operacin a realizar sobre los operandos (datos) que acta. Los operandos pueden ser:

Constantes (expresadas por su valor o con un nombre (identificador)). Variables. Llamadas a funciones.

Elementos de formaciones (arrays).

En este apartado se van a tratar operaciones en donde slo aparecen constantes y variables. Cuando se combinan uno o ms operadores con uno o ms operandos se obtiene una expresin. De modo que, una expresin es una secuencia de operandos y operadores escrita bajo unas reglas de sintaxis. Ejemplo 3: Dadas las siguientes declaraciones de constantes y variables: #define PI 3.141592 int numero = 2; float radio_circulo = 3.2; Algunos ejemplos de expresiones son: 2 * PI * radio_circulo ( PI* PI ) numero * 5

De sus evaluaciones se obtienen los valores: 20.106189 (valor real) ( 2 * 3.141592 * 3.2 ) 9.869600 (valor real) ( 3.141592 * 3.141592 ) 10 (valor entero) ( 2 * 5 ) Un operador siempre forma parte de una expresin, en la cual, el operador siempre acta sobre al menos un operando. Por el contrario, un operando s puede aparecer solo en una expresin. En programacin, de la evaluacin de una expresin siempre se obtiene un valor. Dicho valor puede ser de tipo: entero, real, lgico, carcter o cadena. Por consiguiente, una expresin puede ser:

Aritmtica (devuelve un nmero entero o real). Lgica (devuelve un valor lgico: verdadero o falso) De carcter (devuelve un carcter representable por el ordenador). De cadena (devuelve una cadena).

A continuacin, vamos a estudiar los operadores y las expresiones en lenguaje C, en comparacin con los operadores y expresiones en psedocdigo CEE utilizado por el autor en el libro EMPEZAR DE CERO A PROGRAMAR EN LENGUAJE C.

Estructuras de control e iteraciones


Sentencias de decisin Estructura de control IF DEFINICIN Las sentencias de decisin o tambin llamadas de CONTROL DE FLUJO son estructuras de control que realizan una pregunta la cual retorna verdadero o falso (evala una condicion) y selecciona la siguiente instruccin a ejecutar dependiendo la respuesta o resultado. En algn momento dentro de nuestros algoritmos, es preciso cambiar el flujo de ejecucin de las instrucciones, es decir, el orden en que las instrucciones son ejecutadas. Muchas de las veces tenemos que tomar una decisin en cuanto a que se debe ejecutar basndonos en una respuesta de verdadero o falso (condicion). La ejecucin de las instrucciones incluyendo una estructura de control como el condicional funcionan de esta manera: Las instrucciones comienzan a ejecutarse de forma secuencial (en orden) y cuando se llega a una estructura condicional, la cual esta asociada a una condicion, se decide que camino tomar dependiendo siempre del resultado de la condicion siendo esta falsa o verdadera. Cuando se termina de ejecutar este bloque de instrucciones se reanuda la ejecucin en la instruccin siguiente a la de la condicional. Sentencia if La instruccin if es, por excelencia, la ms utilizada para construir estructuras de control de flujo. SINTAXIS

Primera Forma Ahora bin, la sintaxis utilizada en la programacin de C++ es la siguiente: if (condicion) { Set de instrucciones } siendo "condicion" el lugar donde se pondr la condicion que se tiene que cumplir para que sea verdadera la sentencia y as proceder a realizar el "set de instrucciones" o cdigo contenido dentro de la sentencia. Segunda Forma Ahora veremos la misma sintaxis pero ahora le aadiremos la parte "Falsa" de la sentencia: if (condicion) { Set de instrucciones } else { Set de instrucciones 2 //Parte FALSA } La forma mostrada anteriormente muestra la union de la parte "VERDADERA" con la nueva secuencia la cual es la parte "FALSA" de la sentencia de decision "IF" en la cual esta compuesta por el: else { //PARTE VERDADERA

Set de instrucciones 2 //Parte FALSA } la palabra "else" o "De lo contrario" indica al lenguaje que de lo contrario al no ser verdadera o no se cumpla la parte verdadera entonces realizara el "set de instrucciones 2". EJEMPLOS DE SENTENCIAS IF... Ejemplo 1: if(numero == 0) //La condicion indica que tiene que ser igual a Cero { cout<<"El Numero Ingresado es Igual a Cero"; } Ejemplo 2: if(numero > 0) // la condicion indica que tiene que ser mayor a Cero { cout<<"El Numero Ingresado es Mayor a Cero"; } Ejemplo 3: if(numero < 0) // la condicion indica que tiene que ser menor a Cero { cout<<"El Numero Ingresado es Menor a Cero"; } Ahora uniremos todos estos ejemplos para formar un solo programa mediante la utilizacin de la sentencia "Else" e introduciremos el hecho de que se puede escribir en este espacio una sentencia if ya que podemos ingresar cualquier tipo de cdigo dentro de la sentencia escrita despus de un Else. Ejemplo 4: if(numero == 0) //La condicion indica que tiene que ser igual a Cero

{ cout<<"El Numero Ingresado es Igual a Cero"; } else { if(numero > 0) // la condicion indica que tiene que ser mayor a Cero { cout<<"El Numero Ingresado es Mayor a Cero"; } else { if(numero < 0) // la condicion indica que tiene que ser menor a Cero { cout<<"El Numero Ingresado es Menor a Cero"; } } } Sentencia switch switch es otra de las instrucciones que permiten la construccin de estructuras de control. A diferencia de if, para controlar el flujo por medio de una sentencia switch se debe de combinar con el uso de las sentencias case y break. Notas: cualquier nmero de casos a evaluar por switch as como la sentencia default son opcionales. La sentencia switch es muy til en los casos de presentacin de menus.

Sintaxis: switch (condicin)

{ case primer_caso: bloque de instrucciones 1 break;

case segundo_caso: bloque de instrucciones 2 break;

case caso_n: bloque de instrucciones n break;

default: bloque de instrucciones por defecto } Ejemplo 1 switch (numero) { case 0: cout << "numero es cero"; } Ejemplo 2 switch (opcion) { case 0: cout << "Su opcion es cero"; break; case 1: cout << "Su opcion es uno"; break;

case 2: cout << "Su opcion es dos"; } Ejemplo 3 switch (opcion) { case 1: cout << "Su opcion es 1"; break; case 2: cout << "Su opcion es 2"; break; case 3: cout << "Su opcion es 3"; break; default: cout << "Elija una opcion entre 1 y 3"; } Operador condicional ternario ?: En C, existe el operador condicional ( ?: ) el cual es conocido por su estructura como ternario. El comportamiento de dicho operador es el mismo que una estructura if - then - else del lenguaje BASIC (y de la funcin IIf de Visual Basic). El operador condicional ?: es til para evaluar situaciones tales como: Si se cumple tal condicin entonces haz esto, de lo contrario haz esto otro. Sintaxis: ( (condicion) ? proceso1 : proceso2 ) En donde, condicion es la expresin que se evalua, proceso1 es la tarea a realizar en el caso de que la evaluacin resulte verdadera, y proceso2 es la tarea a realizar en el caso de que la evaluacin resulte falsa. Ejemplo 1 int edad; cout<< "Cual es tu edad: "; cin>> edad; cout<< ( (edad < 18) ? "Eres joven aun" : "Ya tienes la mayora de edad" ); El ejemplo anterior podra escribirse de la siguiente manera:

int edad; cout<< "Cual es tu edad: "; cin>> edad; if (edad < 18) cout << "Eres joven aun"; else cout << "Ya tienes la mayora de edad"; Ejemplo 2 Vamos a suponer que deseamos escribir una funcin que opere sobre dos valores numricos y que la misma ha de regresar 1 (true) en caso de que el primer valor pasado sea igual al segundo valor; en caso contrario la funcin debe retornar 0 (false). int es_igual( int a, int b) { return ( (a == b) ? 1 : 0 ) } Sentencias de iteracin DEFINICIN Las Sentencias de Iteracin o Ciclos son estructuras de control que repiten la ejecucin de un grupo de instrucciones. Bsicamente, una sentencia de iteracin es una estructura de control condicional, ya que dentro de la misma se repite la ejecucin de una o ms instrucciones mientras o hasta que una a condicin especifica se cumpla. Muchas veces tenemos que repetir un nmero definido o indefinido de veces un grupo de instrucciones por lo que en estos casos utilizamos este tipo de sentencias. en C++ los ciclos o bucles se construyen por medio de las sentencias for, while y do - while. La sentencia for es til para los casos en donde se conoce de antemano el nmero de veces que una o ms sentencias han de repetirse. Por otro lado, la sentencia while es til en aquellos casos en donde no se conoce de antemano el nmero de veces que una o ms sentencias se tienen que repetir.

Sentencias For for(contador; final; incremento)

{ Codigo a Repetir; } donde: 1. 2. 3. contador es una variable numrica final es la condicin que se evalua, o sea, el valor final para contador incremento es el valor que se suma o resta al contador

Ejemplo 1: for(i=1; i<=10; i++) { cout<<"Hola Mundo"; } Esto indica que el contador "i" inicia desde 1 y finaliza cuando el contador "i" sea menor o igual a 10 ( en este caso llegar hasta 10) e "i++" realiza la sumatoria por unidad lo que hace que el for y el contador se sumen. repitiendo 10 veces "HOLA MUNDO" en pantalla. Ejemplo 2: for(i=10; i>=0; i--) { cout<<"Hola Mundo"; } Este ejemplo hace lo mismo que el primero, salvo que el contador se inicializa a 10 en lugar de 1; y por ello cambia la condicin que se evalua as como como que el contador se decrementa en lugar de ser incrementado.

Sentencia while While (condicion)

{ cdigo a Repetir } donde: 1. condicion es la expresin a evaluar

Ejemplo 1: int contador = 0;

while(contador<=10) { contador=contador+1; cout<<"Hola Mundo"; } El contador Indica que hasta que este llegue a el total de 10 entonces se detendr y ya no se realizar el cdigo contenido dentro de la sentencia while, de lo contrario mientras el "contador" sea menor a 10 entonces el cdigo contenido se ejecutar desplegando hasta 10 veces "Hola Mundo" en pantalla. Sentencia do - while La sentencia do es usada generalmente en cooperacin con while para garantizar que una o ms instrucciones se ejecuten al menos una vez. Por ejemplo, en la siguiente construccin no se ejecuta nada dentro del ciclo while, el hecho es que el contador inicialmente vale cero y la condicin para que se ejecute lo que est dentro del while es "mientras el contador sea mayor que diez". Es evidente que a la primera evaluacin hecha por while la condicin deja de cumplirse. int contador = 0; while(contador > 10) { contador ++;

cout<<"Hola Mundo"; } Al modificar el segmento de cdigo anterior usando do tenemos: int contador = 0;

do { contador ++; cout<<"Hola Mundo";} while(contador > 10); Observe cmo en el caso de do la condicin es evaluada al final en lugar de al principio del bloque de instrucciones y, por lo tanto, el cdigo que le sigue al do se ejecuta al menos la primera vez. Sentencias break y continue En la seccin (Sentencia switch) vimos que la sentencia break es utilizada con el propsito de forzar un salto dentro del bloque switch hacia el final del mismo. En esta seccin volveremos a ver el uso de break, salvo que esta ocasin la usaremos junto con las sentecias for y la sentencia while. Adems, veremos el uso de la sentencia continue. break La sentencia break se usa para forzar un salto hacia el final de un ciclo controlado por for o por while. Ejemplo: En el siguiente fragmento de cdigo la sentencia break cierra el ciclo for cuando la variable ( i ) es igual a 5. La salida para el mismo ser: 01234 for (i=0; i<10; i++) { if (i == 5) break;

cout<< i << " ";} continue La sentencia continue se usa para ignorar una iiteracin dentro de un ciclo controlado por for o por while. Ejemplo: En el siguiente fragmento de cdigo la sentencia continue ignora la iteracin cuando la variable ( i ) es igual a 5. La salida para el mismo ser: 012346789 for (i=0; i<10; i++) { if (i == 5) continue; cout<< i << " ";} Uso de break y continue junto con while Los dos ejemplos anteriores se presentan en seguida, salvo que en lugar de for se hace uso de while. Nota: no deje de observar que la construccin del ciclo while para el caso de la sentencia continue es diferente, esto para garantizar que el ciclo no vaya a caer en una iteracin infinita. break int i = 0; while (i<10) { if (i == 5) break; cout<< i << " "; i++;} continue int i = -1; while (i<10) { i++;

if (i == 5) continue; cout<< i << " ";}

Tipos Estructurados
Conceptos: Estructura de datos, Array, Vector, Matriz, ndice, String, Cadena, Record, Campo, Set, Conjunto. Resumen: A diferencia de los datos de tipo simple que slo pueden almacenar un valor,los datos estructurados o estructuras de datos pueden recolectar varios valoressimultneamente. Se hace una primera introduccin a los datos estructuradosdestacando en primer lugar que se les asigna una cantidad fija de memoriadurante la ejecucin del programa cuando se declara una variable de undeterminado tipo estructurado. El primer tipo estructurado es el tipo array quepermite agrupar otros datos ms simples de igual tipo bajo un mismo identificador. Este tipo de estructuras permiten definir vectores, matrices, tablas y estructuras multidimensionales. TurboPascal incorpora un tipo especial de array: el tipo string. Se define como una secuencia de caracteres cuya longitud puede variar entre 1 y 255. El tipo record est compuesto de elementos de diferentes tipos a cada uno de los cuales se les asocia un identificador. Finalmente se analiza el tipo estructurado set equivalente al concepto de conjunto matemtico y otros tipos de datos no simples. Objetivos especficos. Al finalizar el tema, el alumno deber ser capaz de: a) Describir los tipos de datos estructurados en el lenguaje de programacin Turbopascal,su formato de representacin y las operaciones ms caractersticas que pueden realizarsecon ellos (Conocimiento) b) Escribir la declaracin de variables de cualquiera de los tipos de datos estructurados(Comprensin) c) Escribir el cdigo necesario para acceder a un elemento o conjunto de elementos de unaestructura de datos (Comprensin) d) Seleccionar la estructura de datos ms adecuada para una aplicacin determinada(Aplicacin) e) Codificar una tarea sencilla convenientemente especificada, utilizando datos estructurados (Aplicacin)
Datos estructurados 63

6.1. INTRODUCCIN
Los tipos estructurados de datos se componen de otros tipos de datos ms simplespreviamente declarados o predefinidos en el lenguaje TurboPascal. Los tipos de datosestructurados en TurboPascal son los siguientes: a) Array b) String c) Record d) Set e) File

f) Text g) Object

Existen otros dos tipos de datos que, aunque no son estrictamente una composicin deotros datos ms simples tambin se van a describir en este captulo: el tipo Pointer y el tipoProcedimiental.

6.2. Tipo
Un dato de tipo array es, en realidad, un conjunto o estructura de datos que engloba unacoleccin de datos del mismo tipo. Pueden ser unidimensionales, denominados tambin vectoreso listas, o multidimensionales, denominados matrices o tablas. Los nmeros o valores queidentifican a cada elemento particular del Array se llaman ndices. Sintaxis: Type ident = Array [TSub1,...,TSubn] of Tipo; donde TSub1,...,TSubn es una sucesin de tipos de dato ordinales (no pueden servariables y no valen tipos de dato reales!: slo enteros, lgico, carcter, enumerado o subrangosde los anteriores) separados por comas y que especifican, segn su producto cartesiano, el nmero de elementos de la estructura. TSubi es un identificador de un tipo de dato ordinal o un subrango de ste: lim_inf_i..lim_sup_i Ej.:TYPE vector1 = Array [1..4] of Char;
matriz1 = Array [1..10, 1..10] of Integer; matriz2 = Array [Boolean, 1..10] of Boolean; color = (blanco, amarillo, negro, rojo); ciudad = (Al,Ca,Co,Gr,Ja,Hu,Ma,Se); estacion = (prim,ver,oto,inv); cestacion = array[estacion] of string[9]; CONST est : cestacion = (primavera,verano,otoo,invierno); VAR v : Integer; vect1,vect2 : vector1; matriz : matriz1; qt : matriz2; raza : Array [1..40] of color; grados : Array [ciudad] of real; begin vect1[1] := 't'; vect1 := vect2; matriz[2,5] := 6; matriz[1,9] := matriz[2,5]; qt[true,4] := false; raza[15] := amarillo;
Fundamentos de programacin - A. Garca-Beltrn, R. Martnez y J.A. Jan 64

grados[Al] := 18.5; ...

En el ejemplo anterior, se observa como puede accederse a cualquier elemento de laestructura Array referenciando el/los subndice/s entre corchetes. Asimismo, pueden realizarseasignaciones entre datos Array del mismo tipo.

Variable vect1 vect1[1] vect1[2] vect1[3] vect1[4]


Figura 19. Espacio de memoria reservado para una variable array vect1de tipo vector1

El tamao reservado en memoria para una variable de tipo Array es igual al nmerototal de elementos por el tamao del elemento, en bytes. As, mientras la variable vect1 delejemplo anterior ocupa 4 elementos x 1 byte = 4 bytes, la variable matriz ocupa 10 x 10elementos x 2 bytes = 200 bytes en la memoria durante la ejecucin del programa. Cuando se trabaja con datos de tipo Array (especialmente si son multidimensionales)hay que tener cuidado con la cantidad de memoria que hay que reservar ya que se podrasobrepasar la memoria disponible. En principio, TurboPascal slo permite tipos de datoestructurados con un tamao mximo de 65520 bytes. Las dos siguientes declaraciones de tiposde dato son, por lo tanto, incorrectas: type vector = array[1..65536] of byte; vector2 = array[1..32800] of integer; Con los tipos de dato Array slo pueden utilizarse los operadores de asignacin y nopueden emplearse, como estructura completa con los procedimientos de entrada y salida dedatos: Read/ReadLn o Write/WriteLn. Esto es independiente de las operaciones quepuedan realizarse con cada uno de los elementos que componen la variable array, si lo permiteel tipo de dato correspondiente.

6.3. Tipo String


Este tipo de dato predefinido en el lenguaje TurboPascal permite representar unasecuencia o cadena de caracteres correspondientes al cdigo ASCII de un tamao mximo de255 (por defecto). Si se desea especificar un tamao menor de 255 se utilizarn corchetes paradelimitar un entero que especifica el tamao mximo de la cadena de caracteres. Una variable de este tipo ocupa en memoria tantos bytes como caracteres tenga ms uno; en este byte se guarda la longitud real de la cadena almacenada en la variable. A esta longitud se le denomina tamao longitud lgica. Puede accederse a cada uno de los caracteres que forman la secuencia de caracteres como si fueran datos de tipo Array unidimensionales de caracteres. Sintaxis: TYPE identificador : String[J]; { donde 1J255 } Ej.: CONST LineLin = 79; TYPE Nombre = String [10]; Linea = String [LineLin]; VAR n : nombre; comentario : linea;
Datos estructurados 65

Para la variable n se reserva un espacio de 11 bytes en la memoria durante la ejecucin del programa.
Figura 20. Espacio de memoria reservado para una variable n tipo nombre

En las expresiones y sentencias que manipulan datos de tipo String, el valor o la constante literal correspondiente va encerrado entre comillas simples. Pueden manipularse datos de tipo String con operaciones de asignacin (:=), comparaciones (operadores de relacin) y concatenaciones (+). Ej.: n := 'mario'; Tiene como resultado...
Figura 21. Asignacuin de valores a la variable n tipo nombre

La variable n, en este caso, almacena una cadena de cinco caracteres. La funcin estndar Length devuelve la longitud de la cadena almacenada en una variable de tipo String. Tras la asignacin anterior, la llamada a la funcin Length(n) devolvera el valor entero 5. Como puede accederse a cada carcter de forma independiente, el mismo valor tambin podra obtenerse del espacio en memoria que se emplea para guardar el tamao de la cadena que se almacena en la variable, con la llamada a la funcin Ord(n[0]). Tambin pueden emplearse datos de cualquier tipo cadena con los procedimientos estndar de entrada y salida de datos Read/ReadLn y Write/WriteLn para asignar valores a variables de tipo cadena y visualizar datos de tipo cadena por la pantalla. A diferencia del tipo de dato Char, NO es un tipo de dato ordinal, ya que no es un conjunto finito de datos. Aunque s se puede establecer el orden entre dos valores de tipo cadena. ste se obtiene por el orden entre los valores de tipo carcter que componen las cadenas segn las posiciones respectivas de los caracteres11: 'a' < 'anterior' < 'antes' < 'despues' < 'fuego' < 'luego' Por otro lado, 'casas' se considera mayor que 'casa', ya que en dos cadenas de distinto tamao, cada carcter en la cadena de mayor tamao sin el correspondiente carcter en la menor supone un valor superior. Tambin puede asignarse a una variable de tipo cadena una constante cadena de caracteres vaca. Ej.: n := ''; Segn muestra la Tabla 18 el operador suma es el nico de este tipo. Es un operador binario que acta sobre dos operandos de tipo Char o String. Da como resultado un valor de tipo String.
Es importante tener en cuenta que, en la tabla de caracteres ASCII, los caracteres alfabticos maysculas van antes que las minsculas
11

n[0] n[1] n[2] ... n[10]


#5 'm' 'a''r' 'i' 'o'
Fundamentos de programacin - A. Garca-Beltrn, R. Martnez y J.A. Jan 66

Tabla 18. Operadores de cadena

Operador Descripcin Ejemplo de expresin Resultado del ejemplo + Suma de cadenas 'coche' + 'azul' 'cocheazul'

6.4. Tipo Record


Un tipo record o registro permite definir una estructura que almacena un conjunto de datos del mismo o de distintos tipos (excepto File). Los datos individuales se

conocen como campos del registro y se declaran como variables cuando se define el tipo de registro. A cada uno de los campos se le asigna un identificador al realizar la declaracin, no pudiendo existir dos identificadores de campo iguales dentro del mismo registro. Sintaxis: TYPE Tiporegistro = Record lista ident1 : tipo1; lista ident2 : tipo2; { ... } lista identn : tipon end;

Ej.: Type meses = (En,Fb,Mr,Ab,My,Jn,Jl,Ag,Sp,Oc,Nv,Dc); fecha = record dia : 1..31; mes : meses; anno : 1900..2000 end; Un campo de un tipo registro puede ser de otro tipo registro (registros anidados). En el siguiente ejemplo, el tipo ficha_personal incluye un campo de tipo fecha. Type ficha_personal = record nombre, ape1, apel2 : string [20]; fecha_nacimiento : fecha; profesion : string [40]; telefono : integer end; Var cumple : fecha; individuo : ficha_personal; El acceso, para entradas o salidas, a los campos de registro, se realiza con el identificador del registro, un punto y el identificador del campo. Sintaxis: IdentificadorRegistro.IdentificadorCampo Ej.: cumple.dia := 15; write(cumple.dia); individuo.fecha_nacimiento.mes := Fb; O pueden manipularse los campos de un dato tipo Record determinado con la estructura With: Ej.: with cumple do begin dia:=27; mes:=En; anno:=1993; write(dia) end;
Datos estructurados 67

with individuo.fecha_nacimiento do begin dia:=2;

mes:=My; anno:=1953 end; El tamao de una variable de tipo Record es la suma de los tamaos de sus campos. As, la variable cumple del ejemplo anterior ocupa 1 + 1 + 2 = 4 bytes en memoria durante la ejecucin del programa. La estructura tipo Record permite la introduccin de campos variantes, que aparecen o no en una variable de ese tipo, en funcin del valor de un cierto campo. En general, los registros variantes tendrn una parte fija, que se declara en primer lugar, y otra variante. La principal ventaja de este tipo de estructura es el ahorro de memoria, ya que el espacio ocupado por una variable de este tipo es la suma del tamao de la parte fija y el tamao de la parte variante msgrande. El campo de seleccin puede ser cualquier variable de tipo ordinal. Sintaxis: TYPE Tiporegistro = Record lista ident1 : tipo1; { ... } lista identn : tipon; casecampo_selector:tipo of valor1 : (lista ident1b); { ... } valorn: (lista identnb) end; Ej.: TYPE ficha = Record nombre: String[20]; dni : String[8]; CASE alumno : Boolean OF False : (prof : Boolean; dpt : String[20]); True : (mat : String[5]; curso : 1..6) END;

6.5. Tipo Set


Un dato de tipo Set corresponde a la definicin matemtica de conjunto. Es una parte de un conjunto universal, de un tipo de dato base ordinal ya definido y tiene un mximo de 256 elementos. Aunque sus elementos deben pertenecer a un mismo tipo ordinal, dentro del conjunto no estn ordenados. Los valores ordinales de todos los elementos deben estar dentro del intervalo [0-255]. La definicin del tipo Set se realiza de la siguiente manera: Sintaxis: TYPE TipoSet = Set of tipo; Ej.: type dia = (lu,ma,mi,ju,vi,sa,dm); Frutas = (limon,naranja,uva,pera,platano); conj_caract = Set of Char; digitos = Set of 0..9; dias = Set of dia;

clase_fruta = Set of frutas; A continuacin pueden declararse variables de tipo Set: Ej.: var laborable : dias;
Fundamentos de programacin - A. Garca-Beltrn, R. Martnez y J.A. Jan 68

letras : conj_caract; conj_num : digitos; La sintaxis de asignacin de datos de tipo Set es: identificador := [valor_i, .., valor_j]; Ej.: laborable := [lu, ma, mi, ju, vi]; o bien, de forma ms condensada: laborable := [lu..vi]; letras :=['A','C','T','m']; conj_num := []; { se le asigna el conjunto vacio } conj_num := conj_num + [2, 3]; El tamao reservado en memoria para una variable de tipo Set es, en bytes, el cocienteentero mas uno del nmero mximo de elementos posibles del conjunto menos uno dividido entre ocho. Por ejemplo, una variable de tipo conjunto que pueda albergar, como mximo, entre 1 y 8 elementos, ocupar 1 byte en memoria; entre 9 y 16 elementos, 2 bytes,... entre 249 y 256 elementos, 32 bytes. No se pueden utilizar estos tipos de dato, los conjuntos o los elementos de un conjunto, con los procedimientos de entrada y salida de datos: Read/ReadLn o Write/WriteLn. Las operaciones que pueden realizarse con datos de tipo Set pertenecen al lgebra de conjuntos. Los operadores de conjuntos definidos en TurboPascal son binarios y se resumen en la Tabla 19.
Tabla 19. Operadores de conjuntos

Operador Descripcin Ejemplo de expresin Resultado del ejemplo + Unin [2,3] + [3,6] [2,3,6] * Interseccin (conjunto de elementos que estn a la vez en dos conjuntos) [2,3] * [3,6] [3] - Diferencia (conjunto de elementos pertenecientes a un primero que no estn en un segundo conjunto) [2,3] - [3,6] [2] = Igualdad [2,3] = [3,6] false <>Desigualdad [2,3] <>[3,6] true <= Inclusin (de un conjunto en otro) [2,3] <= [3,6] false =>Inclusin inversa (de un segundo conjunto en un primero) [2,3] =>[3] true inPertenencia (Nota: el primer operando es

del tipo de dato correspondiente al elemento del conjunto) 3 in [3,6] true

6.6. Tipo File


El tipo predefinido file permite utilizar una estructura de datos que se emplea cuando es necesario manipular grandes cantidades de datos y deben almacenarse en un sistema de almacenamiento masivo (habitualmente, como archivo o fichero en el disco duro del ordenador). Un archivo es una secuencia lineal de valores de datos de un cierto tipo. Esta secuencia no tiene longitud fija, ni predefinida. Si no se especifica el tipo de componentes ser un fichero sin tipo (indefinido). Ej.: TYPE Fich_numeros = File of Integer; Fichero = File of Ficha; Archivo = File; Este tipo de dato se ver con ms detenimiento en el captulo Archivos.

6.7. Tipo Text


El tipo predefinido text permite utilizar una estructura de datos de tipo archivo que contiene caracteres (datos tipo Char) organizados por lneas o filas. Ej.: VAR fichero_texto : Text; Este tipo de dato se ver con ms detenimiento en el captulo Archivos.

6.8. Tipo Pointer


Los punteros representan o almacenan direcciones de memoria en las que se almacenan datos de tipo dinmico. Los punteros no tienen porqu ser datos de tipo dinmico pueden ser datos estticos que apuntan a datos dinmicos. Este tipo de dato se ver con ms detenimiento en el captulo Punteros y Variables Dinmicas.

6.9. Tipo Procedural o Procedimental


Los procedimientos y funciones, tambin llamados genricamente rutinas, son mdulos o conjuntos independientes de sentencias de un programa que pueden ejecutarse a travs de una llamada. Admiten parmetros en funcin de los cuales pueden ejecutarse. Estos parmetros pueden ser de cualquiera de los tipos vistos anteriormente pero, incluso, pueden ser otros procedimientos o funciones. Para permitir esto, deben declararse tipo procedurales o procedimentales que definan un tipo de procedimiento o funcin. La sintaxis de definicin del tipo procedural o procedimental es el siguiente: En el caso de un tipo procedimiento: Type TipoProc = Procedure(Parametros); o bien en el caso de un tipo funcin: Type TipoFunc = Function(Parametros):id_tipo; id_tipo hace referencia al tipo de dato devuelto por la funcin.

Ej.: Type Proced = Procedure; AsignaP = Procedure(var a:integer); FuncionUni = Function(x:real):real; FuncionBi = Function(x,y:real):real; MaxFun = Function(a,b:real; f:FuncionUni):real;

6.10. Tipo Object


Este tipo de dato, que no entra dentro del alcance de este curso, permite trabajar con la metodologa de Programacin Orientada a Objetos en TurboPascal.
Fundamentos de programacin - A. Garca-Beltrn, R. Martnez y J.A. Jan 70

Bibliografa bsica Garca-Beltrn, A., Martnez, R. y Jan, J.A. Mtodos Informticos en TurboPascal, Ed. Bellisco, 2 edicin, Madrid, 2002 Joyanes, L. Fundamentos de programacin, Algoritmos y Estructuras de Datos, McGrawHill, Segunda edicin, 1996 Aho, A.H., Hopcroft, J.E. y Ullman, J.D. Estructuras de Datos y Algoritmos, AddisonWesley Iberoamericana, 1988 Kruse, R. Estructuras de Datos y Diseo de Programas, Prentice-Hall, 1988

Funciones
Una funcin es un conjunto de lneas de cdigo que realizan una tarea especfica y puede retornar un valor. Las funciones pueden tomar parmetros que modifiquen su funcionamiento. Las funciones son utilizadas para descomponer grandes problemas en tareas simples y para implementar operaciones que son comnmente utilizadas durante un programa y de esta manera reducir la cantidad de cdigo. Cuando una funcin es invocada se le pasa el control a la misma, una vez que esta finaliz con su tarea el control es devuelto al punto desde el cual la funcin fue llamada.
<tipo> [clase::] <nombre> ( [Parmetros] ) { cuerpo; }

Ejemplo de una funcin Para comenzar, vamos a considerar el caso en el cual se desea crear la funcin cuadrado(), misma que deber volver el cuadrado de un nmero real (de punto

flotante), es decir, cuadrado() aceptar nmeros de punto flotante y regresar una respuesta como nmero flotante. Nota: aunque para la funcin que veremos el tipo de retorno coincide con el tipo de parmetro pasado, algunas veces las cosas pueden cambiar, es decir, no es obligatorio que una funcin reciba un parmetro de un tipo y que tenga que regresar una respuesta de dicho tipo.
// regresar el cuadrado de un nmero double cuadrado(double n) { return n*n; }

Parmetros
Normalmente, las funciones operan sobre ciertos valores pasados a las mismas ya sea como constantes literales o como variables, aunque se pueden definir funciones que no reciban parmetros. Existen dos formas en C++ de pasar parmetros a una funcin; por referencia o por valor. El hecho es que si en una declaracin de funcin se declaran parmetros por referencia, a los mismos no se les podr pasar valores literales ya que las referencias apuntan a objetos (variables o funciones) residentes en la memoria; por otro lado, si un parmetro es declarado para ser pasado por valor, el mismo puede pasarse como una constante literal o como una variable. Los parmetros pasados por referencia pueden ser alterados por la funcin que los reciba, mientras que los parametros pasados por valor o copa no pueden ser alterados por la funcin que los recibe, es decir, la funcin puede manipular a su antojo al parmetro, pero ningn cambio hecho sobre este se reflejar en el parmetro original. Parametros por valor La funcin cuadrado() (ver arriba) es un clsico ejemplo que muestra el paso de parmetros por valor, en ese sentido la funcin cuadrado() recibe una copia del parmetro n. En la misma funcin se puede observar que se realiza un calculo ( n*n ), sin embargo el parmetro original no sufrir cambio alguno, esto seguir siendo cierto an cuando dentro de la funcin hubiera una instruccin parecida a n = n * n; o n*=n;. Parametros por referencia Para mostrar un ejemplo del paso de parmetros por referencia, vamos a retomar el caso de la funcin cuadrado, salvo que en esta ocasin cambiaremos ligeramente la sintaxis para definir la misma. Veamos:

// regresar el cuadrado de un nmero double cuadrado2(double &n) { n *= n; return n; }

Al poner a prueba las funciones cuadrado() y cuadrado2() se podr verificar que la primera de estas no cambia el valor del parmetro original, mientras que la segunda s lo hace.
Parmetros constantes Los parmetros usados por una funcin pueden declararse como constantes ( const ) al momento de la declaracin de la funcin. Un parmetro que ha sido declarado como constante significa que la funcin no podr cambiar el valor del mismo ( sin importar si dicho parmetro se recibe por valor o por referencia ). Ejemplo: int funcionX( const int n ); void printstr( const char *str ); Parmetros con valor por defecto Los parmetros usados por una funcin pueden declararse con un valor por defecto. Un parmetro que ha sido declarado con valor por defecto es opcional a la hora de hacer la llamada a la funcin. Ejemplo: Dada la funcin: void saludo( char* mensaje = "Hola sudafrica 2010" ); la misma puede ser invocada como: saludo(); // sin parmetro saludo("Sea usted bienvenido a C++"); // con parmetro Para ver un ejemplo ms, vamos a considerar el caso de la funcin binstr() del programa funciones01. Ahora, vamos modificar dicha funcin, salvo que esta ocasin nos interesa que la misma sirva para convertir nmeros decimales en cadenas numricas y cuya base de conversin sea pasada como parmetro. Es decir, la funcin de la que estamos hablando podr convertir nmeros decimales a: binario, octal, decimal, hexadecimal, etc.; y la nica condicin ser que la base indicada est entre el 2 y el 36, inclusive. Nota: Ya que la funcin servir para convertir nmeros a cualquier representacin la nombraremos como numstr() en lugar de binstr(). Si la funcin es invocada sin el parmetro base regresar una cadena de digitos decimales. #include <iostream>

#include <stdlib.h> using namespace std; // declaracin de prototipo char *numstr(unsigned int, const int base = 10); // punto de prueba int main() { int n = 128; cout<< "decimal = " << n << ", binario = " << numstr(n, 2) << endl; cout<< "decimal = " << n << ", octal.. = " << numstr(n, 8) << endl; cin.get(); } // definicin de funcin numstr() // nota: esta funcion requiere de la librera stdlib.h char *numstr(unsigned int n, const int base) { static char buffer[65]; itoa(n, buffer, base); return buffer; } Parmetros de tipo puntero Anteriormente se mencion que en C++ los parmetros a una funcin pueden pasarse por valor o por referencia, al respecto, podemos agregar que los parmetros tambin pueden pasarse como punteros. El paso de parmetros de punteros es bastante parecido al paso de parmetros por referencia, salvo que el proceso de los datos dentro de la funcin es diferente. Por ejemplo, las funciones: void referencia( int &X ) { X = 100; } void puntero( int *X ) { *X = 100; }

ambas reciben un puntero o referencia a un objeto de tipo entero, por lo tanto cualquiera de las funciones del ejemplo puede cambiar el valor de la variable entera apuntada por X, la diferencia radica en la forma en que cada una de las mismas lleva cabo la tarea. Si en la funcin puntero() en lugar de usar *X = 100; se usara X = 100; se le asignara 100 al puntero X, ms no al objeto apuntado por X, y esto podra ser la causa de que el programa se terminara de manera abrupta.

Parmetros estructurados Al igual que cualquier otro tipo los parmetros de tipo estruturado pueden pasarse por valor o por referencia, sin embargo, podra ser que si una estructura es pasada por valor el compilador mostrara una advertencia ( warning ) indicando que se pasado por valor una estructura, puesto que el paso de estructuras por valor es permitido usted puede ignorar la advertencia, pero lo mejor es pasar estructuras por referencia. Si una estructura es pasada por valor y si esta es muy grande podria ser que se agotara la memoria en el segmento de pila ( Stack Segment ), aparte de que la llamada a la funcin sera ms lenta. Para ver un ejemplo, consideremos el caso del siguiente tipo estructurado: struct empleado { char nombre[32]; int edad; char sexo; }; Ahora, pensemos que deseamos escribir una funcin para imprimir variables del tipo empleado. As, la funcin puede escribirse de las tres maneras siguientes: void ImprimeEmpleadoV( empleado e) { cout<< "Nombre: " << e.nombre << endl; cout<< "Edad: " << e.edad << endl; cout<< "Sexo: " << e.sexo << endl; } // Parametro empleado pasado por referencia void ImprimeEmpleadoR( empleado &e ) {

cout<< "Nombre: " << e.nombre << endl; cout<< "Edad: " << e.edad << endl; cout<< "Sexo: " << e.sexo << endl; }

// Parametro empleado pasado como puntero void ImprimeEmpleadoP( empleado *e ) { cout<< "Nombre: " << e->nombre << endl; cout<< "Edad: " << e->edad << endl; cout<< "Sexo: " << e->sexo << endl; }

Recursividad
Se dice que algo es recursivo si se define en funcin de s mismo o a s mismo. Tambin se dice que nunca se debe incluir la misma palabra en la definicin de sta. El caso es que las definiciones recursivas aparecen con frecuencia en matemticas, e incluso en la vida real. Un ejemplo: basta con apuntar una cmara al monitor que muestra la imagen que muestra esa cmara. El efecto es verdaderamente curioso, en especial cuando se mueve la cmara alrededor del monitor. En matemticas, tenemos mltiples definiciones recursivas: - Nmeros naturales: (1) 1 es nmero natural. (2) el siguiente nmero de un nmero natural es un nmero natural - El factorial: n!, de un nmero natural (incluido el 0): (1) si n = 0 entonces: 0! = 1 (2) si n > 0 entonces: n! = n (n-1)! Asimismo, puede definirse un programa en trminos recursivos, como una serie de pasos bsicos, o paso base (tambin conocido como condicin de parada), y un

paso recursivo, donde vuelve a llamarse al programa. En un computador, esta serie de pasos recursivos debe ser finita, terminando con un paso base. Es decir, a cada paso recursivo se reduce el nmero de pasos que hay que dar para terminar, llegando un momento en el que no se verifica la condicin de paso a la recursividad. Ni el paso base ni el paso recursivo son necesariamente nicos. Por otra parte, la recursividad tambin puede ser indirecta, si tenemos un procedimiento P que llama a otro Q y ste a su vez llama a P. Tambin en estos casos debe haber una condicin de parada. Existen ciertas estructuras cuya definicin es recursiva, tales como los rboles, y los algoritmos que utilizan rboles suelen ser en general recursivos. Un ejemplo de programa recursivo en C, el factorial:
int factorial(int n) { if (n == 0) return 1; return n * factorial(n-1); }

Como se observa, en cada llamada recursiva se reduce el valor de n, llegando el caso en el que n es 0 y no efecta ms llamadas recursivas. Hay que apuntar que el factorial puede obtenerse con facilidad sin necesidad de emplear funciones recursivas, es ms, el uso del programa anterior es muy ineficiente, pero es un ejemplo muy claro. A continuacin se expone un ejemplo de programa que utiliza recursin indirecta, y nos dice si un nmero es par o impar. Al igual que el programa anterior, hay otro mtodo mucho ms sencillo de determinar si un nmero es par o impar, basta con determinar el resto de la divisin entre dos. Por ejemplo: si hacemos par(2) devuelve 1 (cierto). Si hacemos impar(4) devuelve 0 (falso).
/* declaracion de funciones, para evitar errores */ int par(int n); int impar(int n);

int par(int n) { if (n == 0) return 1; returnimpar(n-1); } int impar(int n) {

if (n == 0) return 0; returnpar(n-1); }

En Pascal se hace as (notar el uso de forward):


function impar(n : Integer) : Boolean; forward; function par(n : Integer) : Boolean; forward;

function par(n : Integer) : Boolean; begin if n = 0 then par := true else par := impar(n-1) end;

function impar(n : Integer) : Boolean; begin if n = 0 then impar := false else impar := par(n-1) end;

Ejemplo: si hacemos la llamada impar(3) hace las siguientes llamadas: par(2) impar(1) par(0) -> devuelve 1 (cierto) Por lo tanto 3 es un nmero impar.

Qu pasa si se hace una llamada recursiva que no termina? Cada llamada recursiva almacena los parmetros que se pasaron al procedimiento, y otras variables necesarias para el correcto funcionamiento del programa. Por tanto si se produce una llamada recursiva infinita, esto es, que no termina nunca, llega un momento en el que no quedar memoria para almacenar ms datos, y en ese momento se abortar la ejecucin del programa. Para probar esto se puede intentar hacer esta llamada en el programa factorial definido anteriormente: factorial(-1); Por supuesto no hay que pasar parmetros a una funcin que estn fuera de su dominio, pues el factorial est definido solamente para nmeros naturales, pero es un ejemplo claro.

Cundo utilizar la recursin? Para empezar, algunos lenguajes de programacin no admiten el uso de recursividad, como por ejemplo el ensamblador o el FORTRAN. Es obvio que en ese caso se requerir una solucin no recursiva (iterativa). Tampoco se debe utilizar cuando la solucin iterativa sea clara a simple vista. Sin embargo, en otros casos, obtener una solucin iterativa es mucho ms complicado que una solucin recursiva, y es entonces cuando se puede plantear la duda de si merece la pena transformar la solucin recursiva en otra iterativa. Posteriormente se explicar como eliminar la recursin, y se basa en almacenar en una pila los valores de las variables locales que haya para un procedimiento en cada llamada recursiva. Esto reduce la claridad del programa. An as, hay que considerar que el compilador transformar la solucin recursiva en una iterativa, utilizando una pila, para cuando compile al cdigo del computador. Por otra parte, casi todos los algoritmos basados en los esquemas de vuelta atrs y divide y vencers son recursivos, pues de alguna manera parece mucho ms natural una solucin recursiva.

Aunque parezca mentira, es en general mucho ms sencillo escribir un programa recursivo que su equivalente iterativo. Si el lector no se lo cree, posiblemente se deba a que no domine todava la recursividad. Se propondrn diversos ejemplos de programas recursivos de diversa complejidad para acostumbrarse a la recursin.

Apuntadores
Los apuntadores son una parte fundamental de C. Si usted no puede usar los apuntadores apropiadamente entonces esta perdiendo la potencia y la flexibilidad que C ofrece bsicamente. El secreto para C esta en el uso de apuntadores. C usa los apuntadores en forma extensiva. Porqu?

Es la nica forma de expresar algunos clculos. Se genera cdigo compacto y eficiente. Es una herramienta muy poderosa.

C usa apuntadores explcitamente con:


Es la nica forma de expresar algunos clculos. Se genera cdigo compacto y eficiente. Es una herramienta muy poderosa.

C usa apuntadores explcitamente con:

Arreglos,

Estructuras y Funciones

Definicin de un apuntador
Un apuntador es una variable que contiene la direccin en memoria de otra variable. Se pueden tener apuntadores a cualquier tipo de variable. El operador unario o mondico&devuelve la direccin de memoria de una variable. El operador de indireccin o dereferencia* devuelve el ``contenido de un objeto apuntado por un apuntador''. Para declarar un apuntador para una variable entera hacer:
int *apuntador;

Se debe asociar a cada apuntador un tipo particular. Por ejemplo, no se puede asignar la direccin de un short int a un long int. Para tener una mejor idea, considerar el siguiente cdigo:
main() { int x = 1, y = 2; int *ap; ap = &x; y = *ap; x = ap; *ap = 3; }

Cuando

mostrar warning: assignment makes integer from pointer without a cast.

se

compile

el

cdigo

se

el

siguiente

mensaje:

Con el objetivo de entender el comportamiento del cdigo supongamos que la variable x esta en la localidad de la memoria 100, y en 200 y ap en 1000. Nota: un apuntador es una variable, por lo tanto, sus valores necesitan ser guardados en algn lado.
int x = 1, y = 2; int *ap; ap = &x;

100 x 1

200 y 2

1000 ap 100

Las variables x e y son declaradas e inicializadas con 1 y 2 respectivamente, ap es declarado como un apuntador a entero y se le asigna la direccin de x (&x). Por lo que ap se carga con el valor 100.
y = *ap;

100 x 1

200 y 1

1000 ap 100

Despus y obtiene el contenido de ap. En el ejemplo ap apunta a la localidad de memoria 100 -- la localidad de x. Por lo tanto, y obtiene el valor de x -- el cual es 1.
x = ap;

100

200

1000 ap 100

x 100 y 1

Como se ha visto C no es muy estricto en la asignacin de valores de diferente tipo (apuntador a entero). As que es perfectamente legal (aunque el compilador genera un aviso de cuidado) asigna el valor actual de ap a la variable x. El valor de ap en ese momento es 100.
*ap = 3;

100 x 3

200 y 1

1000 ap 100

Finalmente se asigna un valor al contenido de un apuntador (*ap).

Importante: Cuando un apuntador es declarado apunta a algn lado. Se debe inicializar el apuntador antes de usarlo. Por lo que:
main() { int *ap; *ap = 100; }

puede generar un error en tiempo de ejecucin o presentar un comportamiento errtico.

El uso correcto ser:


main() { int *ap; int x; ap = &x; *ap = 100; }

Con los apuntadores se puede realizar tambin aritmtica entera, por ejemplo:
main() { float *flp, *flq; *flp = *flp + 10; ++*flp; (*flp)++; flq = flp; }

NOTA: Un apuntador a cualquier tipo de variables es una direccin en memoria -la cual es una direccin entera, pero un apuntador NO es un entero. La razn por la cual se asocia un apuntador a un tipo de dato, es por que se debe conocer en cuantos bytes esta guardado el dato. De tal forma, que cuando se

incrementa un apuntador, se incrementa el apuntador por un ``bloque'' de memoria, en donde el bloque esta en funcin del tamao del dato. Por lo tanto para un apuntador a un char, se agrega un byte a la direccin y para un apuntador a entero o a flotante se agregan 4 bytes. De esta forma si a un apuntador a flotante se le suman 2, el apuntador entonces se mueve dos posiciones float que equivalen a 8 bytes.

Apuntadores y Funciones
Cuando C pasa argumentos a funciones, los pasapor valor, es decir, si el parmetro es modificado dentro de la funcin, una vez que termina la funcin el valor pasado de la variable permanece inalterado. Hay muchos casos que se quiere alterar el argumento pasado a la funcin y recibir el nuevo valor una vez que la funcin ha terminado. Para hacer lo anterior se debe usar una llamada por referencia, en C se puede simular pasando un puntero al argumento. Con esto se provoca que la computadora pase la direccin del argumento a la funcin. Para entender mejor lo anterior consideremos la funcin swap() que intercambia el valor de dos argumentos enteros:
void swap(int *px, int *py); main() { int x, y; x = 10; y = 20; printf("x=%d\ty=%d\n",x,y); swap(&x, &y); printf("x=%d\ty=%d\n",x,y); } void swap(int *px, int *py) { int temp; temp = *px; /* guarda el valor de la direccion x */ *px = *py; /* pone y en x */ *py = temp; /* pone x en y */ }

Apuntadores y estructuras
Los apuntadores a estructuras se definen fcilmente y en una forma directa. Considerar lo siguiente:
main() { struct COORD { float x,y,z; } punto; struct COORD *ap_punto; punto.x = punto.y = punto.z = 1; ap_punto = &punto; /* Se asigna punto al apuntador */ ap_punto->x++; ap_punto->y+=2; ap_punto->z=3; } /* Con el operador -> se accesan los miembros */ /* de la estructura apuntados por ap_punto */

Otro ejemplo son las listas ligadas:


typedef struct { int valor; struct ELEMENTO *sig; } ELEMENTO; ELEMENTO n1, n2; n1.sig = &n2;

La asignacin que se hace corresponde a la figura 8.3

Figura 8.3: Esquema de una lista ligada con 2 elementos.

Nota: Solamente se puede declarar sig como un apuntador tipo ELEMENTO. No se puede tener un elemento del tipo variable ya que esto generara una definicin recursiva la cual no esta permitida. Se permite poner una referencia a un apuntador ya que los los bytes se dejan de lado para cualquier apuntador.

Fallas comunes con apuntadores


A continuacin se muestran dos errores comunes que se hacen con los apuntadores.

No asignar un apuntador a una direccin de memoria antes de usarlo


int *x *x = 100;

lo adecuado ser, tener primeramente una localidad fsica de memoria, digamos int y;
int *x, y; x = &y; *x = 100;

Indireccin no vlida

Supongamos que se tiene una funcin llamada malloc() la cual trata de asignar memoria dinmicamente (en tiempo de ejecucin), la cual regresa un apuntador al bloque de memoria requerida si se pudo o un apuntador a nulo en otro caso.
char *malloc() -- una funcin de la biblioteca estndar que se ver ms adelante.

Supongamos que se tiene un apuntador char *p Considerar:


*p = (char *) malloc(100): *p = 'y'; /* pide 100 bytes de la memoria */

Existe un error en el cdigo anterior. Cul es? El * en la primera lnea ya que malloc regresa un apuntador y *p no apunta a ninguna direccin.

El cdigo correcto deber ser:


p = (char *) malloc(100);

Ahora si malloc no puede regresar un bloque de memoria, entonces p es nulo, y por lo tanto no se podr hacer:
*p = 'y';

Un buen programa en C debe revisar lo anterior, por lo que el cdigo anterior puede ser reescrito como:
p = (char *) malloc(100): /* pide 100 bytes de la memoria */

if ( p == NULL ) { printf("Error: fuera de memoria\n"); exit(1); } *p = 'y';

Bibliografa
Estructura general de un programa en C mimosa.pntic.mec.es/~flarrosa/lengc.pdf Entornos de programacin C http://www.malavida.com/blog/355/entornos-deprogramacion-c Tipos de Entornos de http://www.fismat.umich.mx/mn1/manual/node8.html Compilacin http://www.fismat.umich.mx/mn1/manual/node8.html Ejecucin del programa http://www.fismat.umich.mx/mn1/manual/node8.html Tipos de datos http://www.slideshare.net/javi2401/variables-constantes-y-tiposde-datos-en-c-presentation Enteros http://www.fismat.umich.mx/mn1/manual/node8.html Flotantes http://www.fismat.umich.mx/mn1/manual/node8.html Caracteres y Cadenas en C http://www.slideshare.net/javi2401/caracteres-ycadenas-en-c-presentation Variables y Constantes en C http://www.slideshare.net/javi2401/variablesconstantes-y-tipos-de-datos-en-c-presentation Entrada y salida http://mimosa.pntic.mec.es/~flarrosa/lengc.pdf Tipos de operadores y http://jtortone.com.ar/utnconfluencia/recursividadypractica.pdf expresiones Programacin

Tipos estructurados http://ocw.upm.es/ciencia-de-la-computacion-e-inteligenciaartificial/fundamentosprogramacion/contenidosteoricos/ocwfundamentosprogramaciontema6.pdf Funciones http://www.algoritmia.net/articles.php?id=11 http://es.wikibooks.org/wiki/Programaci%C3%B3n_en_C%2B%2B/Funciones Apuntadores http://www.fismat.umich.mx/mn1/manual/node9.html

Você também pode gostar