Anda di halaman 1dari 42

FUNDAMENTOS DE PROGRAMACION

Apuntes para el Primer Semestre

IPN

INDICE

INTRODUCCIN AL LENGUAJE C ........................................................................................... 3 Elementos del lenguaje ESTRUCTURA GENERAL DE UN PROGRAMA ........................................................................ 6 Tipos de datos Operadores Funciones de biblioteca Funciones generadas por el usuario Argumentos Sentencias ESTRUCTURAS DE FLUJO PROGRAMATICO ....................................................................... 24 if, else, switch, for, do, while, break, exit, continue, return ESTRUCTURAS DE DATOS: ARREGLOS Y APUNTADORES .............................................. 29 Arreglos Unidimensionales Arreglos bidimensionales Arreglos y apuntadores INTRODUCCION A LAS GRAFICAS POR COMPUTADORA..................................................40 Programas de aplicacin

INTRODUCCIN AL LENGUAJE C Un lenguaje de nivel medio A menudo se denomina al lenguaje C como lenguaje de computadora de nivel medio. Esto no significa que sea menos potente, ms difcil de usar o menos evolucionado que lenguajes de alto nivel como BASIC o Pascal; ni implica que C sea similar al lenguaje ensamblador y por tanto presente al usuario sus problemas asociados. C se presenta como lenguaje de nivel medio porque combina elementos de lenguajes de alto nivel con la funcionalidad del lenguaje ensamblador. Como lenguaje de nivel medio, C permite la manipulacin de bits, bytes y direcciones - los elementos bsicos con los que funciona la computadora -. El cdigo de C es muy portable. (La portabilidad significa que es posible adaptar el software escrito para un tipo de computadora en otra). Por ejemplo, si un programa escrito para un Apple II+ se puede llevar fcilmente a un IBM PC, entonces el programa es portable. Todos los lenguajes de alto nivel soportan el concepto de tipos de datos. Un tipo de datos define un conjunto de valores que puede tener una variable junto con un conjunto de operaciones que se pueden realizar sobre esa variable. Algunos tipos de datos comunes son los enteros, los caracteres y los reales. Aunque el lenguaje C tiene cinco tipos de datos bsicos incorporados, no se trata de un lenguaje fuertemente tipificado en el sentido de Pascal o Ada. C permite casi todas las conversiones de tipos. Por ejemplo, los tipos entero y de carcter pueden ser entremezclados libremente en la mayora de las expresiones. C no lleva a cabo la comprobacin de errores en el tiempo de ejecucin como pueden ser el sobrepasar los lmites de los arreglos o la incompatibilidad de tipos de los argumentos. Esas comprobaciones quedan enteramente como responsabilidad del programador. Una caracterstica especial de C es que permite la manipulacin directa de bits, bytes, palabras y apuntadores. Esto le hace particularmente adecuado para la programacin de sistemas, en la que estas operaciones son muy comunes. Otro aspecto importante del lenguaje C es que slo tiene 32 palabras clave (27 del estndar de Ritchie y Kernighan y 5 aadidas por el comit de estandarizacin del ANSI), que constituyen las rdenes que conforman el lenguaje C. (Turbo C contiene 11 palabras clave ms para permitir ciertas mejoras y extensiones). Como comparacin, considrese que el lenguaje BASIC del IBM PC contiene 159 palabras clave. Un lenguaje sencillamente estructurado Aunque en un sentido acadmico el trmino lenguaje estructurado en bloques no se aplica estrictamente al lenguaje C, el lenguaje C se denomina normalmente lenguaje sencillamente estructurado, ya que tiene similitudes estructurales con ALGOL, Pascal y Modula-2. (Tcnicamente, un lenguaje estructurado en bloques permite declarar procedimientos o funciones dentro de otros procedimientos o funciones. De esta forma, se extienden los conceptos de globalidad y localidad mediante el uso de reglas de alcance, que gobiernan la "visibilidad" de las variables o de los procedimientos. Dado que C no permite la creacin de funciones dentro de funciones, no puede ser formalmente denominado lenguaje estructurado en bloques). La caracterstica distintiva de un lenguaje estructurado es la compartimentalizacin de cdigo y datos. Se trata de la capacidad de un lenguaje de seccionar y esconder del resto del programa toda la informacin y las instrucciones necesarias para llevar a cabo una determinada tarea. Una forma con la que se consigue la compartimentalizacin es mediante el uso de subrutinas que empleen variables locales (temporales). Con el uso de variables locales es posible escribir subrutinas de forma que lo que ocurra en su interior no provoque efectos secundarios en otras partes del programa. Esta posibilidad hace que sea muy fcil que los programas en C compartan secciones de cdigo. Al desarrollar funciones compartimentalizadas slo es necesario conocer qu es lo que la funcin hace, no cmo lo hace.

ELEMENTOS DEL LENGUAJE Un programa en C++ es una secuencia de caracteres que se agrupan en componentes lxicos (tokens) que comprenden el vocabulario bsico del lenguaje. Estos componentes de lxico son: palabras reservadas, identificadores, constantes, constantes de cadena, operadores y signos de puntuacin. Caracteres Los caracteres que se pueden utilizar para construir elementos del lenguaje (componentes lxicos o tokens) son: abcdefghijklmnopqrstuvwxyz ABCDEFCHIJKLMNOPQRSTUVWXYZ 0123456789 Caracteres, espacio (blancos y tabulaciones) Comentarios C++ soporta dos tipos de comentarios. Las lneas de comentarios al estilo C y C ANSI, tal como: /* Comentario estilo C */ /* Comentario mas extenso, pero tambin es estilo C y ANSI C */ El otro tipo de comentarios se pueden utilizar por los programadores de C++: La versin /*...* / se utiliza para comentarios que excedan una lnea de longitud y la versin //... se utiliza, slo, para comentarios de una lnea. Los comentarios no se anidan. Identificadores Los identificadores (nombres de variables, constantes,...) deben comenzar con una letra del alfabeto (mayscula o minscula) o con un carcter subrayado, y pueden tener uno o ms caracteres. Los caracteres segundo y posteriores pueden ser: letras, dgitos o un subrayado, no permitindose caracteres no alfanumricos ni espacios. tescprueba // legal Xl23 // legal multi_palabra // legal var25 // legal l5var // no legal C++ es sensible a las maysculas: Paga_mes es un identificador distinto a paga_mes Una buena prctica de programacin aconseja utilizar identificadores significativos que ayudan a documentar un programa: nombre apellidos salario precio_neto

Palabras reservadas Las palabras reservadas o claves no se deben utilizar como identificadores, debido a su significado estricto en C++; tampoco se deben redefinir. La Tabla B. 1 enumera las palabras reservadas de C++ segn el ARM (Siglas del libro de BJARNE STROUSTRUP en el que se definen las reglas de sintaxis del lenguaje C++ estndar). Tabla 1. Palabras reservadas de C++ asm* continue float new* signed try auto default for operator* sizeof typedef break delete* friend* private* static union case do goto protected* struct unsigned catch*

double if public* switch virtual* char else inline* register template* void enurn int return this* volatile const extern long short throw* while *Estas palabras no existen en ANSI C.

class*

Los diferentes compiladores comerciales de C++ pueden incluir, adems, nuevas palabras reservadas. Estos son los casos de Borland, Microsoft y Sysmantec. Tabla 2. Palabras reservadas de Turbo/Borland C++ asm _ds interrupt short auto else _loadds signed break enum long sizeof case _es _near _ss catch export near static_cdecl extern new struct_cdecl far operator switch char far pascal template class float pascal this const for private typedef continue friend protected union_cs goto pubic unsigned default huge register virtual delete if return void do inline _saveregs volatile_double int _seg while Tabla 3. Palabras reservadas de Microsoft Visual C/C++ 1.5/2.0 asm else int signed auto enum _interrupt sizeof based _except _leave static break_export _loadds _stcall case extern long struct_cdecl _far maked switch char _fastcall _near thread const _finally _pascal _try continue float register typedef_declspec for return union default _fortran _saveregs unsigned dllexport goto _self void dllimport _huge _segment volatile do if _segname while doble _inline short El comit ANSI ha aadido nuevas palabras reservadas (Tabla 4). Tabla 4. Nuevas palabras reservadas de ANSI C++ bool false reinterpretcast namespace true wchart typeid cons_cast mutable static_cast using dynamic_cast

Todas las palabras clave de C estn en minsculas. En C las maysculas y las minsculas son diferentes: else es una palabra clave; ELSE no. Una palabra clave no debe ser usada para otro propsito en un programa en C -es decir, no debe servir como nombre de variable o de funcin. Todos los programas en C consisten en una o ms funciones. La nica funcin que deber estar absolutamente presente es la denominada main( ) en esencia, esboza lo que el programa hace. Ese esbozo est compuesto por llamadas a funciones. Aunque tcnicamente main( ) no forma parte del lenguaje C, trtela como si lo fuera. No intente usar main( ) como nombre para una variable, ya que probablemente confundir al compilador.

ESTRUCTURA GENERAL DE UN PROGRAMA La forma general de un programa en C se ilustra en la siguiente figura, donde desde f1( ) hasta fN( ) representan funciones definidas por el usuario. declaraciones globales main( ) { variables locales secuencia de sentencias } f1( ) { variables locales secuencia de sentencias } f2( ) { variables locales secuencia de sentencias } . . . fN( ) { variables locales secuencia de sentencias }

TIPOS DE DATOS Los tipos de datos simples en C++ se dividen en dos grandes grupos: integrales (datos enteros) y de coma flotante (datos reales). Tabla 5. Tipos de datos simples en C++ char long signed char unsigned char float double_ long double short int long usigned short unsigned unsigned

Los tipos derivados en C++ pueden ser: Enumeraciones (enum), Estructuras (struct), Uniones (union), Arreglos, Clases (class y struct), Uniones y enumeraciones annimas, Apuntadores, Verificacin de tipos La verificacin o comprobacin de tipos en C++ es ms rgida (estricta) que en C. Algunas consideraciones a tener en cuenta son: Usar funciones declaradas. Esta accin es ilegal en C++, y est permitida en C: int main() { //... printf(x) //C int printf(x)

//C++ es ilegal, ya que printf no esta declarada return 0; } Fallo al devolver un valor de una funcin. Una funcin en C++ declarada con un tipo determinado de retomo, ha de devolver un valor de ese tipo. En C, est permitido no seguir la regla. Asignacin de apuntadores void. La asignacin de un tipo void* a un apuntador de otro tipo se debe hacer con una conversacin explcita en C++. En C, se realiza implcitamente. Inicializacin de constantes de cadena. En C++ se debe proporcionar un espacio para el carcter de terminacin nulo cuando se inicializan constantes de cadena. En C, se permite la ausencia de ese carcter. int main() { //...... char car[7] = Cazorla; // legal en C //error en C++ //...... return 0; } Una solucin al problema que funciona tanto en C como en C++ es: char car [] ="Cazorla"; Constantes C++ contiene constantes para cada tipo de dato simple (integer, char,...). Las constantes pueden tener dos sufijos, u, l y f. Que indican tipos unsigned, long y float, respectivamente. As mismo, se pueden aadir los prefijos o y ox, que representan constantes octales y hexadecimales. 456 0456 0x476 // constante enteras: decima1, octal , hexadecimal 1231 123ul // constantes enteras: long, unsigned, long B b 4 // constante de tipo char 3.1415f // constante reales de diferente posicin cadena de caracteres // Constante de cadena Las cadenas de caracteres se encierran entre comillas, y las constantes de un solo carcter se encierran entre comillas simples. Declaracin de constantes En C++, los identificadores de variables/constantes se pueden declarar constantes, significando que su valor no se puede modificar. Esta declaracin se realiza con la palabra reservada const: const double PI= 3.11416; const char BLANCO = ; const double PI_EG = -I; const double DOBLE_I = 2 * PI ; El modificador de tipos const se utiliza en C++, tambin para proporcionar proteccin de slo lectura para variables y parmetros de funciones. Las funciones miembro de una clase que no modifican los miembros dato a que acceden pueden ser declarados const. Este modificador evita tambin que parmetros por referencia sean modificados: void copy (const char * fuente, char * destino):

Conversin de tipos La conversiones explcitas se fuerzan mediante moldes (casts). La conversin forzosa de tipos de C tiene el formato clsico: (tipo) expresion C++ ha modificado la notacin anterior por una notacin funcional como alternativa sintctica: nombre del tipo (expresion) Las notaciones siguientes son equivalentes: float(x); //notacion de casteo en C++ (float)x; //notacion de casteo en C Declaracin de variables En ANSI C, todas las declaraciones de variables y funciones se deben hacer al principio del programa o funcin. Si se necesitan declaraciones adicionales, el programador debe volver al bloque de declaraciones al objeto de hacer los ajustes o inserciones necesarios. Todas las declaraciones deben hacerse antes de que se ejecute cualquier sentencia. As, la declaracin tpica en C++, NombreTipo Nombrevariablel, Nombrevariable2; proporciona declaraciones tales como: int saldo, meses; double clipper, salario; Al igual que en C, se pueden asignar valores a las variables en C++: int mes =4, dia, anio=1995; doble salario = 45.675; En C++, las declaraciones de variables se pueden situar en cualquier parte de un programa. Esta caracterstica hace que el programador declare sus variables en la proximidad del lugar donde se utilizan las sentencias de su programa. El siguiente programa es legal en C++ pero no es vlido en C: #include <stdio.h> int main () { int i ; for ( i= 0; i<100; ++i) printf ( %d\n , i); double j; for ( j= 1.7547; j<25.4675; j+= .001) printf ( %lf\n , j); } El programa anterior se podra reescribir, haciendo la declaracin y la definicin dentro del mismo bucle: int main () { for ( int i= 0; i<100; ++i) cout<< i << endl; for ( int j= 1.7547; j<25.4675; j+= .001) cout << j <<; }

OPERADORES C es un lenguaje muy rico en operadores incorporados. Un operador es un smbolo que indica al compilador que lleve a cabo ciertas manipulaciones matemticas o lgicas. En C hay tres clases generales de operadores: aritmticos, relacionales y lgicos y a nivel de bits. Adems, C tiene operadores especiales para determinadas tareas. Operadores aritmticos Operador + * / % -++ Accin Resta, tambin menos monetario Suma Multiplicacin Divisin Divisin de mdulo Decremento Incremento

Incremento y decremento C contiene dos operadores muy tiles que no existen generalmente en otros lenguajes de computadora. Son el de incremento y el de decremento, ++ y --. El operador ++ aade 1 a su operando y -- le resta 1. Por tanto, las que siguen son operaciones equivalentes: x = x+1; es lo mismo que ++x; y x = x-1; es lo mismo que --x; Los operadores de incremento y de decremento pueden preceder o seguir al operando. Por ejemplo: x = x+1; puede escribirse como ++x; o como x++;

Sin embargo, existe una diferencia cuando se utilizan estos operadores en una expresin. Cuando un operador de incremento o de decremento precede a su operando, C lleva a cabo la operacin de incremento o de decremento antes de utilizar el valor del operando. Si el operador sigue al operando, C utiliza su valor antes de incrementarlo o decrementarlo. Considere lo siguiente: x = 10; y = ++x; En este caso, se pone y a 11. Sin embargo, si se escribe el cdigo como x = 10; y = x++; y toma el valor 10. En ambos casos x queda como 11; la diferencia estriba en cundo cambia de valor. Existen ventajas significativas en poder controlar cundo tiene lugar la operacin de incremento o de decremento.

Operadores relacionales y lgicos En el trmino operador relacional la palabra relacional se refiere a la relacin entre unos valores y otros. En el trmino operador lgico la palabra lgico se refiere a las formas en que esas relaciones pueden conectarse entre s siguiendo las reglas de la lgica formal. Los discutiremos a la vez, ya que a menudo los operadores relacionales y lgicos actan juntos. La clave de los conceptos de operadores relacionales y lgicos es la idea de cierto y falso. En C, cierto es cualquier valor distinto de 0. Falso es 0. Las expresiones que utilizan los operadores relacionales y lgicos devuelven el valor 1 en caso de cierto y 0 en caso de falso. Operadores relacionales Operador > >= < <= == != Operadores lgicos Operador && || ! Accin Y O NO Accin Mayor que Mayor que o igual Menor que Menor que o igual Igual No igual

La tabla de verdad para los operadores lgicos se muestra aqu usando unos y ceros. p 0 0 1 1 q 0 1 1 0 p&&q 0 0 1 0 p || q 0 1 1 1 !q 1 1 0 0

Operadores a nivel de bits Al contrario que muchos otros lenguajes, el lenguaje C soporta un completo juego de operadores a nivel de bits. Dado que el lenguaje C se dise para sustituir al lenguaje ensamblador en muchas tareas de programacin, era importante permitir todas (o al menos muchas de) las operaciones que se pueden hacer en ensamblador. Las operaciones a nivel de bits se refieren a la comprobacin, asignacin o desplazamiento de los bits reales que componen un byte o una palabra, que corresponden a los tipos estndar de C char e int con sus variantes. Las operaciones a nivel de bits no se pueden usar sobre float, double, long double, void u otros tipos ms complejos. La siguiente tabla lista los operadores que se aplican a las operaciones a nivel de bits: Operador & | ^ ~ >> << Accin Y O O exclusiva (XOR) Complemento a uno Desplazamiento a la derecha Desplazamiento a la izquierda

10

Los Y, O y NO (complemento a uno) a nivel de bits estn gobernados por la misma tabla de verdad que sus equivalentes lgicos, excepto en que trabajan bit a bit. La tabla de verdad que sigue se aplica a la O exclusiva (^): p 0 0 1 1 q 0 1 0 1 p^q 0 1 1 0

Como indica la tabla, el resultado de una XOR es cierto slo si exactamente uno de los operandos es cierto; de otro modo, es falso. Las operaciones sobre bits son frecuentes en aplicaciones de controladores de dispositivos tales como programas de modem, rutinas de archivos de disco y rutinas de impresora - debido a que permiten enmascarar ciertos bits, como el de paridad. (El bit de paridad se utiliza para confirmar que el resto de los bits del byte no han cambiado. Normalmente es el bit ms significativo de cada byte). Los operadores de desplazamiento, >> y <<, mueven todos los bits de una variable a la derecha o a la izquierda, segn se especifique. La forma general de una sentencia de desplazamiento a la derecha es: variable >> nmero de posiciones de bits La sentencia de desplazamiento a la izquierda es: variable << nmero de posiciones de bits A medida que se desplazan los bits hacia un extremo se va rellenando con ceros por el extremo opuesto. Recuerde, un desplazamiento no es una rotacin. O sea, los bits que salen por un extremo no se introducen por el otro. Los bits que salen se pierden, introducindose ceros. Sin embargo, un desplazamiento a la derecha de un nmero negativo introduce unos. El operador de complemento a uno, ~, cambia el estado de cada bit en la variable especificada. O sea, los 1 se ponen a 0 y los 0 a 1. El operador ? C contiene un operador muy potente y conveniente que puede usarse para sustituir ciertas sentencias de la forma if-then-else. El operador ternario ? toma la forma general Exp1 ? Exp2 : Exp3 Donde Exp1, Exp2 y Exp3 son expresiones. Observe el uso y la situacin de los dos puntos. El operador ? acta de la siguiente forma: evala Exp1. Si es cierta, evala Exp2 y toma ese valor para la expresin. Si Exp1 es falsa, evala Exp3 tomando su valor para la expresin. Por ejemplo: x = 10; y = x>9 ? 100 : 200; En este ejemplo, a y se le asigna el valor 100. Si x hubiera sido menor que 9, y habra recibido el valor 200. Ese mismo cdigo escrito con la sentencia if/else sera: x = 10; if(x>9) y = 100; else y = 200; Los operadores new y delete C++ define un mtodo para realizar asignacin dinmica de memoria, diferente del utilizado en mediante los operadores new y delete. El operador new sustituye a la funcin malloc tradicional

11

en C, y el operador delete sustituye a la funcin free tradicional, tambin en C. new, asigna memoria, y devuelve un apuntador al new Nombre Tipo y un ejemplo de su aplicacin es: int *ptrl double *ptr2; ptrl = new int; // memoria asignada para el objeto ptrl ptr2 = new double; // memoria ampliada para el objeto ptr2 *ptrl = 5; *ptr2 = 6.55; Dado que new devuelve un apuntador, se puede utilizar ese apuntador para inicializar el apuntador de una sola definicin, tal como: int* p = new int; Si new no puede ocupar la cantidad de memoria solicitada devuelve un valor NULL. El operador delete libera la memoria asignada mediante new. delete prt1; Un pequeo programa que muestra el uso combinado de new y delete es: include <iostream.h> void main (void) { char *c; c = new char[512]; cin >> c; cout << c <<endl; delete [] c; } Los operadores new y delete se pueden utilizar para asignar memoria a arreglos, clases y otro tipo de datos. int *i i = new int[2][35]; //crear el arreglo de 2 x 35 dimensiones //asignar el arreglo delete i; //destruir el arreglo Sintaxis de new y delete new nombre-tipo new int new char[l00] new nombre-tipo nicializador new int(99) new char(C) new nombre-tipo new (char*) delete expresin delete p delete[] expresin delete []p Enumeraciones, estructuras y uniones En C++, un nombre de una enumeracin, estructura o unin es un nombre de un tipo. Por consiguiente, la palabra reservada struct, union, o enum no son necesarias cuando se declara una variable. El tipo de dato enumerado designa un grupo de constantes enteros con nombres. La palabra reservada enum se utiliza para declarar un tipo de dato enumerado o enumeracin. La sintaxis es: enum nombre { lista-simbolos }

12

Donde nombre es el nombre de la variable declarada enumerada, LISTA-SIMBOLOS es una lista de tipos enumerados, a los que se asigna valores cuando se declara la variable enumerada y puede tener un valor de inicializacin. Se puede utilizar el nombre de una enumeracin para declarar una variable de ese tipo (variable de enumeracin). Ej: nombre ver; Considrese la siguiente sentencia: enum color [Rojo, Azul, Verde, Amarillo]; Una variable de tipo enumeracin color es: color pantalle = Rojo; //Estilo C++ Una estructura es un tipo de dato compuesto que contiene una coleccin de elementos de tipos de datos diferentes combinados en una nica construccin del lenguaje. Cada elemento de la coleccin se llama miembro y puede ser una variable de un tipo de dato diferente. Una estructura representa un nuevo tipo de dato en C++. La sintaxis de una estructura es: struct nombre { miembros }; Un ejemplo y una variable tipo estructura se muestran en las siguientes sentencias: struct cuadro { int i; float f; }; struct cuadro nombre; //Estilo C cuadro nombre; //Estilo C++ Una unin es una variable que puede almacenar objetos de tipos y tamaos diferentes. Una unin puede almacenar tipos de datos diferentes, slo puede almacenar uno cada vez, en oposicin a una estructura que almacena simultneamente una coleccin de tipos de datos. La sintaxis de una unin es: union nombre { miembros }; Un ejemplo de una unin es: union alfa { int x; char o; }; Una declaracin de una variable estructura es: alfa w; El modo de acceder a los miembros de la estructura es mediante el operador punto. u.x = 145; u.c = z; C++ admite un tipo especial de unin llamada unin annima, que declara un conjunto de miembros que comparten la misma direccin de memoria. La unin annima no tiene asignado un nombre y, en consecuencia, se accede a los elementos de la unin directamente. La sintaxis de una unin annima es: union

13

{ int nuevolD; int contador; } Las variables de la unin annima comparten la misma posicin de memoria y espacio de datos. int main() { union { int x; float y; double z; } x = 25; y = 245.245; //el valor en y sobreescribe el valor de x z = 9.41415; //el valor en z sobreescribe el valor de z } El operador de tiempo de compilacin sizeof El operador sizeof es un operador monario que devuelve la longitud, en bytes, de la variable o del especificador de tipo entre parntesis al que precede. Por ejemplo, float f; printf("%f", sizeof f); printf("%d", sizeof(int)); mostrar 4 2. Recuerde que para calcular el tamao de un tipo, el nombre del tipo debe ir entre parntesis. No es necesario encerrar los nombres de las variables entre parntesis. Principalmente, sizeof ayuda a generar cdigo portable que dependa del tamao de los tipos de datos incorporados de C. Por ejemplo, imagine un programa de base de datos que necesite guardar seis valores enteros por registro. Si se quiere transportar el programa de base de datos a una gran variedad de computadoras, no se debe asumir que un entero ocupe 2 bytes; se debe determinar la longitud real de los enteros usando sizeof. En ese caso, se puede usar la siguiente rutina para escribir un registro en un archivo de disco: /* escribir un registro en un archivo de disco */ poner_reg(FILE *.fp, int reg[6]) { int long, num; long = sizeof(reg); num = fwrite(reg, long, l, fp); if(num<>1) printf("error de escritura"); } El punto clave de este ejemplo es que, codificada as, poner_reg() compila y ejecuta correctamente en cualquier computadora -incluso en aquellas con enteros de 4 bytes-. El uso correcto de size_of significa que se puede usar Turbo C para desarrollar cdigo que podr al final ejecutarse en diferentes entornos. FUNCIONES DE BIBLIOTECA Para utilizar cualquier funcin de la biblioteca estndar en un programa debe incluirse el archivo de cabecera apropiado para cada funcin. Los archivos de cabecera usan la extensin .H y se proporcionan junto con C. Los archivos de cabecera de Turbo C contienen dos elementos principales: las definiciones usadas por las funciones y los prototipos de las funciones estndar relacionadas con el archivo de cabecera.

14

En la siguiente tabla se muestran los archivos de cabecera de Turbo C junto con la categora de funciones que incluye cada uno. Nombre del archivo alloc.h assert.h bios.h conio.h ctype.h dir.h dos.h errno.h fontl.h float.h graphics.h io.h limits.h locale.h math.h mem.h procces.h setjmp share.h signal.h stdargs.h stddef.h stdio.h stdlib.h strig.h sys\stat.h sys\timeb.h sys\types.h time.h values.h Funciones relacionadas Asignacin dinmica de memoria. Define assert( ). Funciones de interfaz con el BIOS. Funciones de E/S directa por consola. Funciones relacionadas con caracteres. Funciones relacionadas con directorios. Funciones de interfaz con el DOS. Define varios cdigos de error. Define varias constantes usadas por el sistema de archivo tipo UNIX. Define los lmites reales en coma flotante. Funciones relacionadas con grficos. Funciones de E/S de bajo nivel. Define varios lmites de enteros. Funciones especficas de pases. Funciones matemticas. Funciones de manipulacin de memoria. Funciones de control de procesos. Requerido por setjmp( ) y longjmp( ). Soporte a la comparticin de archivos. Soporte para signal( ) y raise( ). Soporte para argumentos de longitud variable. Define tipos y macros estndar. Funciones de E/S estndar. Funciones variadas. Funciones relacionadas con cadenas. Constantes relacionadas con archivos. Soporta la funcin ftime( ). Define time_t, usado por las funciones de hora. Funciones de hora y fecha. Varias constantes dependientes de la implementacin.

La biblioteca y el enlazado Tcnicamente hablando, es posible crear un programa en C que sea funcional y til y que consista solamente en las sentencias realmente creadas por el programador. Sin embargo, esto es bastante raro, ya que C no proporciona, dentro de la definicin real del lenguaje, ningn mtodo para llevar a cabo las operaciones de entrada/salida (E/S). Por ello, la mayora de los programas incluyen llamadas a varias funciones contenidas en la biblioteca estndar del lenguaje C. Turbo C viene con una biblioteca estndar que proporciona funciones para llevar a cabo las tareas necesarias ms comunes. Cuando se llama a una funcin que no es parte del programa que se ha escrito. Turbo C "recuerda" su nombre. Ms tarde, el enlazador combina el cdigo escrito con el cdigo objeto que ya se encuentra en la biblioteca estndar (link). Las funciones que se encuentran en la biblioteca lo estn en formato reubicable. Esto significa que las direcciones de memoria de las diferentes instrucciones de cdigo mquina no han sido definidas en forma absoluta; slo se mantiene informacin sobre desplazamientos. Cuando se enlaza un programa con funciones de la biblioteca estndar, se usan esos desplazamientos de memoria para definir las direcciones reales. Existen varios manuales y libros tcnicos que explican ms detalladamente este proceso. Sin embargo, no necesita una mayor explicacin sobre el proceso concreto de reubicacin para poder programar en Turbo C.

15

FUNCIONES GENERADAS POR EL USUARIO Las funciones son los bloques constructores de C y el lugar donde se da toda la actividad del programa. La forma general de una funcin es: especificador_de_tipo nombre_de_la_funcin(lista de parmetros) { cuerpo de la funcin } El especificador_de_tipo especifica el tipo de valor que devuelve la sentencia return de la funcin. El valor puede ser cualquier tipo vlido. Si no se especifica ningn tipo, el compilador asume que la funcin devuelve como resultado un entero. La lista de parmetros es la lista de nombres de variables separados por comas con sus tipos asociados que reciben los valores de los argumentos cuando se llama a la funcin. Una funcin puede no tener parmetros en cuyo caso la lista de parmetros contiene slo la palabra clave void. Funciones de entrada y salida Al contrario que muchos lenguajes, C++ no tiene facilidades incorporadas para manejar entrada o salida. En su lugar, se manejan por rutinas de bibliotecas. Las clases que C++ utiliza para entrada y salida se conocen como flujos. Un flujo (stream) es una secuencia de caracteres junto con una coleccin de rutinas para insertar caracteres en flujos (a pantalla) y extraer caracteres de un flujo (de teclado). Salida El flujo cout es el flujo de salida estndar que corresponde a stdout en C. Este flujo se deriva de la clase ostream construida en iostream. Uso de flujos para salida de caracteres. Si se desea visualizar el valor del objeto int llamado i, se escribe la sentencia: cout << i; El siguiente programa visualiza en pantalla una frase: #include <iostream.h> int main() { cout << Hola Mundo\n; } Las salidas en C++ se pueden conectar en cascada, con una facilidad de escritura mayor que en C. #include <isostrean.h>. int main() { int i; i = 1099; cout << El valor de i es << i << \n; } Otro programa que muestra la conexin en cascada es: #include <iostream.h> int main(){ int x = 45; double y = 496.125; char *c = "y es multiplicada por x=";

16

cout << c << y * x << "\n; }

Entrada La entrada se maneja por la clase istream. Existe un objeto predefinido istream, llamado cin, que se refiere al dispositivo de entrada estndar (el teclado). El operador que se utiliza para obtener un valor del teclado es el operador de extraccin >>. Por ejemplo, si i era un objeto int, se escribir: cin >> i; que obtiene un nmero del teclado y lo almacena en la variable i. Un programa simple que lee un dato entero y lo visualiza en pantalla es: #include <iostream.h> int main()i { int i; cin >> i; cout << i; } CPU cout Pantalla Al igual que en el caso de cout, se pueden introducir datos en cascada: #include <iostream.h> int main() { char c[60]; int x,y; cin >> c >> x >> y; cout << c << << x << << y << \n; }

Manipuladores Un mtodo fcil de cambiar la anchura del flujo y otras variables de formato es utilizar un operador especial denominado manipulador. Un manipulador acepta una referencia de flujo como un argumento y devuelve una referencia al mismo flujo. El siguiente programa muestra el uso de manipuladores especficamente para conversiones de nmero (dec, oct, y hex): #include <iostream.h> int main () { int i = 36; cout << dec << i << oct << i << << hex << i << \n; } La salida de este programa es: 36 44 24 Otro manipulador tpico es endl, que representa al carcter de nueva lnea (salto de lnea), es equivalente a \ n . El programa anterior se puede escribir tambin as: #include <iostream.h> int main () { int i = 36; cout << dec << i << oct << i << hex << i << endl; }

17

La sentencia return La sentencia return tiene dos usos importantes. Primero, fuerza una salida inmediata de la funcin en que se encuentra. O sea, hace que la ejecucin del programa vuelva al cdigo que llam la funcin. En segundo lugar, se puede utilizar para devolver un valor. A continuacin se examinan ambos usos. Funciones que regresan valores Hay dos formas en las que una funcin puede terminar su ejecucin y volver al sitio en que se llam. La primera ocurre cuando se ha ejecutado la ltima sentencia de la funcin y, conceptualmente, se encuentra la llave } del final de la funcin. (La llave realmente no aparece en el cdigo objeto, por supuesto, pero se puede pensar como si as afuera). Por ejemplo, esta funcin sencillamente imprime una cadena invertida en la pantalla: void imp_inversa(char *s) { register int t; for(t=strlen(s)-1; t>-1, t--) printf("%c", s[t]); } Una vez que ha impreso la cadena, la funcin no tiene nada ms que hacer y devuelve el control al lugar que la llam. Realmente, no hay muchas funciones que utilicen esta forma implcita de terminacin. La mayora de las funciones emplean la sentencia return para terminar la ejecucin, bien porque se tiene que devolver un valor o bien para simplificar el cdigo de la funcin y hacerlo ms eficiente permitiendo mltiples puntos de salida. Es importante recordar que una funcin puede tener varias sentencias return. especificador_de_tipo return void. return return void imp_inversa(char *s) { register int t; for(t=strlen(s)-1; t>-1, t--) printf("%c", s[t]); } return return. Lo que devuelve main( ) Cuando se usa una sentencia return en main( ), el programa devuelve un cdigo de terminacin al proceso de llamada (que generalmente es el sistema operativo). El valor devuelto debe ser un entero. Para muchos sistemas operativos, incluyendo DOS y OS/2, un valor de vuelta de 0 indica que el programa ha terminado normalmente. Todos los dems valores indican que se ha producido algn tipo de error.

ARGUMENTOS Si una funcin va a usar argumentos, debe declarar variables que acepten los valores de los argumentos. Estas variables se llaman parmetros formales de la funcin. Se comportan como otras variables locales dentro de la funcin, crendose al entrar en la funcin y destruyndose

18

al salir. Como muestra la siguiente funcin, la declaracin de parmetros aparece despus del nombre de la funcin y antes de la llave de apertura: /* devuelve 1 si c es parte de la cadena cad; 0 de otro modo */ est_en(char *.cad, char c) { while(*cad) if(*cad==c) return 1; else cad++; return 0; } Llamada por valor, llamada por referencia En general, se pueden pasar argumentos a las subrutinas de dos formas. El primer mtodo se denomina llamada por valor. Este mtodo copia el valor de un argumento en el parmetro formal de la subrutina. De esta forma, los cambios en los parmetros de la subrutina no afectan a las variables que se usan en la llamada. La llamada por referencia es la segunda forma de pasar argumentos a una subrutina. En este mtodo, se copia la direccin del argumento en el parmetro. Dentro de la subrutina se usa la direccin para acceder al argumento usado en la llamada. Esto significa que los cambios hechos a los parmetros afectan a la variable usada en la llamada a la subrutina. En C se utiliza la llamada por valor para pasar argumentos. Esto significa, en general, que no se puede alterar las variables usadas para llamar a la funcin. (Se ver ms adelante, sin embargo, cmo forzar una llamada por referencia usando un apuntador para permitir cambios en las variables de llamada). Es decir, que lo que se pasa a la funcin es una copia del valor del argumento y por lo tanto lo que ocurra dentro de la funcin no tiene efecto sobre la variable utilizada en la llamada. Creacin de una llamada por referencia Aunque el convenio de paso de parmetros en C es la llamada por valor, es posible causar una llamada por referencia pasando un apuntador al argumento. Como esto hace que se pase la direccin del argumento a la funcin, es posible cambiar el valor del argumento exterior de la funcin. Los apuntadores se pasan a las funciones como cualquier otro valor. Por supuesto, es necesario declarar los parmetros como tipo apuntador. Por ejemplo, la funcin inter( ), que intercambia el valor de sus dos argumentos enteros, muestra cmo: void inter(int *x, int *y) { int temp; temp = *x; /*salvar el valor de la direccin x */ *x = *y; /* poner y en x */ *y = temp; /* poner x en y */ } El operador * accede a la variable apuntada por su operando. De esta forma, se intercambian los contenidos de las variables usadas en la llamada a la funcin. Argumentos de main( ) Turbo C soporta tres argumentos de main( ). Los dos primeros son los argumentos tradicionales: argc y argv. Se trata de los nicos argumentos de main( ) que definen el estndar ANSI. Permiten pasar informacin al programa de C mediante argumentos de lnea de rdenes.

19

Un argumento de lnea de rdenes es informacin que sigue al nombre del programa en la lnea de rdenes del sistema operativo. Por ejemplo, cuando se compilan programas con la versin de lnea de rdenes de Turbo C, se introduce algo como: tcc nombre_del_programa Donde nombre_del_programa es el programa que se quiere compilar. El nombre del programa se pasa a Turbo C como un argumento. El parmetro argc contiene el nmero de argumentos de la lnea de rdenes y es un entero. Siempre vale uno por lo menos, ya que el nombre del programa cuenta como primer argumento. El parmetro argv es un apuntador a un arreglo de apuntadores a caracteres. Cada elemento del arreglo apunta a un argumento de la lnea de rdenes. Todos los argumentos de la lnea de rdenes son cadenas; cualquier nmero tendr que ser convertido por el programa al formato correcto. Por ejemplo, este sencillo programa imprime "Hola" y su nombre en la pantalla si se escribe directamente tras el nombre del programa: #include <stdio.h> main(int argc, char *argv[] ) { if(argc!=2) { printf("Ha olvidado escribir su nombre\n"); return 1; } printf("Hola %s",argv[1]); return 0; } Si se llama a este programa nombre y su nombre es Juan, para ejecutar el programa ha de introducir "nombre Juan". La salida del programa sera "Hola Juan". Por ejemplo, si estuviera utilizando la unidad A, vera: A>nombre Juan Hola Juan A> Tras ejecutar nombre. Cada argumento de la lista de rdenes debe estar separado por un espacio. Las comas, puntos y comas, y similares no se consideran separados. Por ejemplo, corre Vuela corre est formado por tres cadenas, mientras que Luis,Juan,Jess es una sola cadena -las comas no son separadores vlidos. Si se quiere pasar una cadena que contiene espacios o tabulaciones como un slo argumento, se debe encerrar entre dobles comillas. Por ejemplo, para Turbo C, lo siguiente es slo un argumento: "esto es una prueba" Es importante declarar argv adecuadamente. Un mtodo usual es char *argv[ ]; Los corchetes vacos indican que es un arreglo de longitud indeterminada. Ahora se puede acceder a los argumentos individualmente indexado argv. Por ejemplo, argv[0] apunta a la primera cadena, que es siempre el nombre del programa; argv[1] apunta al primer argumento, y as sucesivamente.

20

Adems de argc y argv, Turbo C permite tambin un tercer argumento de lnea de rdenes denominado env. El parmetro env permite al programa acceder a la informacin de entorno asociada al sistema operativo. El parmetro env debe seguir a argc y argv y ser declarado as: char *env[ ] Como puede ver, env se declara igual que argv. Al igual que argv, se trata de un apuntador a un arreglo de cadenas. Cada cadena es una cadena de entorno definida por el sistema operativo. El parmetro env no tiene asociado un parmetro similar a argc que indique al programa cuntas cadenas de entorno hay. En lugar de ello, la ltima cadena de entorno ser nula. Aunque en un programa no se usan argc y argv, deben estar presentes en la lista de parmetros. Turbo C no conoce realmente los nombres de los parmetros. En cambio, su uso viene determinado por su orden de declaracin en la lista de parmetros. De hecho, se puede dar a los parmetros el nombre que se quiera. Como argc, argv y env son los nombres tradicionales, es mejor usarlos de forma que alguien que lea el programa pueda reconocerlos inmediatamente como los argumentos de main( ). Es bastante comn que un programa tenga que utilizar el valor de una cadena de entorno concreta. Por ejemplo, bajo DOS, conociendo el valor de la cadena PATH, el programa puede utilizar los encaminamientos de bsqueda que estn definidos en ese momento. El siguiente programa muestra cmo detectar la cadena que define los caminos de bsqueda implcitos. Usa la funcin de la biblioteca estndar strstr( ), cuyo prototipo es: char *strstr(const char *cad1, const char *cad2); La funcin strstr( ) busca en la cadena apuntada por cad1 la primera ocurrencia de la cadena apuntada por cad2. Si la encuentra, devuelve un apuntador a la primera ocurrencia. Si no existe ninguna correspondencia, strstr( ) devuelve un nulo.

/* Este programa busca entre las cadenas de entorno una que contenga el encaminamiento (PATH) actual. */ #include <stdio.h> #include <string.h> main(int argc, char *argv[ ], char *env[ ]) { int t; for(t=0; env[y]; t++) { if(strstr(env[t], "PATH")) printf("%s\n", env[t]); } return 0; }

Funciones que devuelven valores no enteros Cuando no est declarado explcitamente el tipo de una funcin, automticamente por defecto el tipo es int. Para muchas funciones este tipo implcito vale. Sin embargo, cuando es necesario devolver un tipo de dato diferente, el proceso requiere dos pasos: 1. Hay que dar a la funcin un especificador de tipo explcito. 2. El tipo de la funcin debe estar identificado antes de hacer la primera llamada. Esta es la nica forma en que Turbo C puede generar cdigo correcto para funciones que devuelvan valores no enteros.

21

Las funciones se pueden declarar para que devuelvan cualquier tipo de dato vlido en C. El mtodo de declaracin es similar al de declaracin de variables: el especificador de tipo precede al nombre de la funcin. El especificador de tipo le dice al compilador qu tipo de datos va a devolver la funcin. Esta informacin es crtica para que el programa se ejecute correctamente, porque tipos de datos deferentes tienen tamaos y representaciones internas diferentes. Antes de que se pueda usar una funcin que devuelva un tipo no entero, se debe hacer saber su tipo al resto del programa. La razn es que, a menos que se indique lo contrario, Turbo C asume que una funcin va a devolver un valor entero. Si el programa llama a una funcin que devuelva un tipo diferente antes de la declaracin de esa funcin, Turbo C genera errneamente el cdigo de la llamada a la funcin. En general, la forma de indicar a Turbo C el tipo de vuelta de una funcin involucra el uso de una referencia anticipada. Una referencia anticipada declara el tipo de vuelta de una funcin, pero no define realmente lo que la funcin hace. La definicin de la funcin aparece en algn otro lugar del programa. El mtodo tradicional de informar a Turbo C sobre el tipo de vuelta de una funcin, simplemente, declara ese tipo de vuelta y el nombre de la funcin al principio del programa. Por ejemplo, para indicar a Turbo C que una funcin denominada mifunc( ) devuelve un valor double, se pondra la siguiente declaracin cerca del principio del programa: double mifunc( );

Incluso aunque mifunc( ) tenga parmetros, en este mtodo no se muestra ninguno entre los parntesis. Cuando Turbo C lee esa lnea, sabe que mifunc( ) devuelve un double y genera el cdigo de vuelta adecuado. Por ejemplo, el que sigue es un programa correcto (aunque anticuado): #include <stdio.h> #include <math.h> double mifunc( ); /* declaracin anticipada de mifunc( ) */ main(void) { printf("%1f", mifunc(10.0)); return 0; } double mifunc(double x) { return sqrt(x) * 2.0; /* raz cuadrada de x * 2 */ }

SENTENCIAS Un programa en C++ consta de una secuencia de sentencias. Existen diversos tipos de sentencias. El punto y coma se utiliza como elemento terminal de cada sentencia. Sentencia de declaracin Se utilizan para establecer la existencia y, opcionalmente, los valores iniciales de objetos identificados por nombre. nombreTipo identificador, ; nombreTipo identificador = expresin, ; const NombreTipo identificador = expresin, ; Algunas sentencias vlidas en C++ son: char cl;

22

int p, q = 5, r =a + b; //suponiendo que a y b han sido declaradas e inicializadas antes const double IVA = 16.0; Sentencias expresin Las sentencias de expresiones hacen que la expresin sea evaluada. Su formato general es: expresin; Ejemplo: n++; 425; // legal, pero no hace nada a + b; // legal, pero no hace nada n = a < b || b != 0; a += b = 3; // sentencia compleja C++ permite asignaciones mltiples en una sentencia. m = n + (p=5) equivale a p=5; m = n + p; Sentencias compuestas Una sentencia compuesta es una serie de sentencias encerradas entre llaves. Las sentencias compuestas tienen el formato: { sentencia sentencia sentencia .... } Las sentencias encerradas pueden ser cualquiera: declaraciones, expresiones, sentencias compuestas, etc. Un ejemplo es: int i = 5; double x = 3.14, y = -4.25; int j = 4 - i x = 4.5 * (x - y); El cuerpo de una funcin C++ es siempre una sentencia compuesta.

23

ESTRUCTURAS DE FLUJO PROGRAMATICO Sentencias de control de programa If. La forma general de la sentencia if es

if (expresin) sentencia; else sentencia; Donde sentencia puede ser una sentencia simple o un bloque de sentencias. (Recuerde que en C un bloque es un grupo de sentencias rodeadas por llaves). La clusula else es opcional. La forma general del if con bloques de sentencias es if (expresin){ secuencia de sentencias } else { secuencia de sentencias } Si la expresin es cierta (cualquier valor que no sea 0), se ejecuta la sentencia o el bloque de sentencias que constituye el objetivo del if; en cualquier otro caso se ejecuta la sentencia o el bloque de sentencias que constituyen el objetivo del else. La escala if-else-if Una construccin comn en programacin es la escala if-else-if. Su forma general es: if (expresin) sentencia; else if (expresin) sentencia; else if (expresin) sentencia; . . . else sentencia; Las condiciones se evalan de arriba abajo. Tan pronto como se encuentra una condicin cierta, se ejecuta la sentencia asociada con ella y se pasa por alto el resto de la escala. Si ninguna de las condiciones es cierta, se ejecuta el else final. Switch Aunque la escala if-else-if puede realizar pruebas multicamino, es poco elegante. Por esta razn, C incorpora una sentencia de decisin de ramificacin mltiple denominada switch. Esta sentencia compara sucesivamente una variable con una lista de constantes enteras o de caracteres. Cuando se encuentra una correspondencia, se ejecuta una sentencia o bloque de sentencias. La forma general de la sentencia switch es:

24

switch (variable){ case constante1: secuencia de sentencias break; case constante2: secuencia de sentencias break; case constante3: secuencia de sentencias break; . . . default: secuencia de sentencias } Donde la sentencia default se ejecuta si no se encuentra ninguna correspondencia. La parte default es opcional y, si no aparece, no se lleva a cabo ninguna accin al fallar todas las pruebas. Cuando se encuentra una correspondencia, se ejecuta la secuencia de sentencias asociada con ese case, hasta que se encuentra la sentencia break o, en el caso de default (o el ltimo case si no hay default), el final de la sentencia switch. Hay tres cosas importantes que se deben saber sobre la sentencia switch: 1. La sentencia switch se diferencia de la sentencia if en que switch slo puede comprobar la igualdad, mientras que if puede evaluar expresiones relacinales o lgicas. 2. No puede haber dos constantes case en el mismo switch que tengan los mismos valores. Por supuesto, una sentencia switch contenida en otra sentencia switch puede tener constantes case que sean iguales. 3. Si se utilizan constantes de tipo carcter en la sentencia switch, se convierten automticamente a sus valores enteros. Tcnicamente, las sentencias break dentro de la sentencia switch son opcionales. Se utilizan para finalizar la secuencia de sentencias asociada con cada constante. Si se omite la sentencia break, la ejecucin contina en la siguiente sentencia case hasta que se alcanza una sentencia break o el final del switch. For La forma general de la sentencia for es: for(inicializacin; condicin; incremento) sentencia; El bucle for permite muchas variaciones, pero existen tres partes principales: 1. La inicializacin normalmente es una sentencia de asignacin que se utiliza para iniciar la variable de control del bucle. 2. La condicin es una expresin relacional que determina cundo finaliza el bucle. 3. El incremento define cmo cambia la variable de control cada vez que se repite el bucle. Estas tres secciones principales deben estar separadas por punto y coma. El bucle for contina ejecutndose mientras que la condicin sea cierta. Una vez que la condicin se hace falsa, la ejecucin del programa sigue por la sentencia siguiente al for. Variaciones del bucle for Una de las variaciones ms comunes utiliza el operador coma para permitir dos o ms variables de control del bucle. (Recuerde que el operador coma se utiliza para encadenar un nmero de expresiones de la forma "hacer esto y lo otro". Por ejemplo, las variables x e y controlan el siguiente bucle, y ambas son inicializadas dentro de la sentencia for. for(x=0, y=0; x+y<10; ++x) {

25

scanf("%d", &y); . . . } Las comas separan las dos sentencias de inicializacin. Cada vez que se incrementa x, el bucle se repite e y toma el valor del teclado. Ambas, x e y deben contener el valor correcto para que el bucle for termine. Es necesario que y se inicialice a 0, es decir, que su valor est definido antes de la primera evaluacin de la expresin condicional. Si y no estuviera definida, es posible que pudiera contener un 10, haciendo que la prueba condicional fuera falsa e impidiendo la ejecucin del bucle. Otra variacin interesante del bucle for es la creacin de un bucle infinito. Como no se necesita ninguna de las tres expresiones que constituyen el bucle for, se puede conseguir que el bucle no tenga fin dejando la expresin condicional vaca. Por ejemplo: for(; ;) printf(" este bucle estar siempre ejecutndose. \n"); Realmente, la construccin for(;;) no garantiza un bucle infinito, ya que la sentencia de C break, cuando se encuentra en cualquier lugar dentro del cuerpo de un bucle, da lugar a la terminacin inmediata. El control del programa sigue en el cdigo que sigue al bucle, como se muestra a continuacin: c = '\0'; for(;;) { c = getchar( ); /* obtener un carcter */ if(c=='A') break; /* salir del bucle */ } printf("ha pulsado una A"); Este bucle se ejecuta hasta que se pulsa la tecla A. El bucle while El segundo bucle disponible en C es el bucle while. Su forma general es: while (condicin) sentencia; donde sentencia es una sentencia vaca, una sentencia simple o un bloque de sentencias que se repiten. La condicin puede ser cualquier expresin, y cualquier valor distinto de 0 es cierto. El bucle itera mientras la condicin es cierta. Cuando la condicin se hace falsa, el control del programa pasa a la lnea siguiente al cdigo del bucle. El siguiente ejemplo muestra una rutina de entrada por teclado, que se repite hasta que se pulsa la letra A: void esperar_caracter(void) { char c; c = '\0'; /* inicializar c */ while(c != 'A') c = getchar( ); }

26

Do/while A diferencia de los bucles for y while, que analizan la condicin del bucle al principio del mismo, el bucle do/while analiza la condicin al final del bucle. Esto significa que el bucle do/while siempre se ejecuta al menos una vez. La forma general del bucle do/while es: do { secuencia de sentencias; } while(condicin); Aunque las llaves no son necesarias cuando slo hay una sentencia, se utilizan normalmente para evitar confusiones (al lector, no al compilador) con el while. Break La sentencia break tiene dos usos. Se puede usar para finalizar un case en una sentencia switch, lo que ya se ha explicado. Tambin se puede usar para forzar la terminacin inmediata de un bucle, saltando la evaluacin condicional normal del ciclo. Este uso se examina a continuacin. Cuando se encuentra la sentencia break dentro de un bucle, el bucle finaliza inmediatamente y el control sigue en la sentencia que sigue al bucle. Exit( ) Se puede salir anticipadamente de un programa usando la funcin exit( ) de la biblioteca estndar. Como la funcin exit( ) da lugar a la terminacin inmediata del programa, forzando la vuelta al sistema operativo, su uso la convierte especficamente en un dispositivo de control de programa, y muchos programadores de C se basan en ella. La forma general de la funcin exit( ) es sta: void exit(int estado); Usa el archivo de cabecera stdlib.h. El valor de estado se devuelve al sistema operativo. Generalmente se usa un cero como argumento de exit( ) para indicar que se trata de una terminacin normal del programa. Se utilizan otros argumentos para indicar algn tipo de error que pueda ser accedido por un proceso de mayor nivel. Los programadores utilizan frecuentemente exit( ) cuando no se satisface una condicin obligatoria en la ejecucin de un programa. Por ejemplo, imagine un juego de computadora que necesita una tarjeta de grficos en color. La funcin main( ) de este juego puede ser algo parecida a sta: #include <stdlib.h> main(void) { if (!tarjeta_color( ) ) exit(1); jugar( ); return 0; } Donde tarjeta_color( ) es una funcin definida por el usuario que devuelve cierto si encuentra la tarjeta de grficos en color. Si no se encuentra en el sistema, tarjeta_color( ) devuelve falso y el programa finaliza. Continue La sentencia continue funciona de una forma algo similar a break. Sin embargo, en vez de forzar la terminacin, continue fuerza una nueva iteracin del bucle y salta cualquier cdigo que exista entre medias. Por ejemplo, la siguiente rutina muestra slo nmeros positivos:

27

do { scanf("%d", &num); if(x<0) continue; printf("%d", x); } while(x!=100);

Para los bucles while y do/while, una sentencia continue hace que el control del programa pase a la prueba condicional y contine el proceso de iteracin. Para el bucle for, hace que se ejecute la parte de incremento del bucle, seguida de la prueba condicional, y finalmente hace que bucle contine. El ejemplo anterior podra cambiarse para hacer que slo se impriman 100 nmeros, tal como se muestra a continuacin: for(t=0; t<0; ++t) { scanf("%d", &num); if(x<0) continue; printf("%d", x); } Sentencia nula La sentencia nula se representa por un punto y coma, y no hace ninguna accin. char cad[80]=Cazorla; int i; for (i = 0; cad[i] != \0; i++); Sentencia return La sentencia return detiene la ejecucin de la funcin actual y devuelve el control a la funcin llamada. Su sintaxis es: return expresin; Donde el valor de expresin se devuelve como el valor de la funcin.

28

ESTRUCTURAS DE DATOS: ARREGLOS Y APUNTADORES Un arreglo es una coleccin de variables del mismo tipo que se denominan por un nombre comn. A un elemento especfico de un arreglo se accede mediante un ndice. En C todos los arreglos constan de posiciones de memoria contiguas. La direccin ms baja corresponde al primer elemento y la direccin ms alta al ltimo elemento. Los arreglos pueden tener de una a varias dimensiones.

ARREGLOS UNIDIMENSIONALES La forma general de declaracin de un arreglo unidimensional es: tipo nombre_de_variable[tamao]; En C los arreglos tienen que declararse explcitamente para que as el compilador pueda reservar espacio en memoria para ellos. Aqu, tipo declara el tipo base del arreglo, que es el tipo de cada elemento del arreglo. El valor de tamao indica cuntos elementos mantendr el arreglo. Para un arreglo unidimensional, el tamao total del arreglo en bytes se calcula de la siguiente forma: bytes totales = sizeof(tipo base) * nmero de elementos Todos los arreglos tienen el 0 como ndice de su primer elemento. Por tanto, cuando se escribe char p[10]; se est declarando un arreglo de caracteres que tiene diez elementos, desde p[0] hasta p[9]. Por ejemplo, el siguiente programa carga un arreglo de enteros con los nmeros desde el 0 hasta el 9: #include <stdio.h> main(void) { int x[10]; /* esto reserva 10 elementos enteros */ int t; for(t=0; t<10; ++t) x[t] = t; for(t=0; t<10; ++t) printf("%d", x[t]); return 0; } C no comprueba los lmites de los arreglos. Se puede sobrepasar cualquier extremo de un arreglo y escribir en alguna otra variable de datos o incluso en el cdigo del programa. Como programador, es tarea suya proporcionar una comprobacin de lmites cuando sea necesario. Por ejemplo, asegrese de que los arreglos de caracteres que acepten entradas de caracteres sean suficientemente largos para aceptar la mayor entrada. Los arreglos unidimensionales son, en esencia, listas de informacin del mismo tipo. Por ejemplo, la figura muestra cmo aparece un arreglo a en memoria si comienza en la posicin de memoria 1000 y es declarado como: char a[7]; ____________________________________________________ a[0] a[1] a[2] a[3] a[4] a[5] a[6] 1000 1001 1002 1003 1004 1005 1006 ____________________________________________________

Paso de arreglos unidimensionales a funciones Para pasar arreglos unidimensionales a funciones, en la llamada a la funcin se pone el nombre del arreglo sin ndice. Esto pasa la direccin del primer elemento del arreglo a la

29

funcin. En C no se puede pasar un arreglo completo como argumento a una funcin; en su lugar, se pasa automticamente un apuntador. Por ejemplo, el fragmento que sigue pasa la direccin de i a func1( ): main(void) { int i[10]; func1(i); . . . } Si una funcin recibe un arreglo unidimensional, se puede declarar el parmetro formal como un apuntador, como un arreglo delimitado o como un arreglo no delimitado. Por ejemplo, para recibir i en una funcin llamada func1( ), se puede declarar func1( ) como func1(int *x) /*apuntador */ { . . . } o como func1(int x[10]) /* arreglo delimitado */ { . . . } o finalmente como func1(int x[ ]) /* arreglo no delimitado */ { . . . } El resultado de los tres mtodos de declaracin es idntico porque cada uno le indica al compilador que se va a recibir un apuntador a carcter. En la primera declaracin se usa realmente un apuntador; en la segunda se emplea la declaracin estndar de arreglo. En la ltima declaracin, la versin modificada de la declaracin del arreglo simplemente especifica que se va a recibir un arreglo de tipo int de cierta longitud. Como se puede ver que, en lo que a la funcin se refiere, realmente no importa la longitud del arreglo porque C no comprueba los lmites. De hecho, por lo que al compilador se refiere, func1(int x[32]) { . . . } Tambin sirve, porque Turbo C genera cdigo que instruye a func1( ) para recibir un apuntador -realmente no crea un arreglo de 32 elementos. Cadenas El uso ms comn de los arreglos unidimensionales es como cadenas de caracteres. Aunque C no define un tipo cadena, incluye algunas de las funciones de manipulacin de cadenas ms

30

potentes de todos los lenguajes. En C, una cadena se define como un arreglo de caracteres de cualquier longitud que termina en un carcter nulo. Un carcter nulo se especifica como '\0' y es un cero. Por esta razn, para declarar arreglos de caracteres es necesario que sean de un carcter ms que la cadena ms larga que pueda contener. Por ejemplo, para declarar un arreglo s que contenga una cadena de 10 caracteres, se escribira char s[11]; Esto dejar sitio para el carcter nulo del final de la cadena. Aunque C no define un tipo de datos de cadenas, permite disponer de constantes de cadena. Una constante de cadena es una lista de caracteres encerrada entre dobles comillas. Por ejemplo, aqu tenemos dos constantes de cadena: "hola, qu tal" "esto es una prueba" No es necesario aadir explcitamente el carcter nulo al final de las constantes de cadena; el compilador de C lo hace automticamente.

ARREGLOS BIDIMENSIONALES Turbo C soporta arreglos multidimensionales. La forma ms simple de un arreglo multidimensional es el arreglo bidimensional. Un arreglo bidimensional es esencialmente un arreglo de arreglos unidimensionales. Los arreglos bidimensionales se declaran utilizando la siguiente forma general: tipo nombre_del_arreglo[tamao de la 2 dimensin][tamao de la 1 dimensin]; Por lo tanto, para declarar un arreglo d de enteros bidimensional de tamao 10,20, se escribir: int d[10][20] A diferencia de la gran mayora de los lenguajes de computadoras, que utilizan comas para separar las dimensiones del arreglo, C coloca cada dimensin en su propio conjunto de corchetes. De forma similar, para acceder al punto 3,5 del arreglo d, se escribir: d[3][5] El siguiente ejemplo carga un arreglo bidimensional con los nmeros del 1 al 12 y luego los imprime en la pantalla: #include <stdio.h> main(void) { int t, i, num[3][4]; for(t=0; t<3; ++t) for(i=0; i<4; ++i) num[t][i] = (t*4)+i+1; /* ahora mostrarlos */ for(t=0; t<3; ++t) { for(i=0; i<4; ++i) printf("%d", num[t][i]); printf("\n"); } return 0; } En este ejemplo num[0][0] contiene el valor 1, num[0][1] contiene el valor 2, num[0][2] el valor 3, y as sucesivamente. El valor de num[2][3] es 12. Los arreglos bidimensionales se almacenan en matrices fila-columna, en las que el primer ndice indica la fila y el segundo indica la columna. Esto significa que el ndice de ms a la

31

derecha cambia ms rpido que el de ms a la izquierda cuando accedemos a elementos del arreglo en el orden en que realmente se han almacenado en memoria. Cuando se utiliza un arreglo bidimensional como argumento de una funcin, realmente slo se pasa un apuntador al primer elemento. Sin embargo, la funcin que recibe un arreglo bidimensional como parmetro tiene que definir al menos la longitud de la primera dimensin, ya que el compilador necesita saber la longitud de cada fila para manejar los ndices del arreglo correctamente. Por ejemplo, una funcin que recibe un arreglo entero bidimensional de dimensiones 5,10 se declara as: func1(int x[] [10]) { . . . } Se puede especificar la primera dimensin tambin, pero no es necesario. El compilador necesita conocer la segunda dimensin para poder trabajar con declaraciones como x[2][4] dentro de la funcin. Si la longitud de las filas est sin definir, entonces sera imposible saber dnde empieza la siguiente fila. Arreglos multidimensionales C permite arreglos de ms de dos dimensiones. La forma general de declaracin de un arreglo multidimensional es: tipo nombre[tamaoN]...[tamao2][tamao1]; Los arreglos de ms de tres dimensiones no se utilizan a menudo por la cantidad de memoria que se requiere para almacenarlos. El almacenamiento para todos los arreglos globales se asigna de forma permanente al principio de la ejecucin del programa. Por ejemplo, un arreglo de caracteres de cuatro dimensiones con dimensiones 10, 6, 9, 4 requiere 10 x 6 x 9 x 4, 2.160 bytes. Si el arreglo contiene enteros de 2 bytes, se necesitarn 4.320 bytes de memoria. Si el arreglo fuera de tipo double (suponiendo 8 bytes por cada uno), entonces se necesitarn 34.560 bytes. El almacenamiento requerido aumenta exponencialmente con el nmero de dimensiones. ARREGLOS Y APUNTADORES Los operadores de apuntador & y * Un apuntador es la direccin de memoria de una variable. Una variable apuntador es una variable especficamente declarada para contener un apuntador hacia un valor de su tipo especfico. El conocer la direccin de una variable puede ser una gran ayuda en ciertos tipos de rutinas. En C los apuntadores tienen dos funciones principales: 1. Pueden proporcionar una rpida forma de referenciar los elementos de un arreglo. 2. Permiten a las funciones de C modificar los parmetros de llamada. El primer operador de apuntadores es &, un operador monario que devuelve la direccin de memoria del operando. Recuerde que un operador monario es aquel que slo requiere un operador. Por ejemplo, m = &cont; Coloca en m la direccin de memoria de la variable cont. Esta es la direccin de la posicin interna en la computadora de la variable. No tiene nada que ver con el "valor" de cont. Se puede pensar en & como "la direccin de". Por tanto, la sentencia anterior de asignacin significa "m recibe la direccin de cont".

32

El segundo operador de apuntadores es *, que es el complementario de &. Es un operador monario que devuelve el valor de la variable ubicada en la direccin que se especifica. En C los apuntadores y los arreglos estn estrechamente relacionados. Por ejemplo, un nombre de arreglo sin ndice es un apuntador al primer elemento del arreglo. En este arreglo, char p[10]; las sentencias que siguen son idnticas: p &p[0] Puesto de otro modo, p == &p[0] evala a cierto porque la direccin del primer elemento del arreglo es la misma que la direccin del arreglo. Cualquier variable apuntador puede manejarse a travs de ndices como si estuviera declarada como un arreglo del tipo base del apuntador. Por ejemplo: int *p, i[10]; p = i; p[5] = 100; /* asignacin usando ndice */ *(p+5) = 100; /* asignacin usando aritmtica de apuntadores */ Ambas sentencias de asignacin ponen el valor 100 en el sexto elemento de i. La primera sentencia indexa p; la segunda utiliza la aritmtica de apuntadores. De ambas maneras el resultado es el mismo. Este proceso se puede aplicar tambin a los arreglos de dos o ms dimensiones. Por ejemplo, suponiendo que a es un arreglo de enteros de 10 por 10, las dos sentencias que siguen son equivalentes: a &a[0][0] Por tanto, al elemento 0,4 de a se puede hacer referencia mediante ndices a[0][4], o mediante el apuntador, *((*a)+4). De forma similar, el elemento 1,2 es o bien a[1][2] o bien *((*a)+12). En general, para cualquier arreglo bidimensional

a[j][k] es equivalente a *((*a)+(j * longitud fija) +k) La razn por la que a veces se utilizan los apuntadores para acceder a los arreglos es que la aritmtica de los apuntadores es frecuentemente ms rpida que la especificacin de los ndices. La ganancia en velocidad usando apuntadores es mayor cuando el acceso al arreglo es puramente secuencial. En esta situacin, se puede incrementar o decrementar el apuntador con los extremadamente eficientes operadores de incremento y de decremento de C. No as, si se va a acceder de forma aleatoria. Arreglos asignados dinmicamente En muchas situaciones de programacin es imposible saber cmo de grande se necesita un arreglo. En esas situaciones no es posible usar un arreglo predefinido, ya que en ese caso las dimensiones quedan establecidas en tiempo de compilacin y no se pueden cambiar durante la ejecucin. La solucin est en crear un arreglo dinmico. Un arreglo dinmico usa memoria de la regin de memoria libre denominada el montn, y es accedido indexando un apuntador a esa

33

memoria. (Recuerde que cualquier apuntador puede ser indexado como si fuera una variable arreglo). En C se puede asignar y liberar memoria dinmicamente usando las rutinas de la biblioteca estndar malloc( ), que asigna memoria y devuelve un apuntador void* al comienzo de esa memoria, y free( ), que devuelve al montn memoria previamente asignada para que pueda ser reutilizada. Inicializacin de arreglos C permite la inicializacin de arreglos globales y locales en el momento de declararlos. La forma general de inicializacin de un arreglo, que aparece a continuacin, es similar a la de otras variables: especificador_de_tipo nombre_de_arreglo[tamao1]...[tamaoN] = {lista_de_valores}; La lista_de_valores es una lista de constantes separadas por comas cuyo tipo es compatible con especificador_de_tipo. La primera constante se coloca en la primera posicin del arreglo, la segunda constante en la segunda posicin, y as sucesivamente. La ltima entrada de la lista no va seguida de coma. Fjese en que un punto y coma sigue a }. En el ejemplo que sigue se inicializa un arreglo de enteros de 10 elementos con los nmeros del 1 a10: int i[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; Esto significa que i[0] tiene el valor 1 e i[9] tiene el valor 10. Los arreglos de caracteres que contienen cadenas permiten una inicializacin abreviada de la forma: char nombre_de_arreglo[tamao] = "cadena" En esta forma de inicializacin, se aade automticamente el terminador nulo al final de la cadena. Por ejemplo, este fragmento de cdigo inicializa cad con la frase "hola". char cad[5] = "hola"; El cdigo anterior produce el mismo resultado que si se escribe char cad[5] = {'h', 'o', 'l', 'a', '\0'}; Observe que en esta versin se debe incluir explcitamente el terminador nulo. Debido a que todas las cadenas en C terminan con un nulo, se debe estar seguro de que el arreglo que se declara es suficientemente grande para incluirlo. Esto es por lo que cad es de cinco caracteres de longitud aunque "hola" tiene slo cuatro caracteres. Cuando se utiliza una cadena como constante (como en el mtodo anterior), el compilador automticamente proporciona la terminacin nula. Inicializacin de arreglos indeterminados Imagine que est utilizando una inicializacin de arreglo para construir una tabla de mensajes de error como la que se muestra aqu: char e1[18] = "error de lectura\n"; char e2[20] = "error de escritura\n"; char e3[30] = "no se puede abrir el archivo\n"; Como podra pensar, es tedioso contar los caracteres de cada mensaje manualmente para determinar la dimensin correcta del arreglo. Es posible hacer que C calcule automticamente las dimensiones de los arreglos utilizando arreglos indeterminados. Si en una sentencia de inicializacin de un arreglo no se especifica el tamao del arreglo, el compilador de C automticamente crea un arreglo suficientemente grande para contener todos los inicializadores presentes. Utilizando este mtodo, la tabla de mensajes queda como: char e1[ ] = "error de lectura\n"; char e2[ ] = "error de escritura\n"; char e3[ ] = "no se puede abrir el archivo\n";

34

Devolucin de apuntadores Aunque las funciones que devuelven apuntadores se manejan de la misma forma que cualquier otro tipo de funcin, hay que comentar unos cuantos conceptos importantes. Los apuntadores a variables no son ni enteros, ni enteros sin signo. Son las direcciones de memoria de un cierto tipo de datos. La razn de esta distincin est en el hecho de que la aritmtica de los apuntadores depende del tipo base -esto es, si se incrementa un apuntador a un entero, ste contiene un valor que es 2 unidades mayor que el valor anterior (asumiendo palabras de 2 bytes)-. En general, cada vez que se incrementa un apuntador, ste apunta al siguiente elemento de datos de su tipo. Como cada dato puede ser de longitud diferente, el compilador debe saber a qu tipo de dato est apuntando el apuntador para poder hacer que apunte al siguiente elemento. Declaracin de apuntadores Los apuntadores se declaran utilizando el operador unitario*. En las sentencias siguientes se declaran dos variables: n es un entero, y p es un apuntador a un entero. int n; // es un tipo de dato entero int *p; // p es un apuntador a un entero Una vez declarado un apuntador, se puede fijar la direccin o posicin de memoria del tipo al que apunta. p = &n; //p se fija a la direccin de a Un apuntador se declara escribiendo: NombreTipo * Nombre Variable Una vez que se ha declarado un apuntador p, el objeto al que apunta se escribe *p y se puede tratar como cualquier otra variable de tipo NombreTipo. int *p, *q, o; // dos apuntadores a int, y un int *P = 101; // *p a 101 *q= n + *p; // *q a n mas el contenido de lo que apunta p C++ trata los apuntadores a tipos diferentes como tipos diferentes, int *ip; double *dp; Los apuntadores ip y dp son incompatibles, de modo que es un error escribir: dp = ip; Se pueden, sin embargo, realizar asignaciones entre contenidos, ya que se realizara una conversin explcita de tipos: *dp =ip Existe un apuntador especial (nulo) que se suele utilizar con frecuencia en programas C++. El apuntador NULL tiene un valor cero, que lo diferencia de todas las direcciones vlidas. El conocimiento nos permite comprobar si un apuntador p es el apuntador NULL evaluando la expresin (p==0). Los apuntadores NULL se utilizan slo como seales de que ha sucedido algo. En otras palabras, si p es un apuntador NULL, es incorrecto referenciar *p. Apuntadores a arreglos A los arreglos se accede a travs de los ndices: int lista [5]; lista [3] = 5;

35

Sin embargo, tambin se puede acceder a travs de apuntadores: int lista [5]; //arreglo de 5 elementos int *ptr; //apuntador a entero ptr = lista; //fija apuntador al primer elemento del arreglo ptr =+ 3; //suma 3 a por; ptr apunta al 4to elemento *ptr = 5; //establece el 4to elemento a 5. El nombre de un arreglo se puede utilizar tambin como si fuera un apuntador al primer elemento del arreglo. double a [10]; double *p = a; // p y a se refieren al mismo arreglo 0123456789 Este elemento se puede llamar por. Este elemento se puede llamar por: a[10], p ;o bien p[0] a[6], *(p + 6): o bien p[0]. Si nombre apunta al primer elemento del arreglo, entonces nombre + 1 apunta al segundo elemento. El contenido de lo que se almacena en esa posicin se obtiene por la expresin:*(nombre + 1). Aunque las funciones no pueden modificar sus argumentos, si un arreglo se utiliza como un argumento de una funcin, la funcin puede modificar el contenido del arreglo. Apuntadores a estructuras Los apuntadores a estructuras son similares y funcionan de igual forma que los apuntadores a cualquier otro tipo de dato. struct familia { char marido[100]; char esposa[100]; char hijo[100]; } familia Mackoy; //Mackoy estructura de tipo familia struct familia *p; //p, un apuntador a familia p = &Mackoy; //p, contiene direccin de mackoy strcpy (p->marido,Luis Mackoy); //inicializacin strcpy (p ->esposa, Vilma Conzalez); //inicializacin strcpy (p ->hijo, Luisito Mackoy); //inicializacin Apuntadores a objetos constantes Cuando se pasa un apuntador a un objeto grande, pero se trata de que la funcin no modifique el objeto (por ejemplo, el caso de que slo se desea visualizar el contenido de un arreglo), se declara el argumento correspondiente de la funcin como apuntador a un objeto constante. La declaracin: const NombreTipo *v establece v como un apuntador a un objeto que no puede ser modificado. Un ejemplo puede ser: void Visualizar(const ObjetoGrande *v); Apuntadores a void El tipo de dato void representa un valor nulo. En C++, sin embargo, el tipo de apuntador void se suele considerar como un apuntador a cualquier tipo de dato. La idea fundamental que subyace en el apuntador void en C++ es la de un tipo que se puede utilizar adecuadamente para acceder a cualquier tipo de objeto, ya que es ms o menos independiente del tipo. Un ejemplo ilustrativo de la diferencia de comportamiento en C y C++ es el siguiente segmento de programa:

36

int main() { void *vptr; int *iptr; vptr = iptr; iptr = vptr; //Incorrecto en C++, correcto en C iptr = (int *) vprr; //Correcto en C++ } Apuntadores y cadenas Las cadenas en C++ se implementan como arreglos de caracteres, como constantes de cadena y como apuntadores a caracteres. Constantes de cadena Su declaracin es similar a char *cadena = Mi profesor; o bien su sentencia equivalente char varcadena[ ] = Mi profesor; Si desea evitar que la cadena se modifique, aada const a la declaracin: const char *varcadena = M profesor; Los puntos a cadena se declaran: char s[1] o bien: char *s Apuntadores a cadenas Los apuntadores a cadenas no son cadenas. Los apuntadores que localizan el primer elemento de una cadena almacenada. char *varCadena; const char *cadenafija; Consideraciones prcticas Todos los arreglos en C++ se implementan mediante apuntadores: char cadenal[l6] = Concepto Objeto; char * cadena2 = cadenal; Las declaraciones siguientes son equivalentes y se refieren al carcter C: cadenal[0] = a; char car = a; cadena1[0] = car; Aritmtica de apuntadores Dado que los apuntadores son nmeros (direcciones), pueden ser manipulados por los operadores aritmticos. Las operaciones que estn permitidas sobre apuntadores son: suma, resta y comparacin. As, si las sentencias siguientes se ejecutan en secuencia: char *p; // p, contiene la direccin de un carcter char a[l0]; // arreglo de diez caracteres p = &a[0]; // p, apunta al primer elemento del arreglo

37

p++; // p, apunta al segundo elemento del arreglo p++; // p, apunta al tercer elemento del arreglo p--; // p, apunta al segundo elemento del arreglo Un elemento de comparacin de apuntadores, es el siguiente programa: #include <iostream.h> main (void) { int *ptr1, *ptr2; int a[2] = {l0,l0}; ptrl = a; cout << ptr1 es << ptr1 << *ptr1 es << *ptr1 << endl; cout << ptr2 es << ptr2 << *ptr2 es << *ptr2 << endl; //comparar dos apuntadores if (*ptrl == *ptr2) cout << ptr1 es igual a *ptr2 \n; else cout << *ptrl no es igual a *ptr2 \n; } El modificador const El modificador de tipos const se utiliza en C++ para proporcionar proteccin de slo lectura para variables y parmetros de funciones. Cuando se hace preceder un tipo de argumento con el modificador const para indicar que este argumento no se puede cambiar, el argumento al que se aplica no se puede asignar un valor ni cambiar. void copia (const char * fuente, char* dest); void funcdemo (const int I); Paso de parmetros a funciones En C++ existen tres formas de pasar parmetros a funciones: 1. Por valor La funcin llamada recibe una copia del parmetro y este parmetro no se puede modificar dentro de la funcin void intercambio (int x, int y) { int aux = y; y=x; x = aux; } //..... intercambio (i , j ); // las variables i, j, no se intercambian 2. Por direccin. Se pasa un apuntador al parmetro. Este mtodo permite simular en C/C++ la llamada por referencia, utilizando tipos apuntadores en los parmetros formales en la declaracin de prototipos. Este mtodo permite modificar los argumentos de una funcin. void intercambio (int*x, int*y) { int aux = * y; *y = *x *x = aux; } // ... intercambio (&i, &j); // i , j se intercambian sus valores

38

3. Por referencia. Se pueden pasar tipos referencia como argumentos de funciones, lo que permite modificar los argumentos de una funcin. void intercambio (int& x, int& y) { int aux = y; y = x; x = aux; } //..... intercambio (i, j); // i , j intercambian sus valores Si se necesita modificar un argumento de una funcin en su interior, el argumento debe ser un tipo de referencia en la declaracin de la funcin. Paso de arreglos Los arreglos se pasan por referencia. La direccin del primer elemento del arreglo se pasa a la funcin; los elementos individuales se pasan por valor. Los arreglos se pueden pasar indirectamente por su valor si el arreglo se define como un miembro de una estructura. Ejemplo 1: #include <iostream.h> void func1 (int x[] ); // prototipo de funcin void main( ) { int a[3] = {l, 2, 3}; func1 (a) ; // sentencias func1 (&a[0]) ; // equivalentes } void func(int x[]) { int i; for (i = 0; 1 < 3; i + 1) cout << 1 << x[i]<< \n; } Ejemplo 2: #include <iostream.h> const int n + 3; void func2(int x); void main( ) { int a[n] = { l, 2, 3}; func2 (a[2] ); } void func2(int x) { cout << x << \n; }

39

INTRODUCCION A LAS GRAFICAS POR COMPUTADORA En el proceso de enseanza-aprendizaje de un lenguaje de programacin, el aprender a hacer grficas se presenta como un excelente apoyo didctico para que el estudiante profundice sobre algunos de los aspectos de la programacin. A continuacin se presentar un tema enfocado hacia la aplicacin de las instrucciones grficas que tiene el lenguaje Turbo C++ para plataformas personales. Las computadoras estn dotadas de un conjunto de caracteres grficos, en modo de texto, a los que podemos tener acceso mediante el cdigo ASCII, con los cuales se podran generar marcos para la presentacin de datos o resultados; dibujos de cuadros para el diseo de, cuadros para el desplegado de mens y otros usos muy bsicos. Al uso de esta forma de graficacin se le denomina graficacin en lnea o en modo texto. Hay otra forma de graficacin que se realiza a travs de los lenguajes de programacin, mediante un conjunto de instrucciones especiales (funciones en C) para la creacin de graficas como son: putpixel(), line(), circle(), arco(), draw-poly(), por medio de los cuales podemos dibujar puntos, lneas, circunferencias, elipses, arcos, hacer trazos de cualquier tipo, o bien, dar la representacin grafica de una funcin matemtica pero, para poder usar estas funciones de graficacin del lenguaje, debemos conocer los aspectos bsicos de los monitor, de tal forma que cuando un programa de grficas inicia, la interfase BGI utiliza especficamente el manejador que se le indica y carga las rutinas del manejador para habilitar la pantalla en modo grafico. Para habilitar las funciones de la interfase BGI y poder trabajar en modo grafico, los programas se deben ligar con la libreriagraphics.lib a travs del archivo encabezado de igual nombre graphics.h y poder accesar a las constantes, estructuras de datos y funciones definidas en la interfase.

Inicializacin de la interfase BGI Los programas deben iniciar con la inclusin del archivo encabezado graphics.h y posteriormente inicializar el modo grafico con la funcin initgraph(), cuya funcin prototipo tiene la siguiente sintaxis: [Void far] initgraph ([int far]*gdriver,[int far]*gmode,[char far]*<trayectoria del directorio donde se localizan los archivos manejadores>); La funcin que deshabilita el modo grafico es closegraph() sin argumento. Ejemplo: #include <graphics.h> Main() { Int gdriver=DETECT,gmode; Initgraph(&gdriver,&gmode,\\Turboc\\bgi); //introduccin de las funciones requeridas para el proceso grfico, Closegraph(); }

Identificacin de la gama de colores Para desplegar caracteres parpadeantes en modo de texto, el nombre de la constante reservada del sistema BLINK se deber agregar al nombre de la constante del color de frente seleccionado. Estos nombres estn definidos en el archivo conio.h. Los 16 colores de la lista siguiente son los que manejan los adaptadores VGA:

40

CONSTANTE Black Blue Green Cyan Red Magenta Brown Lightgray Darkgray Lightblue Lightgreen Lightcyan Lightred Lightmagenta Yallow White

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

A continuacin desglosaremos las funciones que tiene Turbo C haciendo los comentarios pertinentes a que haya lugar. Las funciones se agrupan por temas afines. I. Fundamentales o de configuracin Para preparar ambientacin de procesos grficos: Initgraph() closegraph() detectgraph() floodfill() cleardevice() setpallete() setpallete() setcolor() setbkcolor() setfillstyle()

II. Dibujos y trazos Puntos, lneas, angulos, cuadros, crculos, arcos y trazos en general: putpixel() line() lineto() rectangle() circle() arc() fillellipse() drawpoly() fillpoly()

III. Animacin Con las que se puede dar movimiento a las grficas: getimage() putimage()

IV. De presentacin Para la presentacin de datos a travs de grficas formales conocidas como de barras y circulares o de pie bar3d() pieslice() sector()

V. De apoyo Que nos facilitan y dan mayor versatilidad a las tareas de graficacin o dibujo: getmaxx() getmaxy() getmaxcolor() getbkcolor() getpalette() getdrivename() getmodename() getgraphmode() getmaxmode() setaspectradio() setactivepage() setvisualpage() setlinestyle() setviewport() setgraphmode() clearviewport() getviewsettings() settextjustify() outtext() outtextxy() moverel() moveto() restorecrtmode()

41

PROGRAMAS DE APLICACIN 1) Programa que detecta el tipo de adaptador grfico instalado y el modo de resolucin activado por omisin. 2) Programa que genera textos con los 16 diferentes colores disponibles. 3) Programa de aplicacin de la funcin putpixel(). Genera la grfica de una funcin matemtica (una parbola). 4) Programa de grfica de otra funcin matemtica aplicando la funcin putpixel(). 5) Programa que genera la grfica de una funcin armnica aplicando la funcin putpixel(). 6) Programa que genera la grfica de una funcin cardioide aplicando la funcin putpixel(). 7) Programa de aplicacin de la funcin linerel(). Genera la grfica de un velero. 8) Programa que genera la grfica de un tringulo aplicando la funcin lineto(). 9) Programa que genera la misma grfica del tringulo pero ahora aplicando la funcin linerel(). 10) Programa da aplicacin de la funcin rectangle(). Genera una tabla con los 12 patrones disponibles para el relleno o ashurado de areas. 11) Programa de generacin de un pentgono aplicando la funcin drawpoly(). 12) Programa de generacin del mismo pentgono anterior generado por drawpoly() pero iluminado. 13) Programa de generacin de un hexgono utilizando la funcin lineto(). 14) Programa de generacin de otras grficas de funciones matemticas utilizando la funcin lineto(). 15) Programa variacin de la grfica anterior. 16) Programa de una segunda variante de la grfica 14. 17) Programa de graficacin de una elipse en alta resolucin dividida en cuatro sectores por lneas que cruzan la pantalla en diagonal, pintando cada sector con un color diferente. 18) Programa de graficacin de una elipse similar a la anterior pero en baja resolucin, ashurando dos sectores opuestos. 19) Programa degraficacin de una elipse que va cambiando de patrn de ashurado, otra variacin. 20) Programa que grafica un sector ashurado que se va modificando en forma similar a la grfica anterior de la elipse. 21) Programa que muestra la aplicacin de la funcin Bar(). 22) Programa que muestra la aplicacin de la funcin Bar3D(). 23) Programa que dibuja una grfica de sectores circular y otra elptica, aplicando la funcin pieslice(). 24) Programa que muestra la aplicacin de la funcin viewport(). 25) Programa que muestra la aplicacin de la funcin outtextxy(). 26) Programa que muestra otra aplicacin de la funcin outtextxy(). 27) Programa que elabora grficas circulares o de pie. 28) Programa que elabora grficas de barras.

42

Anda mungkin juga menyukai