Está en la página 1de 53

ndice de contenido

1 Elementos bsicos de la programacin...........................................................................................4 1.1 Lenguaje.............................................................................................................................4 1.2 Notacin BNF.....................................................................................................................4 1.3 Dato....................................................................................................................................4 1.4 Constante.............................................................................................................................4 1.5 Valores numricos enteros..................................................................................................5 1.6 Valores numricos reales....................................................................................................5 1.7 Caracteres (char)................................................................................................................5 1.8 Caracteres de control..........................................................................................................5 1.9 Cadena de caracteres (string).............................................................................................5 1.10 Tipos predefinidos.............................................................................................................5 1.10.1 int.........................................................................................................................5 1.10.2 float......................................................................................................................6 1.10.3 carcter (char)......................................................................................................6 1.11 Expresiones aritmticas.....................................................................................................7 1.11.1 Mezclando tipos...................................................................................................7 1.12 Operaciones de escritura simples......................................................................................7 1.12.1 El procedimiento printf........................................................................................7 1.13 Estructura de un programa completo................................................................................8 2 Constantes y variables....................................................................................................................9 2.1 Identificadores.....................................................................................................................9 2.2 Palabras clave......................................................................................................................9 2.3 Palabras reservadas.............................................................................................................9 2.4 Constante.............................................................................................................................9 2.5 Expresin constante..........................................................................................................10 2.6 Variables............................................................................................................................10 2.7 Operaciones de lectura simple (scanf)..............................................................................11 2.7.1 Procedimiento scanf.............................................................................................11 2.8 Estructura de un programa con declaracin......................................................................11 3 Estructuras Bsicas de Programacin Imperativa.........................................................................12 3.1 Estructuras bsicas............................................................................................................12 3.1.1 Secuencia.............................................................................................................12 3.1.2 Seleccin..............................................................................................................12 3.1.3 Iteracin (bucle)...................................................................................................12 3.1.4 Estructuras anidadas............................................................................................12 3.2 Expresiones condicionales................................................................................................12 3.3 Condiciones compuestas...................................................................................................12 4 Funciones y Procedimientos..........................................................................................................13 4.1 Funciones..........................................................................................................................13 4.2 return (en funciones).........................................................................................................13 4.3 Procedimientos..................................................................................................................13 4.4 return (en procedimientos)................................................................................................13 4.5 Argumentos reales.............................................................................................................13 4.6 Argumentos formales........................................................................................................13 4.7 Paso de argumentos...........................................................................................................14 4.7.1 Por valor...............................................................................................................14 4.7.2 Por referencia........................................................................................................14 4.8 Recursividad de programas...............................................................................................15 4.9 Transparencia referencial..................................................................................................15 4.10 Redefinicin de elementos..............................................................................................15

4.11 Doble referencia..............................................................................................................15 Definicin de Tipos.......................................................................................................................16 5.1 Tipos escalares..................................................................................................................16 5.1.1 typedef (tipos sinnimos)....................................................................................16 5.1.2 typedef (tipo enumerado).....................................................................................16 5.1.3 El tipo predefinido bool.......................................................................................17 5.2 Tipos estructurados...........................................................................................................17 5.3 Tipo formacin..................................................................................................................17 5.3.1 Tipo vector...........................................................................................................17 5.3.1.1 Declaracin de vectores...........................................................................17 5.3.1.2 Inicializacin de un vector........................................................................18 5.3.1.3 Operaciones con elementos de vectores...................................................18 5.3.1.4 Operaciones con vectores.........................................................................18 5.3.1.5 Paso de argumentos de tipo Vector.(Importante)......................................18 5.3.2 Vector de caracteres (string)................................................................................19 5.4 Tipo tupla..........................................................................................................................19 5.4.1 Tipo registro struct................................................................................................20 5.4.1.1 Declaracin...............................................................................................20 5.4.1.2 Valores e inicializacin.............................................................................20 5.4.1.3 Operaciones..............................................................................................20 Ampliacin de estructuras de control............................................................................................22 6.1 do......................................................................................................................................22 6.2 Continue...........................................................................................................................22 6.3 Switch...............................................................................................................................23 Estructuras de Datos......................................................................................................................25 7.1 Vectores abiertos...............................................................................................................25 7.2 Matrices.............................................................................................................................25 7.2.1 Seleccin o designacin de un elemento..............................................................25 7.2.2 Operaciones con matrices.....................................................................................26 7.2.3 Matriz Abierta.......................................................................................................26 7.3 unin..................................................................................................................................27 7.3.1 Declaracin...........................................................................................................27 7.3.2 Referencia a los elementos...................................................................................27 7.3.3 Registro con variantes...........................................................................................28 7.3.4 Discriminante........................................................................................................28 7.3.5 Formas de combinacin........................................................................................30 7.3.6 tablas.....................................................................................................................31 Esquemas tpicos de operaciones con formaciones.......................................................................32 8.1 Recorrido...........................................................................................................................32 8.1.1 Recorrido de matrices...........................................................................................32 8.1.2 Recorrido no lineal...............................................................................................33 8.2 Bsqueda secuencial.........................................................................................................33 8.3 Insercin............................................................................................................................33 8.4 Ordenacin por insercin directa......................................................................................35 8.5 Bsqueda por dicotoma....................................................................................................36 8.6 Simplificacin de la condiciones de contorno..................................................................37 8.7 Tcnica del centinela.........................................................................................................37 8.7.1 Mejora del esquema general de bsqueda............................................................38 8.7.2 Mejora del esquema de ordenacin por insercin................................................38 8.8 Matrices orladas................................................................................................................39 Punteros y variables dinmicas.....................................................................................................42 9.1 Estructuras secuenciales....................................................................................................42

9.2 Variables dinmicas...........................................................................................................43 9.3 Punteros.............................................................................................................................43 9.3.1 DECLARACION..................................................................................................43 9.4 Uso de variables dinmicas...............................................................................................44 9.4.1 Variables dinmicas perdidas................................................................................45 9.5 Realizacin de secuencias mediante punteros...................................................................45 9.6 Operaciones con secuencias enlazadas.............................................................................46 9.6.1 DEFINICION.......................................................................................................46 9.6.2 RECORRIDO.......................................................................................................47 9.6.3 BSQUEDA........................................................................................................47 9.6.4 INSERCION.........................................................................................................48 9.6.5 BORRADO...........................................................................................................48 9.7 Punteros y paso de argumentos.........................................................................................49 9.7.1 Paso de puntero como argumentos.......................................................................49 9.7.1.1 PASO POR VALOR.................................................................................49 9.7.1.2 PASO POR REFERENCIA......................................................................50 9.7.2 Paso de argumentos mediante punteros................................................................50 9.8 Ejemplo: Leer nmero y escribirlos en orden pag. 378 del pdf...................................52 9.9 Punteros y vectores en C y C++.( Ejemplos validos en c y c++ pero no en c+-).............52 10 Tipos abstractos de datos.............................................................................................................53 11 Mdulos.......................................................................................................................................53

Fundamentos de la Programacin.
1

Elementos bsicos de la programacin.


Los ficheros han de tener la extensin .cpp

1.1 Lenguaje. 1.2 Notacin BNF.


Basada en la descripcin de cada elemento gramatical en funcin de otros mas simples, segn determinados esquemas o construcciones. Estas reglas de cmo han de escribirse los elementos del lenguaje en forma de smbolos usa a su vez otros smbolos llamados metasmbolos. : : = Metasmbolo de definicin. El elemento de la izquierda puede desarrollarse segn el elemento de la derecha. | Metasmbolo de alternativa. Indica que puede elegirse uno y solo uno de los elementos incluidos separados por el metasmbolo. { } Metasmbolo de repeticin. Los elementos incluidos dentro de ellos pueden repetirse una o ms veces. [ ] Metasmbolo de opcin. Los elementos dentro de ellos pueden ser utilizados o no. ( ) Metasmbolo de agrupacin. Agrupan elementos incluidos en su interior.

1.3 Dato.
Elemento de informacin que puede tomar un valor entre varios posibles. Un dato tiene diferentes clases de valores, a estas clase les llamamos tipos (a los tipos es mejor denominarlos como tipos abstractos de datos ya que, por ejemplo, los nmeros enteros del 1 al 12 pueden representar los meses y adems podemos realizar operaciones aritmticas con ellos).

1.4 Constante.
Dato que tienes siempre un valor fijo.

1.5 Valores numricos enteros.


Valor_entero ::= [ + | - ] Secuencia_dgitos ::= Dgito { Dgito } Dgitos ::= 0|1|2|3|4|5|6|7|8|9
NOTA: C considera que cuando se empieza por 0 se esta en base octal.

1.6 Valores numricos reales.


Valor_real ::= Valor_entero.[Secuencia_dgitos][Escala] Escala ::= E Valor_entero Ejemplo: -23.2E+12 ----> -23,2 x 10 12

1.7 Caracteres (char).


El valor de un carcter concreto se escribe poniendo dicho carcter entre apstrofos(' ').

1.8 Caracteres de control.


'\n' Salto al comienzo de una nueva escritura. '\r' Retorno de al comienzo de la misma linea de escritura. '\t' Tabulacin '\'' Apstrofo '\\' Barra inclinada '\f' Salto a una nueva pgina o borrado de pantalla.

1.9 Cadena de caracteres (string).


Se escriben entre comillas dobles. Estetextoesunacadenadecaracteres
NOTAS: Si una cadena incluye comillas en su interior se escribir mediante \. No hay que confundir un tipo carcter ('c'), con un tipo cadena (c) Es posible definir una cadena vaca ().

1.10 Tipos predefinidos.


En el lenguaje C existen cuatro tipos predefinidos. int:nmeros enteros positivos y negativos float:nmeros reales. char:caracteres. bool: booleanos.

1.10.1 int
Tipo para hacer referencia a nmeros enteros positivos y negativos. Rango. Tamao de la palabra Rango de valores enteros 16 bits(2 = 32.718) -32.718............. 32.718

32 bits 64 bits

-2..............2 -2...............2

NOTA: el primer bit es 2 para representar el 0 por eso, por ejemplo, los 16 bits llegan hasta 2.

Para facilitar la escritura de programas que tengan en cuenta el rango mnimo y mximo de valores se utilizaran los nombres simblicos INT_MIN y INT_MAX, estos nombres estn definidos en el mdulo limits de la librera C(cabecera <limits.h>).

1.10.2 float
Representacin de valores reales positivos y negativos

1.10.3 carcter (char)


Los caracteres se representan como un cdigo que luego se codifican en una tabla (charset), que los relaciona cada cdigo con el carcter (codepoint) que representan . Un ejemplo de charset es la tabla ASCII. Por tanto se puede representar cualquier carcter mediante la notacin char('x'), donde x el el nmero correspondiente al smbolo deseado en la tabla. En sentido inverso podemos obtener el cdigo de un carcter mediante la notacin int('c')donde c representa al carcter. Por ejemplo: char(65) ---> Letra A mayscula. int('A') ---> 65 (posicin 65 de la tabla ASCII) En C y C concretamente se puede usar el mdulo de la librera ctype (cabecera <ctype.h>) que facilita el manejo de diferentes clases de caracteres. Incluye funciones como. isalpha(c) Indica si c es una letra isacii(c) Indica si c es un carcter ASCII isblank(c) Indica si c es un carcter de espacio o tabulacin iscntrl(c) Indica si c es un carcter de control isdigit(c) Indica si c es un dgito decimal(0-9) islower(c) Indica si c es una letra minscula isspace(c) Indica si c es espacio en blanco o salto de lnea isupper(c) Indica si c es una letra mayscula Funciones de transformacin tolower(c) Devuelve la minscula correspondiente a c. toupper(c) Devuelve la mayscula correspondiente a c.

1.11 Expresiones aritmticas.


Una expresin aritmtica es una combinacin de operandos y operadores. Para indicar el orden en el que se realizan las operaciones se usarn parntesis. Si estos no se utilizan el orden vendr determinado por: 1 Operadores multiplicativos: * / % 2 Operadores aditivos: +Dentro del mismo nivel las operaciones se ejecutan en el orden en que estn escritas en la expresin aritmtica de izquierda a derecha.

1.11.1 Mezclando tipos.


Si se mezclaran en una misma expresin valores de tipos diferentes, las expresiones aritmticas son completamente ambiguas. Los resultados sern diferentes segn el tipo de operacin que se realice. Adems no queda claro si el resultado que se pretende es un valor entero o real. Para poder realizar estar operaciones combinadas es necesario que previamente se realice una conversin de la representacin de los datos al tipo adecuado. La representacin real de un dato entero se indica de la siguiente manera: float(45)Representa el valor numrico 45.0 con tipo float De forma similar la representacin entera de un dato real se consigue de la siguiente forma: int (34.7) Representa el valor numrico 34 con tipo int Por tanto en una operacin de este tipo seria. Int(33.7) / 5 -------->6 int C no exige una conversin explcita. Pero para evitar errores es conveniente realizarla siempre.

1.12 Operaciones de escritura simples.


Las operaciones de escritura se definen como procedimientos. Estos procedimientos estn definidos en mdulos de librera disponibles de antemano.

1.12.1 El procedimiento printf


Este procedimiento pertenece al modulo stdio( cabecera <stdio.h>). Invocacin. printf ( cadena-de-caracteres); NOTA: Esta forma es solo vlida si la cadena de caracteres no contiene el carcter %. Representacin como texto de una serie de valores.

printf( cadena-con-formatos, valor1, valor1, valorN ); Los formatos se especifican con la notacin %x, donde x es un cdigo que indica el tipo de formato a utilizar. Codigo d f e g c
printf (%d, 120/12); printf (Datos:%d#%d,23*67, -50);

Tipo de valor entero Real Real con notacin exponencial Real con/sin notacin exponencial carcter

1.13 Estructura de un programa completo.


Un programa en C se engloba dentro de una estructura principal o main().
/** Programa : Hola */ #include <stdio.h> //directiva para el compilador int main() { printf( Hola\n );

} Descripcin formal. Programa ::= {Include}int main() Bloque Include ::= #include <Nombre_mdulo.h> Bloque ::= {Parte_ejecutiva} Parte_ejecutiva::={Sentencia}

Constantes y variables.
En programacin se llaman identificadores al os nombres usados para identificar cada elemento del programa. Identificador ::=Letra{Letra|Guin|Dgito} Letra::= Los identificadores no pueden empezar por un smbolo, un nmero, contener espacios en blanco, o la letra .

2.1 Identificadores

2.2 Palabras clave


Sirven para delimitar determinadas construcciones del lenguaje de programacin. Son elementos fijos del lenguaje.

2.3 Palabras reservadas.


Elementos fijos del lenguaje que se utilizan para identificar los tipos fundamentales y funciones del lenguaje. Estas palabras, por tanto no pueden ser redefinidas por el programador para utilizarlas con otros fines.

2.4 Constante.
Una constante es un valor fijo que se utiliza en un programa. Declaracin: Declaracin_de_constante::= const Tipo Nombre = Expresin_constante; Tipo ::= Identificador Nombre ::= Identificador Las constantes han de ser declaradas antes de utilizarse. Una vez declarada se pueden utilizar igual que si fueran un valor explcito. El tipo de valor de la constante hay que definirlo explcitamente ya que no se define por el tipo de valor al que se le asocia.
const float PI = 3.14159265; 2 * PI * r; //ya se puede utilizar PI NOTA: para definir el tipo string se har mediante la notacin. const char cadena[] = Esto es una cadena constante; printf(%s,cadena);//podemos imprimirla

2.5 Expresin constante.


Definicin de una constante mediante una expresin aritmtica o otra en la que interviene constantes que garantizan la inmutabilidad del resultado de la expresin.
const float diametro = 2 * radio;

2.6 Variables.
Una variable representa un valor almacenado en memoria que puede usarse tantas veces como se quiera. Este valor puede ser modificado. Declaracin; Declaracin_de_variable::= Tipo Nombre{, Nombre}; Tipo ::= Identificador Nombre ::= Identificador Inicializacin: Inicializar es dar un valor determinado por primera vez. ***En C slo esta permitido expresar el valor inicial de un variable en una declaracin individual para esa variable. Por tanto, no esta permitido realizar inicializaciones de ninguna variable cuando se declaran como lista de variables del mismo tipo. Declaracin_de_variable::=Variable_simple | Lista_var; Variable_simple ::= Tipo Nombre [=Expresin] Lista_var ::= Tipo Nombre{, Nombre}; Tipo ::= Identificador Nombre ::= Identificador Si no se inicializa la variable en su declaracin, deber inicializarse en el momento de su uso. Asignacin: conseguir que la variable guarde algn valor. Asignacin ::= Variable = Expresin ; Varibale ::= Identificador Compatibilidad de tipos: Realizar siempre que sea necesario una conversin explicita para evitar errores.
int saldo; float gastos; .... saldo = int(gastos);

2.7 Operaciones de lectura simple (scanf).


Otra manera de asignar un valor a una variable es almacenar en ella un valor introducido desde el exterior del computador mediante teclado u otro dispositivo. Los procedimientos generales estn definidos en el mdulo de librera stdio.

2.7.1 Procedimiento scanf.


Ejemplo de uso:
int mes, dia; float saldo; Datos entrada: 2 1,5 3 scanf(%d %f %d,&mes, &saldo, &dia); Resultado: mes = 2, saldo = 1,5 dia = 3

Un formato (%d, %f, %g, .) hace que se salten los siguientes espacios en blanco de la entrada, si los hay. A continuacin se leen los caracteres no blancos que formen una representacin valida de un valor numrico correspondiente al formato, este valor se asignar al argumento de la lista de variables a leer. Un formato %c hace que se lean exactamente el siguiente carcter de la entrada, sea o no espacio en blanco, y se asigne a la siguiente variable a leer. Un carcter de espacio en blanco en la cadena con formatos hace que se salten los siguientes caracteres de espacio en blanco en el texto de entrada, silos hay Un carcter no blanco en la cadena con formatos hace que se lea ( y se salte) el siguiente carcter de la entrada, que debe coincidir exactamente con el carcter del formato. Los formatos de conversin numricos pueden incluir especificacin del tamao , indicando el mximo del dato de entrada a leer. NOTA:En print el tamao es el mnimo de caracteres a escribir.

2.8 Estructura de un programa con declaracin.


Las declaraciones de valores constantes u de las variables forman parte del bloque del programa. Bloque ::={Declaracin} Parte_declarativa::= {Declaracin} Parte_ejecutiva::={Sentencia} Declaracin::= Declaracin_de_constante |Declaracin_de_variable | . Sentencia::= Llamada_a_procedimiento | Asignacin | .

3 Estructuras Bsicas de Programacin Imperativa.


3.1 Estructuras bsicas.
3.1.1 Secuencia.
Secuencias de acciones o partes que se ejecutan de forma sucesiva.

3.1.2 Seleccin.
Se ejecuta una accin u otra dependiendo de una condicin.

3.1.3 Iteracin (bucle).


Se ejecutan una serie de acciones hasta que se cumple una accin de terminada

3.1.4 Estructuras anidadas.


Cualquier parte o accin de un programa puede estar compuesto por varias estructuras bsicas. Mediante la tcnica de refinamientos sucesivos se definen primero las estructuras ms externas y a posterior se van perfilando las estructuras internas.

3.2 Expresiones condicionales.


Se realizaran mediante expresiones aritmticas: No se permitirn comparaciones entre valores de distintos tipos. Operadores: Mayor que Mayor o igual que Menor que Menor o igual que Igual que Diferente a > >= < <= == !=

3.3 Condiciones compuestas.


Conjuncin && .Si el primer operando es falso no se evalan los posteriores(Evaluacin en cortocircuito) Disyuncin ||. Se sigue evaluando si todas las anteriores han sido falsas hasta que encuentra una verdadera. Negacin !

4 Funciones y Procedimientos.
4.1 Funciones
Una funcin es un tipo de subprograma que calcula como resultado un valor nico a partir de unos valores pasados como parmetro. Una funcin predefinida es aquella que forma parte del lenguaje. Una funcin estndar es aquella que esta definida en mdulos ya redactados de antemano. Para usarlas hay que expresar explicitamente el mdulo a usar mediante la sentencia #include. Declaracin: TipoResultado NombreFuncion (Tipo1 argumento1,... TipoN argumentoN)

4.2 return (en funciones).


Esta sentencia sirve para devolver como valor de la funcin el resultado de los clculos realizados. return expresin. La ejecucin de la funcin de la funcin acaba cuando se ejecuta cualquiera de las sentencias return que existen dentro de ella.

4.3 Procedimientos.
Se declaran igual que las funciones pero no se obtiene resultado de ningn tipo. Declaracin: void NombreProcedimiento(Tipo1 argumento1,..TipoN argumentoN) Bloque Se usan por ejemplo para imprimir datos en pantalla, leer datos.

4.4 return (en procedimientos).


La sentencia sirve solamente para terminar la ejecucin del procedimiento, sin devolver ningn valor, y volver al punto siguiente donde se invoco.

4.5 Argumentos reales.


Son los que se invocan en la llamada y debern ser compatibles con los indicados en la declaracin (argumentos formales).

4.6 Argumentos formales.


Son los que estn indicados en la declaracin del procedimiento o funcin

4.7 Paso de argumentos.


4.7.1 Por valor
El modo de paso por valor implica que los valores pasador por los argumentos no pueden ser modificados por la ejecucin de sentencias del subprograma( que en este caso suele ser una funcin). Esto es cierto an considerando que el subprograma ejecute asignaciones a los argumentos formales, que sern considerados como variables locales del subprograma. El paso de argumentos por valor se describe: 1. Se evalan las expresiones de los argumentos reales pasados en la llamada. 2. Los valores obtenidos se copia a los argumentos formales. 3. Los argumentos formales se usan como variables dentro del subprograma. Si a estas variables se les asigna nuevos valores, no se estar modificando el argumento real, sino la copia. NOTA: Puesto que la reasignacin de valor a un argumento pasado por valor resulta algo confusa, el manual de estilo de C recomienda no usar este modo.

4.7.2 Por referencia


En ciertos casos es deseable poder modificar las variables que se usen como argumentos. El paso de argumento por referencia se indica en la cabecera del subprograma, anteponiendo el smbolo & al nombre del argumento formal TipoResultado Nombre(TipoArgumento & argumento,....) Si un argumento se pasa por referencia ya no se podr usar como argumento real una expresin. El argumento real usado en la llamada debe ser una variable del mismo tipo, la cual el subprograma usar como si fuera sura, es decir , la asignacin de nuevo valor al argumento modifica realmente la variable externa pasada como argumento. El paso de argumentos por referencia se describe de la siguiente manera.

1. Se seleccionan las variables usadas como argumentos reales. 2. Se asocia cada variable con el argumento formal correspondiente. 3. Se ejecutan las sentencias del subprograma como si los argumentos formales fuesen los argumentos reales.

4.8 Recursividad de programas.


Subprogramas que hacen una llamada as mismo. Ejemplo factorial de un nmero. n! = n x (n-1)! Las autollamadas deberan estar controladas por una estructura condicional para que no se convierta en un bucle infinito. int FactorialRecursivo( int n) { if (n <= 1) { //Se controla la recursividad aqu. return 1; }else{ return n * FactorialRecursivo( n-1 );} }

4.9 Transparencia referencial.


Siempre que se invoque al subprograma con los mismos valores de los argumentos se debe obtener el mismo resultado. La transparencia referencial se se garantiza si el cdigo del subprograma utiliza solamente elementos mencionados en la lista de argumentos o definidos como elementos locales. La posibilidad de utilizar directamente por su nombre variables globales, que no se mencionan en la lista de argumentos, permite escribir subprograma que carecen de transparencia referencial. Cuando un programa modifica alguna variables externa, se dice que est produciendo efectos secundarios o laterales /side effects).

4.10 Redefinicin de elementos.


Cuando en el interior de un bloque se define un elemento local con el mismo nombre que otro elemento global la situacin es algo distinta. De acuerdo con la reglas de visibilidad, cualquier bloque tiene acceso a todos los elementos globales. Sin embargo, al dar un nombre ya utilizado como global a un nuevo elemento local del bloque se est redefiniendo dicho nombre, y automticamente se pierde la posibilidad de acceso al elemento global del mismo nombre. Se dice que el nombre local oculta o hace sombra al nombre global.

4.11 Doble referencia.


Se produce doble referencia cuando a una misma variable se la referencia con dos nombres. Puede ocurrir cuando. 1. Cuando un subprograma utiliza una variable externa que tambin se le pasa por argumento. 2. Cuando para utilizar un subprograma se pasa la misma argumentos variable en dos o ms

5 Definicin de Tipos.
5.1 Tipos escalares
Datos simples que no se pueden descomponer. Por ejemplo no tiene sentido tratar de reconocer fragmentos de informacin independientes dentro de un valor entero un da de la semana o el nmero de un da del mes.

5.1.1 typedef (tipos sinnimos).


Se usa para declarar nuevos tipos hacindolos equivalente o sinnimos a tipos ya existentes. En C no es posible acotar el rango de valores de un dato, habr, por tanto que hacer las comprobaciones pertinentes dentro del cdigo del programa.

5.1.2 typedef (tipo enumerado).


Una manera de definir un nuevo tipo es hacerlo mediante todos los posibles valores que puede tomar. typedef enum TipoDia{ Lunes, Martes, Miercoles, Jueves, Viernes, Sabado, Domingo } El primer elemento de elemento de la lista ocupa la posicin 0 y el ltimo la posicin n-1. Puesto que entre los valores enumerados existe un orden definido, podremos emplear con ellos los operadores de comparacin para programar sentencias del tipo: if ( mes>=Julio) {} se puede utilizar la notacin int(e) para obtener la posicin de un valor en la lista. Ejemplo. int(Julio) == 6 Definicin de mtodos para pasar a das siguientes o posteriores. TipoDia SumarDias(TipoDia Hoy, int N){ const int int aux; aux = (int(Hoy) + N) % DiasSemana; return TipoDia(aux); } Habra que realizar funciones equivalentes para restar das u para sumar y restar meses. Los tipos de datos enumerados pertenecen a los tipos de datos ordinales DiasSemana = 7;

5.1.3 El tipo predefinido bool.


Responde a la definicin anloga de un tipo enumerado. typedef enum bool {false, true}; Como tipo ordinal se cumple que: int(false) == 0 int(true) == 1 Es frecuente definir funciones cuyo resultado es un valor booleano cuando se quiere realizar un test sobre los argumentos de la funcin. Este tipo de funciones se llaman predicados. Para poder usar las funciones de predicado es necesario incluir la librera <ctype.h>.

5.2 Tipos estructurados


Es un tipo cuyos valores se construyes agrupando datos de otros tipos ms sencillos. Los elementos de informacin que integran un valor estructurado se denominan componentes. Todos los tipos estructurados se definen, en ltimo trmino, a partir de tipos simples combinados.

5.3 Tipo formacin.


Estructuras de datos que facilitaran la tarea de ordenacin. Genricamente se llaman formaciones (array) y permiten la generalizacin en la declaracin, referencia y manipulacin de colecciones de datos todos del mismo tipo.

5.3.1 Tipo vector.


Estructura anloga al concepto matemtico de vector. La sentencia for es la que mejor se adecua al manejo de vectores.

5.3.1.1 Declaracin de vectores.

typedef TipoElemento TipoVector[NumeroElementos] Ejemplos: typedef enum TipoDia{Lunes, Martes, Miercoles, Jueves, Viernes, Sabado, Domingo}; //es similar a la declaracin de tipo enumerado.

typedef float TipoMedidas[3]; Para poder utilizar los tipos declarados es necesario declarar a su vez, posteriormente, las correspondientes variables. TipoDia diasFestivos, diasLaborables;
5.3.1.2 Inicializacin de un vector.

La inicializacin en un vector afecta a todos sus elementos, y por tanto la notacin es un poco especial. TipoAgenda agendaUno = { Lunes, Viernes, Domingo, Martes Martes, Martes, Sabado}; TipoEstados estadoMotor = { true, false, true, true, false};
5.3.1.3 Operaciones con elementos de vectores.

Seleccionar un elementos del vector. estadoMotor[5] Asignar valor a un elemento. estadoMotor[5] = true; La posibilidad de utilizar variables o expresiones para el clculo del ndice de un vector es fundamental en cualquier programa que utilice vectores. int i; EstadoMotor[i];
5.3.1.4 Operaciones con vectores.

Asignacin. La asignacin de valores a todos los elementos a partir de otro vector se realizara mediante una sentencia for. for(int i=0; i<NumeroElementos; i++){ vectorDos[i] = vectorUno[i]; } NOTA:El nmero del indice de la ultima posicin es NumeroElementos1 por eso se expresa con un menor que.
5.3.1.5 Paso de argumentos de tipo Vector.(Importante)

Con vectores el paso por defecto sera por referencia, es decir se modificaran los parmetros reales.

En C cuando se utilizan argumentos de tipo formacin y no se quiere que se modifiquen los parmetros reales(es decir se quieren pasar por valor) en la llamada al procedimiento, los argumentos formales deben ir precedidos de la palabra clave const. Void EscribirVector(const TipoVector v){....} De esta manera al invocar un procedimiento con una sentencia EscribirVector( vectorDos ); La variable vectorDos permanecer inalterada despus de ejecutar el procedimiento.

5.3.2 Vector de caracteres (string).


Una cadena de caracteres es un vector en el que se pueden almacenar textos de diferentes longitudes. Para distinguir la longitud til en cada momento se reserva siempre espacio para un carcter ms, y se hace que toda cadena termine con un carcter nulo '\0' situado al final. Por tanto para declarar una cadena de un mximo de 20 caracteres. typedef char Cadena20[21]; Cadena20 nombre, apellido; //declaracin. Manejo de cadenas con librera string <string.h>

NOTA: Al igual que con cualquier otro vector no se pueden realizar asignaciones globales.

Apellido = Gonzlez; /*Error en C*/ En su lugar utilizaremos la funcin de librera strcpy. strcpy( apellido, Gonzlez);

5.4 Tipo tupla.


Tupla: Coleccin de elementos componentes, de diferentes tipos, cada uno de los cuales se identifica por un nombre. Una tupla, como cualquier otro dato, compuesto, puede verse de forma abstracta como un todo, prescindiendo del detalle de sus componentes. La posibilidad de hacer referencia a toda la coleccin de elementos mediante un nombre nico correspondiente al dato compuesto simplifica en muchos casos la escritura del programa que lo maneja.

En este esquema el dato estructurado est formado por una coleccin de componentes, cada uno de los cuales puede ser de un tipo diferente. Fecha <12, Octubre, 1992> punto <4,2> nombre_completo <Pedro, Palotes, Mojn>

5.4.1 Tipo registro struct.


Un registro o struct es una estructura da datos formada por una coleccin de elementos de informacin llamados campos. Con esta estructura se implementaran las tuplas.
5.4.1.1 Declaracin.

typedef struct

Tipo-registro{

Tipo-campo-1 nombre-campo1; Tipo-campo-2 nombre-campo2; ........... Tipo-campo-N nombre-campoN; } Ejemplo. typedef struct TipoFecha{ int dia; TipoMes mes; int anno; }
5.4.1.2 Valores e inicializacin.

TipoFecha ayer, hoy; TipoPunto punto1, punto2; Inicializacin en la declaracin teniendo en cuenta el tipo de cada campo. TipoFecha hoy = {12, Marzo, 2009};
5.4.1.3 Operaciones.

Con el dato completo la nica operacin posible es la asignacin. hoy = maana; ***NOTA:Para la asignacin no es suficiente que exista compatibilidad estructural; es decir, dos estructuras no son compatibles si sus definiciones se hacen por separado. Tambin se puede operar con cada campo por separado, esta opcin admite ms

operaciones. La forma de hacer referencia a un campo es mediante la notacin: registro.campo Ejemplo. /*Leer el da, mes y ao */ void LeerFecha(TipoFecha &fecha){ int aux; scanf( %d, &aux ); if((aux > 0) && (aux <= 31)){ fecha.dia =aux; }else{ fecha.dia = 1; } LeerMes(fecha.mes); scanf(%d, &aux); fecha.anno = aux; } NOTA:Cuando se trata de funciones es posible devolver el valor de tipo registro pero se acostumbra asociarlo a una variable del tipo registro y hacer un return de esta.

6 Ampliacin de estructuras de control.


6.1 do
A veces resulta mas natural comprobar la condicin que controla las iteraciones al finalizar cada una de ellas, en lugar de hacerlo al comienzo de las mismas.

do {Accin} while (Condicin); Una situacin tpica de empleo de esta sentencia es la que se produce cuando al finalizar cada iteracin se pregunta al operador si desea continuar con una nueva. Tambin resulta adecuado el empleo de la repeticin cuando solamente son vlidos unos valores concretos para una determinada respuesta. do { printf ( Mes actual?); scanf( %d, &mes ); }while((mes < 1) || (mes > 12)); En general , es aconsejable sus uso cuando se sepa que al menos es necesaria una iteracin y por tanto utilizando la sentencia while es necesario forzar las condiciones para que dicha iteracin se produzca.

6.2 Continue
La sentencia continue dentro de cualquier clase de bucle (while, for o do) finaliza la iteracin en curso e inicia la siguiente iteracin. for (int i = 0; i > N ; i++){ if (vectorCoeficientes[i] = = 0){ continue;/*condicion elegida para que no el bcle*/ se ejecute

} calculo = calculo / vectorCoeficientes[i] } La sentencia continue siempre estar incluida dentro de otra sentencia condicional puesto que en cada contrario nunca se ejecutara la parte de la iteracin posterior a la sentencia continue.

6.3 Switch
Cuando la seleccin entre varios casos alternativos depernde del valor que toma una determinada variable o del resultado final de una expresin, es necesario realizar comparaciones de es misma variable o expresin con todos los valores que puede tomar, uno por uno, para decidir el camino a elegir. Una estructura if else como la siguiente: if ( M == Enero){ IncreDias = 0; }else if(M == Febrero){ IncreDias = 3; }else if(M == Marzo){ IncreDias = 3; }else if(M == Abril){ IncreDias = 6; }else{ IncreDias = 5; } Esta sentencia larga y reiterativa (meses con el mismo incremento).Como lo que necesitamos es comparar el resultado de la expresin, por razones de simplicidad y eficiencia utilizaremos una estructura switch.

switch (M){ case Enero://OJO acaba en dos puntos case Octubre: IncreDias = 0; break; case Mayo: IncreDias =2; break; case Agosto; IncreDias =2; break; case Febrero: case Marzo: case Noviembre: IncreDias =3; break; case Junio: IncreDias =4; break; case Septiembre: case Diciembre: IncreDias =5; break; default://valor por defecto IncreDias =6; } Esta sentencia da lugar a un fragmento de programa ms corto y fcil de entender. Si existen valores par los que no se debe realizar ninguna accin, entonces estos valores se deben declarar asociados a una accin vaca o mediante una alternativa default vaca utilizando slo un punto y coma (;).

7 Estructuras de Datos.
7.1 Vectores abiertos
Son aquellos vectores que tienen un tamao indefinido. Los argumentos de tipo vector abierto se declaran omitiendo el tamao explcito pero no los corchetes. void EcribirVectorAbierto ( const int v[], int numElementos){ /*el const es para especificar el paso por valor*/ for(int i = 0; i < numElementos; i++){ printf( %10d, v[i]); } printf (\n) } De esta manera se podr utilizar el procedimiento par escribir vectores de cualquier tamao. Solo habr que especificar la longitud en el procedimiento en cada llamada. Para usar un procedimiento similar , que sirva para vectores de distintas longitudes se puede usar la tcnica empleada en las cadenas de caracteres, donde se reserva un carcter especial('\0' carcter nulo) para indicar el final de la cadena, de esta manera no har falta pasar la longitud como parmetro, pero se tendr en cuenta un espacio ms para dicho carcter de marca de final. NOTA: el carcter nulo se podr usar como centinela en el caso de subprogramas que analicen cadenas.

7.2 Matrices
Las matrices son estructuras de tipo dimensin (arrays) de dos o ms dimensiones.
Declaracin.

/*--Declarando un tipo intermedio--*/ typedef TipoElemento TipoFila[NumCol]; typedef TipoFila TipoMatriz[NumFil]; -----------------------------/*--Declaracin simplificada--*/ typedef TipoElemento TipoMatriz[NumFil][NumCol]

7.2.1 Seleccin o designacin de un elemento


TipoMatriz matriz; //invocacin matriz[3][5];//seleccin elemento.

7.2.2 Operaciones con matrices


Las operaciones con elementos pueden hacerse directamente. En cambio las operaciones globales se plantearan de forma anloga a como se hace con los vectores. Usaremos dobles bucles para elegir cada elemento. Tambin es posible operar con la matriz por filas completas, y detallar por separado cmo se opera con cada fila. void EscribirFila ( const TipoFila f){ for(int i = 0; i < NumCol; i++){ printf(%10d,f[i]); } printf(\n); } void EscribirMatriz ( const TipoMatriz m){ for(int i = 0; i < NumFilas; i++){ EscribirFila(m[i]); } }

7.2.3 Matriz Abierta


No esta permitido pasar como parmetro una matriz abierta al igual que en los vectores abiertos. void EscribirMatrizAbierta( const int m[][], int filas, int col)/*<--- Error*/ Para realizar un smil habr por tanto, que manejar la matriz como vectores. void EscribirFila( const TipoElemento f[], int columnas){ for(int i = 0; i < NumCol; i++){ printf(%10d,f[i]); } printf(\n); } void EscribirMatriz ( const TipoMatriz m){ for(int i = 0; i < NumFilas; i++){ EscribirFila(m[i]);} } Para definir operaciones genricas con formaciones de dimensin indefinida recurriremos al uso explcito de punteros (TEMA 9).

7.3 unin
El esquema unin es un conjunto finito de tipos. Cada uno de los tipos particulares constituye una variante o alternativa del tipo unin. tipo_union = variante | variante Situaciones tpicas de aplicacin. 1. Datos que pueden representarse de diferentes maneras. 2. Programas que operan indistintamente con varias clases de datos. 3. Datos estructurados con elementos opcionales. Ejemplos. Coordenadas = cor_cartesianas |cor_polares datos_persona = da_soltero | da_menor | da_casado

7.3.1 Declaracin.
/*--Definicin tipo tupla--*/ typedef struct TipoFraccion { int numerador; int denominador; };/*Punto y coma al final*/ /*--Definicin tipo unin--*/ typedef union TipoNumero{ int valorEntero; float valorReal; TipoFraccion valorRacional; };/*Punto y coma al final*/

7.3.2 Referencia a los elementos


Al igual que en el tipo struct. Numero.valorEntero = 33; otro.valorReal = float(numero.valorEntero); Si una variante de una unin es a su vez otra tupla o unin habr que usar varios cualificadores para designar los campos anidados: fraccion1.valorRacional.numerador = 33; franccion1.valorRacional.denominador = 44; Solo una de las variantes puede estar vigente en un memento dado. Si asignamos

valor a una de ellas ser sta la que exista a partir de ese momento, al tipo que dejan de existir las dems: fraccion1.valorEntero = 22: printf( %d, fraccion1.valorEntero ); /*Correcto*/ printf( %d, fraccion1.valorRacional.denominador ); /*Error*/ NOTA: Un dato de tipo unin no contiene en s mismo informacin de cul es la variante activa en un momento dado. Al redactar un procedimiento para imprimir un dato deberamos pasar tambin como argumento una indicacin de la variante aplicable: typedef enum ClaseNumero{Entero, Real, Fraccion}; void EscribirNumero( TipoNumero n , ClaseNumero c){ switch (c){ case Entero: printf(%d, n.valorEntero); break; case Real: printf(%f, n.valorReal); break; case Fraccion: printf(%d/%d),n.valorRacional.numerador, n.valorRaciona.denominador); break; default: pritnf( ?????????); } }

7.3.3 Registro con variantes


Agregados o tuplas en los que hay una coleccin de campos fijos, aplicables en todos los casos, y campos variantes que se definen segn el esquema unin.

7.3.4 Discriminante.
Campo fijo para indicar explcitamente cul es la variante aplicable en cada momento.

Recodificacin del ejemplo anterior usando esta tcnica. typedef enum ClaseNumero{Entero, Real, Fraccion}; typedef struct TipoFraccion { int numerador; int denominador; }; typedef union TipoValor{ int valorEntero; float valorReal; TipoFraccion valorRacional; }; typedef struct TipoNumero{ ClaseNumero clase;/*discriminante*/ TipoValor valor; }; void EscribirNumero( TipoNumero n ){ switch (n.clase){ case Entero: printf(%d, n.valor.valorEntero); break; case Realizados: printf(%f, n.valor.valorReal); break; case Fraccion: printf(%d ,n.valor.valorRacional.numerador, n.valor.valorRaciona.denominador); break; default: pritnf( ?????????); } }

NOTA: Si el tratamiento de los registros con variantes se hace slo mediante subprogramas que comprueban siempre el discriminante antes de operar. El cdigo resulta mucho ms seguro.

7.3.5 Formas de combinacin


Se pueden definir estructuras cuyas componentes son a su vez estructuras. Sin lmite de complejidad de los esquemas de datos resultantes. La manera de combinar las estructuras de datos es hacer que los elementos de una estructura sean a su vez otras estructuras , sin limitacin en la profundidad de anidamiento. typedef struct TipoPunto { float x, y; }; typedef TipoPunto TipoTriangulo[3]; const int MaxPuntos = 100; typedef TipoPunto TipoPuntos[MaxPuntos]; typedef struct TipoListaPuntos{ int numeroPuntos; TipoPuntos puntos; }; /*La lista de puntos se estructura como un registro, uno de cuyos campos es una formacin de puntos, que son a su vez registros*/

/*--Tipos sinonimos de la lista de puntos--*/ typedef TipoListaPuntos Poligonal;/*linea abierta */ typedef TipoListaPuntos Poligono; /*linea cerrada*/

7.3.6 tablas
La tabla puede plantearse como una formacin simple de registros. Ejemplo tabla de identificacin de provincias. typedef enum TipoProvincia { SinProvincia, Alava, Albacete, ..., Zaragoza}; const int MaxProvincias = int(Zaragoza); typedef char TipoSiglas[2]; typedef char TipoNombre[30]; typedef struct TipoDatosProvincia { TipoSiglas siglas; TipoNombre nombre; int codigo; }; typedef TipoDatosProvincia TipoTablaProvincias[MaxProvincias+1]; TipoTablaProvincias provincias; Almacenamiento de datos en la tabla. provincias[Cadiz].siglas[0] = 'C'; provincias[Cadiz].siglas[1] = 'A'; strcpy(provincias[Cadiz].nombre, Cdiz); provincias[Cadiz].codigo = 11; ,

8 Esquemas tpicos de operaciones con formaciones.


8.1 Recorrido.
Consiste en realizar cierta operacin con todos y cada uno de los elementos de una formacin (en algunos casos con parte de ellos): Forma general del esquema. Iniciar operacin while (quedan elementos sin tratar){ elegir uno de ellos y tratarlo } completar operacin Si es aceptable tratar todos lo elementos en el orden de sus ndices, el esquema de recorrido se puede concretar como un bucle for. const int N = . . . ; typedef . . . T_Elemento . . .; typedef T_Elemento T_Vector[N]; T_Vector v; . . . iniciar operacin for (int i = 0 ; i <N; i++){ tratar v[i] } completar operacin

8.1.1 Recorrido de matrices.


Para hacer el recorrido de una matriz se necesitan tantos for anidados como dimensin tenga la matriz. Ejemplo multiplicacin de matrices. for (int i= 0 ; i >N ; i ++){ for (int j = 0 : j<N : j++){ /*Primero se inicializa cada elementos de la matriz z a cero*/ z[i][j] = 0: for (int k=0; k<N, k++){ /*Suma de los productos de cada uno de los

elementos de la fila i de la maztriz x por los correspondientes elementos de la comuna j de la matriz y.*/ z[i][j] = z[i][j] + x[i][k]*y[k][j]; } } }

8.1.2 Recorrido no lineal.


En ciertos casos el elemento a procesar debe elegirse realizando cierto clculos, y el contador de iteraciones sirve fundamentalmente para contabilizar el avance del recorrido y detectar el final del bucle.

Ejemplo construccin de un cuadrado mgico. 8.2 Bsqueda secuencial.


En las operaciones de bsqueda secuencial se examinan uno a uno los elementos de la coleccin para tratar de localizar los que cumplen una cierta condicin.

Esquema de recorrido.
typedef . . . T_Elemento . . . ; int Apariciones( T_Elemento buscado, const T_Elemento v[], int N){ <<PRE:>> int veces = 0: <<INVARIANTE:veces=cardinal(v[k=0..i1],v[k]=buscado)>> for (int i = 0; i<N: i++){ if (v[i] == buscado) { veces++; } } return veces; <<POST:veces=cardinal(v[k=0..N1],v[k]=buscado)>> }

Para cuando solo queremos seleccionar un elemento que corresponda con la condicin y no queramos seguir buscamos se realizara mediante un bucle while. 8.3 Insercin.
Insertar un nuevo elemento en una coleccin de elementos ordenados, manteniendo

el orden da la coleccin. La operacin se puede realizar de forma iterativa, examinando los elementos empezando por el final hasta encontrar uno que sea inferior o igual al que se quiere insertar. Los elementos mayores que el que se quiere insertar se van moviendo una posicin hacia adelante, con lo que va quedando un hueco en medio del vector. Al encontrar un elemento menor que el nuevo, se copia el nuevo elemento en el hueco que hay en ese momento.

Esquema del cdigo del la insercin. Iniciar insercin while( ! Final && ! Encontrado hueco){ Desplazar elemento Pasar al siguiente elemento } insertar nuevo elemento A continuacin se concreta este cdigo para la insercin de un nuevo elemento entre los N elementos de un vector, que estn ordenados. typedef . . . T_Elemento . . .; void Insertar ( T_Elemento v[], int N, T_Elemento elemento ){ int j = N; <<INVARIANTE: . . .>> while (j > 0 && elemento < v[j-1]) { v[j] = v[j-1]; j--; }/*Creacion del hueco*/ v[j] = elemento;/*Insercin del elemento*/ <<POST : v'[0 . . .N] est ordenado y contiene los valores v[0..N -1] ms elemento>> }

8.4 Ordenacin por insercin directa.


En este apartado se aborda una solucin para la ordenacin de datos almacenados en un vector. Si suponemos un vector con valores desordenados como el de la figura.

El mtodo de ordenacin consiste en insertar el elemento extrado en su lugar correspondiente entre los elementos ya ordenados. La secuencia de inserciones de los sucesivos elementos del vector se muestra en la siguiente imagen.

Cdigo de realizacin.
typedef . . . <<PRE: >> T_Elemento valor; int j; <<INVARIANTE: v[0... i-1] est ordenado>> <<INVARIATNE: para todo k (1...i-1)*v[k]v[k-1]>> for (int i-1; i<N; i++){ valor = v[i]; T_Elemento . . . ; void Ordenar (T_Elemento v[], int N){

j = i; while (j > 0 && valor < v[j-1]{ v[j] = v[j-1]; j--; } v[j] = valor; } <<POST : v'[0...N-1] est ordenado y contiene valores v[0...N-1]>> }

8.5 Bsqueda por dicotoma.


Cuando los datos estn ordenados la bsqueda resulta mucho mas rpida. Si comparamos el elemento a buscar con el que est justo en la mitad de os datos ordenados, podemos decidir si es se el elemento que buscamos o debemos continuar buscando, pero slo en la mitad derecha o slo en la mitad izquierda. El proceso re repetir hasta que se encuentre el elemento buscado o cuando la zona pendiente de examinar queda reducida a un resultado.

Esquema general.
while(quedan elementos por examinar y no se ha encontrado ninguno aceptable){ elegir el elemento central y ver si es aceptable } completar la operacin.

Ejemplo.
typedef . . . T_Elemento . . . ; int Indice ( T_Elemento buscado, const T_Elemento v[], int N){ <<PRE: v est ordenado>> int izq, dch, mitad, pos; <<INVARIANTE: el elemento buscado, si existe, est en loa zona v[izq . . dcha]>> <<INVARIANTE: para todo k (0izq -1) *(v[k] < buscado y para todo k (dch +1 ..N-1) * (v[k] > buscado)>> <<VARIANTE: dch izq +1>>

while (pos < 0 && izq <= dch) { mitad = ( izq + dch ) / 2; if (v[mitad] == buscado){ pos = mitad; }else if (v[mitad]< buscado){ dch = mitad -1; }else{ izq = mitad +1; } } return pos; <<POST: pos >= 0 v[pos] = buscado y pos >0 buscado no entre v[0 ..N-1]>> } NOTA: El cociente para hallar la mitad se reduce estrictamente a la mitad( cociente entero por defecto) en cada paso, y por tanto se reduce a cero en un nmero finito de pasos.

8.6 Simplificacin de la condiciones de contorno.


La programacin de operaciones con vectores, realizadas elemento a elemento exige con frecuencia realizar un tratamiento especial de los elementos extremos del vector o, en general, del los elementos de contorno de una formacin.

8.7 Tcnica del centinela.


En el procedimiento general de bsqueda haba que comprobar dos condiciones : sin o se ha alcanzado todava el final del vector, y si se encuentra el elemento buscado. Esto supone un tiempo adicional en la ejecucin de cada iteracin. Si garantizamos que el dato buscado est dentro de la zona de bsqueda antes o despus terminar encontrndolo y ya no ser necesaria comprobar explcitamente se se alza el final del vector. La manera de asegurar esto es incluir el dato buscado en el vector antes de comenzar la bsqueda. Se aade un elemento ms al vector(situado al final si la bsqueda se realiza hacia adelante o situado al principio si la bsqueda se realiza hacia atrs). En ese elemento adicional se copia el dato a buscar antes de iniciar la bsqueda para que acte como centinela ( C ) y asegure que la bsqueda nunca acaba de firma infructuosa.

8.7.1 Mejora del esquema general de bsqueda.


Por tanto el esquema general de bsqueda se simplifica de esta manera.
Iniciar operacin (colocar centinela) while ( no se ha encontrado un elemento aceptable){ elegir otro elemento y ver s es aceptable

}
completar operacin( s se ha encontrado el centinela, indicar fallo en bsqueda)

Cdigo.
typedef . . . T_Elemento . . ; int Indice ( T_Elemento buscado, int pos = 0; const T_Elemento v[], int N) {

v[N] = buscado; /*centinela colocado al final*/ while (v[pos]!= buscado){ pos ++;

}
if (pos >= N) { /* lo que se encuentra es el centinela */ pos = -1;

}
return pos;

8.7.2 Mejora del esquema de ordenacin por insercin.


Aprovechamos la tcnica del centinela para aplicarla a la ordenacin por insercin. De esta manera al estar cada elemento a insertar en el final de la parte ordenada la localizacin del lugar que le corresponde y el movimiento de los elementos posteriores para hacer hueco se realizan por separado, y la bsqueda entere los elementos anteriores se hacia delante y no hacia atrs. typedef . . . T_Elemento . . . ; void Ordenar( T_Elemento v[], int N){ T_Elemento valor; int j; for (int i =1; i<N; i++){ valor = v[i]; /*-- Buscar la nueva posicin de elemento, sin mover nada --*/ j = 0;

while (valor > v [j]){ j++; } /*-- Mover elementos mayores y poner el elemento en su sitio --*/ for (int k = i-1;k>=j: k--){ v[k+1]= v[k]; } v[j] = valor; } }

8.8 Matrices orladas.


Cuando se trabaja con matrices tambin se pueden simplificar las condiciones de contorno usando matrices orladas. Estas matrices se dimensionan con dos filas y dos columnas ms de la necesarias. Las filas y columnas extra garantizan que todos los elementos de la matriz original tienen elementos vecinos en todas las direcciones. Antes se operar con la matriz se inicializan las filas y columnas extra con un valor ce contorno ( C ) que permita simplificar la operacin de modo que el tratamiento de los elementos del borde de la matriz original sea idntico al de los dems.

Ejemplo. Supongamos que tenemos una imagen en blanco y negro de Ancho x Alto pixeles almacenada en una matriz definida de la siguiente forma: const int Ancho = 40; /*Achura de la imagen*/ const int Alto = 20;/*Altura de la imagen */ const int imagen */ Borde = -1; /*Indicador de borde de la

const int Blanco = 0;/*Nivel bajo de grises = blanco */ const int Negro = 5;/*Nivel alto de grises = negro*/ typedef int Imagen_t[Alto+2][Ancho+2];

Imagen_t imagen; /*--Tratamiento de los puntos de la imagen--*/ for (int i =1; i>= Alto; i++){ for (int j=1; j<=Ancho; j++){ if (imagen[i][j] <= nivel ) { imagen[i][j] = Blanco; }else{ imagen [i][j] = Negro; } } } Supongamos que ahora queramos eliminar aquellos puntos externos de la imagen que estn en blanco, paro dejando los puntos blanco que son interiores y estn rodeados de puntos negros. El tratamiento de cada punto exige examinar al mismo tiempo los puntos contiguos. El Programa se simplifica se se garantiza que toso punto til de la imagen tiene puntos contiguos en todas las direcciones, es decir, no hay situaciones excepcionales en los bordes. Para ello se aprovecha el contorno de la matriz, es decir, la orla, inicializndola con el valor que indicar los elementos del borde. for (int i = 0; i<=Alto+1; i++={ imagen[i][0] = Borde; imagen [i][Ancho+1] = Borde; } for (int i = 0; i<=Alto+1; i++={ imagen [0][i] = Borde; imagen [Ancho+1][i] = Borde; } /--*Suponiendo que la imagen ya esta contrastada anteriormente el recorte se realizar mediante sucesivos recorridos de la matriz en los que los puntos blancos que tienen algn punto Borde alrededor deben pasar tambin a puntos Borde. El proceso termina cuando en un recorrido completo de toda la imagen no hay ningn punto que cambie--*/ bool fin; do { fin = true;

for (int i =1; i <=Alto; i++){ for (int j=1; j<=Ancho; j++{ if ((imagen[i][j] == Blanco && ((imagen[i-1][j] == Borde) || (imagen [i][j-1] == Borde) || (imagen [i][j+1] == Borde) || (imagen [i+1][j] == Borde))){ imagen [i][j] = Borde; fin = false; } } }while (!fin);

9 Punteros y variables dinmicas.


9.1 Estructuras secuenciales.
Esquema de tipo iterativo con un nmero variable de componentes. Operaciones de construccin. Aadir o retirar componentes al principio de la secuencia Aadir o retirar componentes al final de la secuencia. Aadir o retirar componentes en posiciones intermedias en la secuencia. Operaciones de acceso. Acceso secuencial: Las componentes deben tratarse una por una, en el orden en que aparecen en la secuencia. Acceso directo: Se puede acceder a cualquier componente directamente indicando su posicin, como en una formacin o vector. Cursor. El cursor es una variable que seala a un elemento de la secuencia. El acceso insercin o eliminacin de componentes de la secuencia se hace actuando sobre el elemento sealado por el cursor. Dicho elemento lo representaremos simblicamente como cursor, empleando la flecha () como smbolo grfico para designar el elemento de informacin sealado por otro. Para actuar sobre el cursor se suelen plantear las siguientes operaciones: Iniciar: Pone el cursor sealando al primer elemento. Avanzar: El cursor pasa a sealar al siguiente elemento. Fin: Es una funcin que indica si el cursor ha llegado al final de la secuencia.

9.2 Variables dinmicas.


Una variable dinmica no se declara como tal sino que se crea en el momento necesario, y se destruye cuando ya no se necesita. La variables dinmicas no tienen nombre, sino que se designan mediante otras variables llamadas puntero o referencias.

9.3 Punteros.
Los punteros o referencias son variables simples cuyo contenido es precisamente una referencia a otra variable.

El tipo de un puntero especifica en realidad el tipo de variable a la que puede apuntar.

9.3.1 DECLARACION.
typedef Tipo-de-variable* Tipo-puntero; Una variable puntero se puede usar para designar la variable apuntada mediante la notacin. *puntero Ejemplo. typedef int* Tp_Entero; Tp_Entero pe; *pe = 33;/*puntero sealando a una variable dinmica*/ printf( %d, *pe); Para detectar si un puntero seala realmente o no a otra variable, existe el valor especial NULL. Este valor es compatible con cualquier tipo de puntero, e indica que el puntero no seala a ninguna parte. Por lo tanto debera ser asignado a cualquier puntero que sepamos que no seala a ninguna variable. Normalmente se usara para inicializar las variables de tipo puntero al comienzo del programa. La inicializacin no es automtica, sino que debe ser realizada expresamente por el programador. Por ejemplo. if ( pe != NULL){ *pe = 33; printf( %d, *pe); }

En un principio esta sentencia garantiza que slo se usa la variable apuntada cuando realmente existe. Esto en realidad no es del todo cierto, ya que slo se puede garantizar que solo tienen valor no nulo los puntero que realmente sealan a variables que existen. Por ejemplo se puede destruir una variable dinmica pero conservar punteros que la referenciaban, y que ahora sealan a algo inexistente.

9.4 Uso de variables dinmicas.


Las variables dinmicas no tienen espacio en memoria reservado de antemano, sino que se crean a partir de puntero en el momento en que se indique. Adems, una vez creadas siguen existiendo incluso despus de que termine la ejecucin del subprograma donde se crean. La forma ms sencilla de crear una variable dinmica es mediante el operador new: typedef Tipo-de-variable* Tipo-puntero; Tipo-puntero puntero; puntero = new Tipo-de-variable; Representacin grfica de la sentencia.

Las variables dinmicas, una vez creadas, siguen existiendo hasta que se indique explcitamente que ya no son necesarias, en cuyo caso el espacio que se haba reservado para ellas quedar otra vez disponible par crear nuevas variables dinmicas. Para ello existe la sentencia delete, que permite destruir la variable dinmica a la que seala el puntero.
delete puntero;

Esta sentencia destruye la variable apuntada pero no garantiza que el puntero quede con un valor determinado. En particular no garantiza que tome valor NULL. Una variable dinmica puede estar referenciada por ms de un puntero. typedef int* Tp_Entero; Tp_Entero p1, p2;

p1 = new int; p2 = p1;

9.4.1 Variables dinmicas perdidas.


typedef int* Tp_Entero; Tp_Entero p1, p2; p1 = new int; p2 = new int; p2 = p1;

Las variables dinmicas no tienen espacio en memoria reservado de antemano, sino que se crean a partir de puntero en el momento en que se indique. Adems, una vez creadas siguen existiendo incluso despus de que

9.5 Realizacin de secuencias mediante punteros.


Existe una caracterstica especial, que se usa el identificador Tipo-nodo antes de ser definido completamente. Una vez definidos los tipos de la secuencia y sus componentes se podrn declarar variables de dicho tipos y operar con ellos: Tipo-componente valor; Tipo-secuencia secuencia , siguiente; if (secuencia != NULL) { (*secuencia).primero = valor;

siguiente = (*secuencia).resto; La combinacin del operador de desreferenciacin de puntero (*) y la seleccin de campo de registro (.) se combinan en un operador nico con una grafa ms simple 1 (->). Las sentencias anteriores se pueden reescribir como: if (secuencia != NULL) { secuencia ->primero = valor; siguiente = secuencia ->resto;La definicin simblica de una estructura ilimitada basndose en esquemas con nmero fijo de elementos ser, normalmente, recursiva. Una definicin recursiva es aquella en que se hace referencia a s misma.. Para definir una secuencia ilimitada tendremos que recurrir al empleo de variables dinmicas y punteros. Una manera de hacerlo es usar punteros para enlazar cada elemento de la secuencia con el siguiente tal y como se muestra.

Cada elemento de la secuencia se materializa como un registro con dos campos: 1. El primero contiene el valor de la componente2. El segundo es un puntero que seala al siguiente. El ltimo elemento tendr el puntero al siguiente con valor NULL. La secuencia completa es accesible a travs de un puntero que seala al comienzo de la misma. La siguiente definicin intenta ser lo ms parecida posible al la definicin recursiva propuesta antes: typedef struct Tipo-nodo { Tipo-componente primero; Tipo-nodo * resto; }; typedef Tipo-nodo * Tipo-secuencia;

9.6 Operaciones con secuencias enlazadas. 9.6.1 DEFINICION.


La definicin de la secuencia ser:

typedef struct TipoNodo { int valor; TipoNodo * siguiente; }; //ojo punto y coma despus del struct typedef TipoNodo * TipoSecuencia; TipoSecuencia secuencia;

9.6.2 RECORRIDO.
El recorrido de toda la secuencia se consigue mediante un bucle de acceso a elementos y avance del cursor. Puesto que la secuencia tiene un nmero indefinido de elementos, no se usar un bucle con contador. typedef TipoNodo * TipoPuntNodo; TipoPuntNodo cursor; cursor = secuencia; while (cursor != NULL) { printf ( %5d, cursor ->valor); cursor = cursor -> siguiente; }

9.6.3 BSQUEDA.
La bsqueda en una secuencia enlazada ha de hacerse de forma secuencial. La bsqueda es parecida al recorrido pero la condicin de terminacin cambiar. De hecho existir una doble condicin de terminacin: que se localice el elemento buscado , y/o se agote la secuencia. A continuacin se muestra la bsqueda de la posicin en que ha de insertarse un nuevo nmero en la secuencia ordenada. La posicin ser la que ocupe el primer valor igual o mayor que el que se quiere insertar. int numero; /*valor a buscar */ TipoPuntNodo cursor, anterior; cursor = secuencia; anterior = NULL; while (cursor !=NULL && cursor -> valor < numero) { anterior = cursor; cursor = cursor -> siguiente;

} Al salir del bucle cursor queda sealado al punto en que deber insertarse el nuevo elemento, y anterior seala al elemento que lo precede. Esto resulta til para realizar luego operaciones de insercin o borrado, como se ver a continuacin.

9.6.4 INSERCION.
La insercin de un nuevo elemento se consigue creando una variable dinmico para contenerlo, y modificando los punteros par enlazar dicha variable dentro de la secuencia. El caso ms sencillo es el de insertar un nuevo elemento detrs de uno dado.

El orden de las operaciones a realizar resulta esencial para que no se produzca la prdida de ninguna variable dinmico y por ello, en la figura tambin se ha detallado el orden de los pasos a realizar. int numero; /*valor a insertar*/ TipoPuntNodo cursor, anterior, nuevo; nuevo = new TipoNodo; 1 paso */ nuevo ->valor = numero ; nuevo ->siguiente = anterior ->siguiente; /* 2 paso */ anterior->siguiente = nuevo;
paso */ /* 3

/*

9.6.5 BORRADO.
Para borrar un elemento hay que quitar el nodo que lo contiene, enlazando directamente al anterior con el siguiente tal como se indica en la figura. Es la operacin inversa de ll insercin . Si el nodo que contena el elemento ya no es necesario hay que destruirlo explcitamente. Tambin en este caso es importante seguir el orden que se detalla en la figura.

TipoPuntNodo cursor, anterior; anterior->siguiente = cursor->siguiente; delete cursor; cursor = NULL;

9.7 Punteros y paso de argumentos. 9.7.1 Paso de puntero como argumentos.


Por defecto, los datos de tipo puntero se pasan como argumentos por valor. Si se desea usar un subprograma para modificar datos de tipo puntero, entonces habr que pasar el puntero por referencia mediante el mtodo usual ( smbolo & delante del argumento)
9.7.1.1 PASO POR VALOR.

void ImprimirtLista( TipoSecuencia lista) { TipoPuntNodo cursor = lista;

while (cursor != NULL){ printf ( "%5d", cursor->valor ); cursor = cursor->siguiente; } printf( "/n");

} TipoSecuencia secuencia; ImprimirLista( secuencia );


9.7.1.2 PASO POR REFERENCIA.

void Buscar (TipoSecuencia lista, int numero, TipoPuntNodo & cursor, TipoPuntNodo & anterior){ cursor = lista; anterior = NULL; while ( cursor != NULL && cursor->valor != numero ){ anterior = cursor; cursor = cursor -> siguiente; } }

9.7.2 Paso de argumentos mediante punteros.


Desde un punto de vista conceptual el paso de un puntero como argumento puede ser considerado equivalente a pasar como argumento la variable apuntada. Por ejemplo, si queremos pasar como argumento una variable dinmica podemos recurrir a un puntero como elemento intermedio para designarla. Esto representa una dificultad aadida para entender cmo funciona un determinado fragmento de cdigo, y de hecho representa un peligro potencial de cometer determinado errores de codificacin. La dificultad reside en el hecho de que pasar un puntero por valor no evita que el subprograma pueda modificar la variable apuntada. Por ejemplo: typedef int* Tp_Entero;

void Imprimir (Tp_Entero val ) { /*No modifica la variables apuntada */ printf ("%d", *val); } void Incrementar ( Tp_Entero al) { /*Modifica la variable apuntada */ *val= *val + 1; } Tp_Entero p1; p1 = new int; Imprimir( p1 ); Incrementar( p1 ); Al establecer la analoga entre el paso como argumento del puntero y el paso como argumento de la variable apuntada, la distincin entre paso por valor y por referencia se pierde. El paso por valor de un puntero equivale al paso por referencia de la variable apuntada. En realidad los punteros se usan implcitamente para pasar argumentos por referencia. Cuando se declara un argumento pasado por referencia, lo que hace realmente el compilador es pasar un puntero a la variable externa usada como argumento actual en la llamada. Dado el subprograma: void Duplicar ( int & valor ) { valor = 2 * valor; } El cdigo interno generado por el compilador es equivalente a : typedef int * P_int; void Duplicar (P_int p_valor) { *p_valor = 2 *(*p_valor); } De hecho la notacin & para indicar el paso de argumento por referencia es una mejora de C++ respecto a C. En el lenguaje C hay que usar siempere un puntero

explcito para pasar argumentos por referencia. En leguanje C ese operador corresponde tambin al smbolo &, como se muestra a continuacin: int numero; Duplicar( &numero ); Ahora debe quedar clara la manera de invocar ciertas funciones estndar de C, tal como scanf(). scanf(%d, &numero ); Lo que se hace en esta llamada es pasar como argumento un puntero que seala a la variable numero, a travs del cual se puede modificar su valor. Hay que hacer notar que el puntero en s se esta pasando por valor, y eso es equivalente a pasar el dato apuntado por referencia. ***En C para pasar la variable apuntada por valor hay que hacerlo de la manera convencional, como en el siguiente ejemplo. typedef int* Tp_Entero; void } void Incrementar( Tp_Entero val ) { /* Paso por *val = *val + 1; referencia */ } Tp_Entero p1; p1 = new int; Imprimir ( *p1 ); Incrementar ( p1 ); Imprimit ( int val ) { printf (%d, val) ; /*Paso por valor*/

9.8 Ejemplo: Leer nmero y escribirlos en orden pag. 378 del pdf 9.9 Punteros y vectores en C y C++.( Ejemplos validos en c y c++ pero no en c+-)
En el manual de estilo de C se invorpora una regla de obligad cumplimiento que prohbe el uso de puntero como formaciones. En las siguientes secciones se muestran operaciones que estan expresamente prohibidas y que no se deben utilizar en los programas.

10 Tipos abstractos de datos. 11 Mdulos.

También podría gustarte