Este documento presenta un resumen de 3 conceptos clave de C++:
1) Define los tipos de datos fundamentales como enteros, flotantes, caracteres y booleanos, y explica el tipo void.
2) Explica el concepto de clase en programación orientada a objetos y provee un ejemplo de clase Punto con atributos y métodos.
3) Introduce los constructores como métodos especiales que se ejecutan al crear un objeto y pueden inicializar sus atributos.
1. Mynor Alexander Hernandez Canuz
4to. Bachillerato En Ciencias y Letras
Colegio metropolitano en computacion
Fecha de Entrega: 8 de febredo del 2010
Matematicas
2. Introduccion
Acontinuacion se a realisado un trabajo con
culla funcion es mostras todo lo relacionado con
operadores el cual fue establecido en tres partes
que son , precedencia de operadores,
asociativilidad de operadores y relacion entre
jerarquia y precedencia la caual fue realisado
con la funcion de explicar la funcion, el
significado y la realizacion de cada uno de ellos.
3. Precedencia de operadores
precedencia de operadores java
Por el hecho de poder emplear varios operadores en la misma expresión nos encontramos
con la necesidad de conocer el orden de evaluación de los operadores:
Existe una palabra clave llamada instanceof que puede ser interpretada como un
operador, encargado de comprobar si un objeto es una instancia de una determinada
clase, por ejemplo:
String cad = "unTexto";
Bolean resultado = cad instanceof String;
Precedencia de operadores en C++
C++ es un lenguaje de programación diseñado a mediados de los años 1980 por Bjarne
Stroustrup. La intención de su creación fue el extender al exitoso lenguaje de
programación C con mecanismos que permitan la manipulación de objetos. En ese
sentido, desde el punto de vista de los lenguajes orientados a objetos, el C++ es un
lenguaje híbrido.
Posteriormente se añadieron facilidades de programación genérica, que se sumó a los
otros dos paradigmas que ya estaban admitidos (programación estructurada y la
programación orientada a objetos). Por esto se suele decir que el C++ es un lenguaje de
programación multiparadigma.
Actualmente existe un estándar, denominado ISO C++, al que se han adherido la mayoría
de los fabricantes de compiladores más modernos. Existen también algunos intérpretes,
tales como ROOT.
Una particularidad del C++ es la posibilidad de redefinir los operadores (sobrecarga de
operadores), y de poder crear nuevos tipos que se comporten como tipos fundamentales.
El nombre C++ fue propuesto por Rick Mascitti en el año 1983, cuando el lenguaje fue
utilizado por primera vez fuera de un laboratorio científico. Antes se había usado el
nombre "C con clases". En C++, la expresión "C++" significa "incremento de C" y se
refiere a que C++ es una extensión de C.
4. La tabla siguiente es una lista que muestra el orden de precedencia y la asociatividad de
todos los operadores del lenguaje de programación C++. Están listados de arriba a abajo
por orden de precedencia descendente y con la misma descendencia en la misma celda
(pueden haber varias filas de operadores en la misma celda). La precedencia de los
operadores no cambia por la sobrecarga.
Una tabla de precendencias, aunque adecuada, no puede resolver todos los detalles. Por
ejemplo el operador ternario permite expresiones arbitrarias como operador central
independientemente de la precedencia del resto de operadores. Así a ? b , c : d es
interpretado como a ? (b, c) : d en vez de (a ? b), (c : d). También hay que tener en cuenta
que el resultado sin paréntesis de una expresión de conversión en C no puede ser el
operando de sizeof. Por eso sizeof (int) * x es interpretado como (sizeof(int)) * x y no
como sizeof ((int) *x).
Operador Descripción Asociatividad
:: Resolución de ámbito (solo C++) Izquierda a
++ -- Post- incremento y decremento derecha
() Llamada a función
[] Elemento de vector
. Selección de elemento por referencia
-> Selección de elemento con puntero
typeid() Información de tipo en tiempo de ejecución (solo C++)
const_cast Conversión de tipo (solo C++)
dynamic_cast Conversión de tipo (solo C++)
reinterpret_cast Conversión de tipo (solo C++)
static_cast Conversión de tipo (solo C++)
++ -- Pre- incremento y decremento Derecha a
+- Suma y resta unitaria izquierda
!~ NOT lógico y NOT binario
(type) Conversión de tipo
* Indirección
& Dirección de
sizeof Tamaño de
new new[] Asignación dinámica de memoria (solo C++)
delete delete[] Desasignación dinámica de memoria (solo C++)
5. .* ->* Puntero a miembro (solo C++) Izquierda a
*/% Multiplicación, división y módulo derecha
+- Suma y resta
<< >> Operaciones binarias de desplazamiento
< <= Operadores relaciones "menor que", "menor o igual
> >= que", "mayor que" y "mayor o igual que"
== != Operadores relaciones "igual a" y "distinto de"
& AND binario
^ XOR binario
| OR binario
&& AND lógico
|| OR lógico
c?t:f Operador ternario Derecha a
= izquierda
+= -=
*= /= %= Asignaciones
<<= >>=
&= ^= |=
Operador Throw (lanzamiento de excepciones, solo C+
throw
+)
Izquierda a
, Coma
derecha
Un ejemplo de programa en C++, el clásico Hola mundo
A continuación se cita un programa de ejemplo Hola mundo escrito en C++:
# include <iostream> // Esta biblioteca permite el uso de cout(<<) y de cin(>>)
using namespace std;
int main()
{
cout << "Hola mundo" << endl;
return 0;
}
Al usar la directiva #include estamos diciéndole al compilador que busque determinadas
cosas en un archivo que se llama iostream. Para evitar redefinir cosas ya hechas al
ponerles igual nombre, se creó algo llamado espacios de nombres o namespace en el
6. singular del inglés. En este caso hay un espacio de nombres llamado std, que es donde se
incluyen las definiciones, entre muchas otras cosas del objeto cout, que representa el flujo
de salida estándar (típicamente la pantalla o una ventana de texto), y todo esto es
exactamente lo que decimos al añadir la sentencia using namespace std.
La definición de funciones es igual que en C, salvo por la característica de que si main no
va a recoger argumentos, no tenemos por qué ponérselos, a diferencia de C, donde había
que ponerlos explícitamente, aunque no se fueran a usar. Queda solo comentar que el
símbolo << se conoce como operador de inserción, y grosso modo está enviando a cout lo
que queremos mostrar por pantalla para que lo pinte, en este caso la cadena "¡Hola
mundo!" . El mismo operador << se puede usar varias veces en la misma sentencia, de
forma que gracias a esta característica podemos poner un carácter endl al final, que es el
equivalente del n en C o nr, según el sistema en que se esté programando.
Para los usuarios de Windows que no conocen la consola, para poder ver el Hola mundo
agreguen la línea
system("PAUSE"); // Este operador se incluye solamente en Windows
antes del
return 0;
Tipos de datos
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
El modificador unsigned se puede aplicar a enteros para obtener números sin signo (por
omisión los enteros contienen signo), con lo que se consigue un rango mayor de números
naturales. Tamaños de tipos primitivos bajo i386
(GCC)
Tamaños asociados [editar]
Tipo Número de Bits
Según la máquina y el compilador que se char 8
utilice los tipos primitivos pueden ocupar
short 16
un determinado tamaño en memoria. La
siguiente lista ilustra el número de bits int 32
que ocupan los distintos tipos primitivos float 32
la arquitectura x86.
double 64
7. Otras arquitecturas pueden requerir distintos tamaños de tipos de datos primitivos. C++
no dice nada acerca de cuál es el número de bits en un byte, ni del tamaño de estos tipos;
más bien, ofrece solamente las siguientes "garantías de tipos":
• Un tipo char tiene el tamaño mínimo en bytes asignable por la máquina, y todos
los bits de este espacio deben ser "accesibles".
• El tamaño reconocido de char es de 1. Es decir, sizeof(char) siempre devuelve 1.
• Un tipo short tiene al menos el mismo tamaño que un tipo char.
• Un tipo long tiene al menos el doble tamaño en bytes que un tipo short.
• Un tipo int tiene un tamaño entre el de short y el de long, ambos inclusive,
preferentemente el tamaño de un apuntador de memoria de la máquina.
• Un tipo unsigned tiene el mismo tamaño que su versión signed.
wchar_t [editar]
Para la versión del estándar que se publicó en 1999, se decidió añadir el tipo de dato
wchar_t, que permite el uso de caracteres UNICODE, a diferencia del tradicional char,
que contempla simplemente al código de caracteres ASCII extendido. A su vez, se ha
definido para la mayoría de las funciones y clases, tanto de C como de C++, una versión
para trabajar con wchar_t, donde usualmente se prefija el carácter w al nombre de la
función (en ocasiones el carácter es un infijo). Por ejemplo:
• strcpy - wstrcpy
• std::string - std::wstring
• std::cout - std::wcout
Cabe resaltar que en C se define wchar_t como:
typedef unsigned short wchar_t;
Mientras que en C++ es en sí mismo un tipo de dato.
La palabra clave "void"
La palabra clave void define en C++ el concepto de no existencia o no atribución de un
tipo en una variable o declaración. Como tal, puede ser usada para destacar que una
función no recibe parámetros, como en:
int funcion (void);
Aunque la tendencia actual es la de no colocar la palabra "void".
Además se utiliza para determinar que una función no retorna un valor, como en:
void funcion (int parametro);
8. Cabe destacar que void no es un tipo. Una función como la declarada anteriormente no
puede retornar un valor por medio de return: la palabra clave va sola. No es posible una
declaración del tipo:
void t; //Está mal
En este sentido, void se comporta de forma ligeramente diferente a como lo hace en C,
especialmente en cuanto a su significado en declaraciones y prototipos de funciones.
Sin embargo, la forma especial void * puede utilizarse como un ajuste que convierte
cualquier variable a una "variable sin tipo", la cual puede solo ser accedida y utilizada
bajo una operación de cast. Por ejemplo:
void *memoria;
Indica que memoria es un puntero a alguna parte, donde se guarda información de algún
tipo. El programador es responsable de definir estos "algún", eliminando toda
ambigüedad. Una ventaja de la declaración "void *" es que puede representar a la vez
varios tipos de datos, dependiendo de la operación de cast escogida. La memoria que
hemos apuntado en alguna parte, en el ejemplo anterior, bien podría almacenar un entero,
un flotante, una cadena de texto o un programa, o combinaciones de éstos. Es
responsabilidad del programador recordar qué tipo de datos hay y garantizar el acceso
adecuado.
Principios [editar]
Todo programa en C++ debe tener la función main() (a no ser que se especifique en
tiempo de compilación otro punto de entrada, que en realidad es la función que tiene el
main())
int main()
{}
La función main debe tener uno de los siguientes prototipos:
int main()
int main(int argc, char** argv)
La primera es la forma por omisión de un programa que no recibe parámetros ni
argumentos. La segunda forma tiene dos parámetros: argc, un número que describe el
número de argumentos del programa (incluyendo el nombre del programa mismo), y
argv, un puntero a un array de punteros, de argc elementos, donde el elemento argv[i]
representa el i-ésimo argumento entregado al programa.
El tipo de retorno de main es int. Al finalizar la función main, debe incluirse el valor de
retorno (por ejemplo, return 0;, aunque el estándar prevé solamente dos posibles valores
de retorno: EXIT_SUCCESS y EXIT_ERROR, definidas en el archivo cstddef), o salir
9. por medio de la función exit. Alternativamente puede dejarse en blanco, en cuyo caso el
compilador es responsable de agregar la salida adecuada.
El concepto de clase
Los objetos en C++ son abstraídos mediante una clase. Según el paradigma de la
programación orientada a objetos un objeto consta de:
1. Métodos o funciones
2. Atributos o Variables Miembro
Un ejemplo de clase que podemos tomar es la clase perro. Cada perro comparte unas
características (atributos). Su número de patas, el color de su pelaje o su tamaño son
algunos de sus atributos. Las funciones que lo hagan ladrar, cambiar su
comportamiento... esas son las funciones de la clase.
Este es otro ejemplo de una clase:
class Punto
{
//por omisión los miembros son 'private' para que sólo se puedan modificar desde la
propia clase.
private:
// Variable miembro privada
int id;
protected:
// Variables miembro protegidas
int x;
int y;
public:
// Constructor
Punto();
// Destructor
~Punto();
// Funciones miembro o métodos
int ObtenerX();
int ObtenerY();
};
Constructores
Véase también: Constructor (informática)
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
10. 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
como se muestra a continuación:
class Punto
{
public:
// Coordenadas del punto
float x;
float y;
// Constructor
Punto() : x ( 0 ), y ( 0 ) // Inicializamos las variables "x" e "y"
{}
};
// Main para demostrar el funcionamiento de la clase
# include <iostream> // Esto nos permite utilizar "cout"
using namespace std;
int main()
{
Punto MiPunto; // creamos un elemento de la clase Punto llamado MiPunto
cout << "Coordenada X: " << MiPunto.x << endl; // mostramos el valor acumulado
en la variable x
cout << "Coordenada Y: " << MiPunto.y << endl; // mostramos el valor acumulado
en la variable y
return 0;
}
11. Si compilamos y ejecutamos el anterior programa, obtenemos una salida que debe ser
similar a la siguiente:
Coordenada X:0 Coordenada Y:0
Existen varios tipos de constructores en C++:
1. 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.
2. 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.
3. 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 publico 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.
Funciones miembro
Función miembro es aquella que está declarada en ámbito de clase. Son similares a las
funciones habituales, con la salvedad de que el compilador realizara el proceso de
Decoración de nombre (Name Mangling en inglés): Cambiara el nombre de la función
añadiendo un identificador de la clase en la que está declarada, pudiendo incluir
caracteres especiales o identificadores numéricos. Además, las funciones miembro
reciben implícitamente un parámetro adicional: El puntero this, que referencia al objeto
que ejecuta la función.
Las funciones miembro se invocan accediendo primero al objeto al cual refieren, con la
sintaxis: myobject.mymemberfunction(), esto es un claro ejemplo de una función
miembro.
12. Plantillas
Las plantillas son el mecanismo de C++ para implantar el paradigma de la programación
genérica. Permiten que una clase o función trabaje con tipos de datos abstractos,
especificándose más adelante cuales son los que se quieren usar. Por ejemplo, es posible
construir un vector genérico que pueda contener cualquier tipo de estructura de datos. De
esta forma se pueden declarar objetos de la clase de este vector que contengan enteros,
flotantes, polígonos, figuras, fichas de personal, etc.
La declaración de una plantilla se realiza anteponiendo la declaración template
<typename A,....> a la declaración de la estructura (clase, estructura o función) deseado.
Por ejemplo:
template <typename T>
T max(T x, T y)
{
if (x > y)
return x;
else
return y;
}
La función max() es un ejemplo de programación genérica, y dados dos parámetros de un
tipo T (que puede ser int, long, float, double, etc.) devolverá el mayor de ellos (usando el
operador >). Al ejecutar la función con parámetros de un cierto tipo, el compilador
intentará "calzar" la plantilla a ese tipo de datos, o bien generará un mensaje de error si
fracasa en ese proceso.
Especialización
El siguiente ejemplo:
template <typename A> int myfunction(A a);
crea una plantilla bajo la cual pueden ser definidas en el código de cabecera cualesquiera
funciones especializadas para un tipo de datos como int myfunction(int), int
myfunction(std::string), int myfunction(bool), etcétera:
int myfunction (int a) {
return a + 5;
};
int myfunction (std::string a) {
return -a.size();
};
13. int myfunction (bool a) {
return (a & rand());
};
Cada una de estas funciones tiene su propia definición (cuerpo). Cada cuerpo diferente,
no equivalente ("no convertible") corresponde a una especialización. Si una de estas
funciones no fuera definida, el compilador tratará de aplicar las conversiones de tipos de
datos que le fuesen permitidas para "calzar" una de las plantillas, o generará un mensaje
de error si fracasa en ese proceso.
Todas las definiciones habilitadas de una plantilla deben estar disponibles al momento de
la compilación, por lo cual no es posible actualmente "compilar" una plantilla como
archivo de objeto, sino simplemente compilar especializaciones de la plantilla. Por lo
tanto, las plantillas se distribuyen junto con el código fuente de la aplicación. En otras
palabras, no es posible compilar la plantilla std::vector< > a código objeto, pero sí es
posible, por ejemplo, compilar un tipo de datos std::vector<std::string>.
Clases abstractas
En C++ es posible definir clases abstractas. Una clase abstracta, o clase base abstracta
(ABC), es una que está diseñada sólo como clase padre de las cuales se deben derivar
clases hijas. Una clase abstracta se usa para representar aquellas entidades o métodos que
después se implementarán en las clases derivadas, pero la clase abstracta en sí no
contiene ninguna implementación -- solamente representa los métodos que se deben
implementar. Por ello, no es posible instanciar una clase abstracta, pero sí una clase
concreta que implemente los métodos definidos en ella.
Las clases abstractas son útiles para definir interfaces, es decir, un conjunto de métodos
que definen el comportamiento de un módulo determinado. Estas definiciones pueden
utilizarse sin tener en cuenta la implementación que se hará de ellos.
En C++ los métodos de las clases abstractas se definen como funciones virtuales puras.
class Abstracta
{
public:
virtual int metodo() = 0;
};
class ConcretaA : public Abstracta
{
public:
int metodo()
{
//haz algo
14. return foo () + 2;
}
};
class ConcretaB : public Abstracta
{
public:
int metodo()
{
//otra implementación
return baz () - 5;
}
};
En el ejemplo, la clase ConcretaA es una implementación de la clase Abstracta, y la clase
ConcretaB es otra implementación. Debe notarse que el = 0 es la notación que emplea C+
+ para definir funciones virtuales puras.
Espacios de nombres
Una adición a las características de C son los espacios de nombre (namespace en
inglés), los cuales pueden describirse como áreas virtuales bajo las cuales ciertos
nombres de variable o tipos tienen validez. Esto permite evitar las ocurrencias de
conflictos entre nombres de funciones, variables o clases.
El ejemplo más conocido en C++ es el espacio de nombres std::, el cual almacena todas
las definiciones nuevas en C++ que difieren de C (algunas estructuras y funciones), así
como las funcionalidades propias de C++ (streams) y los componentes de la biblioteca
STL.
Por ejemplo:
# include <iostream>
// Las funciones en esta cabecera existen dentro del espacio de nombres std::
namespace mi_paquete{
int mi_valor;
};
int main()
{
int mi_valor= 3;
mi_paquete::mi_valor= 4;
std::cout<< mi_valor<< 'n'; // imprime '3'
std::cout<< mi_paquete::mi_valor<< 'n'; // imprime '4'
15. return 0;
}
Como puede verse, las invocaciones directas a mi_valor darán acceso solamente a la
variable descrita localmente; para acceder a la variable del paquete mi_paquete es
necesario acceder específicamente el espacio de nombres. Un atajo recomendado para
programas sencillos es la directiva using namespace, que permite acceder a los nombres
de variables del paquete deseado en forma directa, siempre y cuando no se produzca
alguna ambigüedad o conflicto de nombres.
Excepciones
C++ permite la existencia de excepciones, las cuales son una metodología de flujo de
ejecución basada en la prueba del código deseado (try) seguida por la intercepción de
ciertas condiciones bajo un flujo de programa adicional (catch). La declaración de estas
condiciones se hace "arrojando" (throw) sentencias especiales que son capturadas por el
flujo catch correspondiente.
Por ejemplo:
# include <iostream>
// Muestra el uso de try y catch
int main()
{
std::string x = "Hola Mundo";
try {
std::cout<< x.at(99)<<std::endl;
}
catch (std::exception& X) {
std::cerr<< X.what()<<std::endl;
}
return 0;
}
En el ejemplo anterior, se hace el intento de acceder al caracter número 99 de la cadena
"Hola Mundo", el cual no existe. El tipo de datos std::string arroja en estos casos, en la
llamada a la función "at", una excepción, del tipo std::out_of_range, derivado de
std::exception. El bloque catch "atrapará" la excepción arrojada como una variable X,
para la cual el método what() muestra un mensaje con la causa del error (en nuestro caso,
un mensaje similar a "Index Out of Range").
16. Es buena idea al crear nuevas excepciones derivarlas de std::exception ya que es el
bloque catch que muchos programadores colocan por omisión.
Si una excepción se propagara sin ser atrapada por un bloque catch, y llegara hasta el
punto de terminación del programa, se produce la terminación abrupta de éste ("abort").
Herencia
Existen varios tipos de herencia entre clases en el lenguaje de programación C++. Estos
son:
Herencia simple [editar]
La herencia en C++ es un mecanismo de abstracción creado para poder facilitar y mejorar
el diseño de las clases de un programa. Con ella se pueden crear nuevas clases a partir de
clases ya hechas, siempre y cuando tengan un tipo de relación especial.
En la herencia, las clases derivadas "heredan" los datos y las funciones miembro de las
clases base, pudiendo las clases derivadas redefinir estos comportamientos
(polimorfismo) y añadir comportamientos nuevos propios de las clases derivadas. Para no
romper el principio de encapsulamiento (ocultar datos cuyo conocimiento no es necesario
para el uso de las clases), se proporciona un nuevo modo de visibilidad de los
datos/funciones: "protected". Cualquier cosa que tenga visibilidad protected se
comportará como pública en la clase Base y en las que componen la jerarquía de
herencia, y como privada en las clases que NO sean de la jerarquía de la herencia.
Antes de utilizar la herencia, nos tenemos que hacer una pregunta, y si tiene sentido,
podemos intentar usar esta jerarquía: Si la frase <claseB> ES-UN <claseA> tiene sentido,
entonces estamos ante un posible caso de herencia donde clase A será la clase base y
clase B la derivada.
Ejemplo: clases Barco, Acorazado, Carguero, etc. un Acorazado ES-UN Barco, un
Carguero ES-UN Barco, un Trasatlántico ES-UN Barco, etc.
En este ejemplo tendríamos las cosas generales de un Barco (en C++)
class Barco {
protected:
char* nombre;
float peso;
public:
//Constructores y demás funciones básicas de barco
};
y ahora las características de las clases derivadas, podrían (a la vez que heredan las de
barco) añadir cosas propias del subtipo de barco que vamos a crear, por ejemplo:
17. class Carguero: public Barco { // Esta es la manera de especificar que hereda de Barco
private:
float carga;
//El resto de cosas
};
class Acorazado: public Barco {
private:
int numeroArmas;
int Soldados;
// Elresto de cosas
};
Por último, hay que mencionar que existen 3 clases de herencia que se diferencian en el
modo de manejar la visibilidad de los componentes de la clase resultante:
• Herencia publica (class Derivada: public Base ) : Con este tipo de herencia se
respetan los comportamientos originales de las visibilidades de la clase Base en la
clase Derivada.
• Herencia privada (clase Derivada: private Base) : Con este tipo de herencia todo
componente de la clase Base, será privado en la clase Derivada (ojo! siempre será
privado aunque ese dato fuese público en la clase Base)
• Herencia protegida (clase Derivada: protected Base) : Con este tipo de herencia,
todo componente publico y protegido de la clase Base, será protegido en la clase
Derivada, y los componentes privados, siguen siendo privados.
Herencia múltiple
La herencia múltiple es el mecanismo que permite al programador hacer clases derivadas
a partir, no de una sola clase base, sino de varias. Para entender esto mejor, pongamos un
ejemplo: Cuando ves a quien te atiende en una tienda, como persona que es, podrás
suponer que puede hablar, comer, andar, pero, por otro lado, como empleado que es,
también podrás suponer que tiene un jefe, que puede cobrarte dinero por la compra, que
puede devolverte el cambio, etc. Si esto lo trasladamos a la programación sería herencia
múltiple (clase empleado_tienda):
class Persona {
...
Hablar();
Caminar();
...
};
class Empleado {
Persona jefe;
int sueldo;
18. Cobrar();
...
};
class empleado_tienda: public Persona, Empleado {
...
AlmacenarStock();
ComprobarExistencias();
...
};
Por tanto, es posible utilizar más de una clase para que otra herede sus características.
Sobrecarga de operadores
La sobrecarga de operadores es una forma de hacer polimorfismo. Es posible definir el
comportamiento de un operador del lenguaje para que trabaje con tipos de datos definidos
por el usuario. No todos los operadores de C++ son factibles de sobrecargar, y, entre
aquellos que pueden ser sobrecargados, se deben cumplir condiciones especiales. En
particular, los operadores sizeof y :: no son sobrecargables.
No es posible en C++ crear un operador nuevo.
Los comportamientos de los operadores sobrecargados se implementan de la misma
manera que una función, salvo que esta tendrá un nombre especial: Tipo de dato de
devolución operator<token del operador>(parámetros)
Los siguientes operadores pueden ser sobrecargados:
• Operadores Unarios
o Operador * (de indirección)
o Operador -> (de indirección)
o Operador +
o Operador -
o Operador ++
o Operador --
• Operadores Binarios
o Operador ==
o Operador +
o Operador -
o Operador *
o Operador /
o Operador %
o Operador <<
o Operador >>
o Operador &
19. o Operador ^
o Operador |
o Operador []
o Operador ()
• Operadores de Asignación
o Operador =
o Operador +=
o Operador -=
o Operador *=
o Operador /=
o Operador %=
o Operador <<=
o Operador >>=
o Operador &=
o Operador ^=
o Operador |=
Dado que estos operadores son definidos para un tipo de datos definido por el usuario,
éste es libre de asignarles cualquiera semántica que desee. Sin embargo, se considera de
primera importancia que las semánticas sean tan parecidas al comportamiento natural de
los operadores como para que el uso de los operadores sobrecargados sea intuitivo. Por
ejemplo, el uso del operador unario - debiera cambiar el "signo" de un "valor".
Los operadores sobrecargados no dejan de ser funciones, por lo que pueden devolver un
valor, si este valor es del tipo de datos con el que trabaja el operador, permite el
encadenamiento de sentencias. Por ejemplo, si tenemos 3 variables A,B y C de un tipo T
y sobrecargamos el operador = para que trabaje con el tipo de datos T, hay dos opciones:
si el operador no devuelve nada una sentencia como "A=B=C;" (sin las comillas) daría
error, pero si se devuelve un tipo de datos T al implementar el operador, permitiría
concatenar cuantos elementos se quisieran, permitiendo algo como "A=B=C=D=...;"
Precedencia de Operadores de C y C++ 2
Saltar a navegación, búsqueda es una lista de los operadores de los lenguajes C++ y C.
Todos los operadores listados existen en C++. La tercera columna indica si también está
presente en C. También hay que tener en cuenta que C no permite la sobrecarga de
operadores.
Los siguientes operadores son puntos de secuencia en ambos lenguajes (cuando no están
sobrecargados): &&, ||, ?:, y , (el operador coma).
C++ también incluye los operadores de conversión de tipos const_cast, static_cast,
dynamic_cast y reinterpret_cast que no están listados en la tabla por brevedad. El formato
de estos operadores significa que su nivel de precedencia no es importante.
Estos operadores que están en C (con la excepción del operador coma y el operador
flecha también se encuentran en Java, Perl, C# y PHP con la la misma precedencia,
20. asociatividad y semántica. Con una única excepción: la asociatividad del operador
ternario en PHP es de izquierda a derecha.
Tabla
Para los objetivos de esta tabla a, b y c representan valores válidos (literales, valores de
variables o valores de retorno), nombres de objetos o lvalores según el caso.
Operadores aritméticos
Nombre del operador Sintaxis Sobrecargable Incluido en C
Más unitario +a Sí Sí
Suma a+b Sí Sí
Preincremento ++a Sí Sí
Postincremento a++ Sí Sí
Asignación con suma a += b Sí Sí
Menos unitario (negación) -a Sí Sí
Resta a-b Sí Sí
Predecremento --a Sí Sí
Postdecremento a-- Sí Sí
Asignación con resta a -= b Sí Sí
Multiplicación a*b Sí Sí
Asignación con multiplicación a *= b Sí Sí
División a/b Sí Sí
Asignación con división a /= b Sí Sí
Módulo (Resto) a%b Sí Sí
Asignación con módulo a %= b Sí Sí
Operadores de comparación
Nombre del operador Sintaxis Sobrecargable Incluido en C
Menor que a<b No Sí
Menor o igual que a <= b Sí Sí
Mayor que a>b Sí Sí
Mayor o igual que a >= b Sí Sí
No igual que a != b Sí Sí
Igual que a == b Sí Sí
Negación lógica !a Sí Sí
AND lógico a && b Sí Sí
OR lógico a || b Sí Sí
Operadores a nivel de bit
Nombre del operador Sintaxis Sobrecargable Incluido en C
Desplazamiento a la izquierda a << b Sí Sí
Asignación con desplazamiento a la izquierda a <<= b Sí Sí
Desplazamiento a la derecha a >> b Sí Sí
Asignación con desplazamiento a la derecha a >>= b Sí No
21. Complemento a uno ~a Sí Sí
AND binario a&b Sí Sí
Asignación con AND binario a &= b Sí Sí
OR binario a|b Sí Sí
Asignación con OR binario a |= b Sí Sí
XOR binario a^b Sí Sí
Asignación con XOR binario a ^= b Sí Sí
Otros operadores
Nombre del operador Sintaxis Sobrecargable Incluido en C
Asignación básica a=b Sí Sí
Llamada a función a() Sí Sí
Índice de Array a[b] Sí Sí
Indirección (Desreferencia) *a Sí Sí
Dirección de (Referencia) &a Sí Sí
Miembro de puntero a->b Sí Sí
Miembro a.b No Sí
Desreferencia a miembro por puntero a->*b Sí No
Desreferencia a miembro por objeto a.*b No No
Conversión de tipo (tipo) a Sí Sí
Coma a,b Sí Sí
Condicional ternario a?b:c No Sí
Resolución de ámbito a::b No No
Puntero a función miembro a::*b No No
sizeof a
Tamaño de No Sí
sizeof(tipo)
typeid(a)
Identificación de tipo No No
typeid(tipo)
Asignar almacenamiento new tipo Sí No
Asignar almacenamiento (Vector) new tipo[n] Sí No
Desasignar almacenamiento delete a Sí No
Desasignar almacenamiento (Vector) delete[] a Sí No
Extensiones del lenguaje
Nombre del operador Sintaxis Sobrecargable Incluido en C Vendedor
Dirección de la etiqueta && etiqueta No Sí GCC
typeof a
Obtener tipo No Sí GCC
typeof(expr)
a <? b
min y max No No GCC
a >? b
22. La tabla siguiente es una lista que muestra el orden de precedencia y la asociatividad de
todos los operadores del lenguaje de programación C++. Están listados de arriba a abajo
por orden de precedencia descendente y con la misma descendencia en la misma celda
(pueden haber varias filas de operadores en la misma celda). La precedencia de los
operadores no cambia por la sobrecarga.
Una tabla de precendencias, aunque adecuada, no puede resolver todos los detalles. Por
ejemplo el operador ternario permite expresiones arbitrarias como operador central
independientemente de la precedencia del resto de operadores. Así a ? b , c : d es
interpretado como a ? (b, c) : d en vez de (a ? b), (c : d). También hay que tener en cuenta
que el resultado sin paréntesis de una expresión de conversión en C no puede ser el
operando de sizeof. Por eso sizeof (int) * x es interpretado como (sizeof(int)) * x y no
como sizeof ((int) *x).
Operador Descripción Asociatividad
:: Resolución de ámbito (solo C++) Izquierda a
++ -- Post- incremento y decremento derecha
() Llamada a función
[] Elemento de vector
. Selección de elemento por referencia
-> Selección de elemento con puntero
typeid() Información de tipo en tiempo de ejecución (solo C++)
const_cast Conversión de tipo (solo C++)
dynamic_cast Conversión de tipo (solo C++)
reinterpret_cast Conversión de tipo (solo C++)
static_cast Conversión de tipo (solo C++)
++ -- Pre- incremento y decremento Derecha a
+- Suma y resta unitaria izquierda
!~ NOT lógico y NOT binario
(type) Conversión de tipo
* Indirección
& Dirección de
sizeof Tamaño de
new new[] Asignación dinámica de memoria (solo C++)
delete delete[] Desasignación dinámica de memoria (solo C++)
23. .* ->* Puntero a miembro (solo C++) Izquierda a
*/% Multiplicación, división y módulo derecha
+- Suma y resta
<< >> Operaciones binarias de desplazamiento
< <= Operadores relaciones "menor que", "menor o igual
> >= que", "mayor que" y "mayor o igual que"
== != Operadores relaciones "igual a" y "distinto de"
& AND binario
^ XOR binario
| OR binario
&& AND lógico
|| OR lógico
c?t:f Operador ternario Derecha a
= izquierda
+= -=
*= /= %= Asignaciones
<<= >>=
&= ^= |=
Operador Throw (lanzamiento de excepciones, solo C+
throw
+)
, Coma
Precedencia de operadores visual
Cuando aparecen varias operaciones en una expresión, cada parte se evalúa y se resuelve
en un orden determinado llamado prioridad de los operadores. Puede utilizar paréntesis
para pasar por alto el orden de prioridad y obligar a evaluar algunas partes de una
expresión antes que otras. Las operaciones entre paréntesis se realizan siempre antes que
las de fuera. Sin embargo, entre paréntesis se mantiene el prioridad normal de los
operadores.
Cuando las expresiones contienen operadores de más de una categoría, los operadores
aritméticos se evalúan primero, los de comparación después y los lógicos los últimos.
Todos los operadores de comparación tienen la misma prioridad, es decir, se evalúan en
el orden de izquierda a derecha en el que aparecen. Los operadores aritméticos y lógicos
se evalúan en el siguiente orden de prioridad:
Aritmético Comparación Lógico
Negación (-) Igualdad (=) Not
Exponenciación (^) Desigualdad (<>) And
Multiplicación y división (*, /) Menor que (<) Or
División de número entero () Mayor que (>) Xor
Modelo aritmético (Mod) Menor o igual que (<=) Eqv
Suma y resta (+, -) Mayor o igual que (>=) Imp
Concatenación de cadenas (&) Is &
24. Cuando aparecen la multiplicación y la división juntas en una expresión, se evalúa cada
operación según aparece de izquierda a derecha. Asimismo, cuando aparecen la suma y la
resta juntas en una expresión, cada operación se evalúa en orden de aparición de
izquierda a derecha.
El operador de concatenación de cadena (&) no es un operador aritmético, pero por
prioridad va después de todos los operadores aritméticos y antes de todos los operadores
de comparación. El operador Is es un operador de comparación de referencias de objetos.
No compara objetos ni sus valores; sólo comprueba para determinar si dos referencias de
objetos hacen referencia al mismo objeto.
asociatividad de operadores
Al utilizar dos o más operadores en una sentencia, algunos operadores tienen precedencia
sobre otros operadores. La precedencia y asociatividad de los operadores determina el
orden en que se procesan los operadores. ActionScript tiene una jerarquía que determina
qué operadores se ejecutan antes que otros. Al final de esta sección encontrará una tabla
en la que se expone esta jerarquía.
Aunque para aquellos usuarios familiarizados con la programación aritmética o básica
puede parecer algo natural que el compilador procese el operador de multiplicación (*)
antes que el operador de suma (+), el compilador necesita instrucciones explícitas sobre
qué operadores debe procesar primero. Dichas instrucciones se conocen colectivamente
como precedencia de operadores.
Puede ver un ejemplo de precedencia de operadores al utilizar los operadores de
multiplicación y suma:
var mySum:Number;
mySum = 2 + 4 * 3;
trace(mySum); // 14
Observará que el resultado de esta sentencia es 14, ya que la multiplicación tiene una
precedencia de operador superior. Por consiguiente, se calcula primero 4 * 3 y el
resultado se suma a 2.
Puede controlar lo que debe ocurrir colocando las expresiones entre paréntesis.
ActionScript establece una precedencia de operadores predeterminada que puede
modificar utilizando el operador de paréntesis (()). Al colocar la expresión de suma entre
paréntesis, ActionScript calcula primero la suma:
var mySum:Number;
mySum = (2 + 4) * 3;
trace(mySum); // 18
Ahora el resultado de esta sentencia es 18.
Los operadores también pueden tener la misma precedencia. En este caso, la
asociatividad determina el orden en que deben actuar los operadores. La asociatividad
puede ser de izquierda a derecha o de derecha a izquierda.
Observe de nuevo el operador de multiplicación. La asociatividad en este caso es de
izquierda a derecha, por lo que las dos sentencias siguientes son iguales.
var mySum:Number;
var myOtherSum:Number;
mySum = 2 * 4 * 3;
myOtherSum = (2 * 4) * 3;
25. trace(mySum); // 24
trace(myOtherSum); // 24
Pueden darse situaciones en las que dos o más operadores con la misma precedencia
aparezcan en la misma expresión. En estos casos, el compilador utiliza las reglas de
asociatividad para determinar qué operador se procesa primero. Todos los operadores
binarios, salvo los operadores de asignación, tienen asociatividad desde la izquierda, lo
que significa que los operadores de la izquierda se procesan antes que los operadores de
la derecha. Los operadores de asignación y el operador condicional (?:) tienen
asociatividad desde la derecha, lo que significa que los operadores de la derecha se
procesan antes que los operadores de la izquierda. Para más información sobre
operadores de asignación, consulte Utilización de operadores de asignación. Para más
información sobre el operador condicional (?:), consulte El operador condicional.
Piense, por ejemplo, en los operadores menor que (<) y mayor que (>), que tienen la
misma precedencia. Si ambos operadores se utilizan en la misma expresión, el operador
de la izquierda se procesará en primer lugar porque ambos operadores tienen
asociatividad desde la izquierda. Esto significa que las dos sentencias siguientes generan
el mismo resultado:
trace(3 > 2 < 1); // false
trace((3 > 2) < 1); // false
El operador mayor que (>) se procesa primero, lo que da como resultado el valor true
porque el operando 3 es mayor que el operando 2. El valor true se pasa al operador menor
que (<) junto con el operando 1. El operador menor que (<) convierte el valor true en el
valor numérico 1 y compara el valor numérico con el segundo operando 1 para devolver
el valor false (el valor 1 no es menor que 1).
Estudie el orden de los operandos del código ActionScript, especialmente si establece
condiciones complejas y conoce la frecuencia con la que dichas condiciones son
verdaderas (true). Por ejemplo, si sabe i va a ser mayor que 50 en su condición, deberá
escribir primero i<50. De esta forma, se comprobará primero, con lo que no será
necesario comprobar la segunda condición con tanta frecuencia.
En la tabla siguiente se muestran los operadores de ActionScript 2.0 por orden
decreciente de precedencia. Cada fila de la tabla contiene operadores de la misma
precedencia. Cada fila de operadores tiene precedencia superior a la fila que aparece
debajo de ella en la tabla. Para más información y directrices sobre el uso de operadores y
paréntesis, consulte el Aplicación de formato a la sintaxis de ActionScript.
Grupo Operadores
Primario [] {x:y} () f(x) new x.y x[y]
Sufijo x++ x--
Unario ++x --x + - ~ ! delete typeof void
Multiplicativo */%
Aditivo +-
Desplazamiento en modo bit<< >> >>>
Relacional < > <= >= instanceof
Igualdad == != === !==
AND en modo bit &
XOR en modo bit ^
OR en modo bit |
26. AND lógico &&
OR lógico ||
Condicional ?:
Asignación = *= /= %= += -= <<= >>= >>>= &= ^= |=
Coma ,
Asociativilidad de operadores Java
Ahora que vimos todo tipo de operadores, veamos cómo se evalúan cuando intervienen
varios de ellos en una expresión. Si escribimos:
a+b*2
estamos usando variables y constantes, pero también operadores, en este caso,
operadores
aritméticos, como el + para sumar, y el * (asterisco) para multiplicar. Estos operadores
se aplican en un orden, y tiene precedencia y asociatividad definida. Entonces, la
expresión de arriba se evalúa como:
a+(b*2)
es decir, a se suma al doble de b, y no como:
(a+b)*2
Esto es así, porque el operador * (de multiplicar) tiene precedencia sobre el operador +
(de suma). Podemos introducir el concepto de asociatividad de un operador,
mediante un ejemplo. La expresión:
a-5-3
tiene dos operadores - (de resta), que tienen, por supuesto, la misma precedencia.
Como el operador - tiene asociatividad izquierda, la expresión de arriba se evalúa como:
(a-5)-8
en vez de la totalmente distinta:
a-(5-8)
[TBD Tabla de operadores]
Todos los operadores binarios tienen asociatividad izquierda, excepto la asignación,
que la tiene derecha. Así:
a=b=c+1
se evalúa como:
a=(b=c+1)
27. Hemos visto en las aclaraciones de arriba, que podemos usar paréntesis, para aclarar
o cambiar el significado de una expresión. Se recomienda su uso, cuando una expresión
es compleja o induce a confusión, si no se recuerdan las reglas de precedencia,
que no son simples de recordar.
Orden de evaluación
Los operandos de una expresión, se evalúan de izquierda a derecha . Así :
func1()+func2()
es una expresión que provoca la evaluación, en primer lugar, de func1(), y
luego func2(). Esto es importante en el caso de producir algún efecto en esas
funciones, como salidas por pantalla. En general se evalúan todos los operandos,
salvo en el caso de expresiones que involucren el OR lógico || o el AND lógico &&.
Asociativilidad de operadores C#
En C#, un operador es un término o un símbolo que acepta como entrada una o más
expresiones, denominadas operandos, y devuelve un valor. Los operadores que requieren
un operando, como el operador de incremento (++) o new, se denominan operadores
unarios. Los operadores que requieren dos operandos, como los operadores aritméticos
(+, -, *, /) se denominan operadores binarios. Un operador, el operador condicional (?:),
utiliza tres operandos y es el único operador terciario de C#.
La instrucción de C# siguiente contiene un solo operador unario y un solo operando. El
operador de incremento, ++, modifica el valor del operando y.
C#
y++;
La instrucción de C# siguiente contiene dos operadores binarios, cada uno con dos
operandos. El operador de asignación, =, tiene el entero y y la expresión 2 + 3 como
operandos. La propia expresión 2 + 3 contiene el operador de suma y utiliza los valores
enteros 2 y 3 como operandos:
C#
y = 2 + 3;
Un operando puede ser una expresión válida de cualquier tamaño, compuesta por una
cantidad cualquiera de otras operaciones.
Los operadores de una expresión se evalúan en un orden concreto conocido como
prioridad de operadores. La tabla siguiente divide a los operadores en categorías basadas
en el tipo de operación que realizan. Las categorías se muestran en orden de prioridad.
x.y, f(x), a[x], x++, x--, new, typeof, checked,
Principal
unchecked
Unario +, -, !, ~, ++x, --x, (T)x
Aritméticos: multiplicativos *, /, %
Aritméticos: aditivos +, -
Desplazamiento <<, >>
Comprobación de tipos y <, >, <=, >=, is, as
28. relacionales
Igualdad ==, !=
Lógicos, en orden de prioridad &, ^, |
Condicionales, en orden de
&&, ||, ?:
prioridad
Asignación =, +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=
Cuando dos operadores con la misma prioridad están presentes en una expresión, se
evalúan según su asociatividad. Los operadores que son asociativos por la izquierda se
evalúan en orden de izquierda a derecha. Por ejemplo, x * y / z se evalúa como (x * y) / z.
Los operadores que son asociativos por la derecha se evalúan en orden de derecha a
izquierda. Los operadores de asignación y el operador terciario (?:) son asociativos por la
derecha. Todos los otros operadores binarios son asociativos por la izquierda. Sin
embargo, el estándar de C# no especifica cuándo se ejecuta la parte "fija" de una
instrucción de incremento en una expresión. Por ejemplo, el resultado del código de
ejemplo siguiente es 6:
C#
int num1 = 5;
num1++;
System.Console.WriteLine(num1);
Sin embargo, el resultado del código de ejemplo siguiente es indefinido:
C#
int num2 = 5;
num2 = num2++; //not recommended
System.Console.WriteLine(num2);
Por consiguiente, no se recomienda el último ejemplo. Los paréntesis se pueden utilizar
para envolver una expresión y hacer que esa expresión sea evaluada antes que cualquier
otra. Por ejemplo, 2 + 3 * 2 normalmente darían 8 como resultado. Esto es porque los
operadores multiplicativos tienen prioridad sobre los operadores aditivos. Escribir la
expresión (2 + 3 ) * 2 da como resultado 10, ya que ésta indica al compilador de C# que
el operador de adición (+) se debe evaluar antes que el operador de multiplicación (*).
Asociativilidad de operadores 2
Normalmente, las expresiones con operadores se evalúan de izquierda a derecha, aunque
no todos, ciertos operadores que se evalúan y se asocian de derecha a izquierda. Además
no todos los operadores tienen la misma prioridad, algunos se evalúan antes que otros, de
hecho, existe un orden muy concreto en los operadores en la evaluación de expresiones.
Esta propiedad de los operadores se conoce como precedencia o prioridad.
Veremos ahora las prioridades de todos los operadores incluidos los que aún conocemos.
Considera esta tabla como una referencia, no es necesario aprenderla de memoria, en
caso de duda siempre se puede consultar, incluso puede que cambie ligeramente según el
compilador, y en último caso veremos sistemas para eludir la precedencia.
Operadores Asociatividad
() [] -> :: . Izquierda a derecha
29. Operadores unitarios: ! ~ + - ++ -- & (dirección de) * (puntero
Derecha a izquierda
a) sizeof new delete
.* ->* Izquierda a derecha
* (multiplicación) / % Izquierda a derecha
+ - (operadores binarios) Izquierda a derecha
<< >> Izquierda a derecha
< <= > >= Izquierda a derecha
== != Izquierda a derecha
& (bitwise AND) Izquierda a derecha
^ (bitwise XOR) Izquierda a derecha
| (bitwise OR) Izquierda a derecha
&& Izquierda a derecha
|| Izquierda a derecha
?: Derecha a izquierda
= *= /= %= += -= &= ^= |= <<= >>= Derecha a izquierda
, Izquierda a derecha
La tabla muestra las precedencias de los operadores en orden decreciente, los de mayor
precedencia en la primera fila. Dentro de la misma fila, la prioridad se decide por el orden
de asociatividad.
La asociatividad nos dice en que orden se aplican los operadores en expresiones
complejas, por ejemplo:
int a, b, c, d, e;
b = c = d = e = 10;
El operador de asignación "=" se asocia de derecha a izquierda, es decir, primero se
aplica "e = 10", después "d = e", etc. O sea, a todas las variables se les asigna el mismo
valor: 10.
a = b * c + d * e;
El operador * tiene mayor precedencia que + e =, por lo tanto se aplica antes, después se
aplica el operador +, y por último el =. El resultado final será asignar a "a" el valor 200.
int m[10] = {10,20,30,40,50,60,70,80,90,100}, *f;
f = &m[5];
++*f;
cout << *f << endl;
La salida de este ejemplo será, 61, los operadores unitarios tienen todos la misma
precedencia, y se asocian de derecha a izquierda. Primero se aplica el *, y después el
incremento al contenido de f.
f = &m[5];
*f--;
30. cout << *f << endl;
La salida de este ejemplo será, 50. Primero se aplica el decremento al puntero, y después
el *.
a = b * (c + d) * e;
Ahora el operador de mayor peso es (), ya que los paréntesis están en el grupo de mayor
precedencia. Todo lo que hay entre los paréntesis se evalúa antes que cualquier otra cosa.
Primero se evalúa la suma, y después las multiplicaciones. El resultado será asignar a la
variable "a" el valor 2000.
Este es el sistema para eludir las precedencias por defecto, si queremos evaluar antes una
suma que un producto, debemos usar paréntesis.
Relacion entre Jerarquia y precedencia
C++
Objetivos. Al finalizar la práctica los alumnos y alumnas sran capaces de:
Asimilar y poner en práctica los conceptos de datos y operadores, además conocerá sus
tipos.
Resolver expresiones usando la jerarquía de operadores.
Aplicar la jerarquía de operadores (lógicos y aritméticos) propias del Lenguaje C.
OPERADORES ARITMÉTICOS.
Sirven para realizar operaciones aritméticas básicas. Los operadores aritméticos C siguen
las reglas algebraicas típicas de jerarquía o prioridad.
Los paréntesis se utilizan en las expresiones de C de manera muy similar a como se usan
en las expresiones algebraicas, sirven para indicar que la expresión dentro de ellos se
debe realizar primero. Por ejemplo, para multiplicar a por la cantidad b+c escribimos:
a * (b + c)
Pow es la función que permite realizar las potencias. Por ejemplo x=23 se podría
presentar en C de las maneras siguientes: x=pow (2 , 3); o x=2*2*2;
Las reglas de precedencia o jerarquía de operadores son guías de acción, que le permiten
a C calcular expresiones en el orden correcto. Cuando decimos que una evaluación o
cálculo avanza de izquierda a derecha, nos estamos refiriendo a la asociatividad de los
31. operadores.
Ejemplo 1:
El siguiente ejemplo contiene módulo (%), multiplicación, división, adición y
sustracción.
Algebraicamente: z= pr mod q + w ÷ / x - y
En C: z = p * r % q + w / x – y;
1, 2, 4, 3, 5
Los números de las operaciones indican el orden en el cual C valorará o calculará los
operadores. La multiplicación, el módulo y la división, serán evaluadas primero, en un
orden de izquierda a derecha (es decir, se asocian de izquierda a derecha), en vista de que
tienen precedencia mayor que la suma y la resta. La suma y la resta serán calculadas
después. También ellas se evaluarán de izquierda a derecha.
No todas las expresiones con varios pares de paréntesis contienen paréntesis anidados. La
expresión a * ( b + c) + c * (d + e) no contiene paréntesis anidados. En vez de ello, se
dice que estos paréntesis están “en el mismo nivel”. En ese caso, se calcularán las
expresiones del paréntesis primero y en un orden de izquierda a derecha
Ejemplo 2:
Se tiene la siguiente expresión polinómica de segundo grado y=2*5*5+3*5+7, se desea
evaluarla y encontrar el resultado.
Solución:
Paso 1. y = 2 * 5 * 5 + 3 * 5 + 7;
2 * 5 = 10 (Multiplicación más a la izquierda primero)
Paso 2. y = 10 * 5 + 3 * 5 + 7;
10 * 5 = 50 (Multiplicación más a la izquierda)
32. Paso 3. y = 50 + 3 * 5 + 7;
3 * 5 = 15 (Multiplicación antes de la suma)
Paso 4. y = 50 + 15 + 7;
50 + 15 = 65 (Suma más a la izquierda)
Paso 5. y = 65 + 7;
65 + 7 = 72 (Última operación)
Operadores de Igualdad en Lenguaje C.
Como ya hemos visto, en Lenguaje C, los operadores algebraicos tienen la misma
función, pero cambia la forma en la que se presentan.
Los operadores de igualdad no son la excepción y al hablar de estos nos referimos a igual
(=) y no igual (≠). El resultado que generan los operadores de igualdad, puede ser un cero
(falsa) o uno (verdadero).
Tabla de Operadores de Igualdad.
Ejemplo:
a = b , se muestra en Lenguaje C de la siguiente manera: a = = b;
y a ≠ b , se escribiría así: a ! = b.
Operadores Relacionales en Lenguaje C.
Los enunciados ejecutables de C, pueden llevar a cabo ACCIONES (como cálculos o
salidas de datos), o tomar DECISIONES (evaluación de dos o más expresiones). Por
ejemplo, podríamos necesitar tomar una decisión en un programa para determinar si la
calificación de una persona en un examen es mayor o igual a 7, y si es así, imprimir el
mensaje “Felicidades usted pasó”.
Los operadores relacionales tienen un mismo nivel de precedencia y se asocian de
izquierda a derecha. En C, una condición puede ser cualquier expresión que genere un
valor de verdad falso o verdadero.
Tabla de Operadores Relacionales.
33. Ejemplo
Dados a=1, b=2 y c=3 efectúe la siguiente expresión: 10 * a > c * 10 + b
Paso I. 10 * 1 > 3 * 10 + 2
Paso II. 10 > 30 + 2
Paso III. 10 > 32
Respuesta FALSO
Operadores Lógicos.
Se utilizan para evaluar dos o más relaciones, estos operadores son AND, OR y NOT,
siempre devuelven como resultado un 0 (falso) o 1 (verdadero). Se evalúan primero las
relaciones y luego se evalúan las operaciones entre sí tomando en cuenta los operadores
lógicos.
El Operador AND.
Se evalúan primero las expresiones aritméticas, luego las relacionales y lógicas. Con el
operador and, para que la respuesta sea verdadera, ambas relaciones deben ser
verdaderas, de lo contrario, con una que sea falsa, el resultado de la evaluación es falso.
En C se utiliza && para representar el operador AND.
Ejemplo 1:
3 > 5 and 3 < 10; en Lenguaje C se representa por 3 > 5 && 3 < 10;
Para este ejemplo, la primera relación da como resultado FALSO (pues 3 no es mayor
que 5) mientras que la segunda relación da como resultado VERDADERO (3 es menor
que 10). El siguiente paso es evaluar los resultados con el operador lógico, en otras
palabras FALSO and VERDADERO esta evaluación da como resultado FALSO. Si el
resultado de las dos evaluaciones diera como resultado VERDADERO, entonces el
resultado seria VERDADERO.
Ejemplo 2:
5 > 2 and 10 ≥ 9; en Lenguaje C se representa por 5 > 2 && 10 >= 9;
En esta expresión las dos evaluaciones dan como resultado un valor VERDADERO, por
lo que al evaluar VERDADERO and VERDADERO da como resultado VERDADERO.
34. El Operador OR.
En este caso, al evaluar las expresiones aritméticas y luego las relacionales y lógicas;
para que la respuesta sea verdadera, una de las relaciones debe ser VERDADERA, si
todas las evaluaciones son FALSAS, el resultado de la evaluación es falso. En C se
utiliza || para representar el operador OR.
El Operador NOT.
Este operador tiene la función de cambiar el valor de verdad al penúltimo resultado
obtenido de evaluar la expresión. Si al final se obtiene not (verdadero), el resultado será
FALSO; y si es not (falso), el resultado será VERDADERO. En C se utiliza ! para
representar dicho operador.
Ejemplo 1:
Not(99 >= 50 or 10 > = 75); en Lenguaje C se representa !( 99 >= 50 || 10 >= 75)
Al evaluar esta expresión, notamos que en la primera parte nos da un verdadero y en la
segunda nos da un falso. De verdadero or falso obtenemos verdadero y finalmente not de
verdadero nos da como resultado un FALSO.
Jerarquía general de operadores en Lenguaje C.
ASOCIATIVIDAD
En una expresión tal como 3 * 4 + 5 el compilador realiza primero la multiplicación - por
tener el operador * prioridad más alta - y luego la suma, por tanto, produce 17. Para
forzar un orden en las operaciones se deben utilizar paréntesis.
3 * (4 + 5) produce 27, ya que 4 + 5 se realiza en primer lugar.
La asociatividad determina el orden en que se agrupan los operadores de igual prioridad;
35. es decir, de izquierda a derecha o de derecha a izquierda. Por ejemplo,
X – y + z se agrupa como ( x – y ) + z
Ya que – y +, con igual prioridad, tienen asociatividad de izquierda a derecha. Sin
embargo,
x = y = z se agrupa como x = ( y = z ) dado que su asociatividad es de derecha a
izquierda.
Uso de Paréntesis
Los paréntesis se pueden utilizar para cambiar el orden usual de evaluación de una
expresión determinada por su prioridad y asociatividad. Las subexpresiones entre
paréntesis se evalúan en primer lugar según el modo estándar y los resultados se
combinan para evaluar la expresión completa. Si los paréntesis están anidados, es decir,
un conjunto de paréntesis contenido en otro, se ejecutan en primer lugar los paréntesis
más internos. Por ejemplo, considérese la expresión ( 7 * (10 – 5) % 3 ) * 4 + 9
La subexpresión (10 – 5) se evalúa primero, produciendo (7 * 5 % 3) * 4 + 9
A continuación se evalúa de izquierda a derecha la subexpresión (7 * 5 % 3) y obtenemos
(35 % 3) * 4 + 9 luego
2 * 4 + 9 donde se realiza la multiplicación y obtenemos 8 + 9 lo que produce un
resultado final de 17.
Ejercicio 1.
A continuación se muestran expresiones algebraicas en base a las cuales usted deberá
formular expresiones en C, utilizando los operadores aritméticos y tomando en cuenta la
precedencia de operadores aritméticos.
1.) db+ac÷x+y 3.) d mod c (b + a) 5.) ax
2.) x+y ( m) n 4.) x + y + z ( w ÷ a) 6.) (x + y) dn
Ejercicio 2:
Si x=10, y=5 y z=1 encontrar el resultado de las siguientes expresiones:
36. a) x = y ______ b) z ≥ y ______ c) x ≤ y ________
Ejercicio 3:
Si x=2, y=1, c=4 y d=6 evalúe la expresión y diga el resultado.
A) x = y _____________ B) c ≠ d __________
Ejercicio 4. Evalúe las expresiones siguientes; use los mismos valores del ejemplo
anterior:
A) ( y + 2 ) * c > = ( d + 1 ) * c R/ ______________
B) ( ( 2 / c ) * ( d / 2 ) ) + 5 < 10 R/ ______________
OPERADOR DE ASIGNACIÓN:
El operador = asigna el valor de la expresión derecha a la variable situada a su izquierda.
Ej. Pi = 3.1416
Raiz2 = 1.4142
Este operador es asociativo por la derecha, lo que permite realizar asignaciones múltiples.
Así a = b = c = 45; equivale a a= (b = (c = 45)); en otras palabras, a, b y c toman el valor
de 45.
Esta propiedad permite inicializar varias variables con una sola sentencia.
Int a, b, c;
A = b = c = 5;
TABLA DE OPERADORES DE ASIGNACIÓN:
37. Operadores de Incrementación y Decrementación
De las características que incorpora C, una de las más útiles son los operadores de
incremento ++ y decremento -- . Los operadores ++ y --, denominados de incrementación
y decrementación, suman o restan 1 a su argumento, respectivamente, cada vez que se
aplican a una variable.
Entonces a++ equivale a a = a + 1
Estos operadores tienen la propiedad de que pueden utilizarse como sufijo o prefijo, el
resultado de la expresión puede ser distinto, dependiendo del contexto.
Las sentencias ++n; y n++; tienen el mismo efecto; así como --n; y n--;
Sin embargo, cuando se utilizan como expresiones tales como
m = n++;
printf(“ n = %d”, n--) ; el resultado es distinto si se utilizan como prefijo.
++n produce un valor que es mayor en uno que el de n++, y --n produce un valor que es
menor en uno que el valor de n--. Supongamos que
n = 8;
m = ++n; /* incrementa n en 1, dando 9, y lo asigna a m */
n = 9;
printf(“ n = %d”, --n); /*decrementa n en 1, dando 8 y lo pasa a printf( ) */
En este otro ejemplo:
int a = 1 , b;
b = a++; /* b vale 1 y a vale 2 */
int a = 1, b;
b = ++a; /* b vale 2 y a vale 2 */
Entonces, si los operadores ++ y -- están de prefijos, la operación de incremento o
decremento se efectúa antes que la operación de asignación; si los operadores están de
38. sufijos, la asignación se efectúa en primer lugar y la incrementación o decrementación a
continuación.
Jerarquia de las operaciones
1º.Efectuar las operaciones entre paréntesis, corchetes y llaves.
2º.Calcular las potencias y raíces.
3º.Efectuar los productos y cocientes.
4º.Realizar las sumas y restas.
Tipos de operaciones combinadas
1. Operaciones combinadas sin paréntesis
1.1 Combinación de sumas y diferencias.
9 - 7 + 5 + 2 -6 + 8 - 4 =
Comenzando por la izquierda, vamos efectuando las operaciones según aparecen.
= 9 - 7 + 5 + 2 -6 + 8 - 4 = 7
1.2 Combinación de sumas, restas y productos.
3·2-5+4·3-8+5·2=
Realizamos primero los productos por tener mayor prioridad.
= 6 - 5 + 12 - 8 + 10 =
Efectuamos las sumas y restas.
= 6 - 5 + 12 - 8 + 10 = 15
1.3 Combinación de sumas, restas, productos y divisiones.
10 : 2 + 5 · 3 + 4 - 5 · 2 - 8 + 4 · 2 - 16 : 4 =
Realizamos los productos y cocientes en el orden en el que los encontramos porque las
dos operaciones tienen la misma prioridad.
= 5 + 15 + 4 - 10 - 8 + 8 - 4 =
Efectuamos las sumas y restas.
= 5 + 15 + 4 - 10 - 8 + 8 - 4 = 10
1.4 Combinación de sumas, restas, productos, divisiones y potencias.
39. 23 + 10 : 2 + 5 · 3 + 4 - 5 · 2 - 8 + 4 · 22 - 16 : 4 =
Realizamos en primer lugar las potencias por tener mayor prioridad.
= 8 + 10 : 2 + 5 · 3 + 4 - 5 · 2 - 8 + 4 · 4 - 16 : 4 =
Seguimos con los productos y cocientes.
= 8 + 5 + 15 + 4 - 10 - 8 + 16 - 4 =
Efectuamos las sumas y restas.
= 26
2. Operaciones combinadas con paréntesis
(15 - 4) + 3 - (12 - 5 · 2) + (5 + 16 : 4) -5 + (10 - 23)=
Realizamos en primer lugar las operaciones contenidas en ellos.
= (15 - 4) + 3 - (12 - 10) + (5 + 4) - 5 + (10 - 8 )=
Quitamos paréntesis realizando las operaciones.
= 11 + 3 - 2 + 9 - 5 + 2 = 18
3.Operaciones combinadas con paréntesis y corchetes
[15 - (23 - 10 : 2 )] · [5 + (3 ·2 - 4 )] - 3 + (8 - 2 · 3 ) =
Primero operamos con las potencias, productos y cocientes de los paréntesis.
= [15 - (8 - 5 )] · [5 + (6 - 4 )] - 3 + (8 - 6 ) =
Realizamos las sumas y restas de los paréntesis.
= [15 -3 ] · [5 + 2 ] - 3 + 2=
Operamos en los paréntesis.
= 12 · 7 - 3 + 2
Multiplicamos.
= 84 - 3 + 2=
40. Restamos y sumamos.
= 83
4.Con fracciones
Primero operamos con las productos y números mixtos de los paréntesis.
Operamos en el primer paréntesis, quitamos el segundo, simplificamos en el tercero y
operamos en el último.
Realizamos el producto y lo simplificamos.
Realizamos las operaciones del paréntesis.
Hacemos las operaciones del numerador, dividimos y simplificamos el resultado.
Ejercicio de operaciones combinadas
14 − {7 + 4 · 3 - [(-2)2 · 2 - 6)]}+ (22 + 6 - 5 · 3) + 3 - (5 - 23 : 2) =
Primero operamos con las potencias, productos y cocientes de los paréntesis.
14 − [7 + 4 · 3 -(4 · 2 - 6)] + (4 + 6 - 5 · 3) + 3 - (5 - 8 : 2) =
Operamos con los productos y cocientes de los paréntesis.
14 − [7 +12 -(8 - 6)] + (4 + 6 - 15) + 3 - (5 - 4) =
Realizamos las sumas y diferencias de los paréntesis.
14 − (7 +12 -2) + (-5) + 3 - (1) =
41. 14 − (17) + (-5) + 3 - (1) =
La supresión de paréntesis ha de realizarse considerando que:
Si el paréntesis va precedido del signo + , se suprimirá manteniendo su signo los términos
que contenga.
Si el paréntesis va precedido del signo − , al suprimir el paréntesis hay que cambiar de
signo a todo los términos que contenga.
14 − 17 - 5 + 3 - 1 = − 6
42. Conclusion
En conclusion llegamos a entender y a
manipular mejor a lo que encierra el tema
operadores cullas funciones y respuestas nos
ayudan a entender algunas funciones de las
matematicas.