Hemos hablado de números enteros, de cómo realizar operaciones sencillas y de cómo usar variables para reservar espacio y así poder trabajar con datos cuyo valor no sabemos de antemano.
Empieza a ser el momento de refinar, de dar más detalles. El primer "matiz" importante que hemos esquivado hasta ahora es el tamaño de los números que podemos emplear, así como su signo (positivo o negativo). Por ejemplo, un dato de tipo "int" puede guardar números de hasta unas nueve cifras, tanto positivos como negativos, y ocupa 4 bytes en memoria.
(Nota: si no sabes lo que es un byte, deberías mirar el Apéndice 1 de este texto).
Pero no es la única opción. Por ejemplo, si queremos guardar la edad de una persona, no necesitamos usar números negativos, y nos bastaría con 3 cifras, así que es de suponer que existirá algún tipo de datos más adecuado, que desperdicie menos memoria. También existe el caso contrario: un banco puede necesitar manejar números con más de 9 cifras, así que un dato "int" se les quedaría corto. Siendo estrictos, si hablamos de valores monetarios, necesitaríamos usar decimales, pero eso lo dejamos para el siguiente apartado.
Los tipos de datos enteros que podemos usar en C#, junto con el espacio que ocupan en memoria y el rango de valores que nos permiten almacenar son:
Nombre Del Tipo | Tamaño (bytes) | Rango de valores |
sbyte | 1 | -128 a 127 |
byte | 1 | 0 a 255 |
short | 2 | -32768 a 32767 |
ushort | 2 | 0 a 65535 |
int | 4 | -2147483648 a 2147483647 |
uint | 4 | 0 a 4294967295 |
long | 8 | -9223372036854775808 a 9223372036854775807 |
ulong | 8 | 0 a 18446744073709551615 |
Como se puede observar en esta tabla, el tipo de dato más razonable para guardar edades sería "byte", que permite valores entre 0 y 255, y ocupa 3 bytes menos que un "int".
// Ejemplo_03_01_01a.cs
// Tipos de números enteros
// Introducción a C#, por Nacho Cabanes
using System;
public class Ejemplo_03_01_01a
{
public static void Main()
{
byte edad = 74;
ushort anyo = 2001;
long resultado = 10000000000;
Console.WriteLine("Los datos son {0}, {1} y {2}",
edad, anyo, resultado);
}
}
Ejercicios propuestos:
Ejercicio propuesto 3.1.1.1: Calcula el producto de 1.000.000 por 1.000.000, usando una variable llamada "producto", de tipo "long". Prueba también a calcularlo usando una variable de tipo "int".
Si queremos obtener estos datos a partir de una cadena de texto, no siempre nos servirá Convert.ToInt32, porque no todos los datos son enteros de 32 bits (4 bytes). Para datos de tipo "byte" usaríamos Convert.ToByte (sin signo) y ToSByte (con signo), para datos de 2 bytes tenemos ToInt16 (con signo) y ToUInt16 (sin signo), y para los de 8 bytes existen ToInt64 (con signo) y ToUInt64 (sin signo).
// Ejemplo_03_01_02a.cs
// Conversiones para otros tipos de números enteros
// Introducción a C#, por Nacho Cabanes
using System;
public class Ejemplo_03_01_02a
{
public static void Main()
{
string ejemplo1 = "74";
string ejemplo2 = "2001";
string ejemplo3 = "10000000000";
byte edad = Convert.ToByte(ejemplo1);
ushort anyo = Convert.ToUInt16(ejemplo2);
long resultado = Convert.ToInt64(ejemplo3);
Console.WriteLine("Los datos son {0}, {1} y {2}",
edad, anyo, resultado);
}
}
Ejercicios propuestos:
Ejercicio propuesto 3.1.2.1: Pregunta al usuario su edad, que se guardará en un "byte". A continuación, le deberás decir que no aparenta tantos años (por ejemplo, "No aparentas 20 años").
Ejercicio propuesto 3.1.2.2: Pide al usuario dos números de dos cifras ("byte"), calcula su multiplicación, que se deberá guardar en un "ushort", y muestra el resultado en pantalla.
Ejercicio propuesto 3.1.2.3: Pide al usuario dos números enteros largos ("long") y muestra su suma, su resta y su producto.
Conocemos la forma de realizar las operaciones aritméticas más habituales. Pero también existe una operación que es muy frecuente cuando se crean programas, especialmente (como ya hemos visto) a la hora de controlar bucles: incrementar el valor de una variable en una unidad:
a = a + 1;
Pues bien, en C# (y en otros lenguajes que derivan de C, como C++, Java y PHP), existe una notación más compacta para esta operación, y para la opuesta (el decremento):
a++; es lo mismo que a = a+1;
a--; es lo mismo que a = a-1;
// Ejemplo_03_01_03a.cs
// Incremento y decremento
// Introducción a C#, por Nacho Cabanes
using System;
public class Ejemplo_03_01_03a
{
public static void Main()
{
int n = 10;
Console.WriteLine("n vale {0}", n);
n++;
Console.WriteLine("Tras incrementar vale {0}", n);
n--;
n--;
Console.WriteLine("Tras decrementar dos veces, vale {0}", n);
}
}
Pero esto tiene algo más de dificultad de la que puede parecer en un primer vistazo: podemos distinguir entre "preincremento" y "postincremento". En C# es posible hacer asignaciones como
b = a++;
Así, si "a" valía 2, lo que esta instrucción hace es dar a "b" el valor de "a" y aumentar el valor de "a". Por tanto, al final tenemos que b=2 y a=3 (postincremento: se incrementa "a" tras asignar su valor).
En cambio, si escribimos
b = ++a;
y "a" valía 2, primero aumentamos "a" y luego los asignamos a "b" (preincremento), de modo que a=3 y b=3.
Por supuesto, también podemos distinguir postdecremento (a--) y predecremento (--a).
Ejercicios propuestos:
Ejercicio propuesto 3.1.3.1: Crea un programa que use tres variables x,y,z. Sus valores iniciales serán 15, -10, 2.147.483.647. Se deberá incrementar el valor de estas variables. ¿Qué valores esperas que se obtengan? Contrástalo con el resultado obtenido por el programa.
Ejercicio propuesto 3.1.3.2: ¿Cuál sería el resultado de las siguientes operaciones? a=5; b=++a; c=a++; b=b*5; a=a*2; Calcúlalo a mano y luego crea un programa que lo resuelva, para ver si habías hallado la solución correcta.
Aún hay más. Tenemos incluso formas reducidas de escribir cosas como "a = a+5". Allá van
a += b ; es lo mismo que a = a+b;
a -= b ; es lo mismo que a = a-b;
a *= b ; es lo mismo que a = a*b;
a /= b ; es lo mismo que a = a/b;
a %= b ; es lo mismo que a = a%b;
// Ejemplo_03_01_04a.cs
// Operaciones abreviadas
// Introducción a C#, por Nacho Cabanes
using System;
public class Ejemplo_03_01_04a
{
public static void Main()
{
int n = 10;
Console.WriteLine("n vale {0}", n);
n *= 2;
Console.WriteLine("Tras duplicarlo, vale {0}", n);
n /= 3;
Console.WriteLine("Tras dividirlo entre tres, vale {0}", n);
}
}
Ejercicios propuestos:
Ejercicio propuesto 3.1.4.1: Crea un programa que use tres variables x,y,z. Sus valores iniciales serán 15, -10, 214. Deberás incrementar el valor de estas variables en 12, usando el formato abreviado. ¿Qué valores esperas que se obtengan? Contrástalo con el resultado obtenido por el programa.
Ejercicio propuesto 3.1.4.2: ¿Cuál sería el resultado de las siguientes operaciones? a=5; b=a+2; b-=3; c=-3; c*=2; ++c; a*=b; Crea un programa que te lo muestre.
Ya que estamos hablando de las asignaciones, es interesante comentar que en C# es posible hacer asignaciones múltiples:
a = b = c = 1;
// Ejemplo_03_01_05a.cs
// Asignaciones múltiples
// Introducción a C#, por Nacho Cabanes
using System;
public class Ejemplo_03_01_05a
{
public static void Main()
{
int a=5, b=2, c=-3;
Console.WriteLine("a={0}, b={1}, c={2}", a, b, c);
a = b = c = 4;
Console.WriteLine("Ahora a={0}, b={1}, c={2}", a, b, c);
a++; b--; c*=2;
Console.WriteLine("Y finalmente a={0}, b={1}, c={2}", a, b, c);
}
}