[Multi] C++, Los operadores

Volvemos al tutorial, hoy: Operadores.

En este apartado veremos como actuan y se utilizan los diferentes operadores. El signo = es un operador de asignacion. Realmente un operador es el encargado de variar el valor de nuestros datos, sin ellos no hay programa.

Operadores
Son simbolos que indican como se tratan los datos que hay entre ellos, el ejemplo mas claro es el = que ya sabemos como funciona
Ejemplo
int a,b=5;
a = b; //a pasa a valer 5

Los podemos clasificar en 8 diferentes tipos:
Aritmeticos suma,resta....
Relacionales Mayor,menor, igual
Logicos And,or (en su apartado lo explico)
Unitarios Solo afecta a una variable, cambio de signo, complemento a 1.
A nivel de bits And,or,desplazamientos....
Asignacion Suma y asignacion,incremento....
Condicional Sera expresion?verdadero:falso;
Otros sizeof,coma.....

Aritmeticos
Estos operadores llevan una variable a la izquierda y otra a la derecha y devulven la operacion indicada con esas dos variables. Los diferentes tipos son:
+ Suma
- resta
* Multiplicacion
/ division
% devuelve el resto de una division

Ejemplo:
        int a = 10,b = 5; //inicializamos dos variables a 10 y 5 respectivamente
        printf("%d",a+b); //Muestra 15, osea la suma
        printf("%d",a-b); //Muestra 5
        printf("%d",a*b); //Muestra 50
        printf("%d",a/b); //Muestra 2
        printf("%d",a%b); //Muestra 0

Relacionales

Con estos operadores podemos comprobar la relacion entre dos variables situadas una izquierda y otra a la derecha del operador, Devuelven valoes del tipo 0 (falso) distinto de 0 (verdadero). Los tipos son:
> Mayor
>= Mayor o igual
< Menor
<= Menor o igual
== Igual
!= Diferente

Ejemplo
int a = 10,b = 5; //inicializamos dos variables a 10 y 5 respectivamente
printf("%d",a printf("%d",a<=b); //Muestra 0
printf("%d",a>b); //Muestra 1
printf("%d",a>=b); //Muestra 1
printf("%d",a==b); //Muestra 0
printf("%d",a!=b); //Muestra 1


Logicos

Aqui primero vamos a explicar que es esto de And, or,exor...
AND Se comparan dos elementos, uno a cada lado del AND y para devolver un verdaderos los dos elementos deben ser verdaderos osea que sirve para agrupar expresiones devueltas por operadores relacionales. O_o Vale no se como explicarlo mejor asi que ejemplo:
a=5 b=10 c =15 d=20
ad //ad= Falso, Verdadero == falso como no son los dos verdaderos devuelve falso.
OR Su uso es igual al AND pero aqui para que devuelva verdadero tiene que haber al menos un verdadero.
a=5 b=10 c =15 d=20
ad //ad= Falso, Verdadero == falso como uno es verdadero devuelve verdadero.
EXOR or exclusivo igual que el OR pero si todos los terminos son verdaderos tambien devuelve falso.
Y continuamos con C. En C tambien disponemos de estas operaciones, estas son a nivel logico devuelven verdadero o falso. Su sintaxis es condicion Operador condicion... se pueden encadenar varias. Y ahora si los tipos en C son:
&& AND
|| OR (altgr+1 para colocar el pipe)
! Negacion Ahora veremos esto en ejemplos y quedara mas claro

Ejemplos:
int a=5,b=6,c=7,c=8;
printf("%d", a printf("%d", a8); //Muestra 1
int d=0;
printf("%d",!d); //Muestra verdadero, fijate que una condicion con una variable sin ningun otro operador devuelve falso si es 0 y verdadero si es diferente a 0

Unitarios

Solo afectan a un operando, Los tipos son:
~ (altgr+4 y pulsa espacio) Complemento a 1 Los ceros unos y los unos ceros
- Cambia el signo del operando (no se que ocurrira con tipos unsigned, supongo que error) Nombre tesnico Complemento a 2
Otros explicados en otros puntos: !.++.--

Ejemplo
    short a = 8; //a= 0000000000010000
    ~a; //a=1111111111101111



A nivel de bit
Aqui es importante reseñar que estos operadores van a trabajar bit a bit asi que su correcto uso y utilidad van a depender muchisimo de la situacion. Con ejemplos luego se vera mas claro:
& AND en este caso el uso es similar que el anterior, sin embargo la respuesta es diferente. Veamos un ejemplo:
            int a=10,b=5; //Declaramos e inicializamos las variables
            int c= a&b; //Guardamos en c la devolucion de & y devuelve 0
/*            00000000000000000000000000001010
            00000000000000000000000000000101
            00000000000000000000000000000000    */
            b = 6;
            c = a&b; //Devuelve 4
/*            00000000000000000000000000001010
            00000000000000000000000000000110
            00000000000000000000000000000010    */

| OR el uso similar al OR logico, pero como en el & la respuesta es muy diferente
         int a=10,b=5; //Declaramos e inicializamos las variables
            int c= a|b; //Guardamos en c la devolucion de | y devuelve 15
/*            00000000000000000000000000001010
            00000000000000000000000000000101
            00000000000000000000000000001111    */
            b = 6;
            c = a|b; //Devuelve 15
/*            00000000000000000000000000001010
            00000000000000000000000000000110
            00000000000000000000000000001111    */

^ XOR u OR exclusivo. Su uso es similar al OR pero con la salvedad que si una de las condiciones es verdadera la respuesta es verdadera, sin embargo si ambas son verdaderas la respuesta es falsa.
           int a=10,b=5; //Declaramos e inicializamos las variables
            int c= a^b; //Guardamos en c la devolucion de & y devuelve 15
/*            00000000000000000000000000001010
            00000000000000000000000000000101
            00000000000000000000000000001111    */
            b = 6;
            c = a^b; //Devuelve 12
/*            00000000000000000000000000001010
            00000000000000000000000000000110
            00000000000000000000000000001100    */


<< Desplazamiento de bits a la izquierda rellenando con ceros por la derecha. Su uso es Variable << n siendo n la cantidad de posiciones que se desplazaran los bits. Es el equivalente a multiplicar por 2 elevado a n
int a = 10;
int b = a << 4; //b pasa a valer 10*2^4->160
/* 00000000000000000000000000001010 -->10
00000000000000000000000010100000 -->160 */

>> Desplazamiento de bits a la derecha rellenando con ceros por la izquierda. Su uso es Variable >> n siendo n la cantidad de posiciones que se desplazaran los bits. Es el equivalente a dividir por 2 elevado a n
           int a = 65;
            int b = a >> 4; //b pasa a valer 65/2^4->4
/*            00000000000000000000000001000001 -->65
            00000000000000000000000000000100 -->4   */

Asignacion
Estos operadores asignan valores a la variables. Todos se componen de variable operador variable excepto ++ y -- que son unitarios.Los diferentes tipos:
++ incremento.Tiene dos formas a la derecha es postincremento y a la izquierda preincremento. Incremewnta en 1 la variable
-- decremento. Exactamente igual al anterior exceptuando que este en vez de sumar 1 lo resta.
= Asignacion simple. No se, todos sabemos ya como funciona un =.
*= Multiplicacion y asignacion. Multiplica la variable por el numero de la derecha y despues cambia en valor de la variable de la izquierda por el resultado de esa operacion.
+= Suma y asignacion. Analogo al anterior
-= Resta y asignacion
/= Division y asignacion.
%= Modulo mas asignacion.
<<= Desplazamiento mas asignacion.
>>= Analogo
&= AND a nivel de bits mas asignacion
|= OR nb mas asignacion
^= XOR nb mas asignacion.

Ejemplos:
    int a,b,c,d;
    a=5;
    a++; // a pasa a valer 6
    a--; // a pasa a valer 5
    b = a++; //b vale 5 y a vale 6
    c=--a; //a y c valen 5


Condicional o ternario
Se utiliza para poder elegir entre n caminos mediante sentencias de verdadero o falso.Su sintaxis es:
expresion ? valor verdadero: valor falso;

Ejemplo.
    char* verdadero="Mayor";
    char* falso="Menor";
    int a=9,b=5;
    printf("%s", (a>b)? verdadero: falso);


Otros operadores
sizeof devuelve el tamaño en bytes de su opreando. Sintaxis: sizeof(dato);
, (coma) se utiliza para encadenar varias operaciones, que se ejcutaran de izquierda a derecha. Su uso es comun en los bucles for y en la declaracion de variables. Ejemplo: int a , b;
& (referencia)Direccion de, nos devuelve la direccion de memoria del operando. Sintaxis: &dato
* (puntero) Indireccion, accede indirectamente a un valor a traves de una direccion o puntero.

Ejemplo de como funcionan estos dos ultimos:
#include
#include

void main(){
int *px,x=7,y=0;
px = &x;
y =*px;
printf ("Direccion de memoria = %d, dato = %d",&x,x);
printf ("Direccion de memoria = %d, dato = %d",px,*px);
getch();
}

Prioridad de ejecucion.
Al igual que en las matematicas, en la programacion los operadores tienen prefenrecias sobre otros asi que aqui voy a ponerlos del priemro que se ejecuta al ultimo.
( ) [ ] . -> Asocian de izquierda a derecha
-- ! ++ - ~ (tipo) * & sizeof Asocian de derecha a izquierda
* / % Asocian de izquierda a derecha
+ - Asocian de izquierda a derecha
<< >> >>> Asocian de izquierda a derecha
< <= >= > instanceof Asocian de izquierda a derecha
== != Asocian de izquierda a derecha
& Asocian de izquierda a derecha
^ Asocian de izquierda a derecha
| Asocian de izquierda a derecha
&& Asocian de izquierda a derecha
|| Asocian de izquierda a derecha
?: Asocian de derecha a izquierda
= *= += /= -= %= <<= >>= >>>= &= |= ^= Asocian de derecha a izquierda

Bueno pues hemos llegado al fin de los operadores, un poco coñazo eso si pero es necesario conocer las herramientas antes de empezar a trabajr con ellas. A partir de aqui se acabo mas o menos el coñazo, lo siguiente en venir son las funciones y ahi ya empezaremos a crear codigo. Con ellas explicare las sentencias de control (if,for...)
y crearemos un pequeño programa que intente adivinar un numero mediante mayor o menor con la busqueda dicotomica.
Esto es lo que necesitamos los novatos que queremos saber el funcionamiento de los programas y por que no de paso aprender.

5 estrellas
muchos newbies se lo pasarán bien leyendolo ;) buen tuto.

por cierto soy de la opinion q c++ se aprende con libros...
- Cambia el signo del operando (no se que ocurrira con tipos unsigned, supongo que error) Nombre tesnico Complemento a 2


Si es un unsigned, almacena la representacion binaria del numero negativco (aunque eso si, saltará el warning de turno)

Como sabemos, los numeros enteros se almacenan en formato binario
y cada bit representa una potencia de 2.

Los bit se ordenan según su peso, siendo el de menor peso el bit 0 (que representa el valor 1) y el de mayor peso depende del tipo que estemos usando, siendo el bit 7 en el caso de un char, bit 15 en el de short y bit 31 en el caso de un int.

Pues bien, ese bit mas alto, es el bit de signo, usado para diferenciar entre positivo (cuando está a 0 ) y negativo (cuando está a 1)

Asi si almacenamos el valor -1 en un char, realmente, en la variable se almacenan los 8 bits a 1, que equivalen al valor 255 de un unsigned char.

Un truco muy sencillo para conocer exactamente el valor que se almacena cuando el numero es negativo, consiste utilizar el valor del bit que seguiria al de mayor peso y hacer la resta del valor negativo.

Asi por ejemplo, si intentamos almacenar -20 en un short, el bit de mayor peso, sería el 15 y el siguiente seria el 16 que representa un valor de 2^16= 65536

Haciendo la resta nos quedaría: 65536-20=65516 y ese sería el valor real almacenado en nuestra variable o el valor unsigned short, si lo preferís asi.

PD: Creo que no vienen mal este tipo de anotaciones complementarias, pues si bien a los novatos quizá les venga grande en estos momentos, a los que están un poco mas curtidos les viene bien saberlo ;)

saulotmalo escribió:por cierto soy de la opinion q c++ se aprende con libros...


Yo no lo diría así. Los lenguajes de programación, se aprenden trabajando con ellos y los libros son una buena base de consulta para determinadas cuestiones, pero la mecanica se coge a base de trabajo (el trabajo es la clave, muchachos, a lo mejor te parece una tontería hacer un programa que piensas que es muy sencillo cuando los 'monstruos' de la scene hacen cosas flipantes, pero solo mediante ese trabajo, podrás llegar algún día a hacer cosas similares, no hay otro truco)

Ahora bien, si lo dices por los cursillos... pues la verdad, es mucho mejor aprender a traves de un buen libro de programación y trabajando (salvo que no conozcas nada sobre programación y no puedas apañarte a base de libros)
Gracias Hermes por la complementacion. Estoy evitando usar segun que cosas (como bit de mayor o menor peso) pues para un novato no es que venga grande, sino que pueden dejarlo por no entender (me ha pasado con alumnos).
El truco mas facil para saber que ocupa un numero es hacer el complemento a 2 [+risas](cambiar ceros por unos y unos por ceros y sumar 1 al bit de menor peso).
Para no marear la perdiz en las variables, en char no mencione que puede ser unsigned, ni nombre los booleanos porque los veremos como flags en los struct consiguiendo que ocupen realmente solo 1 bit y no 8.
Y ya que estamos complementandolo:
Las operaciones a nivel de bits cuestan menos recursos que las otras. Asi que siempre que sea posible las utilizaremos. En una consola los recursos son muy limitados asi que no es bueno empezar a recargar cuando no hace falta.
Con los operadores se pueden crear soluciones complejas:
a = b == c (a vale b y se comprueba si b y c son iguales)
Tambien habra casos especiales en que el comportamiento original de un operador no nos valga, por ejemplo en las sumas de grados minutos y segundos. Entonces nosotros podremos modificar el comportamiento de los operadores para que hagan lo que deseamos, esto se llama sobrecarga de operadores.

Matematicas:
Cualquier base numerica se basa en esta regla:
Lo dividimos en unidades (100 seria 1, 0 y 0) y empezando desde la derecha y contando la posicion del primer digito como 0:
digito*base^posicion+digito*base^poisicion....
Unos ejemplos
Binario
110
1*2^2+1*2^1+0*2^0=6 en decimal
octal
110
1*8^2+1*8^1+0*8^0=72 en decimal
decimal
110
1*10^2+1*10^1+0*10^0=110 en decimal
Hexadecimal
110
1*16^2+1*16^1+0*16^0=272 en decimal

Me siento orgulloso de tenerte aqui complementando este tutorial pues si bien yo lo oriente hacia novatos tu lo estas complementando hacia todo el espectro. [beer]
[Offtopic]
Me caguen en el puñetero editor avanzado, esta haciendo lo que le sale de los huevos con el formato. Y una pregunta: ¿puedo meter etiquetas para crear hipervinculos? Si es asi me lo curro todo con vinculos hacia las diferentes partes del tutorial e incluso indices
[/Offtopic]

Saulotmalo, lo de los libros esta pillado por los pelos. Solo la experiencia te puede enseñar a depurar.
C++ es un lenguaje que en determinados momentos toma decisiones erroneas, y ahi un libro no te puede ayudar, solo la experiencia frente a este tipo de errores es lo que sirve.
Ahora bien si a lo que te refieres es a que un tuto por internet no se puede comparar a un libro...tienes toda la razon del mundo, pero la interactividad que podemos conseguir aqui, en un libro es imposible.
Y esto lo hace un recurso muy jugoso para aquel que empieza y dice: bits con peso?? los hay anorexicos??[+risas]Que es el ambito?? Vale lo sabes explicar muy bonito pero, que leches es el ambito??clases??polimorfismo??
Y como todos los libros estan escritos de programadores para programadores, o si no es asi te tienes que comprar 7 y algunos de ellos en ingles, esto prentende erradicar ese problema. De todas formas hay unos de Ra-ma que son 4 creo que no estan del todo mal

Y una cosa mas os digo.Gran parte de lo escrito es tirando de memoria, asi que en algun momento la voy a meter hasta el fondo seguro asi que decidmelo y lo corrijo.

Saludos y gracias por participar [beer]
me refiero lo de libros para la gente que empieza... aunque claro... en teoria este foro ( que me acabo de leer las normas) no es para gente que empieza, así que novatos FUERA xD ( es coña, a mi no me molestan )

por cierto si a alguien le interesa que busque un libro que se llama aprender a programar en c++ creo que es de la universidad de navarra y la verdad me encantó a mi me ayudó mucho para empezar ;)
No sera de la serie"aprende lokesea como si estuvieras en primero"?.
Son buenos, pero c++ es un monstruo de 7 cabezas. Da = cuanto leas, siempre hay algo nuevo que aprender.
si, creo que eran de esa serie, es que a mi me gustaron mucho no se...

un mounstruo de 7 cabezas xDDD buena definición xD
C++ pienso que es bastante complicado de entender para un principiante, porque el concepto de los objetos es bastante abstracto para alguien que no haya programado una linea de codigo en su vida.


Sobre lo del complemento a 2, PauSaDRaMaTiCa lo se, pero eso de los complementos a muchos los deja frio XD. En realidad lo que ocurre al restar, es que se produce un desborde de la variable o registro y por eso si añades ese bit mas alto (que corresponde al bit de acarreo), se ve claro de donde sale el valor almacenado.

Pregunta: ¿que valor se almacena en un unsigned short si el valor original es 65520 y le sumamos 16?


cero, ya que 65520+16=65536 el cual para representarse necesitaría del bit 16 (el resto de bits quedarían a 0) y ese bit 16 corresponde al indicador de acarreo (C, carry flag) en el registro de estado del procesador.

De hecho, a nivel maquina, existe una instruccion (ADC) que puede realizar una suma de registros a los que añade ese Carry Flag para
poder realizar la suma de numeros que tienen un tamaño mayor del que se puede almacenar en un registro del procesador

Desde C no se puede consultar ese registro de estado a menos que enlacemos código en lenguaje ensamblador que nos provea de una funcion que nos devuelva ese estado.



PD: Los novatos tomad estos comentarios como de segunda pasada, una vez que tengais cogido el concepto de lo que explica el compañero PauSaDRaMaTiCa, porque esto va mas orientado a gente que se pregunta cosas como: Bueno si el valor maximo que puedo almacenar en esta variable es X y me paso al relizar una suma o resta ¿que valor tengo en el registro?
saulotmalo escribió:no es para gente que empieza, así que novatos FUERA





Vale vale ya me voy eh, tampoco hace falta ponerse asi cacho poota xD
Eskematico escribió:


Vale vale ya me voy eh, tampoco hace falta ponerse asi cacho poota xD


yo lo decia de coña eh! a mi me parece una injusticia y ya se que no eres un novato ;) pero la las normas... en fin...
saulotmalo escribió:
yo lo decia de coña eh! a mi me parece una injusticia y ya se que no eres un novato ;) pero la las normas... en fin...


Las normas están para que no entren novatos preguntando exactamente lo mismo en multitud de hilos (sin leer los foros pimero o tratar deadquirir antes un poco de conocimiento)

Al fin y al cabo, la moderacion efectiva la vamos a hacer NOSOTROS, con nuestros reportes: si no se reporta, jiXo no intervendrá, salvo que sea algo de otra naturaleza.

Un novato tiene que entender, que si por ejemplo, entra en este hilo y plantea una duda sobre el cursillo, va a recibir toda la ayuda que le podamos proporcionar, pero si abre un hilo para cada duda que se le plantee, no será lo mismo.

Esto lo digo de cara a los novatos (de programación, se sobreentiende) que aquí tienen libertad absoluta para preguntar las dudas que tengan sobre el cursillo, pues el cursillo se supone que está destinado a ellos!

Asi que, por favor, no os corteis a la hora de preguntar por aquí, pero eso sí, utilizad el resto del foro con respeto y usad los canales apropiados y no habra ningún problema, que aquí nadie se come a nadie ;)
Me estoy leyendo tus tutos y creo qeu si qeu aprendo algo....
Espero siguientes entregas....
Muchas gracias por pensar en los qeu no sabemos programar....
Me vienen de puta madre los tutoriales, pues he empezado hace poco la carrera de informatica y hay una asignatura de C++.X-D

Un saludo y 5 estrellitas [oki]
que tiempos de facultad.....

if...

else...
swicht...

for....

whiles...
even...

VHDL... uffff
14 respuestas