Capítulo 2 EL LENGUAJE C

July 5, 2017 | Autor: M. Có Panaloj | Categoría: Automata, Método, Propiedad, Objeto, Herencia, Clase, Expresión, Modularidad, C, C Sharp, Clase, Expresión, Modularidad, C, C Sharp
Share Embed


Descripción

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.

16

CAPITULO 2 PROGRAMACION CON C#

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 www.pedrov.phpnet.us

CAPITULO 2: EL LENGUAJE C#

17

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.

[email protected]

18

CAPITULO 2 PROGRAMACION CON C#

/* 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#

www.pedrov.phpnet.us

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

19

CAPITULO 2: EL LENGUAJE C#

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.

Ejemplo 2.2 Rango de valores manejado por cada tipo 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. /* 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); } }

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: Byte: Byte: Byte: Byte:

False y True 0 a 255 a ? 01/01/0001 12:00:00 a.m. a 31/12/9999 11:59:59 p.m. -79228162514264337593543950335 a 79228162514264337593543950335 [email protected]

20

CAPITULO 2 PROGRAMACION CON C#

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:

www.pedrov.phpnet.us

CAPITULO 2: EL LENGUAJE C#

Nombre

21

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.

[email protected]

22

CAPITULO 2 PROGRAMACION CON C#

/* 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; // mayusculas = cadena.ToUpper(); // minusculas = cadena.ToLower(); // subcadena = cadena.Substring(2,5); // posicionCaracter = cadena.IndexOf(caracter, 1);// // 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); } }

Calcula la longitud Convierte a mayúsculas Convierte a minúsculas Toma un trozo de la cadena Posición en la cadena

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.

www.pedrov.phpnet.us

CAPITULO 2: EL LENGUAJE C#

23

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.

Sistema IntelliSense utilizado por entornos de programación como Sharpdevelop y VisualStudio .NET

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.

[email protected]

24

CAPITULO 2 PROGRAMACION CON C#

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' '\n'

// Carácter a // 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 int NumeroPersonas

// una variable local // 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.

www.pedrov.phpnet.us

CAPITULO 2: EL LENGUAJE C#

25

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; [email protected]

26

CAPITULO 2 PROGRAMACION CON C#

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); } } www.pedrov.phpnet.us

CAPITULO 2: EL LENGUAJE C#

27

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 a a a a

+ * / %

b b b b b

= = = = =

13 7 30 3 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 [email protected]

28

CAPITULO 2 PROGRAMACION CON C#

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

=

Mayor o igual que

!=

Diferente de

==

Igual a

Operadores lógicos

A

NOT

V F

F V

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

A

B

AND

V V F F

V F V F

V F F F

A

B

OR

V V F F

V F V F

V V V F

A

B

XOR

V V F F

V F V F

F V V F

A

B

&&

V V F F

V F ? ?

V F F F

A

B

||

V V F F

? ? V F

V V V F

Tablas de verdad para los operadores lógicos

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.

www.pedrov.phpnet.us

29

CAPITULO 2: EL LENGUAJE C#

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 derecha

A

B

&

1 1 0 0

1 0 1 0

1 0 0 0

A

B

|

1 1 0 0

1 0 1 0

1 1 1 0

A

B

^

1 1 0 0

1 0 1 0

0 1 1 0

Operaciones boolenas a nivel de bits

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 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

[email protected]

30

CAPITULO 2 PROGRAMACION CON C#

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,

www.pedrov.phpnet.us

CAPITULO 2: EL LENGUAJE C#

31

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.

[email protected]

32

CAPITULO 2 PROGRAMACION CON C#

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 www.pedrov.phpnet.us

CAPITULO 2: EL LENGUAJE C#

33

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:

[email protected]

34

CAPITULO 2 PROGRAMACION CON C#

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); } }

www.pedrov.phpnet.us

35

CAPITULO 2: EL LENGUAJE C#

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. [email protected]

36

CAPITULO 2 PROGRAMACION CON C#

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 csc /out:sumarhasta.exe ejemplo28.cs

www.pedrov.phpnet.us

CAPITULO 2: EL LENGUAJE C#

37

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. [email protected]

38

CAPITULO 2 PROGRAMACION CON C#

/* 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í:

www.pedrov.phpnet.us

CAPITULO 2: EL LENGUAJE C#

39

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 = 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 = 1 + 8 = 2 + 7 = 3 + 6 = 4 + 5 =

9 9 9 9 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 = 1 + 11 = 2 + 10 = 3 + 9 = 4 + 8 = 5 + 7 = 6 + 6 = www.pedrov.phpnet.us

12 12 12 12 12 12 12

CAPITULO 2: EL LENGUAJE C#

41

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.

[email protected]

42

www.pedrov.phpnet.us

CAPITULO 2 PROGRAMACION CON C#

Lihat lebih banyak...

Comentarios

Copyright © 2017 DATOSPDF Inc.