Si especificamos un programa como un simple conjunto de operaciones sobre variables
U1.55
viernes, 8 de enero de 2010
jueves, 7 de enero de 2010
Tipos de datos fundamentales (Conversiones tipos de datos)
Conversiones de tipo de datos
C# es un lenguaje muy estricto en cuanto a conversiones de tipo. Existen dos tipos de conversiones: implíctas y explícitas.
Las implícitas son las que realiza el compilador sin requerir de nosotros la especificación de ninguna sentencia adicional. Este tipo de conversiones se caracteriza por el hecho de que nunca se pierde información ni precisión. La conversión es siempre válida. En el siguiente ejemplo es convertido a un entero largo. La conversión se da en la segunda línea y es implícita.
int n1 = 10;
long n2 = n1;
El otro tipo de conversión es explícito, y el compilador lo exige cuando podría ocurrir pérdida de información o precisión.
long n1 = 10;
int n2 = n1; // ----> Error!
Ahora, si la operación fracasa, el compilador arrojará una excepción. Esta excepción podrá ser capturada y tratada.
Y así como existe el bloque checked también existe su contrapartida, llamada unchecked. ¿Cuándo utilizaremos un bloque unchecked? Cuando el compilador no nos permita realizar una operación, a pesar de realizar una conversión de tipos explícita como la siguiente:
short n1 = 60000;
No hace falta ser un genio para saber que lo escrito en el código anterior fracasará. El rango de un short es de (-32768,32767), por lo que 60000 es un número demasiado grande. Tal vez el ejemplo sea trivial, pero si queremos que dicho código sea compilado de todos modos, entonces deberemos encerrarlo en un bloque unchecked.
unchecked{
short n1 = 60000;
}
La clase Convert
bool a = 1;
Pero si, en cambio, escribimos:
bool a = Convert.ToBoolean(1);
C# es un lenguaje muy estricto en cuanto a conversiones de tipo. Existen dos tipos de conversiones: implíctas y explícitas.
Las implícitas son las que realiza el compilador sin requerir de nosotros la especificación de ninguna sentencia adicional. Este tipo de conversiones se caracteriza por el hecho de que nunca se pierde información ni precisión. La conversión es siempre válida. En el siguiente ejemplo es convertido a un entero largo. La conversión se da en la segunda línea y es implícita.
int n1 = 10;
long n2 = n1;
El otro tipo de conversión es explícito, y el compilador lo exige cuando podría ocurrir pérdida de información o precisión.
long n1 = 10;
int n2 = n1; // ----> Error!
El código anterior arrojará un error en la segunda línea, pues el compilador no puede realizar dicha conversión de modo implícito.
Para realizar una conversión explícita deberemos utilizar una expresión de casting. Esto significa especificar el tipo de dato sl cual deseamos llevar la expresión, ubicado entre paréntesis y antes de la expresión en cuestión:
long n1 = 10;
int n2 = (int) n1; // realizamos un cast
Ahora, el compilador ya no protesterá. Pero ¿ qué sucede si el número en n1 es más grande de lo que podría albergar n2? ¡Se pierde información! Es por está razón por lo que el compilador nos exige la conversión explícita, ya que es una manera de indicarle que nosotros sabemos lo que hacemos. Veamos el siguiente ejemplo:
long n1 = Int64.MaxValue;
int n2 = (int) n1; // realizamos un cast
Como es de suponer, en n2 no quedará el mismo valor que en n1, simplemente porque en n2 no hay lugar para albergar la magnitud que posee n1. Sin embargo, el compilador no arrojará error alguno. ¿Cómo decirle al compilador que deseamos ser alertados ante semejante circunstancia? Utilizando un bloque chequed como se muestra a continuación:
long n1 = Int64.MaxValue;
chequed{
int n2 = (int) n1; //realizamos un cast
}
Para realizar una conversión explícita deberemos utilizar una expresión de casting. Esto significa especificar el tipo de dato sl cual deseamos llevar la expresión, ubicado entre paréntesis y antes de la expresión en cuestión:
long n1 = 10;
int n2 = (int) n1; // realizamos un cast
Ahora, el compilador ya no protesterá. Pero ¿ qué sucede si el número en n1 es más grande de lo que podría albergar n2? ¡Se pierde información! Es por está razón por lo que el compilador nos exige la conversión explícita, ya que es una manera de indicarle que nosotros sabemos lo que hacemos. Veamos el siguiente ejemplo:
long n1 = Int64.MaxValue;
int n2 = (int) n1; // realizamos un cast
Como es de suponer, en n2 no quedará el mismo valor que en n1, simplemente porque en n2 no hay lugar para albergar la magnitud que posee n1. Sin embargo, el compilador no arrojará error alguno. ¿Cómo decirle al compilador que deseamos ser alertados ante semejante circunstancia? Utilizando un bloque chequed como se muestra a continuación:
long n1 = Int64.MaxValue;
chequed{
int n2 = (int) n1; //realizamos un cast
}
Ahora, si la operación fracasa, el compilador arrojará una excepción. Esta excepción podrá ser capturada y tratada.
Y así como existe el bloque checked también existe su contrapartida, llamada unchecked. ¿Cuándo utilizaremos un bloque unchecked? Cuando el compilador no nos permita realizar una operación, a pesar de realizar una conversión de tipos explícita como la siguiente:
short n1 = 60000;
No hace falta ser un genio para saber que lo escrito en el código anterior fracasará. El rango de un short es de (-32768,32767), por lo que 60000 es un número demasiado grande. Tal vez el ejemplo sea trivial, pero si queremos que dicho código sea compilado de todos modos, entonces deberemos encerrarlo en un bloque unchecked.
unchecked{
short n1 = 60000;
}
La clase Convert
La librería BCL nos ofrece una clase llamada Convert dentro del espacio de nombres System, que es muy útil en el momento de realizar conversiones. La gran variedad de métodos estáticos que posee Convert nos permite pasar un tipo de dato primitivo a cualquier otro tipo de dato primitivo.
Por ejemplo, la siguiente operación no es válida debido a que intentamos pasar de un número entero a un tipo booleano.
Por ejemplo, la siguiente operación no es válida debido a que intentamos pasar de un número entero a un tipo booleano.
bool a = 1;
Pero si, en cambio, escribimos:
bool a = Convert.ToBoolean(1);
Entonces la variable a, si recibe un número entero distinto de 0, será true, y en caso contrario, será false.
Operadores
Es posible combinar números y variables en expresiones por medio de operadores matemáticos. Veamos:
int a = 3 + 4; //Almaceno el número 7 en a
int a = 4;
int b = a / 2; //Almaceno en b el contenido de la variable dividido por 2
int a = 10;
int b = a + 14; //Almaceno en b el contenido de la variable multiplicado por 14
También podemos usar tipos de datos numéricos decimales:
float a = 3.4f / 2;
Y podremos combinar tipos de datos en operaciones:
int a = 5;
float b = 4.3f;
float resultado = a + b;
float a = 5/2; //El resultado de la operación será 2
Para solucionar este inconveniente deberemos convertir al menos uno de los operandos en flotante, para que, de este modo, la división no sea entre números enteros, sino entre un entero y un número flotante:
float a = 5.0f/2; //Ahora el resultado será 2.5
Uso de constantes en operaciones
Utilizar constantes en lugar de números literales de manera directa es considerado una buena práctica, ya que facilita la lectura y comprensión del código fuente. Por ejemplo:
Constantes numéricas literales:
superficie = 3.1415f * 16;
Constantes declaradas:
const float pi = 3.1415f;
superficie = pi * (radio*radio);
El último listado de código es un poco más legible. Más alla de lo trivial del ejemplo, en otros casos podría no resultar tan obvio, en el análisis de una expresión que respresentan determinados números. En cambio, al ver una constante llamada pi rápidamente entenderemos a qué nos referimos.
https://msdn.microsoft.com/en-us/library/bb311038.aspx (Como convertir entre decimales y String, leer esto)
IMPORTANTE
http://www.codeproject.com/Tips/845439/Difference-between-int-Parse-Convert-ToInt-and-int
(Diferencia entre Parse, TryParse y Convert, muy bueno y sencillo este artículo)
Operadores
Es posible combinar números y variables en expresiones por medio de operadores matemáticos. Veamos:
int a = 3 + 4; //Almaceno el número 7 en a
int a = 4;
int b = a / 2; //Almaceno en b el contenido de la variable dividido por 2
int a = 10;
int b = a + 14; //Almaceno en b el contenido de la variable multiplicado por 14
También podemos usar tipos de datos numéricos decimales:
float a = 3.4f / 2;
Y podremos combinar tipos de datos en operaciones:
int a = 5;
float b = 4.3f;
float resultado = a + b;
Sin embargo, cuando operamos de este modo es conveniente tener mucho cuidado, ya que el tipo de dato resultante estará en función de la operación que realicemos.
Por ejemplo, la suma de dos enteros dará como resultado un número entero, y la división de dos números enteros también dará como resultado un número entero; esto último es lo que precisamente puede traer muchos problemas. Este es el caso de que se quiera dividir 5 entre 2, el resultado que pensará cualquier persona es 2,5 lo cual no será expresado al consultar la variable en el computador, la cual es de tipo entera, la cual nos devolverá el valor 2. Colocar una variable para almacenar el resultado de tipo flotante no solucionará el problema.
Por ejemplo, la suma de dos enteros dará como resultado un número entero, y la división de dos números enteros también dará como resultado un número entero; esto último es lo que precisamente puede traer muchos problemas. Este es el caso de que se quiera dividir 5 entre 2, el resultado que pensará cualquier persona es 2,5 lo cual no será expresado al consultar la variable en el computador, la cual es de tipo entera, la cual nos devolverá el valor 2. Colocar una variable para almacenar el resultado de tipo flotante no solucionará el problema.
float a = 5/2; //El resultado de la operación será 2
Para solucionar este inconveniente deberemos convertir al menos uno de los operandos en flotante, para que, de este modo, la división no sea entre números enteros, sino entre un entero y un número flotante:
float a = 5.0f/2; //Ahora el resultado será 2.5
Uso de constantes en operaciones
Utilizar constantes en lugar de números literales de manera directa es considerado una buena práctica, ya que facilita la lectura y comprensión del código fuente. Por ejemplo:
Constantes numéricas literales:
superficie = 3.1415f * 16;
Constantes declaradas:
const float pi = 3.1415f;
superficie = pi * (radio*radio);
El último listado de código es un poco más legible. Más alla de lo trivial del ejemplo, en otros casos podría no resultar tan obvio, en el análisis de una expresión que respresentan determinados números. En cambio, al ver una constante llamada pi rápidamente entenderemos a qué nos referimos.
https://msdn.microsoft.com/en-us/library/bb311038.aspx (Como convertir entre decimales y String, leer esto)
IMPORTANTE
http://www.codeproject.com/Tips/845439/Difference-between-int-Parse-Convert-ToInt-and-int
(Diferencia entre Parse, TryParse y Convert, muy bueno y sencillo este artículo)
martes, 5 de enero de 2010
Tipos de datos fundamentales ()
Booleanos
Las variables booleanas pueden albergar dos valores: true (verdadero) o false (falso).
Declarando una variable del tipo booleana:
bool a;
Caracteres
Para almacenar un caracter en una variable debemos escpecificar su tipo en char. Ejemplo:
char a;
Tabla Carateres de Escape
Nombre Secuencia de Escape
linea nueva \n
tab horizontal \t
backspace \b
retorno de carro \r
barra invertida \\
comilla doble \"
Si escribimos en pantalla el siguiente texto:
Console.Write("\tTexto1\nTexto2");
Lista de tipos de datos primitivos
Se listan a continuación los tipos de datos fundamentales del lenguaje C#:
Tipo de dato fundamental Tamaño en bytes Tipo estructura Descripción
bool 1 System.Booleano Booleano. Su valor puede
true(verdadero) o falso (false)
sbyte 1 System.Sbyte Byte no signado
byte 1 System.Byte Byte
char 2 System.Char Carácter
short 2 System.Int16 Entero corto
ushort 2 System.UInt16 Entero corto no signado
int 4 System.Int32 Entero
uint 4 System.UInt32 Entero no signado
long 8 System.Int64 Entero largo
ulong 8 System.UInt64 Entero largo no signado
float 4 System.Single Número no entero de
precisión simple
double 8 System.Double Número no entero de
precisión simple
decimal 16 System.Decimal Número no entero de
máxima precisión
m = Mes.Enero;
Estas constantes podrían poseer un valor literal asignado a ellas por medio del operador de asignación:
enum{
Enero = 1,
Febrero = 2,
Marzo = 3,
Abril = 4,
Mayo = 5,
Junio = 6,
Julio = 7,
Agosto = 8,
Septiembre = 9,
Octubre = 10,
Noviembre = 11,
Diciembre = 12
}
////Más acerca de enumeradores///
Dos constantes definidas dentro de un enumerador podrían poseer el mismo valor numérico. Esto sería útil para definir constantes que sean sinónimos; por ejemplo, tanto "setiembre" como "septiembre" podrían estar relacionados con el valor 9.
////////////////////////////////
U.1.45
Las variables booleanas pueden albergar dos valores: true (verdadero) o false (falso).
Declarando una variable del tipo booleana:
bool a;
Caracteres
Para almacenar un caracter en una variable debemos escpecificar su tipo en char. Ejemplo:
char a;
Este tipo de datos puede albergar un carácter del tipo Unicode, pensado especialmente para alfabetos orientales que poseen una cantidad mayor a 256. Existen ciertos tipos de caracteres "especiales" que son interpretados por el compilador dentro de la cadena de texto. Éstos son conocidos como caracteres de escape, y en la siguiente table pueden apreciarse algunos de ellos:
Tabla Carateres de Escape
Nombre Secuencia de Escape
linea nueva \n
tab horizontal \t
backspace \b
retorno de carro \r
barra invertida \\
comilla doble \"
Si escribimos en pantalla el siguiente texto:
Console.Write("\tTexto1\nTexto2");
El primer carácter (\t) será interpretado como un tab horizontal, y el carácter \n como una linea nueva, por lo que en pantalla podremos observar:
Texto1
Texto2Texto1
Lista de tipos de datos primitivos
Se listan a continuación los tipos de datos fundamentales del lenguaje C#:
Tipo de dato fundamental Tamaño en bytes Tipo estructura Descripción
bool 1 System.Booleano Booleano. Su valor puede
true(verdadero) o falso (false)
sbyte 1 System.Sbyte Byte no signado
byte 1 System.Byte Byte
char 2 System.Char Carácter
short 2 System.Int16 Entero corto
ushort 2 System.UInt16 Entero corto no signado
int 4 System.Int32 Entero
uint 4 System.UInt32 Entero no signado
long 8 System.Int64 Entero largo
ulong 8 System.UInt64 Entero largo no signado
float 4 System.Single Número no entero de
precisión simple
double 8 System.Double Número no entero de
precisión simple
decimal 16 System.Decimal Número no entero de
máxima precisión
Como se puede observar en la tabla anterior, todo tipo de dato primitivo que define el lenguaje se mapea con una estructura de la librería BCL. Todos los lenguajes que se construyen para la plataforma .NET deberán hacer esta tarea, y de este modo la intercomunicación entre ellos será mucho más sencilla debido a que, en definitiva, utilizan los mismos tipos de datos fundamentales.
Así es que declarar una variable entera como:
int a;
es exactamente igual a hacerlo del siguiente modo:
System.Int32 a;
Notemos que el nombre de la estructura relacionada está compuesto por dos partes: el tipo de dato (con la primera letra en mayúscula) y la cantidad de bits que ocupa en la memoria. De este modo también podemos inferir que un int siempre ocupará 4 bytes, más allá de la plataforma en la cual estemos trabajando (algo que no sucede en C o C++, donde la especificación no ata los tipos de datos a tamaños físicos, sino que simplemente exige una relación entre éstos).
Asignar valor a una variable
Para la asignación de valor para variables se utilizará el símbolo = como operador de asignación.
int a = 1;
/////¿Dónde están los Strings?/////
C# utiliza una clase que representa los strings y se llama string (o System.String). Esta implementación es algo distinta del resto de los tipos de datos, ya que éstos son básicamente estructuras. La razón es que los strings, la cantidad de memoria que se requerirá para la cadena será variable, dependiendo de su contenido. Declarando un string: string miVariableString
////////////////////////////////
Constantes
Existen tres constantes:
Literales: especificadas por medio de un valor escrito en el código.
int a = 25;
string nombre = "Tito";
En el caso citado, 25 es una constante literal al igual que Tito.
Simbólicas: especificadas por medio de identificadores asociados a un literal. Son más recomendables que el uso de literales de modo directo, ya que en ciertos contextos éstos podrían ser vistos como números mágicos sacados de un sombrero de mago.
Estas constantes son muy similares a las variables, con la diferencia de que éstas sólo se les podrá dar un valor en el momento de su declaración. Luego, cualquier intento de modificación será tomado como un error por parte del compilador. Las constantes simbólicas se declaran del mismo modo que las variables, aunque se les debe anteponer la palabra const.
const int unaConstante = 1;
Enumeradores: los enumeradores también son considerados como un tipo de constantes, y adquieren una gran utilidad cuando debemos especificar un grupo de constantes estrechamente relacionadas.
Supongamos que deseamos que una variable pueda adoptar el valor de un mes específico del año. Podríamos definir que esta variable fuese numérica entera y adoptar la convención de que su número equivaliera al número del mes en cuestión. Sin embargo, esta "convención" debería estar especificada en algún documento que se encuentre al alcance de todos los programadores; incluso nosotros, tiempo después de haber escrito el código, podríamos dudar acerca de si el mes de enero era representado por el 1 o acaso por el 0.
Para evitar este tipo de inconvenientes y, también, que algún descuidado especifique un número fuera de rango para el mes (por ejemplo 13), sin tener que estar colocando que el código realice esta verificación, podríamos crear el siguiente enumerador:
enum{
Enero,
Febrero,
Marzo,
Abril,
Mayo,
Junio,
Julio,
Agosto,
Septiembre,
Octubre,
Noviembre,
Diciembre
}
Luego, podríamos declarar una variable como del tipo Mes. Veamos:
Mes m;
Ahora, m sólo podrá adoptar los valores constantes especificados en el enumerador Mes.Así es que declarar una variable entera como:
int a;
es exactamente igual a hacerlo del siguiente modo:
System.Int32 a;
Notemos que el nombre de la estructura relacionada está compuesto por dos partes: el tipo de dato (con la primera letra en mayúscula) y la cantidad de bits que ocupa en la memoria. De este modo también podemos inferir que un int siempre ocupará 4 bytes, más allá de la plataforma en la cual estemos trabajando (algo que no sucede en C o C++, donde la especificación no ata los tipos de datos a tamaños físicos, sino que simplemente exige una relación entre éstos).
Asignar valor a una variable
Para la asignación de valor para variables se utilizará el símbolo = como operador de asignación.
int a = 1;
/////¿Dónde están los Strings?/////
C# utiliza una clase que representa los strings y se llama string (o System.String). Esta implementación es algo distinta del resto de los tipos de datos, ya que éstos son básicamente estructuras. La razón es que los strings, la cantidad de memoria que se requerirá para la cadena será variable, dependiendo de su contenido. Declarando un string: string miVariableString
////////////////////////////////
Constantes
Existen tres constantes:
Literales: especificadas por medio de un valor escrito en el código.
int a = 25;
string nombre = "Tito";
En el caso citado, 25 es una constante literal al igual que Tito.
Simbólicas: especificadas por medio de identificadores asociados a un literal. Son más recomendables que el uso de literales de modo directo, ya que en ciertos contextos éstos podrían ser vistos como números mágicos sacados de un sombrero de mago.
Estas constantes son muy similares a las variables, con la diferencia de que éstas sólo se les podrá dar un valor en el momento de su declaración. Luego, cualquier intento de modificación será tomado como un error por parte del compilador. Las constantes simbólicas se declaran del mismo modo que las variables, aunque se les debe anteponer la palabra const.
const int unaConstante = 1;
Enumeradores: los enumeradores también son considerados como un tipo de constantes, y adquieren una gran utilidad cuando debemos especificar un grupo de constantes estrechamente relacionadas.
Supongamos que deseamos que una variable pueda adoptar el valor de un mes específico del año. Podríamos definir que esta variable fuese numérica entera y adoptar la convención de que su número equivaliera al número del mes en cuestión. Sin embargo, esta "convención" debería estar especificada en algún documento que se encuentre al alcance de todos los programadores; incluso nosotros, tiempo después de haber escrito el código, podríamos dudar acerca de si el mes de enero era representado por el 1 o acaso por el 0.
Para evitar este tipo de inconvenientes y, también, que algún descuidado especifique un número fuera de rango para el mes (por ejemplo 13), sin tener que estar colocando que el código realice esta verificación, podríamos crear el siguiente enumerador:
enum{
Enero,
Febrero,
Marzo,
Abril,
Mayo,
Junio,
Julio,
Agosto,
Septiembre,
Octubre,
Noviembre,
Diciembre
}
Luego, podríamos declarar una variable como del tipo Mes. Veamos:
Mes m;
m = Mes.Enero;
Estas constantes podrían poseer un valor literal asignado a ellas por medio del operador de asignación:
enum{
Enero = 1,
Febrero = 2,
Marzo = 3,
Abril = 4,
Mayo = 5,
Junio = 6,
Julio = 7,
Agosto = 8,
Septiembre = 9,
Octubre = 10,
Noviembre = 11,
Diciembre = 12
}
En realidad, cada constante dentro de un enumerador siempre posee un valor literal numérico asociado a ella, sólo que si no lo especificamos, lo hará automáticamente el compilador, empezando por el número 0 e incrementando en una unidad. De hecho, podríamos consultar por el valor numérico asociado a una variable de tipo enumerador por medio de conversiones de tipo.
////Más acerca de enumeradores///
Dos constantes definidas dentro de un enumerador podrían poseer el mismo valor numérico. Esto sería útil para definir constantes que sean sinónimos; por ejemplo, tanto "setiembre" como "septiembre" podrían estar relacionados con el valor 9.
////////////////////////////////
U.1.45
domingo, 3 de enero de 2010
Tipos de datos fundamentales (numéricos)
Tipos de datos fundamentales
Hemos mencionado que una variable debe poseer un tipo. El lenguaje define un conjunto de tipos de datos primitivos que pueden ser utilizados por nuestras por nuestras variables, propiedades y métodos. También podremos crear nuestras propios tipos por medio de clases y estructuras.
Una variable tiene asociada una posición de memoria, que es donde realmente se almacena un dato en cuestión. El identificador es, al fin y al cabo, una manera amigable de referirnos a ella. Podríamos decir, entonces, que el tipo de dato es una manera de comunicarle al compilador:
*Cuánto espacio en memoria ocupará la variable.
*Que semántica tendrá el dato almacenado.
Un número entero podría ocupar en memoria la misma cantidad de espacio que un número de punto flotante. El compilador sabrá como interpretar la información que allí encuentre precisamente por el tipo de dato que posee la variable asociada a dicha posición de memoria.
También es conveniente destacar que el compilador distingue entre los tipos de datos por el valor y los tipos de datos por referencia. Esto tiene relación con la zona de memoria que se utiliza para crear la variable en cuestión: el stack (pila) o el heap (montículo). Los tipos de datos por valor serán almacenados en el stack, mientras que los tipos de datos por referencia serán almacenados en el heap (en el stack quedará una referencia de la ubicación en dicha zona de memoria).
Números enteros
C# ofrece tres tipos de números enteros:
* short: número entero corto.
* int: número de entero signado.
* long: número de entero largo signado.
Hemos mencionado que una variable debe poseer un tipo. El lenguaje define un conjunto de tipos de datos primitivos que pueden ser utilizados por nuestras por nuestras variables, propiedades y métodos. También podremos crear nuestras propios tipos por medio de clases y estructuras.
Una variable tiene asociada una posición de memoria, que es donde realmente se almacena un dato en cuestión. El identificador es, al fin y al cabo, una manera amigable de referirnos a ella. Podríamos decir, entonces, que el tipo de dato es una manera de comunicarle al compilador:
*Cuánto espacio en memoria ocupará la variable.
*Que semántica tendrá el dato almacenado.
Un número entero podría ocupar en memoria la misma cantidad de espacio que un número de punto flotante. El compilador sabrá como interpretar la información que allí encuentre precisamente por el tipo de dato que posee la variable asociada a dicha posición de memoria.
También es conveniente destacar que el compilador distingue entre los tipos de datos por el valor y los tipos de datos por referencia. Esto tiene relación con la zona de memoria que se utiliza para crear la variable en cuestión: el stack (pila) o el heap (montículo). Los tipos de datos por valor serán almacenados en el stack, mientras que los tipos de datos por referencia serán almacenados en el heap (en el stack quedará una referencia de la ubicación en dicha zona de memoria).
Números enteros
C# ofrece tres tipos de números enteros:
* short: número entero corto.
* int: número de entero signado.
* long: número de entero largo signado.
Si son números enteros, ¿que diferencia existe entre ellos? La respuesta es sencilla: la cantidad de memoria que se deberá reservar y cuán grande es el número que cabrá dentro de nuestra variable.
En 2 bytes (short) es posible especificar un número con rango (-32768, 32767), mientras que en 4 bytes (int) es posible especificar un número dentro dentro del rango (-2147483648, 2147483647).
Por otro lado, los tipos de datos numéricos enteros pueden ser signados o no. Si especificamos un número entero corto no signado (ushort), se sigue ocupando 2 bytes, pero al ser todos positivos, el rango válido ahora es (0,65535). Si intentamos asignar un número negativo a una variable no signada, se producirá una excepción.
Declarando algunas variables enteras:
short a; //Entero corto signado
ushort b; //Entero corto no signado
int d; // Entero signado
uint e; // Entero no signado
long f; // Entero largo signado
ulong g; // Entero largo no signado
///¿Y los punteros?(Información adicional)///
Quienes vengan de C o C++ podrían preguntar: ¿dónde están los punteros? C# permite el uso de punteros igual que C++, pero para esto se deberá marcar el bloque o función como unsafe (no segura), además de modificar parámetros de compilación. En C# su uso queda relegado a necesidades específicas, como interactuar con recursos no gestionados creados en otros lenguajes.
////////////////////////////////////////
Números no enteros
C# diferencia en tipo a un número entero de un número con parte fraccionaria; para estos números de datos existen tres tipos:
* float //Precisión simple
* double //Precisión doble
* decimal //Precisión máxima
La diferencia entre ellos es la precisión. Las computadoras se llevan muy bien con los números enteros, pero al trabajar con números decimales necesitan utilizar un recurso matemático llamado "coma flotante". De esta manera es posible almacenar una cantidad no fija de decimales, pero con determinada precisión máxima; esta precisión en definitiva, se encuentra determinada por el tamaño total que ocupa la variable en la memoria. Los tres tipos de datos de números no enteros que maneja C# son:
* float: número no entero de precisión simple. Las constantes literales deben contener el agregado f en la parte decimal para que el compilador pueda tomarlas como float (por ejemplo, 4.0f).
* double: número de precisión doble (por ejemplo, 4.0).
* decimal: número no entero de precisión máxima. Las constantes literales deben contener el agregado M en la parte decimal para poder ser tomadas con decimal (por ejemplo, 4.0M).
En 2 bytes (short) es posible especificar un número con rango (-32768, 32767), mientras que en 4 bytes (int) es posible especificar un número dentro dentro del rango (-2147483648, 2147483647).
Por otro lado, los tipos de datos numéricos enteros pueden ser signados o no. Si especificamos un número entero corto no signado (ushort), se sigue ocupando 2 bytes, pero al ser todos positivos, el rango válido ahora es (0,65535). Si intentamos asignar un número negativo a una variable no signada, se producirá una excepción.
Declarando algunas variables enteras:
short a; //Entero corto signado
ushort b; //Entero corto no signado
int d; // Entero signado
uint e; // Entero no signado
long f; // Entero largo signado
ulong g; // Entero largo no signado
///¿Y los punteros?(Información adicional)///
Quienes vengan de C o C++ podrían preguntar: ¿dónde están los punteros? C# permite el uso de punteros igual que C++, pero para esto se deberá marcar el bloque o función como unsafe (no segura), además de modificar parámetros de compilación. En C# su uso queda relegado a necesidades específicas, como interactuar con recursos no gestionados creados en otros lenguajes.
////////////////////////////////////////
Números no enteros
C# diferencia en tipo a un número entero de un número con parte fraccionaria; para estos números de datos existen tres tipos:
* float //Precisión simple
* double //Precisión doble
* decimal //Precisión máxima
La diferencia entre ellos es la precisión. Las computadoras se llevan muy bien con los números enteros, pero al trabajar con números decimales necesitan utilizar un recurso matemático llamado "coma flotante". De esta manera es posible almacenar una cantidad no fija de decimales, pero con determinada precisión máxima; esta precisión en definitiva, se encuentra determinada por el tamaño total que ocupa la variable en la memoria. Los tres tipos de datos de números no enteros que maneja C# son:
* float: número no entero de precisión simple. Las constantes literales deben contener el agregado f en la parte decimal para que el compilador pueda tomarlas como float (por ejemplo, 4.0f).
* double: número de precisión doble (por ejemplo, 4.0).
* decimal: número no entero de precisión máxima. Las constantes literales deben contener el agregado M en la parte decimal para poder ser tomadas con decimal (por ejemplo, 4.0M).
Las variables
Las variables
Las variables son utilizadas para almacenar datos. Sin embargo, para poder utilizar una variable, en primer lugar deberemos declararla, a diferencia de lo que ocurriría en Visual Basic 6.0 o en lenguajes scripts.
La declaración de una variable está compuesta mínimamente por dos elementos:
*El tipo de dato *El identificador
identificador
int contador;
tipo
El tipo especifica el tamaño en memoria asignado para el dato almacenado por la variable y el correcto modo de presentarlo.
El identificador es el nombre que tendrá la variable y que utilizaremos luego en el programa.
Para que el compilador los acepte como válidos, los identificadores deberán seguir ciertas reglas, similares a las existentes en otros lenguajes como C,C++,Visual Basic o Java. Veamos:
*Deben comenzar con una letra o un caracter de guión bajo(underscore).
*Deben continuar con una letra, un número o un carácter bajo.
*No deben coincidir con una palabra reservada.
***Lista de Palabras reservadas***
Ejemplo de identificadores
Algunos ejemplos de identificadores válidos son:
MiVariable _contador
Contado_ mi_variable
Por otra parte ejemplo de identificadores no válidos:
1Variable: error porque empieza por número
$Variable: error porque comienza con un signo $
###Contador###: error porque comienza con un signo #
default: error porque esta palabra es una palabra reservada
Exiten nombres más apropiados que otros. En un caso real, cuando estemos construyendo nuestras aplicaciones, lo ideal será que el identificador de una variable sea seleccionado en función de un nombre que describa mejor lo que representa dentro del programa. No es una buena idea colocar nombres que no nos den una idea del tipo de información que se está manejando.
Algo importante respecto a las variables para el caso de C#, es que este lenguaje posee lo que se conoce como Case Sensitive, que significa que puede diferenciar variables con diferencias en mayusculas a pesar de tener los mismos caracteres. Ejemplo, CONTADOR, contador. El lenguaje las verá como distintas variables y aceptará su compilación y uso, aún así no es una práctica de programación recomendable, que sí sería emplear diferentes nombres no sólo respecto a mayúsculas y minúsculas sino en los valores de los caracteres como podría ser ejemplo a lo anterior planteado CONTADOR, acumulador.
Convenciones de nombramiento
Existen diversas convenciones de nombramiento para clases, variables, funciones, etc. La idea detrás de estas convenciones es establecer reglas o normas para la creación de los identificadores y que, de este modo, especialmente en grupos de trabajo, los nombres asignados sean similares en cuanto a escritura.
Una convención que Microsoft solía recomendar era la notación húngara. A grandes rasgos, en dicha notación se anteponía como prefijo a los nombres de las variables su tipo de dato (codificado en una o dos letras) y una m_ si era una variable miembro, una p_ si era un puntero, una g_ si era una variable global, etc.
Hoy día, esta notación ya no es aconsejada con el mismo fervor, pues los editores modernos rápidamente nos indican el tipo de dato al cual pertenece una variable, y de este modo se pierde una de sus grandes ventajas. Sin embargo a fin de cuentas, es una cuestión de gustos. Lo importante será mantener la misma convención a lo largo de todo el proyecto.
Esta es la misma notación que utiliza la librería BCL: notación camello para variables, y notación Pascal para clases, estructuras, enumeradores, funciones, métodos, constantes y propiedades.
La notación camello: consiste en crear identificadores concatenando palabras sin hacer uso de caracteres especiales (como underscore o el guión), sino colocando en mayúscula la primera letra de cada p.alabra, a excepción de la primera.
Ejemplos.
unaVariableEntera contador nombrePersona
La notación Pascal: es similar a la camello, sólo que la primera letra debe ser colocada en mayúscula.
Ejemplos.
ImprimirValor FijarLargo DameAltura
U.1.39
Las variables son utilizadas para almacenar datos. Sin embargo, para poder utilizar una variable, en primer lugar deberemos declararla, a diferencia de lo que ocurriría en Visual Basic 6.0 o en lenguajes scripts.
La declaración de una variable está compuesta mínimamente por dos elementos:
*El tipo de dato *El identificador
identificador
int contador;
tipo
El tipo especifica el tamaño en memoria asignado para el dato almacenado por la variable y el correcto modo de presentarlo.
El identificador es el nombre que tendrá la variable y que utilizaremos luego en el programa.
Para que el compilador los acepte como válidos, los identificadores deberán seguir ciertas reglas, similares a las existentes en otros lenguajes como C,C++,Visual Basic o Java. Veamos:
*Deben comenzar con una letra o un caracter de guión bajo(underscore).
*Deben continuar con una letra, un número o un carácter bajo.
*No deben coincidir con una palabra reservada.
***Lista de Palabras reservadas***
Ejemplo de identificadores
Algunos ejemplos de identificadores válidos son:
MiVariable _contador
Contado_ mi_variable
Por otra parte ejemplo de identificadores no válidos:
1Variable: error porque empieza por número
$Variable: error porque comienza con un signo $
###Contador###: error porque comienza con un signo #
default: error porque esta palabra es una palabra reservada
Exiten nombres más apropiados que otros. En un caso real, cuando estemos construyendo nuestras aplicaciones, lo ideal será que el identificador de una variable sea seleccionado en función de un nombre que describa mejor lo que representa dentro del programa. No es una buena idea colocar nombres que no nos den una idea del tipo de información que se está manejando.
Algo importante respecto a las variables para el caso de C#, es que este lenguaje posee lo que se conoce como Case Sensitive, que significa que puede diferenciar variables con diferencias en mayusculas a pesar de tener los mismos caracteres. Ejemplo, CONTADOR, contador. El lenguaje las verá como distintas variables y aceptará su compilación y uso, aún así no es una práctica de programación recomendable, que sí sería emplear diferentes nombres no sólo respecto a mayúsculas y minúsculas sino en los valores de los caracteres como podría ser ejemplo a lo anterior planteado CONTADOR, acumulador.
Convenciones de nombramiento
Existen diversas convenciones de nombramiento para clases, variables, funciones, etc. La idea detrás de estas convenciones es establecer reglas o normas para la creación de los identificadores y que, de este modo, especialmente en grupos de trabajo, los nombres asignados sean similares en cuanto a escritura.
Una convención que Microsoft solía recomendar era la notación húngara. A grandes rasgos, en dicha notación se anteponía como prefijo a los nombres de las variables su tipo de dato (codificado en una o dos letras) y una m_ si era una variable miembro, una p_ si era un puntero, una g_ si era una variable global, etc.
Hoy día, esta notación ya no es aconsejada con el mismo fervor, pues los editores modernos rápidamente nos indican el tipo de dato al cual pertenece una variable, y de este modo se pierde una de sus grandes ventajas. Sin embargo a fin de cuentas, es una cuestión de gustos. Lo importante será mantener la misma convención a lo largo de todo el proyecto.
Esta es la misma notación que utiliza la librería BCL: notación camello para variables, y notación Pascal para clases, estructuras, enumeradores, funciones, métodos, constantes y propiedades.
La notación camello: consiste en crear identificadores concatenando palabras sin hacer uso de caracteres especiales (como underscore o el guión), sino colocando en mayúscula la primera letra de cada p.alabra, a excepción de la primera.
Ejemplos.
unaVariableEntera contador nombrePersona
La notación Pascal: es similar a la camello, sólo que la primera letra debe ser colocada en mayúscula.
Ejemplos.
ImprimirValor FijarLargo DameAltura
U.1.39
Espacios de Nombres
Espacios de Nombre
Los espacios de nombres son un recurso que utilizan algunos lenguajes para la oraganización de un gran conjunto de tipos de datos. Así como los directorios (o carpetas) permiten organizar archivos de modo que ficheros del mismo nombre convivan en directorios distintos, los espacios de nombres realizan una tarea similar, "pero de manera lógica"(averiguar que es esto!!!), para tipos de datos extendidos como clases y estructuras.
De este modo, dos clases distintas con el mismo nombre podrían ser utilizadas en el mismo proyecto sin que se suscite ningún error.
Los espacios de nombres también pueden ser anidados, por lo que puede haber unos dentro de otros y, de este modo, mejorar la organización de las librerías de un proyecto.
Gracias a esta facilidad, los nombres de los tipos de datos que nosotros crearemos en el futuro podrán ser de lo más sencillos, sin temor a que ya exista alguna clase o estructura de igual nombre que luego podremos querer utilizar.
****aqui va una tabla de espacios de nombres****
Por supuesto que la lista es aún más grande. Un acceso de referncia ideal es la documentación que provee Visual Studio .NET o la provista por MSDN (MSDN Library).
Sentencia using
Un modo de ahorrarnos trabajo, al tener que anteponer nombres de namespaces a cada una de las clases que utilicemos, es colocar en la cabecera de nuestro archivo de código fuente una sentecia using, escribiendo:
using <espacio de nombres> ;
Entonces, el compilador buscará cada clase referenciada en el espacio de nombres global y en los espacios de nombres especificados por sentencias using.
Por lo tanto, el código de nuestro primer programa ahora podría ser:
using System;
class Clase1{
static void Main(string[] args){
Console.WriteLine("Nuestro primer programa");
}
}
Console es una clase que no existe en el espacio de nombres global, sino en el espacio de nombres System. Gracias a que le hemos indicado al compilador que estamos utilizando dicho espacio de nombres, System. Gracias a que le hemos indicado al compilador que estamos utilizamos dicho espacio de nombres, él sabrá que las clases que utilicemos también podrían estar allí.
WriteLine es un método de la clase Console. Recordemos que para acceder a información de referencia sobre la BCL podemos utilizar la ayuda que provee Visual Studio, donde veremos todos los métodos y propiedades de la clase Console.
Los Comentarios
En un principio, nuestro programa será pequeño, y analizar qué sucede dentro de él será sencillo, ya que bastará con echar un ojo al código escrito. Sin embargo, a medida que éste crece, se vuelve muy conveniente poder introducir notas aclaratorias sobre qué es lo que pretendemos que el programa haga. Así, si escribimos un algoritmo en particular, podemos agregar un texto que indique qué debe hacer dicho algoritmo en particular, podemos agregar un texto que indique qué debe hacer dicho algoritmo, y de este modo otro programador podrá entenderlo rápidamente, o quizá nosotros mismos, releyendo el código que hayamos escrito tiempo atrás.
Para que el compilador no interprete el texto aclaratorio como intentos fallidos de instrucciones, debemos indicarle que estamos introduciendo un comentario.
C# acepta dos tipos de comentarios. Uno es el comentario de linea, que debe comenzar con caracteres //, como por ejemplo:
//Este es un comentario
El otro es el comentario clásico del lenguaje C, que comienza con los caracteres /* y termina de manera inversa, con los caracteres */
/* Este es un comentario*/
Este tipo de comentario puede ser multilínea; el siguiente es ejemplo de esto:
/* Este
es un
comentario*/
U.1.36
Los espacios de nombres son un recurso que utilizan algunos lenguajes para la oraganización de un gran conjunto de tipos de datos. Así como los directorios (o carpetas) permiten organizar archivos de modo que ficheros del mismo nombre convivan en directorios distintos, los espacios de nombres realizan una tarea similar, "pero de manera lógica"(averiguar que es esto!!!), para tipos de datos extendidos como clases y estructuras.
De este modo, dos clases distintas con el mismo nombre podrían ser utilizadas en el mismo proyecto sin que se suscite ningún error.
Los espacios de nombres también pueden ser anidados, por lo que puede haber unos dentro de otros y, de este modo, mejorar la organización de las librerías de un proyecto.
Gracias a esta facilidad, los nombres de los tipos de datos que nosotros crearemos en el futuro podrán ser de lo más sencillos, sin temor a que ya exista alguna clase o estructura de igual nombre que luego podremos querer utilizar.
****aqui va una tabla de espacios de nombres****
Por supuesto que la lista es aún más grande. Un acceso de referncia ideal es la documentación que provee Visual Studio .NET o la provista por MSDN (MSDN Library).
Sentencia using
Un modo de ahorrarnos trabajo, al tener que anteponer nombres de namespaces a cada una de las clases que utilicemos, es colocar en la cabecera de nuestro archivo de código fuente una sentecia using, escribiendo:
using <espacio de nombres>
Entonces, el compilador buscará cada clase referenciada en el espacio de nombres global y en los espacios de nombres especificados por sentencias using.
Por lo tanto, el código de nuestro primer programa ahora podría ser:
using System;
class Clase1{
static void Main(string[] args){
Console.WriteLine("Nuestro primer programa");
}
}
Console es una clase que no existe en el espacio de nombres global, sino en el espacio de nombres System. Gracias a que le hemos indicado al compilador que estamos utilizando dicho espacio de nombres, System. Gracias a que le hemos indicado al compilador que estamos utilizamos dicho espacio de nombres, él sabrá que las clases que utilicemos también podrían estar allí.
WriteLine es un método de la clase Console. Recordemos que para acceder a información de referencia sobre la BCL podemos utilizar la ayuda que provee Visual Studio, donde veremos todos los métodos y propiedades de la clase Console.
Los Comentarios
En un principio, nuestro programa será pequeño, y analizar qué sucede dentro de él será sencillo, ya que bastará con echar un ojo al código escrito. Sin embargo, a medida que éste crece, se vuelve muy conveniente poder introducir notas aclaratorias sobre qué es lo que pretendemos que el programa haga. Así, si escribimos un algoritmo en particular, podemos agregar un texto que indique qué debe hacer dicho algoritmo en particular, podemos agregar un texto que indique qué debe hacer dicho algoritmo, y de este modo otro programador podrá entenderlo rápidamente, o quizá nosotros mismos, releyendo el código que hayamos escrito tiempo atrás.
Para que el compilador no interprete el texto aclaratorio como intentos fallidos de instrucciones, debemos indicarle que estamos introduciendo un comentario.
C# acepta dos tipos de comentarios. Uno es el comentario de linea, que debe comenzar con caracteres //, como por ejemplo:
//Este es un comentario
El otro es el comentario clásico del lenguaje C, que comienza con los caracteres /* y termina de manera inversa, con los caracteres */
/* Este es un comentario*/
Este tipo de comentario puede ser multilínea; el siguiente es ejemplo de esto:
/* Este
es un
comentario*/
U.1.36
Sintaxis Básica del Lenguaje
En C#, un programa es una colección de clases, aquí no se permitirán funciones ni variables globales como en el caso de C++. C# es un lenguaje orientado a objetos que pretende ser fiel a sus conceptos, y por medio del framework .NET ofrece una librería de clases que nos serán de gran utilidad cuando construyamos aplicaciones.
Esta librería de clases, que menciomos en el capítulo anterior, se llama BCL (Base Class Library), y se podría decir que es el sueño de todo programador, ya que ofrece una gran variedad de funcionalidades.
Por el momento, de esta librería diremos que se encuentra organizada por espacios de nombres (en inglés, namespaces)
Us.1.36
Esta librería de clases, que menciomos en el capítulo anterior, se llama BCL (Base Class Library), y se podría decir que es el sueño de todo programador, ya que ofrece una gran variedad de funcionalidades.
Por el momento, de esta librería diremos que se encuentra organizada por espacios de nombres (en inglés, namespaces)
Us.1.36
Suscribirse a:
Comentarios (Atom)