viernes, 30 de julio de 2010

UNIDAD 4


UNIDAD 4. CLASES Y OBJETOS
4.1 DEFINICION DE UNA CLASE
Aquí tenemos la sintaxis para definir una clase:
ModifAcceso modifClase class nombreClase [extends nombreBase] [implements listaInterfaces] {
Atributo 1
Atributo N
Método 1
Método N
}
Donde nombreClase es el nombre de la clase, cualquier nombre, pero respetando las reglas de nomenclatura del lenguaje.
ModifAcceso puede ser uno de los siguientes valores: Public indica que la clase es pública, y por tanto que puede ser utilizada desde cualquier otra clase, con independencia de si están en el mismo paquete o no.
Sin especificar indica que la clase tiene visibilidad de paquete, es decir, sólo la pueden usar las clases que se encuentren en el mismo paquete que dicha clase.
ModifClase indica características específicas de la clase que estamos construyendo, los posibles
valores son:
abstract indica que a la clase le falta, al menos uno, el código de algún método. Posee el método (abstracto), pero no tiene el código de ese método, siendo responsabilidad de las clases derivadas proporcionar el código de dicha clase. Una clase abstracta no se puede instanciar. Final se emplea para evitar que esta clase pueda ser derivada.
Extends se utiliza para indicar que la clase hereda de nombreBase, en java sólo se permite heredar de una única clase base. En caso de no incluir la cláusula extends, se asumirá que se está heredando directamente de la clase java.lang.Object Implements indica que esta clase es de los tipos de interfaz indicados por listaInterfaces, pudiendo existir tantos como queramos separados por comas. Esta cláusula es opcional.
La definición de una clase especifica cómo serán los objetos de dicha clase, esto es, de que variables y de que métodos constarán. La siguiente es la definición más simple de una clase:
class nombreClase /* Declaración de la clase */
4.2 DECLARACION DE CLASES
La declaración de una clase define la estructura de la misma. Dicho de otra forma, la declaración de una clase informa de los elementos que la conforman. Posteriormente a ser declarada, una clase debe ser implementada convenientemente, es decir, se debe escribir el código correspondiente a los procedimientos y funciones que determinan el funcionamiento de esa clase.
Indica el nombre de la clase precedido por la palabra clave class.
Para declarar una clase, todo lo que se necesita es escribir una definición de estructura y sustituir la palabra reservada struct por class. Por ejemplo, una clase empleado con campos como el nombre, el departamento, la posición, el una función que nos imprima la información de este.
Quedaría así:
class Empleado {
char* m_nombre;
char* m_departamento;
char* m_posicion;
long m_salario;
void Imprimir( Empleado infoEmpleado);
}
Cuando usted declara una clase en C++, no se reserva memoria para la clase hasta que usted crea un objeto de la clase. Crear un objeto de una clase se llama instanciar un objeto. Un objeto creado de una clase de denomina instancia de una clase. Por ejemplo, yo puedo tener una instancia de empleado con el valor en m_nombre=Jose, m_departamento=Sistemas, m_posicion=programador y m_salario=3000000.
4.3 MIEMBROS DE UNA CLASE
Los miembros (datos miembros y funciones miembro) de una clase puede ser calificado como miembro estable de la declaración anterior con la palabra clave estática. Puede haber miembros de los datos estáticos y funciones miembro de una clase.
Los miembros de Datos Un miembro de datos estáticos de una clase es como una variable global para su clase. Es decir, los datos disponibles a nivel mundial es miembro de todos los objetos de ese tipo de clase. Los datos estáticos son generalmente mantenidos para almacenar los valores comunes a toda la clase. Por ejemplo, una clase puede tener un miembro de mantenimiento de los datos de seguimiento de su número de objetos existentes.
Un miembro de los datos es diferente de los miembros ordinarios de datos de una clase en varios
aspectos:
• Sólo hay una copia de un miembro de los datos mantenida por la totalidad de la clase que es compartida por todos los objetos de esa clase.
• Es visible sólo dentro de la clase, sin embargo, su duración (el tiempo para el que permanece en la memoria) es el programa entero. Dos cosas son necesarias para la fabricación de un miembro
de datos estáticos:
• Declaración en la definición de la clase
• Definición fuera de la definición de la clase
Los miembros de función Un miembro de la función que accede a la estática sólo los miembros de una clase puede ser declarada como estática. Esto puede hacerse mediante la palabra clave estática antes de la declaración de la función en la definición de la clase como se muestra a continuación:
La clase X (static int count; static void mostrar (void) (tribunal <
Sólo por el prefijo palabra clave estática antes de la declaración de la función en la definición de la clase, le han declarado la función como estática.
Una función miembro estática es diferente de los otros miembros de funciones en varios aspectos:
• Una función miembro puede tener acceso sólo los miembros estáticos (funciones o variables) de la misma clase.
• Una función miembro se invoca utilizando el nombre de la clase en lugar de sus objetos como se muestra a continuación:
clase name.function-nombre ();
Es decir, para llamar a la función estática show () se define por encima de la clase X, se escribe X.show ();
4.4 AMBITO REFERENTE A UNA CLASE

Una clase actúa como cualquier otro tipo de dato con respecto al ámbito. Todos los miembros de una clase se dice que están en el ámbito de esa clase; cualquier miembro de una clase puede referenciar a cualquier otro miembro de la misma clase.
Las funciones miembro de una clase tienen acceso no restringido a los miembros dato de esa clase. El acceso a los miembros dato y funciones de una clase fuera del ámbito de la clase está controlado por el programador. La idea es encapsular la estructura de datos y funcionalidad de una clase, de modo que el acceso a la estructura de datos de la clase desde fuera de las funciones miembro de la clase, sea limitada o innecesaria.
El nombre de la clase tiene que ser único dentro de su ámbito.Especificadores de acceso a los miembros de una clase
En una definición de clase, un especificador de acceso se utiliza para controlar la visibilidad de los miembros de una clase fuera del ámbito de la clase.
Los miembros de una clase pueden ser públicos, privados o protegidos. Las palabras reservadas public, private y protected se utilizan para controlar el modo de acceso a la clase.
Dentro de una declaración de clase, cada una de estas palabras se puede utilizar para preceder a una o más declaraciones de los miembros de una clase:- Acceso protegido.
Los miembros protegidos significan que sólo se puede acceder a ellos por funciones miembro dentro de la misma clase y por funciones miembro de clases derivadas de esta clase.- Acceso público. Los miembros públicos son accesibles por cualquier parte del programa.- Acceso privado. Los miembros privados sólo pueden ser utilizados por las funciones miembro de la clase y las funciones amigas de la clase.
Funciones miembro Son miembros de una clase y son funciones diseñadas para implementar las operaciones permitidas sobre los tipos de datos de una clase. Para declarar una función miembro hay que situar su prototipo en el cuerpo de la clase. No hay que definir la función dentro de la clase; dicha definición puede estar fuera de la clase e incluso en un archivo independiente, aunque también pueden ser definidas en línea dentro de la clase.
Las funciones miembro son necesarias para acceder a los datos privados. En general, son públicas; si no lo fueran, ninguna otra función podría llamarlas. Se pueden declarar para devolver valores con tipos incluyendo objetos de clases, punteros o referencias. Pueden ser declaradas también para aceptar cualquier número y tipo de argumentos. Los argumentos por defecto están permitidos, así como la notación de puntos suspensivos.

4.5 ESPECIFICADORES DE ACCESO

C++ introduce tres nuevas palabras clave para establecer las fronteras de una estructura: public, private y protected. Su uso y significado es bastante claro. Los especificadores de acceso se usan solo en la declaración de las estructuras, y cambian las fronteras para todas las declaraciones que los siguen. Cuando use un especificador de acceso, debe ir seguido de “:” .
4.6 CREACION DE OBJETOS

Para disponer de espacio en la memoria para guardar la información de uno de esos alumnos tendremos que crear un objeto con el patrón (clase) alumno. Los objetos se crean con la palabra reservada new.
En la siguiente instrucción:
uno = new alumno();
Creamos un objeto de la clase alumno que referenciamos con la variable uno

La variable tendrá que haberse declarado antes, y la declaramos como una variable del tipo alumno, ya que la vamos a usar para guardar información de objetos del tipo alumno.
Un programa con la declaración de la variable y la creación del objeto sería:
public class p2t1p5{
public static void main(String[] args){
alumno uno; // 1
uno = new alumno(); // 2
uno.nombre = "Joan"; // 3
uno.apellido = "Rosell Mas"; // 4
System.out.println(uno.nombre + " " + uno.apellido);
}
}
4.7 PUNTERO THIS
This es un puntero que se pasa automáticamente a cualquier miembro cuando se invoca. Es un puntero al objeto que genera la llamada, por tanto la función recibe automáticamente un puntero al objeto. A este puntero se referencia como this y solo se pasa a los miembros punteros this.
objeto.funcion(); // a la función recibe automáticamente el puntero this.
This es un puntero al objeto invocante. Este puntero es pasado automáticamente por el compilador como argumento en todas las llamadas a funciones miembro (no estáticas). Como su inclusión es automática y transparente para el programador, es frecuente referirse a él como argumento implícito u oculto.
El resultado es que cuando el compilador encuentra una invocación (con o sin argumentos) del tipo x.pow2(), calcula la dirección del objeto (&x), y realiza una invocación del tipo pow2(&x), utilizando esta dirección como valor del argumento oculto this. Por supuesto, el compilador añade por su cuenta el argumento correspondiente en la definición de la función X::pow2().
This es un puntero muy especial que no puede ser declarado explícitamente, por lo que la definición void pow2(X* this) { /* ... */ } no sería válida. Tampoco puede tomarse su dirección o ser utilizado como Rvalue para una asignación del tipo this = x (si puede en cambio ser utilizado como Lvalue).
this es una variable local
Como ocurre con todos los parámetros de funciones, resulta que this es una variable local (puntero) presente en el cuerpo de cualquier función miembro no estática. this no necesita ser declarado, y es raro que sea referenciado explícitamente en la definición de alguna función, lo que no es obstáculo para que sea utilizado dentro de la propia función para referenciar a los miembros.
Según lo anterior resulta evidente que, como tal variable local, esta palabra clave no puede ser usada fuera del cuerpo de un método de una clase.
En el siguiente ejemplo se definen dos clases, idénticas salvo en la forma de referenciar a sus miembros; en una se utiliza el puntero this de forma explícita, en otra de forma implícita, ambas son equivalentes, aunque es más normal utilizar la forma implícita.
Ejemplo:
#include
class X {
int x;
public:
int getx() { return x; }
void putx (int i) { x = i;
}};
class Y
{
4.8 CONSTRUCTORES Y DESTRUCTORES.
Constructores
Los constructores son unos métodos especiales que se ejecutan automáticamente al crear un objeto de la clase. En su declaración no se especifica el tipo de dato que devuelven, y poseen el mismo nombre que la clase a la que pertenecen. Al igual que otros métodos, puede haber varios constructores sobrecargados, aunque no pueden existir constructores virtuales.
Como característica especial a la hora de implementar un constructor, justo después de la declaración de los parámetros, se encuentra lo que se llama "lista de inicializadores". Su objetivo es llamar a los constructores de los atributos que conforman el objeto a construir.
Cabe destacar que no es necesario declarar un constructor al igual que un destructor, pues el compilador lo puede hacer, aunque no es la mejor forma de programar.Tomando el ejemplo de la Clase Punto, si deseamos que cada vez que se cree un objeto de esta clase las coordenadas del punto sean igual a cero podemos agregar un constructor.
Existen varios tipos de constructores en C++:
Constructor predeterminado: Es el constructor que no recibe ningún parámetro en la función. Si no se definiera ningún constructor, el sistema proporcionaría uno predeterminado. Es necesario para la construcción de estructuras y contenedores de la STL.
Constructor de copia: Es un constructor que recibe un objeto de la misma clase, y realiza una copia de los atributos del mismo. Al igual que el predeterminado, si no se define, el sistema proporciona uno.
Constructor de conversión: Este constructor, recibe como único parámetro, un objeto o variable de otro tipo distinto al suyo propio. Es decir, convierte un objeto de un tipo determinado a otro objeto del tipo que estamos generando.
Destructores
Los destructores son funciones miembro especiales llamadas automáticamente en la ejecución del programa, y por tanto no tienen por qué ser llamadas explícitamente por el programador. Su cometido es liberar los recursos computacionales que el objeto de dicha clase haya adquirido en tiempo de ejecución al expirar este.
Los destructores son invocados automáticamente al alcanzar el flujo del programa el fin del ámbito en el que está declarado el objeto.
Existen dos tipos de destructores pueden ser públicos o privados, según si se declaran:
si es público se llama desde cualquier parte del programa para destruir el objeto.
si es privado no se permite la destrucción del objeto por el usuario.
El destructor es muy similar al constructor, excepto que es llamado automáticamente cuando cada objeto sale de su ámbito de validez. Recordemos que las variables automáticas tienen un tiempo de vida limitado, ya que dejan de existir cuando se sale del bloque en que han sido declaradas.
Cuando un objeto es liberado automáticamente, su destructor, si existe, es llamado automáticamente.Un destructor tiene el mismo nombre que la clase a la que pertenece, pero precedido con una tilde (~). Igual que el constructor, un destructor no devuelve nada.
Si algún bloque de memoria fue reservado dinámicamente en un objeto, se puede utilizar el destructor para liberarlo antes de que se pierdan los punteros a esas variables.

martes, 27 de julio de 2010

UNIDAD 3 PUNTEROS, REFERENCIAS Y ARREGLOS


UNIDAD 3

PUNTEROS, REFERNCIAS Y ARREGLOS

3.1 CREACION
En C++ se puede crear un puntero genérico que puede recibir la dirección de cualquier tipo de dato.
La declaración de punteros utiliza un asterisco *, que en este caso actúa como calificador de tipo, en una sintaxis muy parecida a la utilizada en la declaración de objetos normales. En este capítulo nos referimos exclusivamente a declaración de punteros a objetos; la declaración de punteros a función será comentada en otro apartado. Cuando los punteros que señalan a miembros de clase (propiedades o métodos) presentan ciertas características especiales por lo que también serán tratados aparte.

En C++ se puede crear un puntero genérico que puede recibir la dirección de cualquier tipo de dato.
La declaración de punteros utiliza un asterisco *, que en este caso actúa como calificador de tipo, en una sintaxis muy parecida a la utilizada en la declaración de objetos normales. En este capítulo nos referimos exclusivamente a declaración de punteros a objetos; la declaración de punteros a función será comentada en otro apartado. Cuando los punteros que señalan a miembros de clase (propiedades o métodos) presentan ciertas características especiales por lo que también serán tratados aparte.
La sintaxis general de la declaración de puntero a objeto es: * [= ]
void main(){void *p;int a=1;double x=2.4;p=&a;p=&x; }
No se puede desreferenciar un puntero void.void main (){void *p;double x=2.5;p=&x;*p=3.6; // error: se desreferencia a un puntero void}
Los punteros siguen las reglas de creación y destrucción del resto de las variables, sin embargo hay que recordar que los objetos tienen duración independiente de los posibles que los señalan, de forma que cuando un puntero-a-objeto sale de ámbito, no se invoca implícitamente ningún destructor para el objeto señalado. A la inversa, la destrucción del objeto señalado no supone necesariamente la destrucción de los punteros que los referencian.
En la práctica pueden presentarse ambas circunstancias, ocasionando situaciones potencialmente peligrosas o erróneas. Por ejemplo, el primer caso puede ocurrir con objetos persistentes creados con los operadores new o new.

Este tipo de objetos son accesibles a través de un puntero, generalmente un objeto automático que es destruido automáticamente al salir de ámbito. Pero el objeto señalado permanece ocupando memoria, por lo que se hace necesaria una invocación explícita al operador delete para destruirlo antes que sea destruido el puntero, pues de lo contrario se produciría una perdida irrecuperable de memoria.
El segundo caso, la destrucción de un objeto sin que sean destruidos los punteros que lo señalan, también es bastante frecuente, dando lugar a los denominados punteros descolgados (“Dangling pointers”), cuyo uso inadvertido es especialmente .

3.2 OPERACIONES CON PUNTEROS

Un puntero es un tipo de dato similar a un entero, y hay un conjunto de operaciones definidas para punteros:
La suma o resta de un entero produce una nueva localización de memoria.
Se pueden comparar punteros, utilizando expresiones lógicas, para ver si están apuntando o no a la misma dirección de memoria.
La resta de dos punteros da como resultado el número de variables entre las dos direcciones.

Veamos cómo trabaja este programa:
princPunt es la dirección del primer elemento de vector, y finPunt la dirección del último elemento. int princPunt = vector; es una combinación de declaración y definición.
La expresión *(princPunt+2) incrementa el valor del puntero princPunt en dos y devuelve el número guardado en esa localización, es decir, apunta a la tercera localización de memoria y su valor es 15.
Se pueden utilizar también enteros en formato hexadecimal. Así,
cout << *(princPunt + 17 ) y cout << *(princPunt + 0x11 ) producen la misma salida.

La expresión princPunt == finPunt comprueba si los dos punteros son iguales. Esto sólo puede ser verdad si los dos punteros apuntan a la misma variable.
Siempre que se realiza una operación aritmética sobre un puntero, sumando o restando un entero, el puntero se incrementa o decrementa un número apropiado de sitios tal que el nuevo valor apunta a la variable que está n elementos (no n bytes) antes o después que el dado.

De la misma forma, al restar dos punteros se obtiene el número de objetos entre las dos localizaciones. Finalmente, dos punteros son iguales si y sólo si apuntan a la misma variable (el valor de las direcciones es el mismo). No son necesariamente iguales si sus valores indirectos son los mismos, ya que estas variables podrían estar en diferentes localizaciones de memoria.

3.3 REFERENCIAS
Las referencias son un tipo de dato C++ estrechamente relacionado con los punteros. Una referencia de un objeto no es un objeto, en el sentido que no tiene su propio espacio de almacenamiento como ocurre con los punteros, y en consecuencia no pueden realizarse con ellas muchas de las operaciones que se relacionan con objetos. Por ejemplo obtener su dirección, crearlas con el operador new, o crear matrices de referencias.
Una referencia es una especie de alias o "alter ego" del objeto. Como se verá a continuación, este concepto, que también existe en otros lenguajes, es un recurso de C++ para pasar argumentos a funciones permitiendo que los argumentos no sean simples variables locales de la función, sino objetos del ámbito que realiza la invocación, lo que permite que la función pueda modificar objetos externos a ella.
Sintaxis:
La declaración de una variable de este tipo se realiza mediante
el declarador de referencia &. La sintaxis general es:
& [ = ]
Ejemplo:
int x;
int & z = x; // decimos que x es el 'iniciador' y que z es la 'referencia'
Estas sentencias declaran e inicia la variable z como referencia-a-entero,
y la asocia con la variable x (que es un entero). En adelante z actúa como un alias de x,
de forma que cualquier operación sobre z equivale a hacerla sobre x. En realidad puede considerarse que z es "casi" un sinónimo de x (como si fuesen la misma variable). , si hacemos:
int x = 4;

Declaración: Las referencias no pueden ser declaradas aisladas, de forma que tienen que estar indefectiblemente unidas a un objeto en su propia definición (deben ser inicializadas en la declaración). Además, una vez declaradas no pueden ser reasignadas a otro objeto (como los punteros), por lo que resultan unidas de por vida al objeto inicial. Por ejemplo:Por la razón anterior, puesto que tienen que estar unidas a un objeto, no pueden referenciar a void:
int& z = void; // Error.
Sí pueden ser inicializadas a otra referencia del mismo tipo, en cuyo caso señalan al objeto inicial. Ejemplo:int& max
(int& a, int& b) {

3.4 ARREGLOS UNIDIMENSIONALES, BIDIMENSIONALES Y MULTIDIMENSIONALES
Arreglos Unidimensionales
Un arreglo unidimensional es un tipo de datos estructurado que está formado de una colección finita y ordenada de datos del mismo tipo. Es la estructura natural para modelar listas de elementos iguales. El tipo de acceso a los arreglos unidimensionales es el acceso directo, es decir, podemos acceder a cualquier elemento del arreglo sin tener que consultar a elementos anteriores o posteriores, esto mediante el uso de un índice para cada elemento del arreglo que nos da su posición relativa. Para implementar arreglos unidimensionales se debe reservar espacio en memoria, y se debe proporcionar la dirección base del arreglo, la cota superior y la inferior.
Representación en Memoria

Los arreglos se representan en memoria de la forma siguiente:
x : array[1..5] of integer

Arreglos Bidimensionales
Este tipo de arreglos al igual que los anteriores es un tipo de dato estructurado, finito ordenado y homogéneo. El acceso a ellos también es en forma directa por medio de un par de índices.Los arreglos bidimensionales se usan para representar datos que pueden verse como una tabla con filas y columnas. La primera dimensión del arreglo representa las columnas, cada elemento contiene un valor y cada dimensión representa una relación La representación en memoria se realiza de dos formas: almacenamiento por columnas o por renglones.

Arreglos Multidimensionales
Los arreglos multidimensionales tienen más de una dimensión. En C#, las dimensiones se manejan por medio de un par de corchetes, dentro de los que se escriben los valores de cada dimensión, separados por comas.Este también es un tipo de dato estructurado, que está compuesto por n dimensiones. Para hacer referencia a cada componente del arreglo es necesario utilizar n índices, uno para cada dimensión.
3.5 CADENAS DE CARACTERES
En programación, una cadena de caracteres, palabra, ristra de caracteres o frase (string en inglés) es una secuencia ordenada de longitud arbitraria (aunque finita) de elementos que pertenecen a un cierto alfabeto. En general, una cadena de caracteres es una sucesión de caracteres (letras, números u otros signos o símbolos).
Siguiendo en el ámbito de la informática, al considerar las cadenas como un tipo de datos, hay que definir (o conocer) cuales son las operaciones que podemos hacer con ellas, en principio éstas podrían ser muchas y llegar a ser muy sofisticadas.
Aquí se exponen algunas de ellas:
• Asignación: Consiste en asignarle una cadena a otra.
• Concatenación: Consiste en unir dos cadenas o más (o una cadena con un carácter) para formar una cadena de mayor tamaño.
• Búsqueda: Consiste en localizar dentro de una cadena una subcadena más pequeña o un carácter.

• Extracción: Se trata de sacar fuera de una cadena una porción de la misma según su posición dentro de ella.

• Comparación

3.6 ASIGNACION DINAMICA DE MEMORIA
Es la asignación de almacenamiento de memoria para utilización por parte de un programa de computador durante el tiempo de ejecución de ese programa. Es una manera de distribuir la propiedad de recursos de memoria limitada entre muchas piezas de código y datos. Un objeto asignado dinámicamente permanece asignado hasta que es desasignado explícitamente, o por el programador o por un recolector de basura; esto es notablemente diferente de la asignación automática de memoria y de la asignación estática de memoria (la de las variables estáticas). Se dice que tal objeto tiene tiempo de vida dinámico.
La asignación dinámica de memoria es una característica de C. Le permite al usuario crear tipos de datos y estructuras de cualquier tamaño de acuerdo a las necesidades que se tengan en el programa.

Se revisarán dos de las aplicaciones más comunes:
• Arreglos dinámicos
• Estructuras dinámicas de datos.
En C la asignación dinámica de memoria se manipula con las funciones malloc() y free(). En C++ se define un método de hacer asignación dinámica utilizando los operadores new y delete.

El operador new está disponible directamente en C++, de modo que no se necesita utilizar ningún archivo de cabecera; new se puede utilizar con dos formatos:new tipo // asigna un único elemento new tipo[num_eltos] // signa un arraySi la cantidad de memoria solicitada no está disponible, el operador new proporciona el valor 0. El operador delete libera la memoria signada con new.delete variabledelete [n] variable.

new es superior a malloc por tres razones:
1.- new conoce cuánta memoria se asigna a cada tipo de variable.
2.- malloc() debe indicar cuánta memoria asignar.
3.- new hace que se llame a un constructor para el objeto asignado y malloc no puede.
delete produce una llamada al destructor en este orden:
1. Se llama al destructor

3.7 USO DE CLASES DEFINIDAS PARA ARREGLOS

En el lenguaje de programación C una estructura(struct) es lo mismo que una clase, en este caso se explica referente a un struct.

Se puede crear un array de estructuras tal como se crea un array de otros tipos. Los arrays de estructuras son idóneos para almacenar un archivo completo de empleados, un archivo de inventario, o cualquier otro conjunto de datos que se adapte a un formato de estructura.

Mientras que los arrays proporcionan un medio práctico de almacenar diversos valores del mismo tipo, los arrays de estructuras le permiten almacenar juntos diversos valores de diferentes tipos, agrupados como estructuras.

Muchos programadores de C utilizan arrays de estructuras como un método para almacenar datos en un archivo de disco. Se pueden introducir y calcular sus datos de disco en arrays de estructuras y a continuación almacenar esas estructuras en memoria. Los arrays de estructura proporcionan también un medio de guardar datos que se leen del disco.La declaración de un array de estructuras info_libro se puede hacer de un modo similar a cualquier array es decir

struc info_libro libros [100];
asigna un array de 100 elementos denominado libros. Para acceder a los miembros de cada uno de los elementos estructura se utiliza una notación de array. Para inicializar el primer elemento de libros, por ejemplo, su código debe hacer referencia a los miembros de libros [0] de la forma siguiente:
strcpy (libros [0].titulo, "C++ a su alcance");
strcpy (libros [0].autor, "Luis Joyanes");

strcpy (libros [0].editorial, "McGraw-Hill");
libros [0].anyo=1999;

Tambien puede inicializarse un array de estructuras en el punto de la declaración encerrando la lista de inicializadores entrellaves, {}.

Por ejemplo:
struct info_libro libros [3] = { "C++ a su alcance", "Luis Joyanes", "McGraw-
Hill", 1999, "Estructura de datos", "Luis Joyanes", "McGraw-Hill", 1999,
"Problemas en pascal", "Angel Hermoso", "McGraw-Hill", 1997};

martes, 6 de julio de 2010

UNIDAD I PROGRAMACION I

1.1 INTRODUCCION AL LENGUAJE Y A SU ENTORNO DE DESARROLLO

Luego de la aparición de B y BCPL, en los Laboratorios Bell, Ken Thompson modeló muchas características sacadas de su lenguaje B, según las equivalentes en BCPL, con B creó las primeras versiones del sistema operativo UNIX, durante los 70s, en una computadora DEC PDP-7.
En 1972, Dennis Ritchie, estaba finalizando su proyecto, en los famosos Laboratorios Bell. "El lenguaje C", una evolución del B, implementado originalmente en una DEC PDP-11. Al contrario de sus antecesores, C era un lenguaje con tipos, es decir, que cada elemento de información ocupaba un 'palabra' en memoria y la tarea de tratar cada elemento de datos como número entero, real, o arreglos, no recaía en el programador.

C era conocido como el lenguaje con el cual se desarrolló el sistema operativo UNIX, y actualmente la mayoría de los sistemas operativos se codifican en C. Lo bueno de este lenguaje es que no depende de la arquitectura de hardware. Es posible escribir código en C, y llevarlos a otras máquinas. Eso lo convirtió en unos de los lenguajes más portátiles del mercado. A fines de los 70s, evolucionó lo que conocemos como... 'C de Kernigham y Ritchie', y el libro The C Programming Languaje que publicó Prentice Hall en 1978 se hizo impresionantemente famoso.
Claro que C tuvo un inconveniente, su amplia difusión ahora le estaba jugando una mala pasada, al ser tan universal, habían muchas variantes, además bastante incompatibles, creando serios problemas para los desarrolladores de software, que necesitaban escribir código para diferentes plataformas, y claro que era imprescindible que exista compatibilidad. Todo el mundo necesitaba que se cree una versión universal de C. Tarea llevada a cabo por la ANSI, que no fué sino hasta 1989 para que se aprobara el estándar. La ANSI cooperó con la ISO, en la estandarización mundial de C, el documento se publicó en 1990 y es posible pedirle a la ANSI una copia de ese documento.

Ahora, volvemos al principio de los 80s. Donde Bjarne Stroustrup, diseñó una extensión del lenguaje C, llamándolo C con Clases. El término clase provenía de Simula 67, y servía para entender mas el comportamiento del mundo real y llevarlo a los códigos, ocultando los detalles de su implementación.
En 1984, C con Clases fue rediseñado en un compilador y se lo denominó C ++. Como lo indica la nota Data Abstraction in C, en el Técnical Journal de AT&T Bell Laboratories. (vol. 63, núm 8, Octubre 1984). En 1985 estuvo disponible la primera versión del lenguaje C ++ y se realizó el libro de Bjarne Struostrup: The C ++ Programming Languaje, publicado por Addison-Wesley en 1986.
El nombre de C ++, fue porque éste último era una variante del C original. En el lenguaje C, el operador ++ significa, incrementar la variable, se eligió en nombre C ++, debido a que éste agregaba al C original el término de Programación Orientada a Objetos (POO), basadas en Simula 67.
Al ser C ++ una variación de C, los programas codificados en C pueden correr tranquilamente en C ++. En 1990, el lenguaje ha sido descrito por Stroustrup y Ellis en el Annotated C ++ Reference Manual editado por Addison -Wesley, existiendo una versión en español del mismo, con el título de C ++. Manual de Referencia con anotaciones publicado por Addison-Wesley/Días de Santos en 1994.
La versión actual estandarizada por ANSI, la versión 3.0 es la que soportan la mayoría de los fabricantes mundiales, como ser, Borland, AT&T, WatCom, Microsoft, etc, es sus respectivas actualizaciones.
Hoy en día, Borland ofrece el compilador de C++ en la versión 5.5 de forma gratuita.

1.2 COMENTARIOS

Son anotaciones; observaciones, recordatorios, etc. en el programa. Son para uso exclusivo del programador, y eliminados del código fuente en la fase de preprocesado; antes del análisis sintáctico.
Aparte de las consideraciones estrictamente formales que se indican en esta sección, no debemos perder de vista que los comentarios, aunque voluntarios (no es obligatorio escribirlos), representan una ayuda inestimable durante la construcción del programa. Siendo imprescindibles para el programador original, o los que le sucedan en las tareas de mantenimiento, cuando es necesario habérselas con el código un tiempo después de que fue escrito. Además de clarificar ideas, los comentarios son también un valioso instrumento de depuración, pues permiten eliminar provisionalmente secciones enteras de código.

Comentarios C
Un comentario C es cualquier secuencia de caracteres contenida entre los delimitadores /* ... */. La totalidad de la secuencia, incluyendo los delimitadores /* y */ son sustituidos por un simple espacio después de la expansión de macros (algunas implementaciones de C pueden eliminar los comentarios sin reemplazarlos por espacios).
Ejemplo:
int x = 2; /* esto es un comentario que será eliminado o sustituido por un simple espacio después en la frase de preprocesado. Como puede verse, el comentario puede ocupar varias líneas de texto en el código fuente. Se recomienda utilizarlos con profusión, a veces todas las explicaciones son pocas, ya que el C++ es un lenguaje bastante críptico en algunas ocasiones, sobre todo algunas sentencias muy "elegantes" y comprimidas, pero ininteligibles en una primera lectura */

Comentarios C++
C++ admite comentarios de una sola línea utilizando dos barras inclinadas ( // ) como señal de comienzo. El comentario empieza en este punto (incluyendo las señales de comienzo) y continúa hasta el próximo carácter de nueva línea.
Ejemplo:
class X { // esto es un comentario
...
};

Hay tres tipos de comentarios en Java:
// Este es un comentario de una sola línea
/* Este es un comentario de una o más líneas */
/** Este

1.3 VARIABLES Y CONSTANTES

Una variable es un nombre asociado a un elemento de datos que está situado en posiciones contiguas de la memoria principal, y su valor puede cambiar durante la ejecución de un programa.
Una constante es un dato cuyo valor no puede cambiar durante la ejecución del programa. Recibe un valor en el momento de la compilación y este permanece inalterado durante todo el programa.

El término variable describe a los datos que pueden cambiar de valor mientras el programa está en ejecución, mientras que el término constante describe a los datos cuyo valor se establece al inicio del programa y permanecen sin cambio durante toda la ejecución.
Aunque las variables pueden cambiar de valor mientras el programa está en ejecución, hay algunas ocasiones en que el valor de inicio se establece por los programadores para permitir a las variables que se utilicen con un valor conocido. Esto se conoce como inicializar la variable.
Cómo nombrar las variables y las constantes?
Las variables y las constantes se alojan en alguna dirección particular de la memoria. Aunque el valor de las variables puede modificarse, la dirección de la memoria que ocupan, permanece siendo la misma.
Las direcciones de la memoria se pueden identificar con números enteros en base hexadecimal, como AD56 o F0FF. Sin embargo, para que los programadores puedan recordar más fácilmente la dirección de memoria que aloja el valor deseado, se les pone un nombre.
Algunos lenguajes de programación no permiten el uso de ciertos caracteres en los nombres de las variables y las constantes. Es posible que los nombres no empiecen con dígitos y no deben tener el mismo nombre que las palabras reservadas en el lenguaje de programación.
Principales diferencias:
• Las constantes ya reciben un valor inicial en su declaración
• Las variables primero se declaran, luego se inician, y luego se usan
• Las constantes, una vez declaradas mantienen su valor durante toda la ejecución del programa
• En cambio, las variables pueden cambiar su valor tantas veces como deseen
• Además de cambiar su valor, las variables también pueden cambiar de tamaño en tiempo de ejecución (
1.4 OBJETOS QUE PERMITEN E/S POR CONSOLA

En C++ se pueden seguir utilizando las mismas sentencias para mostrar información por pantalla o pedirla mediante teclado. Pero a estas antiguas se añaden 2 nuevas de la misma potencia y mayor facilidad de uso. La cabecera que utilizan estas dos sentencias es iostream.h.
Mostrar por pantalla (Objeto de Salida):cout <<>> variable; La variable pude ser de cualquier tipo.
Ejemplo:#include #include #include void main(){int i,j;double d;clrscr();i=10;j=15;cout <<"Introducir valor: ";cin>>d;cout << "Estos son los valores: ";cout <<>

En Java Existen varios Objetos que permiten Entrada y Salida de datos a través de la Consola (es decir teclado y pantalla). System.out.print (clase de salida)la Clase System.out contiene 2 flujos de salida, a saber: - print - println La diferencia entre ambos sería que println da un “enter” al final de cada línea de código mostrado.
Por ejemplo: System.out.print(“Hola mundo”);System.in (Clase de entrada)
La clase System.in podriamos decir que por si misma no puede funcionar y requiere de otra para dicho propósito: Scanner. A diferencia de System.out.print que se puede usar “directo” en el caso de Scanner y System.in se requiere de un objeto intermediario.
La sintaxis sería: Scanner nombreObjeto = new Scanner(System.in);Donde nombreObjeto puede ser cualquier identificador (o sea nombre) que usted desee darle. Por ejemplo, yo decidí nombrar mi objeto con el identificador tepic. Por tanto mi sintaxis queda: Scanner tepic = new Scanner(System.in);

1.5 OPERADORES
C es un lenguaje muy rico en operadores. Se definen seis tipos de operadores: aritméticos, relacionales, de asignación, lógicos, de dirección y de movimiento.
Existe otro tipo de operador denominado molde que su función es hacer posible que una expresión sea de un tipo determinado utilizando la sintaxis (tipo) expresión; Siendo tipo uno de los tipos estándar de C (ver capítulo 4). Por ejemplo, si se quiere asegurar que la expresión x/2 se evalúe de tipo float, se puede escribir: (float) x/2;.

Operadores aritméticos:Lista de operadores aritméticos con su significado+ Suma- Resta* Producto/ Cociente de una división% Resto de una división
Operadores lógicos ! Not (no lógico)&& And (y lógico) Or (ó lógico)

Operadores relacionales: == Igual a!= No igual a> Mayor que<>= Mayor o igual que<= Menor o igual que Operadores de asignación: = = =++ m++ m=m+1-- m-- m=m-1+= m+=n m=m+n-= m-=n m=m-n*= m*=n m=m*n/= m/=n m=m/n%= m%=n m=m%n Los operadores de asignación ++ y ¿ pueden ir antes o delante de una expresión formando una nueva expresión. Estas expresiones se denominan post-incrementos o pre-incrementos (decrementos si el operador es --) y son expresiones compuestas, normalmente son del tipo y=x++; (y=++x;). Operadores de dirección: * Operador de contenido de apuntado u operador de indirección & Operador de direcciónOperadores de movimientoExiste un último tipo de operadores, no comentado hasta el momento, los operadores de movimiento (<<, movimiento a la izquierda y >>, a la derecha). Su función es desplazar los bits de la palabra de memoria dada tantos espacios como se le indiquen a derecha o izquierda. La forma general es: expresion1<

1.5 TIPOS DE DATOS
En lenguajes de programación un tipo de dato es un atributo de una parte de los datos que indica al ordenador (y/o al programador) algo sobre la clase de datos sobre los que se va a procesar. Esto incluye imponer restricciones en los datos, como qué valores pueden tomar y qué operaciones se pueden realizar. Tipos de datos comunes son: enteros, números de coma flotante (decimales), cadenas alfanuméricas, fechas, horas, colores, coches o cualquier cosa que se nos ocurra.

Por ejemplo, en Java, el tipo "int" representa un conjunto de enteros de 32 bits cuyo rango va desde el -2.147.483.648 al 2.147.483.647, así como las operaciones que se pueden realizar con los enteros, como la suma, resta y multiplicación. Los colores, por otra parte, se representan como tres bytes denotando la cantidad de rojo, verde y azul, y una cadena de caracteres representando el nombre del color; las operaciones permitidas incluyen la adición y sustracción, pero no la multiplicación

Éste es un concepto propio de la informática, más específicamente de los lenguajes de programación, aunque también se encuentra relacionado con nociones similares de las matemáticas y la lógica.En un sentido amplio, un tipo de datos define un conjunto de valores y las operaciones sobre estos valores.1 Casi todos los lenguajes de programación explícitamente incluyen la notación del tipo de datos, aunque lenguajes diferentes pueden usar terminología diferente. La mayor parte de los lenguajes de programación permiten al programador definir tipos de datos adicionales, normalmente combinando múltiples elementos de otros tipos y definiendo las operaciones del nuevo tipo de dato. Por ejemplo, un programador puede crear un nuevo tipo de dato llamado "Persona" que especifica que el dato interpretado como Persona incluirá un nombre y una fecha de nacimiento
Un tipo de dato puede ser también visto como una limitación impuesta en la interpretación de los datos en un sistema de tipificación, describiendo la representación, interpretación y la estructura de los valores u objetos almacenados en la memoria del ordenador. El sistema de tipificación usa información de los tipos de datos para comprobar la verificación de los programas que acceden o manipulan los datos.

Tipos de datos máquinaTodos los datos en los ordenadores basados en la electrónica digital se representan como bits (valores 0 y 1) en el nivel más bajo. La más pequeña unidad direccionable
de datos es un grupo de bits llamado un byte (normalmente un octeto, que son 8 bits). La unidad procesada por las instrucciones del código máquina se le llama una palabra (en 2006, normalmente 32 o 64 bits). La mayor parte de las instrucciones.

interpretan la palabra como un número binario, como por ejemplo una palabra de 32 bits puede representar valores enteros sin signo desde el 0 al 232 − 1 o valores enteros con signo desde − 231 al 231 − 1. Por medio del complemento a dos, la mayor parte del tiempo, el lenguaje máquina y la propia máquina no necesitan distinguir entre tipos de datos con o sin signo.
Existe un específico conjunto de instrucciones aritméticas que usa una diferente interpretación de los bits de una palabra como número en coma flotante.

Tipos primitivosSe llama tipo primitivo o tipo elemental a los tipos de datos originales de un lenguaje de programación, esto es, aquellos que nos proporciona el lenguaje y con los que podemos (en ocasiones) construir tipos de datos abstractos y estructuras de datos.

1.6.1 FUNDAMENTALES

C++ tiene los siguientes tipos fundamentales:
• Caracteres: char (también es un entero), wchar_t
• Enteros: short int, int, long int, long long int
• Números en coma floante: float, double, long double
• Booleanos: bool
• Vacío: void

1.6.2 DEFINIDOS POR EL USUARIO
Existen dos diferentes tipos de datos simples definidos por el usuario: enumerados y subrago.
Tipos enumerados
Los tipos enumerados se componen de una lista de identificadores encerrados entre paréntesis y separados por comas.
Ejemplo:
Type
Estaciones = (primavera, verano, otoño, invierno);
Colores (rojo, amarillo, verde, azul, violeta);
Los tipos enumerados son ordinales ya que llevan asociado cada uno un número entero, empezando por el primero, al que se le asigna el O, al segundo un 1, y así sucesivamente, por lo que no es independiente el orden de declaración. Un valor de tipo enumerado no puede pertenecer a dos declaraciones de tipo distintas y no pueden leerse desde teclado, ni escribirse en pantalla.

Tipos subrango
Es un subconjunto de un tipo ordinal (enteros, boolean, carácter y enumerado) que se especifica indicando el primero y el último elemento del conjunto.
Ejemplo 1:
Type
Identificador=primerelemento..ultimoelemento;
Ejemplo 2:
Type
Fecha= 1..31;
Var
Dia: Fecha;
Los tipos enteros, carácter, booleanos, enumerados y subrango se denominan tipos ordinales. Un tipo ordinal representa una secuencia ordenada de valores individuales, a los que se puede aplicar los conceptos de predecesor y sucesor. En cada tipo de datos ordinales hay un primer valor y un último valor.

1.7 PALABRAS RESERVADAS

En los lenguajes de programación, una palabra reservada es una palabra que tiene un significado gramatical especial para ese lenguaje y no puede ser utilizada como un identificador en ese lenguaje.
Por ejemplo: en SQL, un usuario no puede ser llamado "group", porque la palabra group es usada para indicar que un identificador se refiere a un grupo, no a un usuario. Al tratarse de una palabra clave su uso queda restringido.
Ocasionalmente la especificación de un lenguaje de programación puede tener palabras reservadas que están previstas para un posible uso en futuras versiones. En Java const y goto son palabras reservadas — no tienen significado en Java, pero tampoco pueden ser usadas como identificadores. Al reservar los términos pueden ser implementados en futuras versiones de Java, si se desea, sin que el código fuente más antiguo escrito en Java deje de funcionar.

Palabras reservadas C/C++:
abstract event namespace static
as explicit new string
base extern null struct
bool false object switch
break finally operator this
byte fixed out throw
case float override true
catch for params try
char foreach private typeof
checked goto protected uint
class if public ulong
const implicit readonly unchecked
continue in ref unsafe
decimal int return ushort
default interface sbyte using
delegate internal sealed virtual
do is short volatile
double lock sizeof void
else long stackalloc while
enum

1.8 EXPRESIONES

Las expresiones son combinaciones de constantes, variables, símbolos de operación, paréntesis y nombres de funciones especiales. Las mismas ideas son utilizadas en notación matemática tradicional.
Por ejemplo:
a + (b+3) + c
Aquí los paréntesis indican el orden de cálculo y representa la función raíz cuadrada.
Cada expresión toma un valor que se denomina tomando los valores de las variables y constantes implicadas y la ejecución de las operaciones indicadas. Una expresión consta de operandos y operadores.
Según sea el tipo de objetos que manipulan, se clasifican las expresiones en:
• Aritméticas
• Relacionales
• Lógicas
• Carácter
El resultado de la expresión aritmética es de tipo numérico; el resultado de una expresión relacional y de una expresión lógica es de tipo lógico; el resultado de una expresión carácter es de tipo carácter.

1.9 ESTRUCTURAS DE CONTROL

En lenguajes de programación, las estructuras de control permiten modificar el flujo de ejecución de las instrucciones de un programa.
Con las estructuras de control se puede:
•De acuerdo a una condición, ejecutar un grupo u otro de sentencias (If-Then-Else y Select-Case-if-else-switch)
• Ejecutar un grupo de sentencias mientras exista una condición (While)
• Ejecutar un grupo de sentencias hasta que exista una condición (Do- While)
• Ejecutar un grupo de sentencias un número determinado de veces (For)
Todas las estructuras de control tienen un único punto de entrada y un único punto de salida.

Las estructuras de control se puede clasificar en :
• secuenciales
• iterativas
• control avanzadas
Esto es una de las cosas que permite que la programación se rija por los principios de la programación estructurada.

1.9.1 ASIGNACION

Se puede asignar la información contenida en una estructura a otra estructura del mismo tipo mediante una única instrucción de asignación. No es necesario asignar el valor de cada miembro por separado.
El siguiente ejemplo ilustra las asignaciones de estructuras:
#include
int main (void)
{
struct {
int a;
int b;
} x, y;
x.a = 10;
y = x; /* asigna una estructura a la otra*/
prinf ("%d", y.a);
return 0;
}
Tras la asignación, y.a contiene el valor 10.

1.9.2 SELECCION

La instrucción selectiva determina si una determinada instrucción se ejecuta o no, según el cumplimiento de una condición P.
Ejemplo:
Si condición P entonces
Instrucciones
Fin si
La condición P es una variable booleana o una función reducible a booleana (lógica, Verdadero/Falso). Si esta condición es cierta se ejecuta Instrucciones1, si no es así, ésta no se ejecuta.
La estructura selectiva permite la realización de una instrucción u otra según un criterio, solo una de estas instrucciones se ejecutara.
Ejemplo:
IF a > b THEN
PRINT a ; "es mayor que" ; b
ELSE
PRINT a ; "no es mayor que" ; b
END IF
Esta instrucción selectiva puede presentar dos mensajes, uno a es mayor que b, y el otro a no es mayor que b, solo uno de ellos será presentado, según el resultado de la comparación de a y b, si el resultado de a > b es cierto, se presenta el primer mensaje, si es falso el segundo, las palabras IF, THEN, ELSE, END IF; son propias de la instrucción (palabra reservadas) que tienen un significado en el lenguaje, sirven de separadores, y el usuario no debe utilizarlas salvo para este fin.

• IF señala el comienzo de la instrucción condicional, y se espera que después esté la condición de control de la instrucción.
• THEN señala el fin de la condición, y después estará la instrucción a realizar si la condición es cierta.
• ELSE separa la instrucción que se ejecutará si la condición es cierta de la que se ejecutará si es falsa.
• END IF indica que la instrucción condicional finaliza y el programa seguirá su curso.
Ampliemos un poco el ejemplo anterior:
IF a > b THEN
PRINT a ; "es mayor que" ; b
ELSEIF a < a=" 0" b=" 7"> a;
Cout<< a=" a" a="0" b="7."> a.
Cuando a=0 y b=7. la condición es cierta, en el cuerpo del bucle se escribe el valor de a en pantalla y se incrementa a en una unidad. Entonces a=1 y b=7.
...
...
Cuando a=6 y b=7. la condición es cierta, se escribe el valor de a en pantalla y se incrementa en una unidad.
Resultando que a=7 y b=7. Entonces la condición es falsa y la instrucción WHILE finaliza.
La salida por pantalla de este ejemplo seria 0 1 2 3 4 5 6.

1.9.3 ITERACION

Las instrucciones iterativas abren la posibilidad de realizar una secuencia de instrucciones más de una vez.
Un bucle iterativo o iteración de una secuencia de instrucciones, hace que se repitan mientras se cumpla una condición, en un principio el número de iteraciones no tiene porque estar determinado.
Ejemplo: a= 0 b= 7 While b > a; Cout<< a=" a" a="0" b="7."> a.Cuando a=0 y b=7. la condición es cierta, en el cuerpo del bucle se escribe el valor de a en pantalla y se incrementa a en una unidad. Entonces a=1 y b=7.......Cuando a=6 y b=7. la condición es cierta, se escribe el valor de a en pantalla y se incrementa en una unidad.Resultando que a=7 y b=7. Entonces la condición es falsa y la instrucción WHILE finaliza.La salida por pantalla de este ejemplo seria 0 1 2 3 4 5 6


ver los codigo resuelto












































































bibliografia
http://www.tutoriales.itsa.edu.mx/programacion1/index.php?mod=tiposdedatos&ban=0



jercicio resulto de programacion I
en esta pagina podra descargarlo
http://www.zshare.net/download/78350267a24e1aaf/



UNIDAD 2. SUBPROGRAMAS
2.1 DEFINICION DE UN SUBPROGRAMA

Los subprogramas son pequeños programas que pueden usarse para dividir un programa por tareas. Entre las tareas más comunes en un programa están las tareas para recolectar datos, calcular, mostrar información o coordinar la ejecución de otros subprogramas.
Los subprogramas para recolectar datos son los responsables de recoger los datos que el programa necesita para realizar su labor.
En esta categoría están los subprogramas que:

• piden los datos al usuario• adquieren los datos a través de otros medios de entrada (por ejemplo, archivos)
Los subprogramas que realizan cálculos reciben los datos que necesitan de los subprogramas que recolectan datos o de otros subprogramas que realizan cálculos. Entre las tareas efectuadas por los subprogramas de esta categoría están las operaciones para:
• evaluar fórmulas (por ejemplo, F = 9/5C + 32)• determinar propiedades (por ejemplo, ¿es un número positivo?)• comparar cantidades (por ejemplo, ¿es un número mayor que otro número?)
Los subprogramas para mostrar información presentan al usuario los resultados producidos por los subprogramas que realizan cálculos. Además, pueden usarse para mostrar instrucciones al usuario de cómo usar el programa o para qué es el programa.
En la última categoría, subprogramas que coordinan tareas, están los subprogramas que gobiernan otros subprogramas. En otras palabras, son subprogramas que le indican a otros subprogramas cuando deben realizar su tarea y que datos deben recibir. Un ejemplo de un subprograma que gobernará otros subprogramas es el main.
2.1.1 ESTRUCTURA DE UN SUBPROGRAMA
Un subprograma es, sencillamente, un conjunto de sentencias que se pueden llamar desde cualquier parte de un programa. Los subprogramas permiten al programador un grado de abstracción en la resolución de un problema.
Los subprogramas en C no se pueden anidar. Esto significa que un subprograma no se puede declarar dentro de otro subprograma. La razón para esto es permitir un acceso muy eficiente a los datos. En C todos los subprogramas son externos o globales, es decir, pueden ser llamadas desde cualquier punto del programa.
La estructura de un subprograma en C se muestra a continuación:
Tipo_de_retorno nombreFuncion (listadeParámetros)
{
cuerpo de la función
return expresión
}
Tipo_de_retorno: Tipo de valor devuelto por el subprograma o la palabra reservada void si el subprograma no devuelve ningún valor.
nombreFuncion: Identificador o nombre del subprograma.
listadeParámetros: Lista de declaracione de los parámetros del subprograma separados por comas.
expresión: Valor que devuelve el subprograma.

Ejemplo:
float suma (float num1, float num2)
{
float resp;
resp=num1+num2;
return resp;
}

2.1.2 VALOR DE RETORNO
El tipo del valor a retornar puede ser:
• un tipo primitivo, por ejemplo, int, double, char o bool.• la localización (dirección) de un lugar en la memoria donde hay un valor de algún tipo.• definido por el programador.• void; si no tiene instrucción de retorno.
El valor retornado por la instrucción de retorno tiene que coincidir con el tipo del valor a retornar a menos que sea void. Un subprograma con etiqueta void es el equivalente a una subrutina. El valor retornado puede estar guardado en una variable, en una constante o puede ser un literal.
2.2 DECLARACION DE UN SUBPROGRAMA

Cualquier nombre en C++, incluyendo el nombre de un subprograma, que se utilice en un programa tiene que haber sido declarado antes de usarse en el programa. De lo contrario, el compilador mostrará un error indicando que el nombre no está definido.
Por lo tanto, antes de invocar una función para que haga su tarea hay que declarar el subprograma de la siguiente forma:
( ) ;
La declaración del subprograma tiene que coincidir con el encabezado de la definición del subprograma. La diferencia entre el encabezado y el prototipo es el punto y coma al final del prototipo.

2.3 BIBLIOTECAS O LIBRERIAS DE SUBPROGRAMAS

C++ proporciona una nueva biblioteca de funciones que realizan operaciones de E/S: la biblioteca iostream. Esta biblioteca es una implementación orientada a objetos y está basada, al igual que stdio, en el concepto de flujos. Cuando se introducen caracteres desde el teclado, puede pensarse en caracteres que fluyen desde el teclado a las estructuras de datos del programa. Cuando se escribe en un archivo, se piensa en un flujo de bytes que van del programa al disco.Para acceder a la biblioteca iostream se debe incluir el archivo iostream.h. Este archivo contiene información de diferentes funciones de E/S. Define también los objetos cin y cout

Manipuladores de salida
La biblioteca iostream define varios operadores particulares, llamados manipuladores, que le permiten controlar precisamente, el formato de los datos visualizados. Situando un manipulador en la cadena de operadores <<, se puede modificar el estado del flujo.Una característica importante de un flujo que debe tratar con valores numéricos es la base de los números. Hay tres manipuladores (dec, hex y oct) para controlar la situación. La base por omisión es 10 y por tanto sólo será necesario indicar dec cuando se haya fijado la base a otro valor: cout <
Los manipuladores que toman argumentos se declaran en iomanip.h, el resto en iostream.h.
A continuación mostraremos un listado con los manipuladores, su aplicación y la descripción. Cada uno de ellos lo separaremos mediante --:
dec -- cout<
dec -- cin>>dec>>x; -- Conversión a decimal
Hex -- out<
Hex -- cin>>hex>>x; -- conversión a hexadecimal
oct -- cout<
oct -- cin>>oct>>x; -- conversión a octal
ws -- cin>>ws; Salta espacios en la entrada
ende -- cout<
flush -- cout<
fill(int) -- cout<
tprecision(int) -- cout<
(6); -- Fija la conversión en coma flotante al nº de dígitos especificadose
tw(int) -- cout<>setw(10)>>x; -- Fija la anchura
Con setw() los valores numéricos se justifican a derechas y los datos carácter a izquierdas.

La información de la justificación de la salida se almacena en un modelo o patrón de bits de una clase llamada ios, que constituye la base de todas las clases de flujos. Puede establecer o reinicializar bits específicos utilizando los manipuladores setiosflags() y resetiosflags() respectivamente.
Para utilizar cualquiera de los indicadores de formato hay que insertar el manipulador setiosflags() con el nombre del indicador como argumento. Hay que utilizar resetiosflags() con el mismo argumento para invertir el estado del formato antes de utilizar el manipulador setiosflags().
Indicador -- Significado del indicador activadoios::left -- Justifica la salida a la izquierdaios::right -- Justifica la salida a la derechaios::scientific -- Utiliza notación científica para números de coma flotanteios::fixed -- Utiliza notación decimal para números de coma flotanteios::dec -- Utiliza notación decimal para enterosios::hex -- Utiliza notación hexadecimal para enterosios::oct -- Utiliza notación octal para enterosios::showpos -- Muestra un signo positivo cuando se visualizan valores positivosEn C++, la biblioteca estándar es una colección de Clases y funciones, escritas en el núcleo del lenguaje. La biblioteca estándar proporciona varios contenedores genéricos, funciones para utilizar y manipular esos contenedores, funciones objeto, cadenas y flujos genéricos (incluyendo E/S interactiva y de archivos) y soporte para la mayoría de las características del lenguaje. La biblioteca estándar de C++ también incorpora la ISO C90 biblioteca estándar de C.

Las características de la biblioteca estándar están declaradas en el espacio de nombres (namespace) std.La Standard Template Library es un subconjunto de la biblioteca estándar de C++ que contiene los contenedores, algoritmos, iteradores, funciones objeto, etc; aunque algunas personas utilizan el término STL indistintamente con la biblioteca estándar de C++.Los archivos de Cabecera de la biblioteca estándar de C++ no terminan en ".h".La siguiente tabla contiene las declaraciones de la biblioteca estándar

2.4 PRIMER ACERCAMIENTO A CLASES Y OBJETOS

¿Cuál es una clase?
Una clase define un tipo de datos, como un struct estaría en C. En un sentido de la informática, un tipo consiste en un sistema de estados y un sistema de las operaciones que transición entre esos estados. Así interno es un tipo porque tiene un sistema de estados y tiene operaciones como i + j o i++, etc. Exactamente de la misma manera, una clase proporciona un sistema de operaciones (generalmente públicas), y un sistema de bits de datos (generalmente no públicos) que representan los valores del extracto que los casos del tipo pueden tener.
Usted puede imaginarse que interna es una clase que tiene funciones del miembro llamadas operator++, etc. (interno no está realmente una clase, pero la analogía básica es ésta: una clase es un tipo, como interno es un tipo.) Nota: un programador de C puede pensar en una clase como struct de C que miembros omitan privado. Pero si ése es todo usted piensa en una clase, después usted necesita probablemente experimentar un cambio personal del paradigma.
¿Cuál es un objeto?
Una región del almacenaje con la semántica asociada. Después del declaración i interno; decimos que “i es un objeto del tipo interno.” En OO/C++, “opóngase” significa generalmente “un caso de una clase.” Así una clase define el comportamiento posiblemente de muchos objetos (casos).
A todos aquellos acostumbrados a trabajar con sistemas de programación orientada a objetos les resultara algo obvio, pero como este es un concepto nunca antes aplicado a Remedy vamos a intentar definir de una forma sencilla lo que implica la POO.
La POO aporta un enfoque distinto, convirtiendo la estructura de datos en objetos que pueden almacenar, manipular y combinar información. Para almacenar e identificar estos objetos se hace uso de las clases. Las clases son elementos abstractos y genéricos que por si tienen entidad propia. Están definidas por unos atributos básicos (características) y unos métodos (funciones que permitan el control sobre su uso).
Un ejemplo básico de una clase sería el siguiente:
Clase: vehículo
Atributos: motor, ruedas
Métodos: moverse, pararse, hacia delante, atrás, derecha e izquierda.
En la aplicación de este concepto a Remedy y a la gestión de inventario, tenemos el siguiente ejemplo:
Clase: Pc
Atributos: Marca, Modelo, memoria RAM, Procesador
Métodos: Toda la funcionalidad que se puede gestionar a través de Asset Management o cualquier otra herramienta (dar de alta, enviar a almacen, dar de baja, etc.).

2.5 AMBITO Y TIEMPO DE VIDA DE VARIABLES

Según el lugar donde son declaradas puede haber dos tipos de variables:
Globales: las variables permanecen activas durante todo el programa. Se crean al iniciarse éste y se destruyen de la memoria al finalizar. Pueden ser utilizadas en cualquier función.
Locales: las variables son creadas cuando el programa llega a la función en la que están definidas. Al finalizar la función desaparecen de la memoria.
Si dos variables, una global y una local, tienen el mismo nombre, la local prevalecerá sobre la global dentro de la función en que ha sido declarada.
Dos variables locales pueden tener el mismo nombre siempre que estén declaradas en funciones diferentes.

2.6 ARGUMENTOS Y PASO DE PARAMETROS
Las palabras parámetro y argumento, aunque de significado similar, tiene distintas connotaciones semánticas:
Se denominan parámetros los tipos declarados en el prototipo (que deben corresponder con los declarados en la definición ). Cuando se realiza una llamada a la función, los “valores” pasados se denominan argumentos. A veces se utilizan también las expresiones argumentos formales, para los parámetros y argumentos actuales para los valores pasados.
Parámetros (en prototipo o definición) argumentos formales. Valores pasados (en tiempo de ejecución) argumentos actuales.
La sintaxis utilizada para la declaración de la lista de parámetros formales es similar a la utilizada en la declaración de cualquier identificador.
A continuación se exponen varios ejemplos:
int func(void) {…} // sin parámetros inf func() {…} // ídem. int func(T1 t1, T2 t2, T3 t3=1) {…} // tres parámetros simples,

// uno con argumento por defecto
int func(T1* ptr1, T2& tref) {…} // los argumentos son un puntero y // una referencia.
int func(register int i) {…} // Petición de uso de registro para // argumento (entero)
int func(char* str,…) {…} /* Una cadena y cierto número de otros argumentos, o un número fijo de argumentos de tipos variables */
Los argumentos son siempre objetos.
  • Sus tipos pueden ser:
    escalares
    estructuras
    uniones o enumeraciones
    clases definidas por el usuario
    punteros o referencias a estructuras y uniones
    punteros a funciones, a clases o a matrices.
  • El tipo void está permitido como único parámetro formal. Significa que la función no recibe ningún argumento.

  • Existen dos formas de enviar parámetros a una función:
  • Por valor: cualquier cambio que se realice dentro de la función en el argumento enviado, NO afectará al valor original de las variables utilizadas en la llamada. Es como si trabajaramos con una copia, no con el original. No es posible enviar por valor arrays, deberemos hacerlo por referencia.
  • Por referencia:
lo que hacemos es enviar a la función la dirección de memoria donde se encuentra la variable o dato. Cualquier modificación SI afectará a las variables utilizadas en la llamada. Trabajamos directamente con el original.

2.7 SOBRECARGA DE SUBPROGRAMAS

Un subprograma sobrecargará un significado ya existente siempre que su especificación sea suficientemente diferente, es decir, pueden existir dos subprogramas con el mismo identificador siempre que se distingan por el número o tipo de sus parámetros.
En el mismo ámbito existen diferentes subprogramas con el mismo nombre. Cada versión debiera tener una firma diferente, de manera que a partir de los parámetros reales se pueda resolver a cual versión se refiere.
Las versiones pueden diferir en la codificación. Es una conveniencia notacional, que es evidente cuando se usan nombres convencionales, como en siguiente ejemplo:
Double abs(double);
int abs(int); abs(1); // invoca
int abs(int); abs(1.0); // invoca
double abs(double); // se sobrecargará
print void print(int);
void print (char*);


2.8 RECURSIVIDAD

La recursividad es una técnica de programación importante. Se utiliza para realizar una llamada a una función desde la misma función. Como ejemplo útil se puede presentar el cálculo de números factoriales. El factorial de 0 es, por definición, 1. Los factoriales de números mayores se calculan mediante la multiplicación de 1 * 2 *..., incrementando el número de 1 en 1 hasta llegar al número para el que se está calculando el factorial.
DefiniciónHablamos de recursividad, tanto en el ámbito informático como en el ámbito matemático, cuando definimos algo (un tipo de objetos, una propiedad o una operación) en función de sí mismo. La recursividad en programación es una herramienta sencilla, muy útil y potente.
Tipos Directa:
Cuando un subprograma se llama a sí mismo una o más veces directamente.Indirecta: Cuando se definen una serie de subprogramas usándose unos a otros.
Características.Un algoritmo recursivo consta de una parte recursiva, otra iterativa o no recursiva y una condición de terminación. La parte recursiva y la condición de terminación siempre existen. En cambio la parte no recursiva puede coincidir con la condición de terminación.Algo muy importante a tener en cuenta cuando usemos la recursividad es que es necesario asegurarnos que llega un momento en que no hacemos más llamadas recursivas. Si no se cumple esta condición el programa no parará nunca.
Ventajas e inconvenientes La principal ventaja es la simplicidad de comprensión y su gran potencia, favoreciendo la resolución de problemas de manera natural, sencilla y elegante; y facilidad para comprobar y convencerse de que la solución del problema es correcta.El principal inconveniente es la ineficiencia tanto en tiempo como en memoria, dado que para permitir su uso es necesario transformar el programa recursivo en otro iterativo, que utiliza bucles y pilas para almacenar las variables.
Ejemplo de Recursividad
#include
using namespace std;
int f(int n);int main (){
cout << "La funcion es: " <<>
;cout << "\n";
return 0;}int f(int n)
{
int answer;
if (n==1) return (1);
cout << "El valor de n es: " <<>
answer = f(n-1);
cout << "Ahora el valor de n es: " <<>
return (answer);}
El resultado de este código es:
El valor de n es: 5
El valor de n es: 4
El valor de n es: 3
El valor de n es: 2
Ahora el valor de n es: 2
Ahora el valor de n es: 3
Ahora el valor de n es: 4
Ahora el valor de n es: 5
La función