Upload
others
View
5
Download
0
Embed Size (px)
Citation preview
Capítulo 2
EL LENGUAJE C#
C# es un moderno lenguaje de programación orientada a objetos desarrollado para
programar sobre la plataforma .NET. Comenzando con su nombre, la intención
fundamental ha sido ofrecer a los programadores de C++, un entorno familiar para
programar aplicaciones de software sobre esta plataforma y aquellas que cumplan la
especificación de .NET. En consecuencia se han adoptado muchos de los recursos de
programación que maneja este lenguaje, pero adaptados a .NET y todas las
herramientas que este entorno pone a disposición del programador.
En este capítulo se realizará una breve descripción de los elementos básicos del
lenguaje como tal, intentando hacer una explicación precisa sobre estos. Aunque el
lector debe tener una noción básica sobre programación de computadores, no se
requiere ser experto en programar con C++, ya que la realidad es que este lenguaje ha
sido solo un punto de partida para C#, y solo se conservan sus estructuras básicas. C#
está dotado de su propia estructura y evita los aspectos difíciles de C++, al menos en lo
básico, como es el manejo de los recursos de programación.
Se espera con el desarrollo de este capítulo dejar claros los conceptos básicos de la
estructura del lenguaje C# y poner a disposición del programador los recursos más
importantes que le permitan comprender la programación en .NET con este lenguaje.
El estilo de programación C#
Todos los programas desarrollados en C# comienzan su ejecución a través de una
función o método principal llamado Main(), sin importar el entorno donde se vaya a
ejecutar la aplicación: consola, entorno gráfico o web. Este método es quien se encarga
de informarle al sistema operativo el inicio de la ejecución, cargar los componentes
básicos del programa en memoria y al final terminar la ejecución.
En el instante en que se inicia la ejecución de un programa cualquiera, el sistema
operativo no posee nada de ese programa en su memoria. En un entorno orientado a
objetos, como lo es .NET, se esperaría un objeto producto de alguna clase, pero en este
punto es imposible contar con alguna clase de nuestro programa en memoria, por lo
tanto es necesario recurrir a una función o método que se ejecute independiente de un
objeto. La solución, en C#, es declarar el método Main como estático, mediante la
palabra static, lo cual permite llamar a Main en forma independiente, sin necesidad de
un objeto.
El lenguaje C# dentro de su sintaxis utiliza obligatoriamente las llaves, { }, para
determinar bloques de código, y el carácter punto y coma (;) para establecer el final de
una instrucción. La apertura de una llave marca el punto de inicio de un bloque, y su
cierre el punto de finalización.
Uno de los problemas más frecuentes para en este tipo de lenguajes, es el cierre no
adecuado de una llave, o la no colocación de una finalización de instrucción al final de
una instrucción, lo cual provoca un error de compilación, por eso es recomendable
distinguir los bloques con tabulaciones creadas a partir de los puntos de apertura y
cierre de una llave y escribir en cada línea una instrucciones completa.
CAPITULO CAPITULO CAPITULO CAPITULO 2 2 2 2 PROGRAMACION CON C#
www.pedrov.phpnet.us
16161616
La mayoría de programadores han adoptado, como regla de estilo, establecer sangrías
para cada bloque de código, dejando claro donde empieza y donde termina dicho
bloque, como por ejemplo:
namespace HolaMundo
{
public class PrimerPrograma
{
static void Main()
{
System.Console.WriteLine("Hola mundo");
}
}
}
Para el compilador, y tal vez para muchos programadores, es válido escribir un
programa como,
namespace HolaMundo
{
public class PrimerPrograma
{
static void Main()
{
System.Console.WriteLine("Hola mundo");
}
}
}
o incluso así,
namespace HolaMundo {public class PrimerPrograma {
static void Main() {System.Console.WriteLine(
"Hola mundo");}}}
Sin embargo este tipo de codificación, aunque es válida, perjudica la lectura posterior
del programa, ya sea por el mismo programador o por cualquier otra persona, y además
vuelve casi imposible encontrar los errores de programación.
Comentarios
Los comentarios son trozos de texto que pretenden explicar algo dentro del código de
un programa, pero que no son tenidos en cuenta por el compilador, y su utilidad solo es
válida para el programador o quién desee interpretar el código. Esto no quiere decir
que los cometarios no sean importantes, todo lo contrario son una parte muy
importante de la programación ya que, bien utilizados, permiten explicar el código
programado y de esta forma facilitar su interpretación y posterior mantenimiento.
Al igual que C++, el lenguaje C# interpreta como comentarios todo aquello que este
precedido por dos caracteres de línea diagonal (//), siempre y cuando se encuentren en
una sola línea. Por ejemplo, se consideran comentarios los siguientes:
// Esta línea es ignorada por el compilador
// por que se trata de un comentario
Los comentarios se pueden colocar al principio de una línea o al final, pero nunca
pueden partirse a dos o más líneas. Si se desea colocar comentarios de más de una
CAPITULO CAPITULO CAPITULO CAPITULO 2222: EL LENGUAJE C#
17171717
línea, deberá incluirlos entre los caracteres /* y */, que permite escribir cualquier
cantidad de líneas. El siguiente programa tiene las dos formas de comentarios:
/* Este es un comentario que ocupa
más de una línea */
namespace HolaMundo
{
// Este es un comentario de una línea
public class PrimerPrograma
{
static void Main()
{
System.Console.WriteLine("Hola mundo");
}
}
}
Un buen programador no puede confiarse de su memoria, son tantas las líneas que
puede llegar a tener un programa que con el tiempo se olvidan o se pierde la
explicación sobre su forma de funcionar. Una buena documentación del código a través
de los comentarios facilita en mucho el posterior mantenimiento del código o su
aprovechamiento para otros programas.
Secuencias de escape
Los caracteres especiales, también llamados secuencias de escape, le permiten al
programa realizar algunas acciones especiales, relacionadas especialmente con cadenas
de caracteres. Estos caracteres no son imprimibles y están compuestos por dos
grafemas, de los cuales el primero siempre será la línea diagonal invertida, \. La
siguiente tabla muestra las secuencias de escape definidas en C#:
Secuencia de escape Descripción
\a Alerta (timbre)
\b Retroceso
\f Avance de página
\n Nueva línea
\r Retorno de carro
\t Tabulador horizontal
\v Tabulador vertical
\0 Nulo
\' Comilla sencilla
\" Comilla doble
\\ Diagonal invertida
Ejemplo 2.1 Tabla de países
En este ejemplo se construirá, en la consola, una pequeña tabla con los nombres de
algunos países suramericanos, aprovechando la secuencia de escape tabulador
horizontal. Al final del programa se coloca una secuencia de escape de alerta que
produce un pitido de la bocina del computador.
CAPITULO CAPITULO CAPITULO CAPITULO 2 2 2 2 PROGRAMACION CON C#
www.pedrov.phpnet.us
18181818
/* Archivo: Ejemplo21.cs
Programa para mostrar el uso de las secuencias de escape
*/
using System; // Espacio de nombres
public class TablaPaises
{
static void Main()
{
Console.WriteLine("-----------------");
Console.WriteLine("No.\tPAIS");
Console.WriteLine("-----------------\n");
Console.WriteLine("1\tColombia");
Console.WriteLine("2\tEcuador");
Console.WriteLine("3\tParaguay");
Console.WriteLine("4\tBolivia");
Console.WriteLine("5\tUruguay");
Console.WriteLine("6\tArgentina");
Console.WriteLine("7\tVenenzuela");
Console.WriteLine("\a");
}
}
Tipos
Un tipo se debe entender como una palabra del lenguaje de programación que establece
como se comporta, se almacena en memoria y se procesa un valor por parte del
computador. Estos tipos son fijados por estructuras definidas en System.
La siguiente tabla muestra los tipos básicos definidos en C#:
Tipo C# Estructura .NET Tamaño en bits
bool Boolean
byte Byte 8
char Char 16
DateTime DateTime 64
decimal Decimal 128
double Double 64
int Int32 32
long Int64 64
object Object 32
sbyte SByte 8
short Int16 16
float Single 32
string String
uint UInt32 32
ulong UInt64 64
ushort UInt16 16
CAPITULO CAPITULO CAPITULO CAPITULO 2222: EL LENGUAJE C#
19191919
En .NET todos los tipos son en realidad estructuras, cuyo objetivo no es solo fijar el
tamaño del tipo en memoria sino ofrecer una serie de operaciones que permiten
manipular el valor definido por dicho tipo. C# por ser el lenguaje base de .NET hace
un manejo directo de esta forma de definir los tipos, pero para mantener la consistencia
con los estándares de lenguajes de programación se han establecido alias para cada uno
de ellos, y de esta forma ahorrarle al programador el uso de los nombres de las
estructuras en las declaraciones que deba realizar. Por ejemplo, en C# el tipo valor
entero, que se identifica con la palabra clave int, en realidad lo establece la estructura
Int32 que en .NET corresponde a un número entero de 32 bits.
Todos los tipos básicos que se manejan en C# pueden asociarse a un alias, como lo
muestra la tabla anterior, pero se debe tener en cuenta que estos alias, cuyos nombres
coinciden con los tipos definidos en otros lenguajes de programación, no
necesariamente coinciden en sus características con sus correspondientes utilizados en
otros lenguaje. Estas diferencias se ven especialmente en cuanto al tamaño ocupado en
la memoria del sistema.
El programa de este ejemplo le muestra los rangos de valores que maneja cada uno de
los tipos definidos en C#. Teniendo en cuenta que los tipos son definidos por clases se
utilizará un método incluido en cada uno de ellos.
En este programa se ha utilizado otra versión del método WriteLine, con tres
argumentos. En los anteriores ejemplos se había utilizado una versión que trabajaba
con un solo argumento. Esta posibilidad que tienen un método, de ofrecer diferentes
versiones para su uso, es lo que se denomina sobrecarga.
La salida que se obtiene después de la ejecución de este programa es similar a la
siguiente:
Byte: False y True
Byte: 0 a 255
Byte: a ?
Byte: 01/01/0001 12:00:00 a.m. a 31/12/9999 11:59:59 p.m.
Byte: -79228162514264337593543950335 a 79228162514264337593543950335
Ejemplo 2.2 Rango de valores manejado por cada tipo
/* Archivo: Ejemplo22.cs
Programa que muestra los rangos de los diferentes tipos
*/
using System;
public class RangoTipos
{
static void Main()
{
Console.WriteLine("boolean: {0} y {1}", Boolean.FalseString, Boolean.TrueString);
Console.WriteLine("byte: {0} a {1}", Byte.MinValue, Byte.MaxValue);
Console.WriteLine("char: {0} a {1}", Char.MinValue, Char.MaxValue);
Console.WriteLine("DateTime: {0} a {1}", DateTime.MinValue, DateTime.MaxValue);
Console.WriteLine("decimal: {0} a {1}", Decimal.MinValue, Decimal.MaxValue);
Console.WriteLine("double: {0} a {1}", Double.MinValue, Double.MaxValue);
Console.WriteLine("int: {0} a {1}", Int32.MinValue, Int32.MaxValue);
Console.WriteLine("long: {0} a {1}", Int64.MinValue, Int64.MaxValue);
Console.WriteLine("sbyte {0} a {1}", SByte.MinValue, SByte.MaxValue);
Console.WriteLine("short: {0} a {1}", Int16.MinValue, Int16.MaxValue);
Console.WriteLine("float: {0} a {1}", Single.MinValue, Single.MaxValue);
Console.WriteLine("uint: {0} a {1}", UInt32.MinValue, UInt32.MaxValue);
Console.WriteLine("ulong: {0} a {1}", UInt64.MinValue, UInt64.MaxValue);
Console.WriteLine("ushort: {0} a {1}", UInt16.MinValue, UInt16.MaxValue);
}
}
CAPITULO CAPITULO CAPITULO CAPITULO 2 2 2 2 PROGRAMACION CON C#
www.pedrov.phpnet.us
20202020
Byte: -1,79769313486232E+308 a 1,79769313486232E+308
Byte: -2147483648 a 2147483647
Byte: -9223372036854775808 a 9223372036854775807
Byte: -32768 a 32767
Single -3,402823E+38 a 3,402823E+38
Tipo de dato object
El tipo object es un tipo de dato que puede contener a cualquier otro tipo. En C# todo
es un objeto y los tipos que se definen en .NET se encuentran definidos en el espacio
de nombres System y se heredan directamente de System.Object, la estructura a la cual
representa el alias object.
Tipo de datos short, int y long
El tipo short es un entero de 16 bits, lo que significa que puede manipular 216 valores
numéricos enteros con signo. Esto da un total de 65536 posibles valores enteros
diferentes. Para manipular por igual, valores negativos y positivos se divide esta cifra
entre 2 y se obtiene 32768 posibles valores para cada uno de esos grupos, pero para
incluir el cero es necesario sacrificar un valor negativo, quedando para estos un
máximo de 32767. Esto significa que este tipo puede manejar valores comprendidos en
el rango de -32767 a 32768.
En los primeros compiladores de C++ se definía un tipo int como un número entero de
16 bits, pero en C# el tipo int es el alias de la estructura Int32, que como se dijo, es un
entero de 32 bits, que permite manipular 232 (4294967296) valores numéricos, los
cuales se reparten entre valores enteros positivos, negativos y el cero, con lo cual
permite un rango de valores comprendidos entre -2147483647 y 2147483648.
El tipo long es un entero de 64 bits, lo que da la posibilidad de manipular 264 valores
numéricos enteros con signo, repartidos, al igual que los anteriores, entre enteros
positivos, negativos y el cero.
Tipos de datos enteros sin signo
Los números enteros sin signo ocupan el mismo espacio en memoria que sus
correspondientes enteros con signo, pero se diferencian en que estos tipos solo
manipulan enteros positivos y el cero, lo cual significa que se los posibles valores a
generar son todos los valores comprendidos entre cero y el valor igual a la cantidad
total posible menos uno.
El tipo char
El tipo char se utiliza para definir un espacio de memoria que almacenara un único
carácter. El espacio utilizado en memoria por este tipo es de 16 bits, lo cual permite la
definición de 65536 posibles valores, suficientes para el sistema de caracteres
UNICODE, en el cual se incluyen todos los símbolos necesarios para todos los idiomas
que existen actualmente en el mundo.
El tipo string
Este tipo de datos sirve para definir cadenas de caracteres de la familia UNICODE. En
el momento este tipo de datos admite manejar cadenas de hasta 2 billones de
caracteres.
La estructura String cuenta con muchos métodos que permiten la manipulación de las
cadenas. En la siguiente tabla se describen brevemente algunas de ellas:
CAPITULO CAPITULO CAPITULO CAPITULO 2222: EL LENGUAJE C#
21212121
Nombre Descripción
Contains Establece si una cadena de texto aparece dentro de aquella que ejecuta a este método
Copy Crea una copia exacta de la cadena.
CopyTo Copia un cierto numero de caracteres a una posición que se haya establecido.
EndsWith Determina si el final de una instancia de la cadena es igual a una cadena especificada.
Equals Determina si dos cadenas tienen el mismo valor.
IndexOf Retorna el índice de la primera aparición de una cadena o carácter dentro de otra cadena.
Insert Inserta una cadena especificada en una posición indicada de otra cadena.
LastIndexOf Informa la posición de la última aparición de un carácter Unicode especificado o de una cadena dentro de otra.
PadLeft Alinea a la derecha los caracteres de la cadena e inserta a la izquierda espacios en blanco o un carácter Unicode especificado hasta alcanzar la longitud total especificada.
PadRight Alinea a la izquierda los caracteres de la cadena e inserta a la derecha espacios en blanco o un carácter Unicode especificado hasta alcanzar la longitud total especificada.
Remove Elimina un número de caracteres especificado de la cadena.
Replace Reemplaza todas las apariciones de un carácter Unicode o una cadena en la cadena que ejecuta este método, por otro carácter o cadena.
StartsWith Determina si el principio de una cadena coincide con una cadena especificada.
Substring Recupera una subcadena de la cadena que lo ejecuta.
ToLower Devuelve una copia de esta cadena convertida en minúsculas.
ToString Convierte el valor del objeto que lo ejecuta en una cadena.
ToUpper Devuelve una copia de esta cadena convertida en mayúsculas.
Trim Quita todas las apariciones de un conjunto de caracteres especificados desde el principio y el final de la cadena.
TrimEnd Quita todas las apariciones de un conjunto de caracteres especificado en una matriz del final de esta instancia.
TrimStart Quita todas las apariciones de un conjunto de caracteres especificado en una matriz del principio de esta instancia.
Ejemplo 2.3 Trabajando con cadenas
El programa debe solicitar una cadena al usuario, para hacer algunos cálculos y
cambios en ella. Entre los cálculos están: determinar la longitud de la cadena y
establecer la posición donde aparece un carácter. Los cambios consisten en recortar la
cadena y cambiarle su forma a minúsculas o mayúsculas.
CAPITULO CAPITULO CAPITULO CAPITULO 2 2 2 2 PROGRAMACION CON C#
www.pedrov.phpnet.us
22222222
/* Archivo: Ejemplo23.cs */
using System;
public class CadenaTexto
{
static void Main()
{
// Declaración de variables
string cadena;
string mayusculas, minusculas;
string subcadena;
int longitud;
int posicionCaracter;
char caracter;
// Lectura de datos
Console.Write("Escriba una cadena: ");
cadena = Console.ReadLine();
Console.Write("Escriba un caracter: ");
caracter = Convert.ToChar(Console.ReadLine());
// Tareas sobre la cadena
longitud = cadena.Length; // Calcula la longitud
mayusculas = cadena.ToUpper(); // Convierte a mayúsculas
minusculas = cadena.ToLower(); // Convierte a minúsculas
subcadena = cadena.Substring(2,5); // Toma un trozo de la cadena
posicionCaracter = cadena.IndexOf(caracter, 1);// Posición en la cadena
// Mostrar los resultados
Console.Write("\nLongitud de la cadena: ");
Console.WriteLine(longitud);
Console.Write("En mayúsculas: ");
Console.WriteLine(mayusculas);
Console.Write("En minúsculas: ");
Console.WriteLine(minusculas);
Console.Write("Subcadena: ");
Console.WriteLine(subcadena);
Console.Write("Primera posición del caracter: ");
Console.WriteLine(posicionCaracter);
}
}
Al ejecutar este programa se debe ingresar una cadena de texto de al menos 5
caracteres, de lo contrario se producirá un error en la ejecución, al momento de intentar
obtener la subcadena, con la instrucción,
subcadena = cadena.Substring(2,5);
la cual lee los caracteres comprendidos entre la posición 2 a 5 de la cadena.
En la instrucción,
caracter = Convert.ToChar(Console.ReadLine());
el método estático ToChar() de la clase Convert, se encarga de convertir el carácter
ingresado en forma de cadena de texto, al tipo char. Esta clase contiene todos los
métodos necesarios para realizar la conversión de un tipo de dato a otro diferente,
siempre y cuando sea posible. También cuenta con algunos métodos para el manejo de
tipos.
CAPITULO CAPITULO CAPITULO CAPITULO 2222: EL LENGUAJE C#
23232323
Tipos enumerados
Los tipos enumerados son tipos definidos por el usuario y corresponden a conjuntos de
constantes numéricas enteras que comienzan en 0. Para crearlos se utiliza la palabra
clave enum.
Por ejemplo, supongamos que un programador en el desarrollo de una aplicación de
software necesita hacer referencia a los cargos de una empresa, tal como: Gerente,
Portero, Mensajero, Secretario, Contador. Si la referencia a estos nombres es necesaria
en varias partes del código del programa, pueden presentarse muchos errores de
digitación que complicarían la programación. Una solución sería relacionar a estos
cargos con valores numéricos.
Cargo Constante
Gerente 0
Portero 1
Mensajero 2
Secretario 3
Contador 4
Pero en un momento dado esto puede complicar aún más las cosas por que con el
tiempo puede llegarse a olvidar la relación existente entre la constante numérica y el
nombre del cargo. Para facilitar las cosas el programador podría definir un tipo
enumerado, en la siguiente forma:
enum Cargo
{
Gerente,
Portero,
Mensajero,
Secretario,
Contador,
};
De esta manera se dispone de cuatro constantes numéricas que relacionan los cargos
con un valor. Para referirse a una de estas constantes se debe hacer mediante el
llamado al tipo seguido de un punto y el nombre de la constante.
Cargo.Mensajero // Se refiere al valor numérico 2
En la tarea de escribir un programa resulta muy importante el uso de estos tipos por
que facilitan al programador hacer referencia a las constantes sin tener que memorizar
la correspondencia entre su nombre y el valor numérico. En los entornos de desarrollo
integrado que cuentan con herramientas asistentes de generación de código,
IntelliSense, resulta bastante práctico, ya que con el nombre del tipo seguido del punto
se muestra automáticamente los nombres de las constantes.
Literales
Un literal es la forma escrita que tiene el lenguaje C# para crear una constante. Un
literal puede ser un número entero, un real, un valor booleano, un carácter, una cadena
de texto, una fecha y hora, o un valor null.
Sistema IntelliSense utilizado por entornos de programación
como Sharpdevelop y VisualStudio .NET
CAPITULO CAPITULO CAPITULO CAPITULO 2 2 2 2 PROGRAMACION CON C#
www.pedrov.phpnet.us
24242424
C# permite básicamente especificar un literal entero en base 10 y 16. Por ejemplo, para
codificar el decimal 105 en base diez basta con escribir el valor tal cual, 105; para
codificar el valor hexadecimal 200, se debe escribir 0x200.
Un literal real se codifica formado por una parte entera y una parte decimal, tal como
12.35.
Un literal de un solo carácter se codifica escribiéndolo entre comillas simples, como
'a' // Carácter a
'\n' // Retorno de carro más avance de línea
Un literal de cadena de caracteres es una secuencia de caracteres encerrados entre
comillas dobles. Estas cadenas, inmediatamente se crean, son asociadas con un objeto
del tipo System.String.
Los literales del tipo fecha y hora son asociados a un objeto del tipo DateTime. Estos
literales están formados por una fecha y una hora. Una variable de este tipo bien
podría cargarse de la siguiente forma:
DateTime fecha = new System.DateTime(2009, 02, 15)
Identificadores
Un identificador es el nombre que se la da a un tipo, un literal, una variable, una clase,
una interface, un espacio de nombres y las sentencias de un programa. Los
identificadores deben iniciar por un carácter alfabético, seguido de una cadena de
letras, números o el carácter de subrayado. En C# se admiten identificadores formados
hasta por 1023 caracteres.
La documentación de .NET sugiere una serie de reglas para nombrar a los
identificadores, que si bien no son de estricto cumplimiento, es importante tenerlas en
cuenta para generar código estándar y fácilmente comprensible a otros programadores
y de esta manera facilitar el trabajo en equipo.
Para identificadores de variables se sugiere utilizar minúsculas cuando su alcance sea
local, es decir que se defina para un determinado bloque de código. Se sugiere utilizar
palabras simples, o palabras compuestas, iniciando cada palabra en mayúscula cuando
su alcance sea global, entendido este como una definición que permite visualizarlos a
nivel público1.
int numero // una variable local
int NumeroPersonas // una variable pública
Los parámetros deben iniciar con minúscula y usar mayúsculas intermedias para
separar las palabras compuestas, tal como,
codigoEmpleado // un parámetro de alguna función
En lo posible se recomienda utilizar identificadores significativos, es decir que por si
solos resulte fácil de interpretar su finalidad y esencia. Por ejemplo, es fácil hacerse
una idea a simple vista para que sirve un identificador como NombreAutor, que si se
utiliza un identificador como na.
1 En programación orientada a objetos no es admisible, y en C# no es posible, que se utilicen variables
globales como aquellas que se utilizan en programación estructurada. Toda variable debe hacer parte de
alguna clase.
CAPITULO CAPITULO CAPITULO CAPITULO 2222: EL LENGUAJE C#
25252525
Variables
Una variable es la unidad básica que utiliza un programa para almacenar un dato. Las
variables en esencia son secciones de memoria que el programa asigna para colocar los
valores que se requieran para su correcto funcionamiento.
Cualquier variable se declara, a lo mínimo, mediante dos elementos básicos: un tipo y
un identificador. En la siguiente forma se muestra como debe manejarse una
declaración de una variable cualquiera en C#:
tipo identificador;
Por ejemplo, para establecer una variable que se encargue de almacenar valores enteros
y se identifique como numero, se utiliza la siguiente instrucción:
int numero;
El lenguaje C# admite la declaración de varias variables del mismo tipo en una sola
instrucción, incluso iniciándolas con algún valor. Por ejemplo, la instrucción
double valorIVA, precio = 1000;
declara dos variable de tipo double y al mismo tiempo a la variable precio, le asigna un
valor inicial igual a 1000.
Algunos lenguajes como C++, admiten declarar variables por fuera de las clases, y
estas se denominan variables globales, pero en C# esto no es válido. Para este lenguaje
todo debe hacer parte de alguna clase y los datos deben obtenerse a través de las
variables que estas clases y sus objetos pongan a disposición del programa.
Se pueden identificar tres lugares o espacios básicos donde puede ser declarada una
variable y de ello depende su alcance o posibilidad de ser leída. Estos espacios,
denominados ámbitos de una variable, son:
- A nivel de la clase. Son variables que se declaran por fuera de cualquier
método que compone la clase. En este caso la variable puede ser leída y
utilizada por cualquier elemento de la clase. A este tipo de variables también
se les llama campos.
- A nivel de un método. Estas variables se declaran dentro del bloque de código
que compone a un método y están al alcance de todos los elementos que
trabajan dentro del mismo, pero no pueden ser leídas por fuera del método.
- A nivel de un bloque de código. Son variables que se declaran dentro de
cualquier bloque de código, definido por la apertura y cierre de las llaves. Este
tipo de variables solo son válidas dentro del bloque donde se declaran y no son
visibles por fuera de él.
El siguiente fragmento de código muestra los diferentes ámbitos donde puede
declararse una variable:
public class Curso
{
// Ambito de clase
string nombreCurso;
static void Main()
{
// Ambito a nivel de método
int numero;
CAPITULO CAPITULO CAPITULO CAPITULO 2 2 2 2 PROGRAMACION CON C#
www.pedrov.phpnet.us
26262626
if (numero > 0)
{
// Ambito a nivel de bloque
string libro;
// Instrucciones...
}
}
}
Las variables definidas a nivel da la clase, que en el .NET Framework comúnmente se
les conoce como campos, podrían ser declaradas como variables pública, es decir que
su alcance sea visible hacia afuera de la clase, tanto para ser leídas como para ser
modificadas. Sin embargo, no es recomendable hacer esto por cuanto va en contra del
principio de encapsulamiento que es uno de los pilares clave de la programación
orientada a objetos. Los campos deben ser declarados como privados, para evitar su
contacto directo con el mundo exterior (es decir permanecen encapsulados) y sus
valores se asignan o leen a través de métodos o propiedades definidas en la clase.
Las variables campo de una clase son inicializadas por el compilador C# para cada
objeto que se instancia de la misma: las variables numéricas son inicializadas con cero,
los caracteres con ‘\0’ y los demás tipos incluyendo las cadenas de texto con un valor
null. En cambio las variables locales, a nivel de método y de bloque de código, no son
inicializadas y por lo tanto es el programador quién debe asignarles un valor antes de
su utilización, de lo contrario se puede generar un error en el momento de la ejecución.
Ejemplo 2.4: Cálculos aritméticos
El siguiente ejemplo de programa recibe dos datos numéricos y realiza con ellos las
operaciones de suma, resta, multiplicación, división y cálculo del residuo entero, y
muestra los resultados en pantalla. Los datos serán ingresados en forma de argumentos
del método Main( );
/* Archivo: Ejemplo24.cs */
using System;
public class OperacionesAritmeticas
{
static void Main(string[] numero)
{
int a = 0, b = 0;
int suma = 0, resta = 0;
int producto = 0, division = 0, residuo = 0;
// Conversión de cadena a entero
a = Convert.ToInt32(numero[0]);
b = Convert.ToInt32(numero[1]);
// Realizar las operaciones
suma = a + b;
producto = a * b;
resta = a - b;
division = a / b;
residuo = a % b;
// Mostrar resultados en pantalla
Console.WriteLine("a + b = {0}", suma);
Console.WriteLine("a - b = {0}", resta);
Console.WriteLine("a * b = {0}", producto);
Console.WriteLine("a / b = {0}", division);
Console.WriteLine("a % b = {0}", residuo);
}
}
CAPITULO CAPITULO CAPITULO CAPITULO 2222: EL LENGUAJE C#
27272727
Compile el programa con el nombre de ejecutable Operar.EXE. Para ello debe
utilizarse la opción /out del compilador. Así:
> csc /out:operar.exe ejemplo24.cs
Para ejecutar el programa debe teclear en la línea de comando el nombre del ejecutable
seguido de dos números enteros separados por un espacio. Por ejemplo, para realizar
las operaciones aritméticas con los números 10 y 3 se debe ejecutar el programa de la
siguiente forma:
> operar 10 3
La salida que se obtiene es la siguiente:
a + b = 13
a - b = 7
a * b = 30
a / b = 3
a % b = 1
Los primeros cuatro operadores son fáciles de distinguir para cualquier programador
sin importar el nivel que posea. Todos loe hemos utilizado desde los primeros años
escolares. El operador módulo, %, realiza el cálculo del residuo de hacer la división
entera del número a con el número b.
Operadores
Los operadores son caracteres especiales que le informan al compilador que se debe
realiza una operación sobre unos elementos llamados operandos que se encuentran
antes o después de ellos. Las instrucciones de operación se indican mediante
operadores y los operandos pueden ser variables, expresiones o literales que
representan valores.
Algunos operadores se aplican sobre un único operando y se les llama operadores
unarios. De estos algunos se colocan antes del operando y se los denomina operadores
prefijo. Otros se colocan después del operador y se llaman operadores sufijo. La
mayoría de los operadores actúan sobre dos operandos y se escriben en medio de ellos,
y se les denomina operadores binarios infijo.
En C# los operadores se pueden considerar clasificados en siete grupos: aritméticos,
relacionales, lógicos, unarios, a nivel de bits, de asignación y operadores
condicionales.
Operadores aritméticos
Los operadores aritméticos se utilizan para operaciones matemáticas, exactamente de
la misma forma que están definidos en la aritmética y el álgebra. Los operandos deben
ser de tipo numérico.
Operador Operación
+ Suma
- Resta
* Multiplicación
/ División
% Residuo
CAPITULO CAPITULO CAPITULO CAPITULO 2 2 2 2 PROGRAMACION CON C#
www.pedrov.phpnet.us
28282828
En cualquier caso, los operandos pueden ser enteros o reales. En caso de aplicarse el
operando a dos números de diferente tipo, ambos son convertidos al tipo del operando
que ofrezca mejor precisión. En el caso del residuo, cuando uno de los operandos es un
real, el resultado será un valor real.
Operadores relaciónales
Los operadores relacionales permiten comparar dos operandos. El resultado de la
comparación es un valor booleano verdadero (true) cuando la relación se cumple, o
falso (false) cuando no se cumple.
Operador Operación
< Menor que
> Mayor que
<= Menor o igual que
>= Mayor o igual que
!= Diferente de
== Igual a
Operadores lógicos
Los operadores lógicos son utilizados para operar valores boléanos, que en la mayoría
de los casos se obtienen como resultado de la aplicación de los operadores relacionales.
Los valores devueltos son de tipo booleano.
Operador Operación
& AND
| OR
! NOT
^ XOR
&& AND en cortocircuito
|| OR en cortocircuito
Las cuatro primeras operaciones corresponden a las operaciones de la Lógica
Matemática, conjunción, disyunción, negación y disyunción exclusiva,
respectivamente. El operador AND devuelve verdadero (true) únicamente si ambos
operandos sobre los cuales se aplica son verdaderos; el operador OR devuelve
verdadero (true) cuando al menos uno de los dos operandos es verdadero; el operador
NOT, es unario, y devuelve el valor booleano contrario al que posea el operando; el
operador XOR, devuelve verdadero únicamente cuando se aplica a dos operandos de
valores opuestos, uno verdadero (true) y el otro falso (false).
Los operadores en cortocircuito empiezan evaluando el primer operando, y la
evaluación del segundo depende del valor booleano obtenido en este. El operador AND
en cortocircuito, evalúa el segundo operando únicamente si el primero devuelve un
valor verdadero. En cambio el operador OR en cortocircuito, cuando el primer
operando es verdadero, deja de evaluar el segundo operando.
Operadores unarios
Estos operadores se encargan de actuar sobre un único valor numérico. Su trabajo,
básicamente consiste en modificar los bits que componen a dicho valor.
A B AND V V V
V F F
F V F
F F F
A NOT V F
F V
A B OR V V V
V F V
F V V
F F F
A B XOR V V F
V F V
F V V
F F F
A B && V V V
V F F
F ? F
F ? F
A B || V ? V
V ? V
F V V
F F F
Tablas de verdad para los operadores lógicos
CAPITULO CAPITULO CAPITULO CAPITULO 2222: EL LENGUAJE C#
29292929
Operador Operación
~ Complemento a 1
- Signo menos
El complemento a 1, cuyo carácter corresponde al Unicode 126, se encarga de cambiar
ceros por unos y unos por ceros, en la cadena de bits que conforman el valor numérico.
El operando debe ser de tipo int, uint, long o ulong.
El signo menos, al igual que en las matemáticas, cambia el signo al operando. Esto se
logra, calculando el complemento a 2 sobre los bits que conforman el valor numérico.
Operadores a nivel de bits
Los operadores a nivel de bits actúan sobre las cadenas de bits que conforman a un
valor entero.
Operador Operación
& Operación AND a nivel de bits
| Operación OR a nivel de bits
^ Operación XOR a nivel de bits
<< Desplazamiento a la izquierda
>> Desplazamiento a la derecha
Operadores de asignación
Un operador de asignación se encarga de leer un valor, que puede encontrarse
representado por un literal, como resultado de una operación o en incluido en algún
elemento de programación y colocarlo en memoria. En la práctica, la sección de
memoria puede ser una variable o constante explícitamente identificada
Operador Operación
++ Incremento
-- Decremento
= Asignación simple
*= Multiplicación más asignación
/= División más asignación
%= Residuo más asignación
+= Suma más asignación
-= Resta más asignación
<<= Desplazamiento a la izquierda más asignación
>>= Desplazamiento a la derecha más asignación
&= Operación AND sobre bits más asignación
|= Operación OR sobre bits más asignación
^= Operación XOR sobre bits más asignación
A B & 1 1 1
1 0 0
0 1 0
0 0 0
A B | 1 1 1
1 0 1
0 1 1
0 0 0
A B ^ 1 1 0
1 0 1
0 1 1
0 0 0
Operaciones boolenas a nivel de bits
CAPITULO CAPITULO CAPITULO CAPITULO 2 2 2 2 PROGRAMACION CON C#
www.pedrov.phpnet.us
30303030
Operador condicional
El operador condicional, que se representa mediante un signo de interrogación y el
carácter dos puntos, trabaja sobre tres operadores y por esta razón se lo denomina
operador ternario. Las expresiones sobre las que actúa este operador, generalmente
tienen la forma,
variable = Operando1 ? Operando2 : Operando3
El Operando1 debe ser obligatoriamente una expresión que retorna un valor booleano,
mientras que los otros operandos pueden ser de cualquier tipo. Si Operando1 es
verdadero (true) entonces variable recibe el valor del Operando2; en cambio si
Operando1 es falso (false) entonces variable recibe el valor de Operando3.
Precedencia de operadores
En una expresión existe un orden, o precedencia de los operadores, que indica cual
operación se realiza antes que otra. Este manejo en la mayoría de lenguajes de
programación se realiza en forma similar a como lo hacen las matemáticas. En una
operación como,
2 * 5 + 10
es importante saber que operación, entre la multiplicación y la suma, se realizará
primero, para de acuerdo a eso prever el resultado que se obtendrá en el procesamiento
de la expresión. Al observar este sencillo ejemplo, nos damos cuenta que si se realiza
primero la multiplicación, 2 * 5, se obtiene como resultado final, 20; pero si se realiza
primero la suma, 5 + 10, el resultado final es 30. Esta ambigüedad se ha resuelto tanto
en matemáticas, como en programación de computadores, dando un orden bien
definido a los operadores y a los símbolos de agrupación, como los paréntesis.
En la siguiente tabla se muestran las operaciones en C#, de acuerdo al orden de
precedencia, las de más alta precedencia hasta las de más baja precedencia,
entendiéndose como alta precedencia aquellas que se aplican primero.
La más alta precedencia
() [] .
- ~ ! ++ --
* / %
+ -
<< >>
< <= > >=
== !=
&
^
|
&&
||
?:
= += -= &= |= La más baja precedencia
Retomando nuestro ejemplo, y basados en la anterior tabla, vemos que la
multiplicación tiene mayor precedencia que la suma, por lo tanto se aplica primero. En
definitiva el resultado de la expresión es,
CAPITULO CAPITULO CAPITULO CAPITULO 2222: EL LENGUAJE C#
31313131
2 * 5 + 10 = 10 + 10 = 20
Una buena técnica, para evitar confusiones, cuando no se tenga muy claro el orden de
precedencia de un grupo de operadores, es utilizar los paréntesis. Una expresión entre
paréntesis siempre se evalúa primero. Los paréntesis tienen mayor prioridad y son
evaluados desde el más interno hasta el más externo.
Sobrecarga de operadores
La sobrecarga de operadores hace referencia a la posibilidad que tiene un operador de
actuar y producir un resultado de acuerdo al tipo de datos sobre los cuales se aplique.
Por ejemplo, si se aplica el operador + a los literales numéricos 5 y 6, se procesará
como una suma, en este caso 5 + 6 = 11. En consecuencia el operador + actúa como un
operador aritmético que realiza la suma de los dos números. Pero, si este mismo
operador se aplica a dos cadenas de texto, “Curso” + “C Sharp” , el operador realiza la
operación de concatenación (unión de cadenas), dando como resultado la cadena
“CursoC Sharp”. Vemos que el operador actúa de acuerdo al tipo de datos que se
aplique, numéricos o cadenas. Entonces se dice que el operador + esta sobrecargado.
Lo realmente importante es que el programador puede sobrecargar la gran mayoría de
operadores definidos en C#, permitiendo que estos se ajusten a los tipos de datos que
se estén utilizando y de esta manera ampliar su funcionalidad. Sin embargo, aunque la
sobrecarga es un proceso que solo depende de la creatividad del programador, no se
debe abusar de esta capacidad del lenguaje de programación y se recomienda usarla
solo en los casos estrictamente necesarios y en forma conveniente. No está bien
sobrecargar el operador + para que con algún tipo de datos realice una operación
similar a la resta, ya que esto le hace perder claridad y coherencia al código.
Control de flujo
Uno de los logros más importantes en los años 60’s, desde la aparición de los lenguajes
de programación de alto nivel, fue el hecho de haber reconocido que cualquier
algoritmo, sin importar su complejidad podía ser construido con la combinación de tres
estructuras de control de flujo estandarizadas: secuencial, selección y repetitiva, más
una cuarta estructura denominada de salto o bifurcación.
Los programas que hemos realizado hasta el momento, se han construido utilizando
únicamente la estructura secuencial. Las instrucciones se ejecutan en estricto orden, de
izquierda a derecha y de arriba hacia abajo, sin obviar ninguna.
Las sentencias de selección en C# son if y switch; las de repetición, for, while,
do…while y foreach; las sentencias de salto incluyen break, continue y return.
Sentencia if
La construcción if, en su forma simple provoca que la ejecución de un conjunto de
instrucciones se realice siempre y cuando se cumpla una condición.
if (condición)
instrucciones;
La condición es una expresión que devuelve un valor booleano (true o false). Si esta
condición es verdadera, genera el valor true, entonces se ejecuta el bloque de
instrucciones. En caso de que la instrucción sea falsa, retorna el valor false, la
ejecución salta a la línea de código que se encuentra inmediatamente después del
bloque de instrucciones.
CAPITULO CAPITULO CAPITULO CAPITULO 2 2 2 2 PROGRAMACION CON C#
www.pedrov.phpnet.us
32323232
Pero además, la sentencia if posee la forma múltiple conocida generalmente como
if…else, la cual permite ejecutar un bloque de instrucciones para el caso en que se
cumpla la condición y otro bloque para el caso en que esta no se cumpla. Su sintaxis
es la siguiente:
if (condición)
instrucciones1;
else
instrucciones2;
En este caso se evalúa inicialmente la condición y su el valor devuelto es verdadero
(true), se ejecuta el bloque de instrucciones 1 y si no es así, se ejecuta el bloque de
instrucciones 2. En cualquier caso la ejecución del programa continúa en la línea de
código que se encuentra después del bloque de instrucciones 2.
Ejemplo 2.5: Controlar la división por cero
En los ejemplos que se han realizado anteriormente, relacionados con operaciones
matemáticas, no se tuvo en cuenta que para algunas entradas de valores el programa
podía fallar. Esta situación es la que se presenta en el programa que hace la división de
números, cuando el divisor (número que divide) es igual a cero, el programa falla por
que esta operación no está definida ni para las matemáticas ni para el computador. En
el siguiente ejemplo vamos a programar la división, controlando que se realice
únicamente para aquellos divisores diferentes de cero.
/* Archivo: Ejemplo25.cs */
using System;
public class ControlDivision
{
static void Main()
{
// Declaración de variables
double dividendo, divisor, cociente = 0;
string numero1, numero2;
// Lectura de las cadenas de entrada
Console.Write("\nDividendo = ");
numero1 = Console.ReadLine();
Console.Write("Divisor = ");
numero2 = Console.ReadLine();
// Conversión de cadena a tipo numérico
dividendo = Convert.ToDouble(numero1);
divisor = Convert.ToDouble(numero2);
// Si el divisor es diferente de cero...
if (divisor != 0)
{
cociente = dividendo / divisor;
Console.WriteLine("Cociente = {0} ", cociente);
}
else
Console.WriteLine("La división por cero no existe...");
Console.WriteLine("\nPrograma finalizado...");
}
}
La estructura if que se utiliza en este programa se encarga de controlar el valor del
divisor. Si la condición, el divisor es diferente de cero, se cumple, entonces se realiza
la operación de división y se muestra el resultado en pantalla, pero en caso de que no
CAPITULO CAPITULO CAPITULO CAPITULO 2222: EL LENGUAJE C#
33333333
se cumpla la condición, es decir que el divisor sea igual a cero, entonces se muestra en
pantalla un mensaje indicando que la división por cero no existe.
Observe que, en la estructura if, el primer bloque de instrucciones se ha colocado
entre llaves, mientras que en el segundo bloque, correspondiente a else, no ha sido
necesario utilizarlas. Los bloques se deben colocar, obligatoriamente, entre llaves
cuando están formados por más de una instrucción, en caso contrario se pueden obviar
estos símbolos. Cuando no se escriben las llaves, el compilador considera que el
bloque correspondiente está formado por una sola instrucción y como tal se ejecuta.
La instrucción que se encuentra inmediatamente después de la estructura if es,
Console.WriteLine("La división por cero no existe...");
y es en este punto donde continúa la ejecución del programa.
Sentencia switch
La estructura switch permite seleccionar una de varias opciones, en función del valor
obtenido en una expresión que se analiza inicialmente. Su estructura general en C#
tienen el siguiente formato:
switch (expresión)
{
case valor1:
instrucciones1;
break;
case valor2:
instrucciones2;
break;
.
.
.
[default:]
[instruccionespordefecto;]
}
Donde la expresión que se evalúa puede retornar un tipo entero, enumerado o cadena
de texto. Los valores de cada uno de los casos, case, deben ser del mismo tipo que la
expresión o de un tipo que pueda ser convertido implícitamente a ese tipo. Cada case
va seguido de un posible valor que pueda tomar la expresión, y al final el carácter dos
puntos ( : ). No es necesario que las instrucciones que hacen parte de un case se
encierren con llaves. En cada case, incluida la opción por defecto, default, debe
incluirse un break, que tiene como finalidad sacar la ejecución del programa fuera de
al estructura switch.
La estructura switch se encarga de determinar el valor que tiene expresión y de acuerdo
a eso manda la ejecución a uno de los case que la componen. Si ningún case y su valor
respectivo es igual al valor de la expresión, entonces se ejecutan las instrucciones por
defecto, incluidas bajo default. Esta última es opcional, y bien puede no incluirse, en
cuyo caso, el programa de no encontrar ningún case que cumpla con el valor de la
expresión continua su ejecución inmediatamente después del cierre de la estructura.
Cuando se desee ejecutar un mismo grupo de instrucciones para varios casos, se
pueden escribir varios case, seguidos unos de otros, siempre y cuando entre ellos no se
coloque una instrucción. Por ejemplo la siguiente estructura case ejecuta las mismas
acciones para los casos en que la variable numero sea igual a 1, 2 y 3:
CAPITULO CAPITULO CAPITULO CAPITULO 2 2 2 2 PROGRAMACION CON C#
www.pedrov.phpnet.us
34343434
switch (numero)
{
case 1:
case 2:
case 3:
instrucciones;
break;
.
.
.
}
Ejemplo 2.6: Días de la semana
En este programa el usuario debe ingresar un número comprendido entre 1 y 7, para
que el sistema le devuelva el nombre del día de la semana que le corresponde. En caso
de que se ingrese un valor diferente el programa deberá mostrar un mensaje
informando que ese día no existe.
/* Archivo: Ejemplo26.cs */
using System;
public class DiasSemana
{
static void Main()
{
// Declaración de variables
string numeroDia;
string nombreDia;
// Lectura de datos
Console.Write("Día número: ");
numeroDia = Console.ReadLine();
// Seleccionar el nombre del día acuerdo al número
switch (numeroDia)
{
case "1":
nombreDia = "LUNES";
break;
case "2":
nombreDia = "MARTES";
break;
case "3":
nombreDia = "MIERCOLES";
break;
case "4":
nombreDia = "JUEVES";
break;
case "5":
nombreDia = "VIERNES";
break;
case "6":
nombreDia = "SABADO";
break;
case "7":
nombreDia = "DOMINGO";
break;
default:
nombreDia = "(Este día no existe...)";
break;
}
// Escribir en pantalla el nombre del día
Console.WriteLine("Nombre del día: {0}", nombreDia);
}
}
CAPITULO CAPITULO CAPITULO CAPITULO 2222: EL LENGUAJE C#
35353535
En este programa la estructura switch se encarga de evaluar el valor de la variable
numeroDia y de acuerdo a eso selecciona el caso que le corresponde. De esta manera,
siempre y cuando el valor se encuentre entre 1 y 7, encontrará un nombre apropiado
para ese día. No olvidemos que el método ReadLine de la clase Console únicamente
lee cadenas de texto, por lo cual fue necesario definir la variable numeroDia del tipo
string.
Ejemplo 2.7: Números pares e impares
En el siguiente ejemplo se muestra como utilizar switch para procesar múltiples casos,
los cuales tienen la misma salida. El usurario debe ingresar un número entre 1 y 9, para
que el sistema determine si es par o impar. Son pares los números 2, 4 , 6 y 8, y se sabe
que la salida en este programa debe ser la misma para todos ellos, por lo tanto, se
programan varios casos con una única posibilidad de salida.
/* Archivo: Ejemplo27.cs */
using System;
public class ParImpar
{
static void Main()
{
Console.Write("Ingrese un número entero [1 a 9]: ");
string numero = Console.ReadLine();
switch (numero)
{
case "1": case "3": case "5": case "7": case "9":
Console.WriteLine("{0} es un número impar", numero);
break;
case "2": case "4": case "6": case "8":
Console.WriteLine("{0} es un número par", numero);
break;
default:
Console.WriteLine("{0} está fuera de rango", numero);
break;
}
}
}
La forma como se han escrito los casos (case), uno en seguida de otro, solo es cuestión
de estilo, si se quiere pueden escribirse cada uno en diferente línea.
Sentencia while
La estructura repetitiva while (en español mientras) repite un conjunto de instrucciones
mientras se cumpla una condición dada.
while (condición)
{
Instrucciones;
}
La condición es una expresión que devuelve un valor booleano. La repetición se
produce siempre y cuando el valor devuelto sea verdadero (true). En el instante en que
el valor devuelto sea falso (false), la ejecución sale del ciclo repetitivo y continúa en la
siguiente línea después del cierre del bloque de código correspondiente a la estructura.
Cuando en el cuerpo de la estructura while solo existe una instrucción, puede escribirse
sin necesidad de utilizar las llaves, e incluso en una sola línea.
CAPITULO CAPITULO CAPITULO CAPITULO 2 2 2 2 PROGRAMACION CON C#
www.pedrov.phpnet.us
36363636
while (condición) instrucción;
Una característica básica de esta estructura, que se debe tener en cuenta, es que antes
de iniciar la ejecución, por primera vez, de las instrucciones, se revisa el cumplimiento
de la condición. Si esta no se cumple, nunca se ejecutará la repetición de las
instrucciones.
Supongamos el siguiente fragmento de código, donde inicialmente se asigna el valor 2
a la variable i,
i = 2;
while (i < 1)
Console.WriteLine("Número = {0}", i);
En este caso, la condición exige que el valor de i sea menor que 1, pero antes esta
variable a asumido el valor 2, por lo cual la condición nunca se cumple y en
consecuencia no se ejecuta ni una sola vez la línea del cuerpo de while, Console.WriteLine("Número = {0}", i);
También puede suceder que la condición se cumpla siempre y en tal situación la
ejecución entra en una repetición indefinida, que nunca termina. Si esta situación se
produce por error de programación, y no existe una forma de control establecida en el
programa, este no podrá salir del ciclo y el usuario deberá acudir a alguna forma de
terminación forzada.
Ejemplo 2.8: Sumatoria de enteros positivos
Este ejemplo nos permite tener un programa que sume todos los números
comprendidos entre 1 y cualquier valor ingresado por el usuario utilizando la estructura
repetitiva while.
/* Archivo: Ejemplo28.cs */
using System;
public class Sumatoria
{
static void Main(string[] numero)
{
// Convierte a entero el texto ingresado, como argumento
// por el usuario, y lo asigna a la variable numeroFinal
int numeroFinal = Convert.ToInt32(numero[0]);
int i = 1, suma = 0;
// Repetir mientras i sea menor que numeroFinal...
while (i <= numeroFinal)
{
suma = suma + i;
i++;
}
// Mostrar el resultado de la suma
Console.WriteLine("Sumatoria = {0}", suma);
}
}
Compile el programa con la sentencia,
> csc /out:sumarhasta.exe ejemplo28.cs
CAPITULO CAPITULO CAPITULO CAPITULO 2222: EL LENGUAJE C#
37373737
Para ejecutarlo, recuerde, debe llamar el nombre del programa, seguido de un
argumento numérico, por ejemplo así:
> sumarhasta 500
El programa sumarhasta realiza la suma entre 1 y cualquier valor que ingrese como
argumento el usuario, repitiendo la suma acumulativa,
suma = suma + i
En esta expresión, incluso con poco sentido matemático, el sistema realiza la operación
indicada en la derecha del signo igual, =, y lo almacena en la misma variable
sustituyendo cualquier valor anterior.
La operación i++ se encarga de incrementar el valor de i en 1 cada vez que se ejecute
esta instrucción, y el resultado lo almacena en la misma variable i. en el momento que
el valor de i supere al valor de la variable numeroFinal, deja de ser verdadera la
condición y se da por terminado el ciclo, pasando a mostrar en pantalla el último valor
acumulado en la variable suma.
Puede probar a ingresar como argumento, en la ejecución, cualquier valor negativo, o
incluso el cero, y el programa no realizará ninguna operación, devolviendo siempre 0.
Esto ocurre por que bajo estas condiciones jamás se realiza la suma acumulativa.
Sentencia do…while
La sentencia do… while ejecuta un conjunto de instrucciones una o varias veces. Esta
estructura de control, primero ejecuta el bloque de instrucciones y al final comprueba
si se cumple la condición que le permite repetir la ejecución. Su estructura básica es la
siguiente:
do
{
instrucciones;
}
while (condición);
En esta estructura de control las instrucciones se ejecutan al menos una vez, antes de
que se verifique la condición. Esta es la diferencia sustancial con la estructura while,
quien antes de realizar cualquier ejecución, verifica el cumplimiento de la condición.
Una vez realizada la primera ejecución de las instrucciones, se comprueba que la
condición, que corresponde a una expresión booleana, devuelva un valor verdadero
(true) para continuar con el ciclo repetitivo. En caso que la condición devuelva un
valor falso (false) se da por terminado el ciclo y se continua la ejecución en la
instrucción que sigue al cierre de esta estructura de control.
Ejemplo 2.9 Validación de una contraseña de paso
Las contraseñas son cadenas de caracteres alfanuméricos que deben ser tecleadas por el
usuario de un programa para permitirle ingresar o utilizar algún componente de la
aplicación. El programa se encarga de leer la cadena de texto ingresada por el usuario y
luego compararla con una cadena preestablecida y que se encuentra almacenada en
algún lugar del programa. Si la cadena ingresada coincide con esta última se deja
continuar con la ejecución del programa, en caso contrario, generalmente, se vuelve a
pedir la contraseña. El siguiente es un programa que valida una contraseña utilizando
la sentencia de control do… while.
CAPITULO CAPITULO CAPITULO CAPITULO 2 2 2 2 PROGRAMACION CON C#
www.pedrov.phpnet.us
38383838
/* Archivo: Ejemplo29.cs */
using System;
public class Contrasena
{
static void Main()
{
// Declaración de variables
string contrasena = "tangua";
string cadena = "";
// Hacer lectura de cadena mientras....
do
{
Console.Write("Ingrese la contraseña: ");
cadena = Console.ReadLine();
cadena = cadena.ToLower() // convierte la cadena a minúsculas
} while (cadena != contrasena);
// La contraseña fue correcta, mostrar un mensaje
Console.WriteLine("Contraseña correcta... Bienvenido");
}
}
Al ejecutar este programa solicita al usuario escribir una contraseña. Si el usuario
escribe una palabra incorrecta, diferente a tangua, el programa volverá a pedir la
contraseña, y repetirá esta acción hasta que se escriba la contraseña correcta. Es
importante destacar, que como se ha diseñado el programa, es necesario pedir el
ingreso de la contraseña antes de verificarla. Si la cadena es diferente a la contraseña
preestablecida se vuelve a repetir el ciclo.
El método ToLower se encarga de convertir la cadena sobre la cual se aplica, a
minúsculas. De esta forma el usuario puede ingresar su contraseña en mayúsculas o
minúsculas e igual el programa la aceptará.
Sentencia for
La sentencia for se encarga de repetir un conjunto de instrucciones un número definido
de veces. En la teoría general de algoritmos esta estructura se utiliza solo para casos en
que se conoce exactamente el número de veces que debe repetirse el ciclo, pero en C#
y otros lenguajes similares se ha ampliado este concepto, y su ejecución depende de
una condición, semejante a como funciona while. En cualquier caso, una estructura
while puede ser convertida a una estructura for, o viceversa.
La estructura general de for es,
for (inicialización; condición; variación)
{
instrucciones;
}
La sección de inicialización es donde se especifican los valores iniciales de la variable
o variables que influyen sobre la condición. La condición es una expresión booleana
que controla la repetición. Si la condición devuelve verdadero (true), se ejecutan las
instrucciones, de lo contrario se sale del ciclo. La variación está conformada por
operaciones que se aplican a la variable o variables de control, ya sea incrementando su
valor o disminuyéndolo.
En la mayoría de los casos los programadores utilizan la versión básica de esta
estructura, en la cual interviene una sola variable de control. Así:
CAPITULO CAPITULO CAPITULO CAPITULO 2222: EL LENGUAJE C#
39393939
for (v = valorinicial; condición; variación(v))
{
instrucciones;
}
En este caso v es una variable, generalmente numérica y la condición depende del
valor que vaya adquiriendo v.
En general la estructura de control for permite incluir en la sección de inicialización
más de una variable, separadas por comas. De igual manera en la sección de variación
se pueden incluir una o más operaciones que modifiquen el valor de las respectivas
variable. Así, por ejemplo si se utilizan dos variables, v1 y v2, se tendría una
estructura como la siguiente:
for (v1 = ini1, v2 = ini2; condición; var(v1), var(v2))
{
instrucciones;
}
Ejemplo 2.10 Cadena de decenas
El programa de este ejemplo va a imprimir una cadena de texto formada por todas las
decenas comprendidas entre 10 y 500. En este caso se necesita una variable cuyo valor
inicie en 10 y se vaya incrementando de 10 en 10 hasta llegar a 500. La estructura for
permite implementar la secuencia de una forma clara y efectiva.
/* Archivo: Ejemplo210.cs */
using System;
public class Decenas
{
static void Main()
{
string decenas = "";
// Repetir desde i = 10 hasta 500...
for (int i = 10; i <= 500; i += 10)
{
// Formar una cadena con las decenas
decenas = decenas + i.ToString() + ", ";
}
// Mostrar la cadena de las decenas
Console.WriteLine(decenas);
}
}
El programa imprime en pantalla una cadena de números de 10 en 10. la primera vez
que se ejecuta la sentencia for inicializa la variable i en el valor 10, comprueba que el
valor sea menor que 500 y si esto se cumple ejecuta el bloque de instrucciones, que en
este caso consiste en asignar a la variable decenas el valor de i convertido al tipo
string. En la siguiente ejecución del ciclo, primero se aplica la variación a la variable
i, incrementando su valor en 10, luego se comprueba la condición y se ejecuta la
instrucción que conforma el cuerpo de la estructura. Cuando i asuma el valor 510,
inmediatamente se da por terminada la ejecución de la estructura de control y se
continúa con la instrucción que se encuentra por debajo de esta. En este caso se
imprime la cadena en pantalla.
Se ha utilizado el método, ToString, que está incluido en todos los objetos de C# , en
particular en la clase Int32 que define el tipo int. Este método se encarga de devolver
CAPITULO CAPITULO CAPITULO CAPITULO 2 2 2 2 PROGRAMACION CON C#
www.pedrov.phpnet.us
40404040
una representación en cadena del objeto sobre el cual se aplica. En este caso dicha
representación corresponde al valor que representa el entero.
Ejemplo 2.11 Regla de los simétricos de una secuencia de enteros
Existe un problema clásico de cálculo que consiste en determinar la suma desde 0 hasta
cierto valor entero dado (supongamos hasta 1000). Para quienes manejan unos
mínimos conocimientos de Cálculo, la solución a este tipo de problemas puede resultar
trivial, pero para la mayoría de las personas, este puede ser un problema de difícil
solución. Sin embargo existe una propiedad que cumplen todas las secuencias de
números y que aplicándola nos facilitará encontrar la suma tan solo con la ayuda de un
pedazo de papel y un lápiz.
Tomaremos la secuencia de números, la partimos a la mitad, colocando en forma
invertida una de las mitades con respecto a la otra, sumamos los números consecuentes
y ponemos al descubierto la regla matemática que se oculta detrás de todas estas
sucesiones. Para encontrarla, compile y ejecute este programa y todo quedará al
descubierto.
/* Archivo: Ejemplo211.cs */
using System;
public class ReglaSecuencias
{
static void Main()
{
int numero = 0;
int suma = 0;
Console.Write("Escriba un número entero: ");
numero = Convert.ToInt32(Console.ReadLine());
// Para j >= i hacer...
for (int i = 0, j = numero; j >= i; i++, j--)
{
suma = i + j;
Console.WriteLine("{0} \t + \t {1} \t = \t {2} ", i, j, suma);
}
}
}
Para empezar ejecute el programa e ingresando un numero impar, por ejemplo el valor
9. Obtenemos una salida como la siguiente:
Escriba un número entero: 9
0 + 9 = 9
1 + 8 = 9
2 + 7 = 9
3 + 6 = 9
4 + 5 = 9
Si repetimos la ejecución ingresando un número par, como por ejemplo 12, se obtiene:
Escriba un número entero: 12
0 + 12 = 12
1 + 11 = 12
2 + 10 = 12
3 + 9 = 12
4 + 8 = 12
5 + 7 = 12
6 + 6 = 12
CAPITULO CAPITULO CAPITULO CAPITULO 2222: EL LENGUAJE C#
41414141
En ambos casos observamos que la suma de los números simétricos respecto a la
mitad, reproduce el número original dado. El lector puede comprobar que para el caso
de los impares, la suma total de la secuencia se obtiene multiplicando el número dado
por la cantidad de sumas que se han realizado, la cual es igual al numero más 1
dividido entre 2 (en este caso 5). Para los números pares se aplica la misma regla, pero
teniendo en cuenta que la cantidad de sumas se obtienen sumando 2 al numero dado, y
restando el valor medio, que siempre se va a repetir la última suma (en este caso 6).
Sentencia foreach
La sentencia foreach repite un grupo de instrucciones para cada elemento que hace
parte de una colección o de una matriz.
Sentencia break
Una sentencia break se encarga de finalizar la ejecución de una estructura de control.
Esta sentencia únicamente actúa sobre la estructura de control que la contiene
directamente. En el caso de existir un anidamiento, de estructuras repetitivas, como por
ejemplo,
for (int i =0; i < 50; i++)
{
for (int j = 0; j < 10; j++)
{
if (i + j == 50) break;
}
}
break da por terminada la ejecución del for interno, controlado por la variable j,
dejando que continúe la ejecución del for externo.
Sentencia continue
De la misma manera como puede desearse salir prematuramente de un ciclo repetitivo,
también puede desearse continuar dentro del bucle pero sin ejecutar algunas o todas las
instrucciones que hagan falta. La sentencia continue se encarga de evitar que se
ejecuten las instrucciones que hacen parte de una estructura de control y que están a
continuación de la sentencia, pero dejando que siga la ejecución de la estructura.
CAPITULO CAPITULO CAPITULO CAPITULO 2 2 2 2 PROGRAMACION CON C#
www.pedrov.phpnet.us
42424242