Operadores

LOs operadores se pueden clasificar en:

1. Asignación

Se llama operador de asignación a un único signo =. Tiene un significado diferente que en la clase de álgebra donde indica una ecuación o igualdad. El operador de asignación le dice al uC que evalúe cualquier valor o expresión que esté en el lado derecho del signo igual y lo almacena en la variable a la izquierda del signo igual.

variable = valor;
n = 5;
x = n + 5;

La variable en el lado izquierdo del operador de asignación necesita poder contener el valor almacenado en ella. Si no es lo suficientemente grande como para contener un valor, el valor almacenado en la variable será incorrecto.

No confunda el operador de asignación = (signo igual individual) con el operador de comparación == (doble signos igual), que evalúa si los dos expresiones son iguales.

if (n = 5){...};                  //Grave error, estas asignando y no comparando.
for (byte n=0; n=10; n++){...}    //Grave error, estas asignando y no comparando.

2. Aritmético

2.1 Suma

La suma es una de las cuatro operaciones aritméticas primarias. El operador + (más) opera en dos operandos para producir la suma.

int x = 10;
int y = 5;
x = x + 30;  //40
x++;         //41 (Incrementa x en uno)
x += y;      //46 (Incrementa x en y)

La operación de adición puede desbordarse si el resultado es mayor que el que se puede almacenar en el tipo de datos (por ejemplo, agregar 1 a un número entero con el valor 32.767 da -32.768).

Si uno de los números (operandos) son del tipo float (o tipo double), se usará matemática de punto flotante para el cálculo. Si los números (operandos) son de tipo float (o double) y la variable que almacena la suma es tipo entero, entonces solo se almacena la parte entera y se pierde la parte fraccional del número.

2.2 Resta

La resta es una de las cuatro operaciones aritméticas primarias. El operador -(menos) opera en dos operandos para producir la diferencia entre el segundo y el primero.

int x = 10;
int y = 5;
x = x - 3;  //7
x--;        //6 (decremente x en uno)
x -= y;     //1 (decremente x en y)

2.3 Multiplicación

La multiplicación es una de las cuatro operaciones aritméticas primarias. El operador *(asterisco) opera en dos operandos para producir el producto.

int x = 10;
int y = 5;
x = 2*x;   /20
x *= y     //100 (Multiplica x por y)

2.4 División

La división es una de las cuatro operaciones aritméticas primarias. El operador /(barra inclinada) opera en dos operandos para producir el resultado.

int x = 20;
int y = 5;
x = x/2;  //10
x /= y;   //2 (Divide x entre y)

2.5 Modulo

La operación Modulo calcula el resto cuando un entero se divide por otro. Es útil para mantener una variable dentro de un rango particular (por ejemplo, el tamaño de una matriz). El símbolo % (por ciento) se usa para llevar a cabo la operación de módulo.

x = 7 % 5;    //2
x = 9 % 5;    //4
x = 5 % 5;    //0
x = 4 % 5;    //4

3. Comparadores

Son operadores que usamos para crear condiciones lógicas. Son: ==, !=, >, <, >=, <=

x == y; //Igual
x != y; //Diferente
x < y; //Menor
x > y; //Mayor 
x <= y; //Menor o igual
x >= y; //Mayor o igual 

4. Booleanos

Son operadores que usamos para unir condiciones lógicas.

NOT - !
AND - &&
OR - ||
!m         //Si m es falso la expresión es verdad
x=1 && y=2 //Se deben cumplir ambas condiciones para resultar verdad.
x=1 || y=2 //Basta que una de las condiciones sea verdad para resultar verdad.
x>=0 && x<=9 //Si es un dígito entre 0 y 9.

No confundir el operador booleano AND (&&) con el operador bit a bit AND (&)

5. Compuestos

Son operadores matemáticos compuestos que hacen operaciones: ++, --, +=, -=, *=, /=, &= y |=

Operadores compuestos
OperadorDescripciónEjemplo
++Incrementon++
--Decrementon--
+=Adiciónn += 3
-=Restan -= 3
*=Multiplicaciónn *= 3
/=Divisiónn /= 3
&=And bit a bit
|=Or bit a bit
x += 7;  //Aumentar x en 7

6. Bit a bit

Estos operadores se aplican de manera individual a cada dígito en binario de los números. Se común aplicarlo a números tipo byte (1 byte), pero también se puede aplicar a números tipo int (2 bytes)

a & b
Operadores bit a bit
OperadorDescripciónEjemplo
~Not~a
&And
|Ora | b
^Xora ^ b
<<Bitshift izquierda
>>Bitshift derecha

Es importante tener en mente que un numero del tipo byte puede contener hasta 8 valores verdadero/falso empacados en un solo byte y que se puede operar con ellos con operadores bit a bit y funciones internas de bits y byte.

No confundir el operador AND bit a bit (&) con el operador booleano AND (&&)

6.1 Not

El operador binario bit a bit NOT es representado por el caracter tilde ~. NOT opera sobre el numero a su derecha cambiando cada bit a su valor opuesto, es decir: cada 0 se convierte en 1 y 1 se convierte en 0.

byte a = B11110000;
byte b = ~a;  //B00001111
int a = 103; //B0000000001100111 = 103
int b = ~ a; //B1111111110011000 = -104
x = ~ x; // alternar todos los bits en x y almacenar de nuevo en x

Es posible que se sorprenda al ver un número negativo como -104 como resultado de esta operación. Esto se debe a que el bit más alto en una variable tipo int es el llamado bit de signo. Si el bit más alto es 1, el número se interpreta como negativo. Es interesante notar que cualquier numero entero n, si lo negamos ~n sera el complemento -n-1.

6.2 And

El operador binario bit a bit AND es representado con el símbolo comercial: &, usado entre otras dos expresiones enteras. AND opera en cada posición de bit de las expresiones circundantes de forma independiente, de acuerdo con esta siguiente regla: si ambos bits de entrada son 1, la salida resultante es 1; de lo contrario, la salida es 0. Otra forma de expresar esto es:

Operador AND
ExpresiónResultado
0 & 00
0 & 10
1 & 00
1 & 11
b = a & 0;  //asegura que b=0

6.3 Or

El operador binario bit a bit OR es representado con el símbolo de barra vertical: |, usado entre dos expresiones enteras. OR opera en cada posicion de bit de las expresiones circundantes de forma independiente, de acuerdo con la siguiente regla: la salida es 1 si uno o ambos bits de entrada son 1, de lo contrario es 0. Otra forma de expresar esto es:

Operador OR
ExpresiónResultado
0 | 00
0 | 11
1 | 01
1 | 11
b = a | 1;  //asegura que b=1

6.4 Xor

El operador binario bit a bit XOR, también llamado O exclusivo es representado por el símbolo de intercalación ^, usado entre dos expresiones enteras. XOR opera en cada posición de bit en las expresiones circundantes de forma independiente, de acuerdo con la siguiente regla: la salida es 1 solo si uno de las entrada es 1, de lo contrario es 0. Otra forma de expresar esto es:

Operador XOR
ExpresiónResultado
0 ^ 00
0 ^ 11
1 ^ 01
1 ^ 10
b = a ^ 1;  //cambia o niega el valor de a. b=!a

6.5 BitShift izquierda

El operador de desplazamiento de bit a la izquierda, es representado por el símbolo doble menor que <<, este operador hace que los bits del operando de la izquierda se desplacen hacia la izquierda según el número de posiciones especificado por el operando de la derecha.

Operador <<
ExpresiónResultado
1 << 01
1 << 12
1 << 24
1 << 38
1 << 8256
1 << 9512
1 << 101024
int a = 5; // B00000101, o 5 decimal
int b = a << 3; //B00101000, o 40 en decimal
int c = b >> 3; //B00000101, o de vuelta a 5 como comenzamos

6.6 BitShift derecha

El operador de desplazamiento de bit a la derecha, es representado por el símbolo doble mayor que >>, este operador hace que los bits del operando de la izquierda se desplacen hacia la derecha según el número de posiciones especificado por el operando de la derecha.

int a = 5;             //B0000000000000101
int b = a >> 14; //B0100000000000000 - se descartó el primer 1 del 101
int x = -16;           //B1111111111110000, 65520 decimal
int y = x >> 3;  //B1111111111111110, 65534 decinal

6.7 Bit a bit de asignación

A menudo en programación se quiere operar una variable y guardar el nuevo valor en la propia variable. Podrías hacer x = x + 7; pero también se puede hacer x += 7; con el mismo resultado. Lo mismo se puede hacer con los operadores bit a bit.

Operadores de asignación
ExpresiónNombre
&=And
|=Or
~=Xor
<<=Izquierda
>>=Derecha
int x = 1;      //B0000000000000001, 1 dec
x << = 3; //B0000000000001000, 8 dec
x |= 3;         //B0000000000001011, 11 dec (Dec 3 es B0011)
x &= 1;     //B0000000000000001, 1 dec
x ^= 4;         //B0000000000000101, 5 dec (alternar usando la máscara B0100, 4 dec)
x ^= 4;         //B0000000000000001, 1 dec (alternar de nuevo con la máscara B0100, 4 dec)

7. Punteros

En primer lugar debemos entender que la memoria de Arduino (como cualquier memoria) está numerada en posiciones. Cada posición de memoria tiene una dirección única, que debe ser especificada cuando queremos leer o escribir su valor. Arduinos UNO dispone de 32K de memoria Flash para programas y de 2K de RAM para almacenar variables. Cuando definimos una variable, el compilador le asigna una posición en la memoria RAM. Si la variables es del tipo char o byte asigna un byte de memoria, si es del tipo int se le asigna dos posiciones de memoria y si es un tipo long le asigna 4 bytes de memoria.

Si declaramos la variable: int numero=10; por ejemplo le estamos indicando al compilador que vamos a usar una variable que se llama numero y que tiene un valor de 10. Pero lo mas importante al definir el tipo, entero en este caso, le estamos diciendo al compilador que reserve 2 bytes para almacenar dicha variable. De modo que por ejemplo le asigna a la variable numero la dirección de memoria 200~216.

De modo que la variable tendrá una dirección de memoria de inicio y la dirección de fin depende del tipo de variable declarado. Pues existe una manera de saber la dirección de memoria de inicio de una variable anteponiendo & al nombre de la variable. Un cast consiste en forzar la conversión de un tipo en otro y se efectúa precediendo a la variable que queremos forzar por el tipo que deseamos entre paréntesis.

El operador "&" le dice al compilador que lo que queremos no es el valor de la variable sino su dirección de memoria. El operador "*" le dice el compilador que queremos leer o modificar el valor que contiene una posición de memoria.

int numero=10;
Serial.println((long)&numero); //200
int ptNumero=&numero;
*ptNumero=7;
Serial.println(numero); //7

Nota que es necesario hacer lo que se llama un cast es decir decirle el tipo de valor que obtendra, sino dará un error. Un cast consiste en forzar la conversión de un tipo en otro, y se efectúa precediendo a la variable que queremos forzar por el tipo que deseamos entre paréntesis.