sábado, 22 de abril de 2017

Curso de C#: introducción, variables y constantes

Introducción


La sintaxis de C# es muy parecida a la de C, C++ y, sobre todo, Java. Así, por ejemplo, declarar una variable o un puntero en C# se escribe igual que en C:

int a;
int* pA;

Aunque el código sea sintácticamente idéntico, semánticamente puede ser muy distinto, es decir: mientras en C la una variable de tipo int es eso y nada más, en C# una variable de tipo int es en realidad un objeto de la clase System.Int32. Las diferencias más importantes entre C y C# no suelen ser sintácticas sino sobre todo semánticas.

En C# todas las instrucciones y declaraciones deben terminar con ; (punto y coma), salvo que haya que abrir un bloque de código.  Al contrario que en Visual Basic, aquí se puede poner una instrucción que sea muy larga en varias líneas sin poner ningún tipo de signo especial al final de cada una.

CURSO DE C#: introducción, variables y constantes




A = Metodo(argumento1, argumento2, argumento3, argumento4
       argumento5, argumento6, argumento7, argumento8);

El compilador entiende que toda la línea forma parte de la misma instrucción hasta que encuentre un punto y coma.

Un bloque de código es una parte del mismo que está "encerrado" dentro de algún contexto específico, como una clase, un método, un bucle.


public bool Metodo(int numero)
{
    if (numero>0)
    {
        return true;
    }
    return false;
}

Los bloques de código están muy claramente delimitados por las llaves, pero ambos bloques están delimitados del mismo modo, es decir, ambos se delimitan con llaves. Además, detrás de la línea en que se declara el método no está escrito el punto y coma, igual que en el if, lo cual quiere decir que la llave de apertura del bloque correspondiente se podía haber escrito a continuación, y no en la línea siguiente. Según está escrito, es fácil determinar cuáles son las llaves de apertura y cierre de un bloque y cuáles las del otro. Sin embargo, si hubiésemos quitado las tabulaciones y colocado la llave de apertura en la misma línea, esto se habría complicado algo:

bool Metodo(int numero) {
if (numero>0) {
return true;
}
return false;
}

Si, dentro de este método hubiera más bucles anidados, la cosa se puede  complicar. De ahí la importancia de tabular correctamente el código en todos los lenguajes, pero especialmente en los lenguajes basados en C, como el propio C, C++, Java y C#, ya que así será fácil ver dónde empieza y dónde termina un bloque de código.

Los programas escritos en C# se organizan en clases y estructuras, de modo que todo el código debe ir siempre dentro de una clase o bien de una estructura, salvo la directiva using. Por eso las funciones ahora se llaman métodos, porque serán métodos de la clase donde las pongas, y las variables y constantes (dependiendo de dónde se declaren) pueden ser propiedades de la clase.

En cada aplicación en C# se debe poner un método llamado Main, que además ha de ser public y static. No importa en qué clase se escriba el método Main. Pero en todo programa escrito en C# debe haber un método Main, pues será el que busque el CLR para ejecutar la aplicación. A partir de aquí, lo más aconsejable es escribir el método Main en una clase que se llame igual que el programa más las letras App. Por ejemplo, si es un juego de ajedrez, lo más recomendable es situar el método Main en una clase que se llame AjedrezApp. Ahora bien, esto no lo exige el compilador, así que si se pone el método Main en cualquier otra clase, el programa funcionará.

C# distingue las mayúsculas de las minúsculas de modo, que, una variable que se llame “Nombre” es distinta de otra que se llame “nombre”, y un método que se llame “Abrir” será distinto de otro que se llame “abrir”.

C# soporta la sobrecarga de métodos, es decir, que se pueden escribir varios métodos en la misma clase que se llamen exactamente igual, pero la lista de argumentos ha de ser diferente en cada uno de ellos, ya se diferencian en el número de argumentos o bien en el tipo de dato de dichos argumentos.

También soporta la sobrecarga de operadores y conversiones definidas por el usuario. Esto quiere decir que al diseñar una clase, es posible modificar el comportamiento de varios operadores del lenguaje para que hagan cosas distintas de las que se esperan, y también que si se usa una clase diseñada por otro programador, uno o varios operadores pueden estar sobrecargados, por lo que es conveniente revisar la documentación de dicha clase antes de empezar a usarla.

En C# no existen archivos de cabecera ni módulos de definición.

los comentarios al código son de de dos formas: // indica que es un comentario de una sola línea. /* ... comentario ... */ es un comentario de una o varias líneas.

Ejemplo:

// Esto es un comentario de una única línea

/* Esto es un comentario que consta de
varias líneas */



Las clases: Unidades básicas de estructuramiento


Todo programa en C# se organiza en clases y estructuras. Las clases son, por lo tanto, la base fundamental de cualquier programa escrito en este lenguaje. Una clase se construye así:

class NombreClase
{
    // Aquí se codifican los miembros de la clase
}

No todas las clases tienen por qué ser igualmente accesibles desde otra aplicación. Es posible que se necesite una clase que sólo se pueda usar por código que pertenezca al mismo ensamblado. En este caso, bastaría con poner el modificador de acceso private delante de la palabra class o bien no poner nada, pues private es el modificador de acceso por defecto para las clases:
  
private class NombreClase
{
    // Aquí se codifican los miembros de la clase
}

Si deseamos una clase accesible desde otros ensamblados, necesitamos que sea pública, usando el modificador public:

public class NombreClase
{
    // Aquí se codifican los miembros de la clase
}

 Variables y constantes


Para declarar una variable hay que colocar previamente el tipo y después el nombre.

string Nombre; // Declaración de la variable nombre, de tipo string
  
También se puede inicializar el valor de una variable en el momento de declararla, y se puede modificar después:

int num=10;

Las constantes. En este caso ese dato es siempre el mismo y no se puede modificar durante la ejecución del programa. Además, es necesario saber previamente qué valor ha de almacenar. Basta con añadir la palabra const en la declaración.
     
const double PI=3.1415926; // Esto es una constante

Igual que las clases, también tienen modificadores de acceso. Si se pone, va en primer lugar. Si no se pone, el compilador entenderá que es private.

MODIFICADOR
COMPORTAMIENTO
public
Hace que el indicador sea accesible desde otras clases.
protected
Hace que el indicador sea accesible desde otras clases derivadas de aquella en la que está declarado, pero no desde el cliente
private
Hace que el indicador solo sea accesible desde la clase donde está declarado. Este es el modificador de acceso por omisión.
internal
Hace que el indicador solo sea accesible por los miembros del ensamblaje actual.

Un caso de variable con nivel de acceso protected, por ejemplo, sería:

protected int Variable;

Cuando se declara una variable o constante dentro de un bloque que no es el de una clase o estructura, esta  será siempre privada para ese bloque, de modo que no será accesible fuera del mismo. 

Tipos en C#


El uso correcto de los distintos tipos de datos es algo fundamental para que una aplicación sea eficiente con el menor consumo posible de recursos.

En C# (más propiamente en .NET Framework) contamos con un sistema de tipos unificado, el CTS (Common Type System), que proporciona todos los tipos de datos como clases derivadas de la clase de base System.Object (incluso los literales pueden tratarse como objetos). Sin embargo, el hecho de que todos los de un programa sean objetos, puede provocar que baje el rendimiento de la aplicación. Para solventar este problema, .NET Framework divide los tipos en dos grandes grupos: los tipos valor y los tipos referencia.

Cuando se declarara variable que es de un tipo valor se está reservando un espacio de memoria en la pila para que almacene los datos reales que contiene esta variable. Por ejemplo en la declaración:

int num =10;

Se está reservando un espacio de 32 bits en la pila (una variable de tipo int es un objeto de la clase System.Int32), en los que se almacena el 10, que es lo que vale la variable.  

En el caso de una variable que sea de tipo referencia, lo que se reserva es un espacio de memoria para almacenar el valor, pero lo que se devuelve internamente es una referencia al objeto, es decir, un puntero a la dirección de memoria que se ha reservado.

A continuación la tabla de los tipos que se pueden manejar en C# con su equivalente en el CTS (Common Type System).

RESUMEN DEL SISTEMA DE TIPOS
Tipo CTS
Alias C#
Descripción
Valores que acepta
System.Object
object
Clase base de todos los tipos del CTS
Cualquier objeto
System.String
string
Cadenas de caracteres
Cualquier cadena
System.SByte
sbyte
Byte con signo
Desde -128 hasta 127
System.Byte
byte
Byte sin signo
Desde 0 hasta 255
System.Int16
short
Enteros de 2 bytes con signo
Desde -32.768 hasta 32.767
System.UInt16
ushort
Enteros de 2 bytes sin signo
Desde 0 hasta 65.535
System.Int32
int
Enteros de 4 bytes con signo
Desde -2.147.483.648 hasta  2.147.483.647
System.UInt32
uint
Enteros de 4 bytes sin signo
Desde 0 hasta 4.294.967.295
System.Int64
long
Enteros de 8 bytes con signo
Desde
-9.223.372.036.854.775.808 hasta      9.223.372.036.854.775.807
System.UInt64
ulong
Enteros de 8 bytes sin signo
Desde 0
Hasta
18.446.744.073.709.551.615
System.Char
char
Caracteres Unicode de 2 bytes
Desde 0 hasta 65.535
System.Single
float
Valor de coma flotante de 4 bytes
Desde 1,5E-45  hasta 3,4E+38
System.Double
double
Valor de coma flotante de 8 bytes
Desde 5E-324 hasta  1,7E+308
System.Boolean
bool
Verdadero/falso
true ó false
System.Decimal
decimal
Valor de coma flotante de 16 bytes (tiene 28-29 dígitos de precisión)
Desde 1E-28 hasta 7,9E+28

Para declarar una variable de uno de estos tipos en C# hay que colocar primero el tipo del CTS o bien el alias que le corresponde en C#, después el nombre de la variable y después, opcionalmente, asignarle su valor:

System.Int32 num=10;
int num=10;

La variable num sería de la clase System.Int32 en ambos casos: en el primero se ha utilizado el nombre de la clase tal y como está en el CTS, y en el segundo se ha usado el alias para C#. La asignación del valor en la declaración es opcional.

Hay que ajustar lo máximo posible el tipo de las variables a los posibles valores que estas vayan a almacenar. Un tipo que admite valores de coma flotante admite valores con un número de decimales que no está fijado previamente, es decir, números enteros, o con un decimal, o con dos, etc.... Por eso se dice que la coma es flotante, porque no está siempre en la misma posición con respecto al número de decimales (el separador decimal en el código siempre es el punto).

double num=10.75;
double num=10.7508;

Las cadenas son una concatenación de caracteres, ya sean numéricos, alfabéticos o alfanuméricos. Cuando se va a asignar un valor literal a una variable de tipo string hay que colocar dicho literal entre comillas:

string mensaje = “Buenos días”;

Los caracteres unicode son un conjunto de caracteres de dos bytes. Hasta hace relativamente poco en occidente se estaba utilizando el conjunto de caracteres ANSI, que constaba de 256 caracteres que ocupaban un byte. ¿Qué pasaba? Que este conjunto de caracteres se quedaba muy corto en oriente, por lo que ellos usaban el conjunto unicode, que consta de 65.536 caracteres. Lo que se pretende con .NET es que, a partir de ahora, todos usemos el mismo conjunto de caracteres, es decir, el conjunto unicode. Por eso, todas las variables de tipo char almacenan un carácter unicode.

Para las fechas también hay una clase, aunque en C# no hay ningún alias para estos datos. Es la clase System.DateTime:

System.DateTime fecha;

A menudo será necesario efectuar operaciones matemáticas con variables de distintos tipos. Por ejemplo, sumar una variable de tipo int con otra de tipo double e introducir el valor en una variable de tipo decimal. Para poder hacer esto es necesario convertir los tipos. Para convertir una expresión a un tipo definido basta con poner delante de la misma el nombre del tipo entre paréntesis. Por ejemplo, (int) 10.78 devolvería 10, es decir, 10.78 como tipo int. Si ponemos (int) 4.5 * 3 el resultado sería 12, ya que (int) afecta únicamente al valor 4.5, de modo que lo convierte en 4 y después lo multiplica por 3. Si, por el contrario, usamos la expresión (int) (4.5 * 3), el resultado sería 13, ya que en primer lugar hace la multiplicación que está dentro del paréntesis (cuyo resultado es 13.5) y después convierte ese valor en un tipo int. Pero hay que tener en cuenta que no podemos convertir una cadena en un tipo numérico:

int a = (int) cadena; // Error. Una cadena no se puede convertir a número

Para este caso necesitaríamos hacer uso de los métodos de conversión que proporcionan cada una de las clases del .NET Framework para los distintos tipos de datos:


int a = System.Int32.Parse(cadena); 

No hay comentarios:

Publicar un comentario