c# aprenda a programar

404
por Nicolás Arrioja Landa Cosio

Upload: yuri-barzola

Post on 12-Jun-2015

1.881 views

Category:

Education


10 download

DESCRIPTION

Programación .net

TRANSCRIPT

Page 1: C# aprenda a programar

This book is a full C# learning course. Aimedfor those who want to migrate to thislanguage, as well as for those who want tolearn programming, even if they do not haveprevious knowledge on the subject.

C# 2010

Este libro es un completo curso de programación en C#, actualizado a la ver-

sión 4.0, incluida en Visual Studio 2010. Es ideal tanto para quienes desean

migrar a este potente lenguaje, como para quienes quieran aprender a pro-

gramar, incluso, sin tener conocimientos previos.

C# es el lenguaje más utilizado en la actualidad, por ser poderoso, flexible y

robusto. En esta obra cubriremos desde las bases de la programación estruc-

turada hasta los fundamentos de la orientada a objetos, sin dejar de apren-

der el manejo de estructuras complejas, como los archivos y las clases.

Nicolás Cosio aporta su vasta experiencia y la didáctica comprobada de sus obras

previas, para facilitar al lector la tarea de comprender cómo se logra desarrollar

código optimizado destinado a obtener aplicaciones poderosas y eficientes.

Una obra imprescindible para fundar bases sólidas en el desarrollo y apren-

der a programar de la mejor manera.

Versión completamente mejorada, actualizada y ampliada de la obra "Curso de programación C#"

por Nicolás Arrioja Landa Cosio

CONTENIDO

N I V E L D E U S U A R I O

PRINCIPIANTE INTERMEDIO AVANZADO EXPERTO

1 | C# Y .NETProgramación para Windows / Comprender .NET /Compilador de C# / El ambiente de desarrollo

2 | LOS ELEMENTOS BÁSICOS DE UN PROGRAMALenguajes / Errores en los programas / Las variables /Comentarios / Precedencia de operadores / Pedido de datos

3 | EL PROGRAMA TOMA DECISIONESLa toma de decisiones / Expresiones y operadoresrelacionales / El uso de if y else / If anidados / Escalera de if-else / Expresiones lógicas / El uso de switch

4 | CREACIÓN DE CICLOSEl ciclo for / El valor de inicio / Límite de conteo / Control de incremento / El contador y el acumulador / Incrementos y decrementos / El ciclo while y do while

5 | FUNCIONES Y MÉTODOSLas funciones / Tipos de funciones / Optimizar con funciones/ Pasaje de parámetros por copia y paso por referencia

6 | LOS ARREGLOSDeclaración de arreglos / Asignación y uso de valores /Acceso a arreglos / Arreglos de tipo jagged

7 | LAS COLECCIONESArrayList / Declaración / Agregar información / El cicloforeach / Stack / Queue / Hashtable

8 | LAS CADENASEl método ToString() / StringBuilder / Justificación del texto /Intercambio entre mayúsculas y minúsculas

9 | ESTRUCTURAS Y ENUMERACIONESDefinición / Crear variables del nuevo tipo / Acceso a laestructura / Creación de un constructor

10 | CÓMO CREAR NUESTRAS PROPIAS CLASESProgramación orientada a objetos / Clases / Datos / Métodos/ Protección de datos / Métodos públicos y privados

CAPÍTULO 11: FLUJOS Y ARCHIVOSLos flujos / Streams en memoria / Uso de archivos

CAPÍTULO 12: DEPURACIÓNCómo depurar un programa / Errores de compilación /Errores en tiempo de ejecución / Manejo de errores / Erroresde lógica / Detener la ejecución

C#

En este sitio encontrará una gran variedad de recursos y software relacionado, quele servirán como complemento al contenido del libro. Además, tendrá la posibili-dad de estar en contacto con los editores, y de participar del foro de lectores, endonde podrá intercambiar opiniones y experiencias.

Si desea más información sobre el libro puede comunicarse connuestro Servicio de Atención al Lector: [email protected]

GUÍA TOTAL DEL PROGRAMADOR

Tapa C#.qxp 29/07/2010 16:15 PÆgina 1

Page 2: C# aprenda a programar

>> DESARROLLO / MICROSOFT>> 400 PÁGINAS>> ISBN 978-987-1347-74-2

>> DESARROLL>> 400 PÁGINA>> ISBN 978-98

>> DESARROLLO / INTERNET>> 400 PÁGINAS>> ISBN 978-987-1347-70-4

>> DESARROLL>> 400 PÁGINA>> ISBN 978-98

>> DESARROLLO / INTERNET>> 368 PÁGINAS>> ISBN 978-987-663-039-9

>> DESARROLL>> 368 PÁGINA>> ISBN 978-98

>> DESARROLLO>> 336 PÁGINAS>> ISBN 978-987-1347-97-1

>> DESARROLL>> 336 PÁGINA>> ISBN 978-98

Bombo - RT - LIBRO C# 2010 - Jul 10 - EDITABLE.indd 1Bombo - RT - LIBRO C# 2010 - Jul 10 - EDITABLE.indd 1 28/07/2010 15:58:3428/07/2010 15:58:34

Page 3: C# aprenda a programar

C#GUÍA TOTALDEL PROGRAMADOR

por Nicolás Arrioja Landa Cosio

00_C#2010.qxd 8/11/10 9:41 AM Page 1

Page 4: C# aprenda a programar

TÍTULO: C#

AUTOR: Nicolás Arrioja Landa Cosio

COLECCIÓN: Manuales USERS

FORMATO: 17 x 24 cm

PÁGINAS: 400

Copyright © MMX. Es una publicación de Fox Andina en coedición con Gradi S.A. He-cho el depósito que marca la ley 11723. Todos los derechos reservados. No se permi-te la reproducción parcial o total, el almacenamiento, el alquiler, la transmisión o latransformación de este libro, en cualquier forma o por cualquier medio, sea electró-nico o mecánico, mediante fotocopias, digitalización u otros métodos, sin el permisoprevio y escrito del editor. Su infracción está penada por las leyes 11723 y 25446. Laeditorial no asume responsabilidad alguna por cualquier consecuencia derivada dela fabricación, funcionamiento y/o utilización de los servicios y productos que se des-criben y/o analizan. Todas las marcas mencionadas en este libro son propiedad ex-clusiva de sus respectivos dueños. Impreso en Argentina. Libro de edición argentina.Primera impresión realizada en Sevagraf, Costa Rica 5226, Grand Bourg, MalvinasArgentinas, Pcia. de Buenos Aires en VIII, MMX.

IISSBBNN 997788--998877--2266001133--55--55

Landa Cosio, Nicolás ArriojaC#. - 1a ed. - Buenos Aires : Fox Andina; Gradi; Banfield - Lomas de Zamora, 2010.400 p. ; 24x17 cm. - (Manual Users; 195)

ISBN 978-987-26013-5-5

1. Informática. I. TítuloCDD 005.3

00_C#2010.qxd 8/11/10 9:41 AM Page 2

Page 5: C# aprenda a programar

REDISEÑO BOMBOS LIBROS - PAG 01 - Base Editable - Nov 09.indd 1REDISEÑO BOMBOS LIBROS - PAG 01 - Base Editable - Nov 09.indd 1 08/03/2010 11:00:2008/03/2010 11:00:20

Page 6: C# aprenda a programar

4

PRELIMINARES

www.redusers.com

Nicolás Arrioja Landa Cosio

Catedrático de IUNIVERTECH y de la Universidad Madero, ele-gido el mejor profesor de los ciclos 2006-2007 y 2007-2008, se de-dica a la investigación, consulta y capacitación en áreas relacionadascon la realidad virtual, la visualización científica y los videojuegos. En 1997, desarrolló el primer videojuego de realidad virtual in-mersiva en Latinoamérica, conocido como VRaptor. Tambiéndesarrolló el primer lenguaje de programación para realidad vir-tual en Latinoamérica CND-VR, que es usado en el medioacadémico para enseñar de forma sencilla los conceptos de pro-

gramación de gráficas 3D. Ha sido catedrático en algunas de las universidades másimportantes de México durante más de diez años. En esas instituciones enseñó des-de las bases de programación en lenguaje C hasta Inteligencia Artificial. Ha otor-gado más de 25 conferencias relacionadas con el desarrollo de la realidad virtual ylos videojuegos en diversas universidades de México. Tiene una patente referida ainterfaces cinemáticas para video juegos. Diseñó el plan y el programa de estudiospara la Maestría en Realidad Virtual y Video Juegos en IUNlVERTECH. Es au-tor del los libros DirectX, Inteligencia Artificial y Robótica Avanzada de esta mis-ma editorial. Actualmente, realiza una investigación sobre Inteligencia Artificialno-Algorítmica y tiene disposición a realizar investigación y dar conferencia en es-tas áreas en cualquier parte del mundo.

Dedicatoria

A María Eugenia Pérez Duarte por todo su apoyo y gran amistad.

Agradecimientos

A todas aquellas personas que hace 25 años me introdujeron a la programación decomputadoras y me enseñaron las bases de esta disciplina. De Sistem Club al Ing.Alfonso Fernández de la Fuente y a Jacky, Annie y David Fox, Herbert Schildt yKris Jamsa. Un agradecimiento especial a mis alumnos y al equipo de la editorial.

00_C#2010.qxd 8/6/10 8:14 PM Page 4

Page 7: C# aprenda a programar

PRÓLOGO

La facilidad con que hoy en día se tiene acceso a una computadora ha llevado a las per-sonas a emplearlas en gran cantidad de actividades, usando para ello software que rea-liza tareas específicas. Cuando se requiere que la computadora realice otro tipo de ac-ciones y los programas con los que se cuenta no lo hacen, es necesario decirle en su pro-pio idioma cómo deberá actuar, y para esto se recurre a los lenguajes de programación.Los lenguajes de programación intentan parecerse a nuestra propia forma de expre-sarnos, para ello cuentan con características propias de sintaxis y semántica, así co-mo símbolos que permiten decirle a la computadora qué procesos y qué datos de-be manejar, cómo almacenarlos, qué acciones realizar con ellos y cómo presentarlosal usuario. Por esta razón es importante contar con una metodología que permitaaprender hábitos correctos y efectivos para resolver problemas, los cuales, al ser sub-divididos para su mejor comprensión, facilitarán su resolución.Una vez que se ha comprendido el problema, se construye una secuencia de los pa-sos a realizar, mejor conocida como algoritmo, el cual permitirá probar si la lógicaes correcta y si los resultados que se obtendrán serán los adecuados. El potencial delos actuales lenguajes de programación es enorme, ya que permiten automatizar muydiversos tipos de actividades, disminuyendo de ese modo el tiempo que se invierteal hacerlo de forma manual y, si se aprende a usarlos correctamente, se podrá hacermás sencilla la vida de los usuarios que emplean dichos programas.La experiencia adquirida en el desarrollo de sistemas por parte del Dr. Nicolás Arriojalo ha convertido en una autoridad en cuanto a programación y buenas prácticas, com-partiéndolas y enseñando a alumnos de diferentes instituciones de nivel superior, conresultados excelentes. Es por eso que esta nueva versión del libro podrá guiar paso a pa-so al lector en el uso del poderoso lenguaje de programación C# del Visual Studio 2010,de modo que al finalizar su aprendizaje, esté listo para hacer sus propios programas.Aprender a programar es una tarea que requiere práctica y paciencia, pero tam-bién es una actividad fascinante, y si además se cuenta con un excelente libro yla constancia necesaria, los resultados serán excelentes. ¡Felicidades por este nue-vo reto que está por comenzar!

María Eugenia Pérez DuarteMaestra en Administración de Tecnologías de Información

Coordinadora de Ingenierías en Sistemas Computacionales y Desarrollo de Software

Universidad Madero de Méjico

Prólogo

5www.redusers.com

00_C#2010.qxd 8/6/10 8:14 PM Page 5

Page 8: C# aprenda a programar

PRELIMINARES

6 www.redusers.com 6

EL LIBRO DE UN VISTAZOEl desarrollo de aplicaciones con C# se ha visto modificado en los últimos tiempos,

y este libro apunta a afianzar los conocimientos indispensables que nos permitirán generar

aplicaciones profesionales de nivel. Cada capítulo está dedicado a una técnica específica e

ilustrado mediante ejemplos prácticos listos para implementar.

Capítulo 1

C# Y .NET

Este capitulo nos introduce a la historia del

desarrollo de los programas para Windows y

cómo el Framework de .NET ayuda a resolver

muchos problemas. Aprenderemos cómo

crear y ejecutar nuestro primer programa.

Capítulo 2

LOS ELEMENTOS BÁSICOS DE UN

PROGRAMA

Aprender cómo resolver problemas en la

computadora es aún más importante que

conocer la sintaxis de un lenguaje. Aquí

aprenderemos los elementos básicos de un

programa, pero también la metodología para

diseñar buenos programas desde el inicio.

Capítulo 3

EL PROGRAMA TOMA DECISIONES

Los programas de computadora necesitan

lógicas complejas, por lo que es importante

conocer las estructuras necesarias que nos

permitirán decirle a la computadora cómo

tomar una decisión.

Capítulo 4

CREACIÓN DE CICLOS

Los ciclos nos permiten repetir algo un

número de veces. Los diferentes tipos de

ciclos, sus partes y aplicaciones serán

enseñados en este capítulo.

Capítulo 5

FUNCIONES Y MÉTODOS

Las funciones y los métodos nos brindan

flexibilidad y la capacidad de poder volver a

utilizar código fácilmente, y también nos

ayudan a ordenar nuestros desarrollos, y

facilitan su mantenimiento.

Capítulo 6

LOS ARREGLOS

Los arreglos, muy útiles en todos los casos,

nos permiten administrar la información de

una manera fácil y práctica, como si

trabajásemos con una planilla de cálculo. En

este capítulo estudiaremos arreglos de una y

dos dimensiones, y por supuesto no

dejaremos de lado los arreglos de tipo jagged.

Capítulo 7

LAS COLECCIONES

Las colecciones son estructuras de datos

que nos permiten trabajar con grupos de

información. Veremos aquellas más

importantes, como el ArrayList, Stack,

Queue y Hashtable.

Capítulo 8

LAS CADENAS

Las cadenas permiten guardar y manipular

texto o frases. C# nos provee de éstas para

su manejo. Aprenderemos cómo hacer uso

de las cadenas y trabajar con ellas.

00_C#2010.qxd 8/6/10 8:14 PM Page 6

Page 9: C# aprenda a programar

www.redusers.com

El libro de un vistazo

7

Capítulo 9

ESTRUCTURAS Y ENUMERACIONES

En este capítulo aprenderemos cómo crear

nuestros propios tipos por medio de las

estructuras y enumeraciones. Las

estructuras también nos permiten agrupar la

información de una manera óptima, lo cual

nos ayuda a manejarla más fácilmente.

Capítulo 10

CÓMO CREAR NUESTRAS PROPIAS CLASES

En este capítulo empezaremos a conocer los

conceptos de la programación orientada a

objetos, lo más utilizado hoy en día. Podremos

crear nuestras propias clases y nuestros

propios objetos, y también trabajaremos con

métodos definidos en las clases.

Capítulo 11

FLUJOS Y ARCHIVOS

Es muy frecuente que necesitemos guardar

información desde un programa al disco. Por

medio de los flujos y los archivos lo podemos

hacer. Guardaremos y leeremos cadenas, y

veremos que la manipulación de archivos

también es posible.

Capítulo 12

DEPURACIÓN

La depuración nos permite corregir los

problemas que tiene un programa.

Conoceremos los tipos de errores y cómo

usar el depurador para eliminarlos.

También aprenderemos cómo administrar

las excepciones de la mejor manera .

!A lo largo de este manual encontrará una serie de recuadros que le brindarán información com-

plementaria: curiosidades, trucos, ideas y consejos sobre los temas tratados.

Cada recuadro está identificado con uno de los siguientes iconos:

INFORMACIÓN COMPLEMENTARIA

CURIOSIDADES

E IDEAS

DATOS ÚTILES

Y NOVEDADES

ATENCIÓN SITIOS WEB

00_C#2010.qxd 8/6/10 8:14 PM Page 7

Page 10: C# aprenda a programar

PRELIMINARES

8 www.redusers.com

Sobre el autor 4

Prólogo 5

El libro de un vistazo 6

Introducción 12

Capítulo 1

C# Y .NET

Breve historia de la programación

para Windows 14

Descubrir .NET 15

Cómo crear una aplicación .NET 17

Conseguir un compilador de C# 18

El ambiente de desarrollo 18

Crear nuestra primera aplicación 19

Resumen 29

Actividades 30

Capítulo 2

LOS ELEMENTOS BÁSICOS

DE UN PROGRAMA

Los lenguajes de programación 32

Los programas de computadora 32

Las variables 42

Operaciones aritméticas 49

Cómo pedirle datos al usuario 56

Cómo resolver problemas

en la computadora 60

Resolución de problemas

en la computadora 64

Resumen 69

Actividades 70

Pedir ancho

Pedir alto

Mostrar área

Mostrar

perímetro

Área = ancho • alto

Perímetro =

(ancho + alto) • 2

Inicio

Fin

CONTENIDO

00_C#2010.qxd 8/6/10 8:14 PM Page 8

Page 11: C# aprenda a programar

Contenido

9www.redusers.com

Capítulo 3

EL PROGRAMA TOMA DECISIONES

La toma de decisiones 72

Expresiones relacionales 72

El uso de if 76

El uso de else 84

Cómo usar if anidados 89

Escalera de if-else 92

Expresiones lógicas 96

El uso de switch 105

Resumen 109

Actividades 110

Capítulo 4

CREACIÓN DE CICLOS

El ciclo for 112

El valor de inicio 117

El límite de conteo del ciclo 119

Control del incremento 121

Ejemplos con el ciclo for 128

El ciclo do while 134

El ciclo while 141

Resumen 145

Actividades 146

Pedir dividendo

Pedir divisor

Mostrar resultado

Inicio

Fin

Resultado =

dividendo/divisor

Divisor!=0SÍ

NO

Capítulo 5

FUNCIONES Y MÉTODOS

Las funciones 148

Funciones que ejecutan código 150

Funciones que regresan un valor 156

Funciones que reciben valores 159

Funciones que reciben parámetros

y regresan un valor 162

Optimizar con funciones 171

Paso por copia y paso por referencia 178

Resumen 185

Actividades 186

R=a+b

Pedimos b

Mostramos r

Pedimos a

Inicio

Fin

Condición

NO

Código

00_C#2010.qxd 8/6/10 8:14 PM Page 9

Page 12: C# aprenda a programar

PRELIMINARES

10 www.redusers.com

Capítulo 6

LOS ARREGLOS

Los arreglos 188

Declaración de los arreglos

de una dimensión 189

Asignación y uso de valores 191

Arreglos de dos dimensiones 196

Arreglos de tipo jagged 205

Los arreglos como parámetros

a funciones 212

Resumen 215

Actividades 216

Capítulo 7

LAS COLECCIONES

Las colecciones más importantes 218

El ArrayList 218

El Stack 232

El Queue 241

El Hashtable 249

Resumen 253

Actividades 254

Inicialización

Inicio

Fin

Condición

NO Código

Incremento

Capítulo 8

LAS CADENAS

El uso de las cadenas 256

Cómo declarar la cadena 256

El método ToString() 256

Cómo convertir y formatear

fechas a cadenas 257

Para darles formato a valores

numéricos 259

Cómo concatenar cadenas 260

Uso de StringBuilder 261

Comparación de cadenas 263

Para encontrar una subcadena 264

Para obtener una subcadena 265

Para determinar si una cadena

finaliza en una subcadena 266

Cómo copiar una parte de la cadena 267

Cómo insertar una cadena 268

Para encontrar la posición de una

subcadena 269

Justificación del texto 270

Para eliminar caracteres de la cadena 271

Cómo reemplazar una subcadena 271

Cómo dividir la cadena 272

Intercambiar mayúsculas y minúsculas 273

Cómo podar la cadena 275

Resumen 277

Actividades 278

'H' 'o' 'l' 'a'

'H' 'o' 'l' 'a'

'' 'm' 'u' 'n'

'm' 'u' 'n' 'd' 'o'

'r' 'n''o''e' 'd' 'o''d'

00_C#2010.qxd 8/6/10 8:14 PM Page 10

Page 13: C# aprenda a programar

Contenido

11www.redusers.com

Capítulo 9

ESTRUCTURAS Y ENUMERACIONES

Las estructuras 280

Cómo definir una estructura 280

Cómo crear una variable del nuevo tipo 282

Cómo acceder a los campos

de la estructura 283

Cómo mostrar los campos

de la estructura 283

Creación de un constructor

para la estructura 286

Estructuras enlazadas 299

Las enumeraciones 309

Resumen 315

Actividades 316

Capítulo 10

CÓMO CREAR NUESTRAS PROPIAS CLASES

La programación orientada a objetos 318

Las clases 318

Cómo declarar la clase y los datos 320

Cómo crear la instancia

de nuestra clase 324

Cómo asignarles valores

a datos publicos 324

Cómo invocar métodos de un objeto 325

Cómo imprimir un dato público 325

Protección de datos

y creación de propiedades 329

Cómo acceder a las propiedades 333

Métodos públicos y privados 333

Agenda Nombre: String

Dirección: String

Teléfono: String

Edad: Int

Convertir un objeto a cadena 334

El constructor en las clases 336

Sobrecarga del constructor 339

Resumen 347

Actividades 348

Capítulo 11

FLUJOS Y ARCHIVOS

Los flujos 350

Los stream en la memoria 351

El uso de archivos 363

Resumen 371

Actividades 372

Capítulo 12

DEPURACIÓN

Cómo empezar a depurar un programa 374

Corregir los errores de compilación 374

Cómo corregir los errores

en tiempo de ejecución 379

Cómo manejar los errores 383

Resumen 391

Actividades 392

Tamaño

Capacidad

P. Actual

H O L A A T O D O

Cubo

+ lado: int

+ área: int

+ volumen: int

+ CalculaArea() : void

+ CalculaVolumen() : void

00_C#2010.qxd 8/6/10 8:14 PM Page 11

Page 14: C# aprenda a programar

PRELIMINARES

12 www.redusers.com

INTRODUCCIÓN

La programación de computadoras es una actividad fascinante, el poder haceruna aplicación a la medida y de acuerdo a nuestras necesidades es una actividadinteresante y llena de recompensas. Mucha gente llega a pensar que solamentecon aprender la sintaxis de un lenguaje de programación es suficiente para po-der hacer programas, pero se equivocan. Aun más importante que la sintaxis dellenguaje es la técnica de resolución del problema y el análisis adecuado. El tenerbuenos hábitos de análisis y programación desde el inicio es fundamental paraconvertirnos en buenos programadores.

Una de los lenguajes que está adquiriendo gran popularidad es C#, un lenguaje sen-cillo, amigable y poderoso. Con C# se pueden crear todo tipo de aplicaciones, des-de programas de consola para Windows y para páginas web en unión con ASP, has-ta video juegos para Xbox 360 con XNA.

El presente libro introduce a cualquier persona, aun sin conocimientos de progra-mación, al lenguaje C#. Esta obra está actualizada para Visual Studio 2010 y el Fra-mework de .NET 4.0. En un inicio veremos la forma de realizar el análisis de unproblema e iremos construyendo el conocimiento hasta llegar a las bases de la pro-gramación orientada a objetos y, por supuesto, la depuración.

El convertirse en un buen programador requiere de mucha práctica y experi-mentación, pero también de una guía adecuada que vaya construyendo paso apaso las habilidades necesarias. Esperamos que este libro sea de utilidad a todosaquellos que, aun sin experiencia en programación, tengan el deseo de aprendercomo hacer sus propios programas.

Nicolás Arrioja Landa Cosio

00_C#2010.qxd 8/6/10 8:14 PM Page 12

Page 15: C# aprenda a programar

C#.NET

Breve historia de la programación para Windows 14

Comprendiendo .NET 15Cómo se crea una aplicación .NET 16Cómo conseguir un compilador de C# 17El ambiente de desarrollo 18Cómo crear nuestra primera aplicación 19

Resumen 29Actividades 30

Capítulo 1

Este libro está dirigido a todas aquellas

personas que desean aprender

el lenguaje de programación C# y tienen

conocimientos básicos de programación

o no tienen ninguna experiencia previa

programando computadoras. El enfoque

del libro es guiar paso a paso

en el aprendizaje del lenguaje y aunque

C# es un lenguaje orientado a objetos,

en los primeros capítulos tomaremos una

filosofía estructurada con el fin de hacer

todavía más fácil el aprendizaje para

todos nosotros.

C#

SERVICIO DE ATENCIÓN AL LECTOR: [email protected]

01_C#2010_AJUSTADO.qxd 8/11/10 9:44 AM Page 13

Page 16: C# aprenda a programar

BREVE HISTORIA DE LA PROGRAMACIÓN

PARA WINDOWS

Hace algunos años la única forma como se podía programar para Windows erahacer uso de un compilador de C o C++ y de un API de Windows. El API esuna gran colección de funciones que se relacionan, las que nos permiten comu-nicarnos con el sistema operativo. Por medio del API de Win32 se programabanlas ventanas, botones y demás elementos. El problema de este tipo de programación es que el API de Win32 es realmente com-plejo y enorme. Con miles de funciones en su interior, por lo que pocos programa-dores podían conocerlo en su totalidad. Pero la complejidad no solamente estaba enla cantidad de funciones, también en la sintaxis y la forma como se programa.Para facilitar la programación de aplicaciones para Windows surgen diferentes op-ciones; la finalidad de estos intentos era poder hacer las aplicaciones sin tener quepasar por la complejidad de Win32. Uno de estos intentos fue conocido comoOWL; sin embargo, obtuvo más éxito MFC, creado por Microsoft. MFC es un conjunto de clases que envuelve a Win32 y facilita su programación.Con MFC los procesos más comunes se agrupan en funciones de tal forma que conuna simple llamada a una función de MFC se puede hacer una determinada tarea,para la que antes necesitábamos por lo menos 10 llamadas en Win32 y muchos pa-rámetros. Sin embargo Win32 está debajo de MFC; la programación MFC simpli-fica mucho las cosas, pero muchos programadores que venían del paradigma de pro-gramación estructurada no se sentían a gusto con él.Otra de las opciones que surgieron es Visual Basic, este lenguaje logró gran popu-laridad, especialmente en Latinoamérica. Visual Basic también trabaja por arriba deWin32, pero basa su sintaxis en el antiguo lenguaje Basic. Es muy sencillo de apren-der y una de las características que le dio gran popularidad fue la facilidad con laque se podían crear interfaces de usuario y conectividad a bases de datos. Pero has-ta antes de la versión .NET, este lenguaje tenía ciertos limitantes ya que no se po-día llevar a cabo programación orientada a objetos con él.Otro lenguaje que surge, pero con su propio Framework, es JAVA; su principalventaja es ser multiplataforma. Una de sus características es el uso de un runtime,la aplicación en lugar de correr directamente en el microprocesador, se ejecutaen un programa llamado runtime y este se encarga de ejecutar el código en el mi-croprocesador correspondiente. Si se tiene el runtime para Windows, sin pro-blema se ejecuta el programa de JAVA.Cuando nosotros deseábamos tener un programa que se pudiera ejecutar, era necesa-rio compilarlo. Cada uno de los lenguajes tenía su propio compilador, por ello no erasencillo poder compartir código de C++ con código de Visual Basic ya que el traducirentre lenguajes era difícil. Para poder compartir código entre los lenguajes surge un mo-

1. C#.NET

14 www.redusers.com

01_C#2010_AJUSTADO.qxd 8/6/10 8:15 PM Page 14

Page 17: C# aprenda a programar

delo conocido como COM, éste nos permite crear componentes binarios, esto quieredecir que es posible programar un componente en Visual Basic y un programador deC++ puede tomarlo y hacer uso de él. Esto se debe a que el componente ya es códigocompilado y no código fuente en el lenguaje de origen; la programación de COM tam-bién tenía sus complejidades y surge ATL para ayudar en su desarrollo.Con todo esto, llega el momento en el cual es necesario ordenar, facilitar y organi-zar el desarrollo de las aplicaciones para Windows, con esta filosofía surge .NET.

Descubrir .NETEl Framework de .NET es una solución a toda la problemática en torno al desa-rrollo de aplicaciones, brinda grandes beneficios no solamente al desarrollador, si-no también al proceso de desarrollo. En primer lugar .NET permite trabajar concódigo ya existente, podemos hacer uso de los componentes COM, e incluso, si lonecesitáramos usar el API de Windows. Cuando el programa .NET está listo es mu-cho más fácil de instalar en la computadora de los clientes, que las aplicaciones tra-dicionales ya que se tiene una integración fuerte entre los lenguajes. Un programador de C# puede entender fácilmente el código de un programador deVisual Basic .NET y ambos pueden programar en el lenguaje con el que se sientenmás cómodos. Esto se debe a que todos los lenguajes que hacen uso de .NET com-parten las librerías de .NET, por lo que no importa en qué lenguaje programemos,las reconocemos en cualquiera. A continuación conoceremos los diferentes compo-nentes de .NET: CLR, assembly y CIL.

CLREl primer componente de .NET que conoceremos es el Common LanguageRuntime, también denominado CLR. Este es un programa de ejecución común atodos los lenguajes. Este programa se encarga de leer el código generado por el com-pilador y empieza su ejecución. Sin importar si el programa fue creado con C#,con Visual Basic .NET o algún otro lenguaje de .NET el CLR lo lee y ejecuta.

AssemblyCuando tenemos un programa escrito en un lenguaje de .NET y lo compilamos se ge-nera el assembly. El assembly contiene el programa compilado en lo que conocemoscomo CIL y también información sobre todos los tipos que se utilizan en el programa.

CILLos programas de .NET no se compilan directamente en código ensamblador delcompilador, en su lugar son compilados a un lenguaje intermedio conocido comoCIL. Este lenguaje es leído y ejecutado por el runtime. El uso del CIL y el runtimees lo que le da a .NET su gran flexibilidad y su capacidad de ser multiplataforma.

Breve historia de la programación para Windows

15www.redusers.com

01_C#2010_AJUSTADO.qxd 8/6/10 8:15 PM Page 15

Page 18: C# aprenda a programar

El Framework de .NET tiene lo que se conoce como las especificaciones comunes delenguaje o CLS por sus siglas en inglés, estas especificaciones son las guías que cual-quier lenguaje que desee usar .NET debe de cumplir para poder trabajar con el runti-me. Una ventaja de esto es que si nuestro código cumple con las CLS podemos tenerinteroperabilidad con otros lenguajes, por ejemplo, es posible crear una librería en C#y un programador de Visual Basic .NET puede utilizarla sin ningún problema.Uno de los puntos más importantes de estás guías es el CTS o sistema de tiposcomunes. En los lenguajes de programación, cuando deseamos guardar informa-ción, ésta se coloca en una variable, las variables van a tener un tipo dependiendodel la información a guardar, por ejemplo, el tipo puede ser para guardar un nú-mero entero, otro para guardar un número con decimales y otro para guardar unafrase o palabra. El problema con esto es que cada lenguaje guarda la informaciónde manera diferente, algunos lenguajes guardan los enteros con 16 bits de memo-ria y otros con 32 bits; incluso algunos lenguajes como C y C++ no tienen un ti-po para guardar las cadenas o frases. Para solucionar esto el Framework de .NET define por medio del CTS cómo vana funcionar los tipos en su entorno. Cualquier lenguaje que trabaje con .NET de-be de usar los tipos tal y como se señalan en el CTS. Ahora que ya conocemos losconceptos básicos, podemos ver cómo es que todo esto se une.

Cómo se crea una aplicación .NETPodemos crear una aplicación .NET utilizando un lenguaje de programación, paraeste efecto será C#; con el lenguaje de programación creamos el código fuente delprograma (instrucciones que le dicen al programa qué hacer). Cuando hemos finalizado con nuestro código fuente, entonces utilizamos el com-pilador. El compilador toma el código fuente y crea un assembly para nosotros, es-te assembly tendrá el equivalente de nuestro código, pero escrito en CIL; esto noslleva a otra de las ventajas de .NET: nuestro código puede ser optimizado por elcompilador para la plataforma hacia la cual vamos a usar el programa, es decir queel mismo programa puede ser optimizado para un dispositivo móvil, una PC nor-mal o un servidor, sin que nosotros tengamos que hacer cambios en él.

1. C#.NET

16 www.redusers.com

El Framework de .NET se puede ejecutar en muchas plataformas, no solo en Windows. Esto

significa que podemos programar en una plataforma en particular y si otra plataforma tiene el

runtime, nuestro programa se ejecutará sin ningún problema. Un programa .NET desarrollado

en Windows puede ejecutarse en Linux, siempre y cuando se tenga el runtime correspondiente.

.NET ES MULTIPLATAFORMA

01_C#2010_AJUSTADO.qxd 8/6/10 8:15 PM Page 16

Page 19: C# aprenda a programar

Cuando nosotros deseamos invocar al programa, entonces el runtime entra en ac-ción, lee el assembly y crea para nosotros todo el entorno necesario. El runtimeempieza a leer las instrucciones CIL del assembly y conforme las va leyendo lascompila para el microprocesador de la computadora en la que corre el programa;esto se conoce como JIT o compilación justo a tiempo. De esta manera confor-me se avanza en la ejecución del programa se va compilando; todo esto ocurre demanera transparente para el usuario.El Framework de .NET provee, para los programas que se están ejecutando, losservicios de administración de memoria y recolector de basura. En lenguajesno administrados como C y C++ el programador es responsable de la adminis-tración de memoria, en programas grandes esto puede ser una labor complicada,que puede llevar a errores durante la ejecución del programa. Afortunadamentelenguajes administrados como C# tienen un modelo en el cual nosotros comoprogramadores ya no necesitamos ser responsables por el uso de la memoria. Elrecolector de basura se encarga de eliminar todos los objetos que ya no son ne-cesarios, cuando un objeto deja de ser útil el recolector lo toma y lo elimina. Deesta forma se liberan memoria y recursos. El recolector de basura trabaja de forma automática para nosotros y ayuda a elimi-nar toda la administración de recursos y memoria que era necesaria en Win32. Enalgunos casos especiales como los archivos, las conexiones a bases de datos o de redse tratan de recursos no administrados, para estos casos debemos de indicar explíci-tamente cuando es necesario que sean destruidos.

Cómo conseguir un compilador de C#Existen varias opciones de compiladores para C#, en este libro utilizaremos la ver-sión de C# que viene con Visual Studio 2010, pero también es posible utilizar ver-siones anteriores. Este compilador, al momento de publicación de este libro, utili-za la versión 4.0 del Framework. La mayoría de los ejemplos deben poder compi-larse y ejecutarse sin problema, aún utilizando versiones anteriores del Framework,esto es válido incluso para aquellos programadores que decidan trabajar con el lla-mado Mono, como alternativa libre y gratuita.

Breve historia de la programación para Windows

17www.redusers.com

Al compilador JIT también se le conoce como Jitter. Forma parte del runtime y es muy eficiente,

si el programa necesita volver a ejecutar un código que ya se ha compilado, el Jitter en lugar de

volver a compilar, ejecuta lo ya compilado, mejorando de esta forma el desempeño y los tiempos

de respuesta de cara al usuario.

EL COMPILADOR JIT

01_C#2010_AJUSTADO.qxd 8/6/10 8:15 PM Page 17

Page 20: C# aprenda a programar

Una mejor opción, en caso de que no podamos conseguir la versión profesional deVisual Studio 2010, es la versión Express. Esta versión es gratuita y se puede des-cargar directamente de Internet, lo único que se necesita es llevar a cabo un peque-ño registro por medio de cualquier cuenta de Hotmail o passport. Para descargar el compilador de C# Express de forma completamente gratuita, po-demos acceder al sitio web que se encuentra en la dirección www.microsoft.com/express, dentro del portal de Microsoft. Para realizar esta descarga sólo seránecesario completar un formulario de registro.Una vez que hemos descargado el compilador, podemos proceder a llevar a cabo lainstalación; esta tarea es muy similar a la instalación de cualquier otro programa deWindows, pero no debemos olvidar registrarlo antes de 30 días.

El ambiente de desarrolloUna vez finalizada la instalación podemos iniciar el programa seleccionándolo desdeel menú Inicio de Windows, veremos una ventana como la que aparece a continua-ción, que muestra la interfaz de uso de la aplicación.

Figura 1. Aquí vemos la ventana principal de CC## EExxpprreessss22001100. Esta interfaz aparece cada vez que iniciamos el programa.

Básicamente la interfaz está dividida en dos partes, en el centro tenemos la página deinicio, aquí encontramos enlaces a nuestros proyectos más recientes, pero también

1. C#.NET

18 www.redusers.com

01_C#2010_AJUSTADO.qxd 8/6/10 8:15 PM Page 18

Page 21: C# aprenda a programar

podemos recibir comunicados y noticias sobre el desarrollo de software usando C#. En esta misma parte de la interfaz pero como páginas diferentes, tendremos las zo-nas de edición. Estas zonas de edición nos permitirán editar el código del progra-ma, editar la interfaz de usuario, iconos y demás recursos. Editar el código del programa es una actividad muy sencilla que no debe preocu-parnos, si sabemos utilizar cualquier tipo de editor de textos como Microsoft Wordo el Bloc de notas de Windows, entonces podemos editar el código del programa.Los demás editores también son bastante amigables para el usuario, pero no los ne-cesitaremos para realizar los ejemplos mostrados en este libro.Del lado derecho tenemos una ventana que se conoce como Explorador de solucio-nes, en esta misma área aparecerán otras ventanas que nos dan información sobreel proyecto que estamos desarrollando. Veremos los detalles mostrados por algunasde estas ventanas un poco más adelante en este libro.En la parte inferior encontramos otra ventana, en esta zona generalmente aparecenlos apartados que utilizará el compilador para comunicarse con nosotros. Por ejem-plo, en esta zona veremos la ventana que nos indica los errores que tiene nuestroprograma, en la parte superior aparecen los menús y las barras de herramientas.

Cómo crear nuestra primera aplicaciónPara familiarizarnos más con C# Express, lo mejor es crear un primer proyecto ytrabajar sobre él. Generaremos un pequeño programa que nos mande un mensajeen la consola, luego adicionaremos otros elementos para que podamos explorar lasdiferentes ventanas de la interfaz de usuario.Para crear un proyecto tenemos que seleccionar el menú Archivo y luego de esto de-bemos hacer clic en la opción llamada Nuevo Proyecto, de esta forma veremos uncuadro de diálogo que muestra algunas opciones relacionadas.En la parte central del cuadro de diálogo aparecen listados los diferentes tipos deproyectos que podemos crear, para este ejemplo debemos seleccionar el que indicaaplicación de consola. En la parte inferior escribiremos el nombre de nuestro pro-yecto, que en este caso será MiProyecto. Cada nuevo proyecto que crearemos tendrásu propio nombre; después, simplemente oprimimos el botón OK.

Breve historia de la programación para Windows

19www.redusers.com

Si por algún motivo llegamos a cerrar el editor del código fuente o no aparece en nuestra

interfaz de usuario, la forma más sencilla de encontrarlo es por medio del Explorador de

soluciones. Simplemente debemos dirigirnos al documento que representa nuestro código

fuente y hacer doble clic en él, la ventana con el editor de código fuente aparecerá.

ENCONTRAR CÓDIGO FUENTE RÁPIDAMENTE

01_C#2010_AJUSTADO.qxd 8/6/10 8:15 PM Page 19

Page 22: C# aprenda a programar

Figura 2. Éste es el cuadro de dialogo que usamos para crear un nuevo

proyecto, gracias a sus opciones podemos generar diferentes tipos de proyectos.

En unos pocos segundos C# Express crea el proyecto para nosotros. Visual Studioy la versión Express hacen uso de soluciones y proyectos, una solución puede tenervarios proyectos, por ejemplo, Office tiene diferentes productos como Word, Excely PowerPoint. Office es una solución y cada producto es un proyecto. El proyectopuede ser un programa independiente o una librería, y puede tener uno o varios do-cumentos, estos documentos pueden ser el código fuente y recursos adicionales.Podemos observar que nuestra interfaz de usuario ha cambiado un poco, las venta-nas ya nos muestran información y también podemos ver que en la zona de ediciónse muestra el esqueleto para nuestro programa.

Figura 3. Esta figura nos muestra el panel derecho denominado Solution Explorer.

1. C#.NET

20 www.redusers.com

01_C#2010_AJUSTADO.qxd 8/6/10 8:15 PM Page 20

Page 23: C# aprenda a programar

El Explorador de soluciones nos muestra la información de la solución de formalógica, si observamos es como un pequeño árbol. En la raíz encontramos a la so-lución, cada proyecto que tengamos en esa solución será una rama, cada proyecto,a su vez, tendrá también sus divisiones. En nuestro caso vemos tres elementos, dosde esos elementos son carpetas, en una se guardan las propiedades del proyecto yen la otra las referencias (durante este libro no haremos uso de estas carpetas). Eltercer elemento es un documento llamado Program.cs, éste representa al documentodonde guardamos el código fuente de nuestra aplicación. Vemos que la extensiónde los programas de C# es .CS.En el área de edición podemos observar que tenemos un esqueleto para que, apartir de ahí, podamos crear nuestro propio programa. Para entender lo que te-nemos ahí es necesario conocer un concepto: namespace. El namespace es unaagrupación lógica, por ejemplo, todo el código que podemos tener relacionadocon matemáticas puede quedar agrupado dentro del namespace de Math. Otrouso que tiene el namespace es el de resolver conflictos con los nombres, por ejem-plo, supongamos que tenemos un proyecto muy grande y varios programadorestrabajando en él. Es posible que ambos programadores crearan un método quetuviera el mismo nombre, esto nos genera un conflicto ya que el programa nopodría saber cual versión utilizar. La forma de resolver esto es que cada progra-mador tenga su propio namespace y hacer referencia al namespace correspon-diente según la versión que deseáramos utilizar.El Framework de .NET nos provee de varios namespaces donde tenemos miles declases y métodos ya creados para nuestro uso. Cuando deseamos utilizar los recur-sos que se encuentran en un namespace programado por nosotros o por otros pro-gramadores, debemos hacer uso de un comando de C# conocido como using.Como podemos ver en la parte superior del código, tenemos varios using haciendoreferencia a los namespace que necesita nuestra aplicación; si necesitáramos adicio-nar más namespaces, lo haríamos en esta sección.Más abajo se está definiendo el namespace propio de nuestro proyecto, esto se ha-ce de la siguiente manera:

namespace MiProyecto{

}

El namespace que estamos creando se llama MiProyecto, como podemos ver el na-mespace usa { } como delimitadores, esto se conoce como un bloque de código,todo lo que se coloque entre { } pertenecerá al namespace; ahí es donde será nece-sario escribir el código correspondiente a nuestra aplicación.

Breve historia de la programación para Windows

21www.redusers.com

01_C#2010_AJUSTADO.qxd 8/6/10 8:15 PM Page 21

Page 24: C# aprenda a programar

Dentro del bloque de código encontramos la declaración de una clase, C# es unlenguaje orientado a objetos y por eso necesita que declaremos una clase para nues-tra aplicación. La clase tiene su propio bloque de código y en nuestra aplicación sellamará Program. El concepto de clase se verá en el Capítulo 10 de este libro.Todos los programas necesitan de un punto de inicio, un lugar que indique dóndeempieza la ejecución del programa, en C#, al igual que en otros lenguajes, el pun-to de inicio es la función Main(); esta función también tiene su propio bloque decódigo. Dentro de esta función generalmente colocaremos el código principal denuestra aplicación, aunque es posible tener más funciones o métodos y clases. Laspartes y características de las funciones se ven en el Capítulo 5 de este libro.Ahora es el momento de crear nuestra primera aplicación. Vamos a modificar el có-digo de la función tal y como se muestra a continuación. Cuando estemos adicio-nando la sentencia dentro de Main(), debemos fijarnos que sucede inmediatamen-te después de colocar el punto.

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MiProyecto{

class Program{

static void Main(string[] args){

Console.WriteLine(“Hola Mundo!”);}

}}

Si logramos observar, cuando se escribió la palabra Console y luego el punto, apare-ció un recuadro listando diferentes elementos. Este cuadro se llama autocompletary nos permite trabajar rápidamente y reducir la cantidad de errores de sintaxis. Elcuadro de autocompletar nos muestra sugerencia de la palabra, comando, variable,etc. que se podría usar a continuación. Si lo deseamos, lo seleccionamos de esa lis-ta, y él lo escribe por nosotros, conforme avancemos y nos familiaricemos con laprogramación de C# veremos que es de gran ayuda.En nuestro ejemplo hemos colocado una sentencia que escribirá el mensaje HolaMundo en la consola. Es un programa muy sencillo, pero nos permitirá aprender có-mo llevar a cabo la compilación de la aplicación y ver el programa ejecutándose.

1. C#.NET

22 www.redusers.com

01_C#2010_AJUSTADO.qxd 8/6/10 8:15 PM Page 22

Page 25: C# aprenda a programar

Para compilar la aplicaciónUna vez que terminemos de escribir nuestro programa, podemos llevar a cabo lacompilación, como aprendimos anteriormente esto va a generar el assembly que lue-go usará el runtime cuando se ejecute.Para poder compilar la aplicación debemos seleccionar el menú de Depuración o De-bug y luego Construir Solución o Build Solution. El compilador empezará a trabajar yen la barra de estado veremos que nuestra solución se ha compilado exitosamente.

Figura 4. Para compilar nuestra aplicación, primero debemos

construirla, seleccionando la opción adecuada desde el menú.

Para ejecutar la aplicaciónUna vez que la compilación ha sido exitosa, podemos ejecutar nuestro programa yver cómo trabaja. Para esto tenemos dos opciones: ejecutar con depuración y eje-cutar sin depurador. En la versión Express únicamente aparece la ejecución condepuración, pero podemos usar la ejecución sin depurador con las teclas CTRL+F5 oadicionándola usando el menú de herramientas.El depurador es un programa que nos ayuda a corregir errores en tiempo de eje-cución y también errores de lógica. En el Capítulo 12 de este libro aprenderemos có-mo utilizarlo. De preferencia debemos utilizar la ejecución sin depurador y hacer

Breve historia de la programación para Windows

23www.redusers.com

Éste es un libro de inicio a la programación con C#, por eso todos los programas se ejecutarán

en la consola. Una vez comprendidos los conceptos principales que se enseñan, es posible

aprender cómo se programan las formas e interfaz gráfica en C#. Este tipo de programación no

es difícil, pero si requiere tener los conocimientos básicos de programación orientada a objetos.

INTERFAZ GRÁFICA

01_C#2010_AJUSTADO.qxd 8/6/10 8:15 PM Page 23

Page 26: C# aprenda a programar

uso de la ejecución con depuración únicamente cuando realmente la necesitemos.Ahora ejecutaremos nuestra aplicación, para esto oprimimos las teclas CTRL+F5.

Figura 5. Con el menú Debug/Start WithoutDebbuging nuestro programa se ejecutará.

Cuando el programa se ejecuta, aparece una ventana, a ella la llamamos consola yse encarga de mostrar la ejecución del programa. De esta forma podremos leer elmensaje que habíamos colocado en nuestro ejemplo.

Figura 6. Ahora podemos ver nuestra aplicación ejecutándose en la consola.

Cómo detectar errores en un programaEn algunas ocasiones puede ocurrir que escribimos erróneamente el programa, cuan-do esto sucede, la aplicación no podrá compilarse ni ejecutarse; si esto llegara a ocu-rrir debemos cambiar lo que se encuentra mal.

1. C#.NET

24 www.redusers.com

01_C#2010_AJUSTADO.qxd 8/6/10 8:15 PM Page 24

Page 27: C# aprenda a programar

Escribamos a propósito un error para que veamos cómo se comporta el compilador.

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace MiProyecto{

class Program{

static void Main(string[] args){

Consola.WriteLine(“Hola Mundo!”);}

}}

En el programa hemos cambiado Console por Consola, esto provocará un error; aho-ra podemos tratar de compilar nuevamente y ver lo que sucede.

Figura 7. En esta imagen vemos que el programa

tiene un error y por lo tanto no se puede compilar.

Breve historia de la programación para Windows

25www.redusers.com

01_C#2010_AJUSTADO.qxd 8/6/10 8:15 PM Page 25

Page 28: C# aprenda a programar

Como ya sabemos, la ventana que aparece en la parte inferior de nuestra interfaz deusuario es utilizada por el compilador para comunicarse, vemos que aparece unaventana que nos entrega un listado de errores; en el Capítulo 12, dedicado a la depu-ración, aprenderemos a utilizarla, ahora simplemente debemos saber que siempre esnecesario resolver el primer problema de la lista y que podemos ir directamente alerror haciendo doble clic con el mouse sobre él.

La vista de clasesAhora revisaremos la vista de clases. En esta vista podemos obtener informaciónsobre la solución que estamos creando, pero a diferencia del Explorador de solu-ciones, la información se encuentra ordenada en forma lógica.Con esta vista podemos encontrar rápidamente los namespace de nuestra solución ydentro de ellos las clases que contienen; si lo deseamos, podemos ver los métodos quese encuentran en cada clase. Esta vista no solamente permite observar la informaciónlógica, también nos da la posibilidad de navegar rápidamente en nuestro código. En la versión Express no viene la opción previamente configurada, por lo que es ne-cesario adicionar el comando al menú Vista.Para mostrar la vista de clases debemos de ir al menú Vista y luego seleccionar Vis-ta de Clases, una ventana aparecerá en nuestra interfaz de usuario.

Figura 8. Para mostrar la vista de clases debemos de usar el menú View.

La ventana de la vista de clases está divida en dos secciones, la sección superior nosmuestra la relación lógica y jerárquica de los elementos mientras que en la parte in-ferior vemos los métodos que componen a alguna clase en particular.

1. C#.NET

26 www.redusers.com

Si deseamos trabajar bajo Linux, es posible utilizar Mono. Solamente debemos recordar que no

siempre la versión .NET que maneja Mono es la más reciente de Microsoft. El sitio de este

proyecto lo encontramos en la dirección web www.mono-project.com/Main_Page, desde ella

podemos descargarlo en forma completamente gratuita.

.NET EN LINUX

01_C#2010_AJUSTADO.qxd 8/6/10 8:15 PM Page 26

Page 29: C# aprenda a programar

Figura 9. Aquí podemos observar a la vista de clases en el lado

derecho. El árbol está abierto para poder ver los elementos que lo componen.

En la raíz del árbol encontramos al proyecto, éste va a contener las referencias ne-cesarias y el namesapace de MiProyecto. Si tuviéramos más namespaces estos apare-cerían ahí, al abrir el namespace de Miproyecto encontramos las clases que están de-claradas dentro de él. En este caso solamente tenemos la clase Program, si la selec-cionamos veremos que en la parte inferior se muestran los elementos que estén de-clarados en su interior. En nuestro ejemplo tenemos el método Main(). Si en este momento damos doble clic en cualquiera de los métodos, nos dirigiremosautomáticamente al código donde se define, como nuestro programa es muy pe-queño, posiblemente no vemos la ventaja de esto, pero en programas con miles delíneas de código, el poder navegar rápidamente es una gran ventaja.

Configurar los menús del compiladorPara poder adicionar las opciones que nos hacen falta en los menús debemos seguiruna serie de pasos muy sencillos. Nos dirigimos primero al menú Tools o Herra-mientas y seleccionamos la opción Customize.

Breve historia de la programación para Windows

27www.redusers.com

Uno de los sitios más importantes que tenemos que visitar cuando desarrollamos para .NET

es el llamado MSDN. En este sitio encontraremos toda la documentación y variados ejemplos

para todas las clases y métodos que componen a .NET. El sitio se encuentra en la dirección

web www.msdn.com.

MSDN

01_C#2010_AJUSTADO.qxd 8/6/10 8:15 PM Page 27

Page 30: C# aprenda a programar

Figura 10. Es necesario seleccionar la opción de Customize… en el menú Tools.

Nos aparece un cuadro de diálogo, en el cual debemos seleccionar Commands, enesta sección podemos elegir el menú al cual queremos adicionar un comando,por ejemplo el menú View.

Figura 11. En esta ventana debemos seleccionar el menú que deseamos modificar.

1. C#.NET

28 www.redusers.com

01_C#2010_AJUSTADO.qxd 8/6/10 8:15 PM Page 28

Page 31: C# aprenda a programar

Aparecen listados los comandos actuales del menú, damos clic en la zona donde de-seamos que se inserte el nuevo comando y oprimimos el botón Add Command. Conesto aparece un nuevo cuadro de dialogo que muestra todos los posibles comandosque podemos adicionar clasificados en categorías.En las categorías seleccionamos View y en los comandos Class View, este comandoes el que nos permite tener la vista de clases. El comando de Iniciar Sin Depurar seencuentra en la categoría Debug.

Figura 12. En esta ventana seleccionamos el comando que deseamos insertar.

Hasta aquí hemos analizado los conceptos básicos más importantes necesarios paracomprender el funcionamiento de .NET, a partir del próximo capítulo comenzare-mos con nuestro aprendizaje de programación y del lenguaje C#.

Breve historia de la programación para Windows

29www.redusers.com

… RESUMEN

Hace algunos años la programación para Windows resultaba complicada y requería de un alto

grado de especialización. El Framework de .NET soluciona muchos de los problemas

relacionados con la programación en Windows y la interoperabilidad, las aplicaciones de

.NET se compilan a un assembly que contiene el programa escrito en CIL; éste es un lenguaje

intermedio que lee el runtime cuando se ejecuta la aplicación. El CLR compila el CIL para el

microprocesador según va siendo necesario, el uso de un runtime le da a .NET la flexibilidad

de ser multiplataforma. Todos los lenguajes .NET deben cumplir con los lineamientos que

encontramos en el CLS.

01_C#2010_AJUSTADO.qxd 8/6/10 8:15 PM Page 29

Page 32: C# aprenda a programar

30 www.redusers.com

TEST DE AUTOEVALUACIÓN

1 ¿Cuál es la historia del desarrollo

de las aplicaciones para Windows?

2 ¿Qué problemas ayuda a resolver .NET?

3 ¿Qué es un assembly?

4 ¿Cuál es la definición de CIL y CLR?

5 Describa qué hace el CLR con el

assembly.

6 ¿Cuál es el significado de Jitter?

7 Mencione algunos compiladores de C#

que podemos utilizar.

8 ¿Qué es el CTS?

9 ¿Porqué .NET puede ser multiplataforma?

10¿Qué otro lenguaje que use .NET existe?

11¿Cuál es la última versión de .NET?

12 ¿Qué otro lenguaje que use .NET existe?

ACTIVIDADES

EJERCICIOS PRÁCTICOS

1 Cree un proyecto nuevo que imprima su

nombre en la ventana de la consola.

2 Coloque un error a propósito y vea cómo

se comporta el compilador.

3 Explore el proyecto usando la vista de

clases.

4 Experimente con el explorador de

soluciones y vea la información que le

provee.

5 Agregue más mensajes a la aplicación

que ha creado.

01_C#2010_AJUSTADO.qxd 8/6/10 8:15 PM Page 30

Page 33: C# aprenda a programar

Los elementos

básicos de un

programa

Los lenguajes de programación 32Los programas de computadora 32Las variables 42Operaciones aritméticas 49Cómo pedirle datos al usuario 56Cómo resolver problemas en la computadora 60Resolución de problemasen la computadora 64

Resumen 69Actividades 70

Capítulo 2

Llegó el momento de aprender cómo

desarrollar programas de computadoras.

Algunas personas piensan que programar

software es complejo y difícil,

sin embargo, esto no es cierto,

o lo fue hace muchísimo tiempo atrás.

Para ser programadores, sólo

necesitamos conocer un lenguaje

de programación y las técnicas necesarias

para desarrollar programas. A lo largo

de estos capítulos aprenderemos ambas.

C#

SERVICIO DE ATENCIÓN AL LECTOR: [email protected]

02_C#2010.qxd 8/11/10 9:45 AM Page 31

Page 34: C# aprenda a programar

LOS LENGUAJES DE PROGRAMACIÓN

Cuando queremos comunicarnos con una persona, hacemos uso de un idioma encomún para entendernos. Nosotros, con este libro, nos comunicamos por mediodel lenguaje español, pero si llegara a visitarnos una persona de otro país donde nose hable español, entonces tendríamos un problema. La solución a este problemaes muy sencilla: necesitamos aprender el idioma de esta persona para poder co-municarnos con ella. Lo mismo sucede con la computadora si queremos progra-marla, es necesario comunicarnos con ella, y la forma correcta de hacerlo es ha-blando su idioma. Entonces podemos decir que el idioma de la computadora seconoce como lenguaje de programación y el lenguaje de programación que apren-deremos es C#. Este lenguaje es sencillo y poderoso a su vez.Una vez que sepamos el lenguaje de programación, entonces la computadora en-tenderá qué es lo que queremos que haga.Los lenguajes de programación existen desde hace muchos años y son de diferentestipos. Algunos han evolucionado y han surgido nuevos lenguajes como C#. Otroslenguajes son especializados para determinadas labores y muchos otros se han ex-tinguido o han quedado obsoletos.

Los programas de computadoraTodos o casi todos sabemos cómo cocinar una torta, y de hecho, éste es un buenejemplo para saber cómo hacer un programa de computadora. Cuando queremoscocinar una torta, lo primero que necesitamos son los ingredientes. Si falta alguno,entonces no tendremos una rica torta. Ya una vez que hemos preparado o recolec-tado nuestros ingredientes, seguimos la receta al pie de la letra. Ésta nos dice pasoa paso qué es lo que tenemos que hacer.Pero, ¿qué sucedería si no seguimos los pasos de la receta?, ¿qué sucede si ponemos losingredientes primero en el horno y luego los revolvemos?, ¿el resultado es una torta?La respuesta a estas preguntas es evidente: el resultado no es una torta. De esto dedu-cimos que para lograr algo, necesitamos una serie de pasos, pero también es necesarioseguirlos en el orden adecuado. A esta serie de pasos la llamamos receta.

2. LOS ELEMENTOS BÁSICOS DE UN PROGRAMA

32 www.redusers.com

Un error que se puede tener al iniciarnos con la programación de computadoras con C# es

olvidar colocar ; al finalizar la sentencia. Si nuestro programa tiene algún error y todo parece

estar bien, seguramente olvidamos algún punto y coma. Es bueno reconocer estos tipos de

errores ya que nos permite reducir el tiempo de corrección necesario.

CÓMO EVITAR ERRORES

02_C#2010.qxd 8/6/10 8:16 PM Page 32

Page 35: C# aprenda a programar

Cualquier persona puede pensar en una actividad y mencionar la lista de pasosy el orden en el que se deben cumplir. Podemos hacer sin problema la lista depasos para cambiar el neumático del automóvil o para alimentar a los peces delacuario. Con esto vemos que no encontraremos problema alguno para listar lospasos de cualquier actividad que hagamos.Ahora, seguramente nos preguntamos: ¿qué tiene esto que ver con la programaciónde computadoras? y la respuesta es simple. Cualquier persona que pueda hacer unalista de pasos puede programar una computadora. El programa de la computadorano es otra cosa que una lista de los pasos que la computadora tiene que seguir parahacer alguna actividad. A esta lista de pasos la llamamos algoritmo. Un algoritmoson los pasos necesarios para llevar a cabo una acción. Una característica importan-te del algoritmo es que tiene un punto de inicio y un punto de fin, lo que indicaque los pasos se llevan a cabo de forma secuencial, uno tras otro. El algoritmo se-ría equivalente a la receta de la torta y los ingredientes necesarios generalmente se-rán los datos o la información que usaremos.Hagamos un pequeño programa para ver cómo funcionaría esto. Para esto creamosun proyecto, tal y como vimos en el Capítulo 1. Nuestro programa mostrará los pa-sos para hacer una torta o un pastel. Colocamos el siguiente código en nuestro pro-grama y veremos cómo se corresponde con lo que hemos aprendido.

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la funcion principal del programa// Aqui inicia la aplicacionstatic void Main(string[] args)

Los lenguajes de programación

33www.redusers.com

Las funciones son secciones del programa en las que podemos tener código especializado. La

función Main() es invocada por el sistema operativo cuando queremos que nuestro programa se

inicie. Es la única función que deben tener todos los programas que desarrollemos.

LAS FUNCIONES EN C#

02_C#2010.qxd 8/6/10 8:16 PM Page 33

Page 36: C# aprenda a programar

{Console.WriteLine(“1- Precalentar el horno”);Console.WriteLine(“2- Batir margarina con azucar”);Console.WriteLine(“3- Agregar huevos”);Console.WriteLine(“4- Cernir harina”);Console.WriteLine(“5- Agregar a la mezcla y leche”);Console.WriteLine(“6- Hornear por 40 minutos”);Console.WriteLine(“7- Decorar y comer”);

}}

}

C# es un lenguaje orientado a objetos y necesita que definamos una clase para po-der crear un programa. En este momento no veremos las clases, pero regresaremos aellas en un capítulo posterior. Lo primero que debemos encontrar es una funciónque se llama Main(), que es muy importante, como vimos en el Capítulo 1.Ya sabemos que los algoritmos necesitan un inicio y un fin. En nuestro programael punto donde siempre inicia es la función Main(). Esta función indica el puntode arranque de nuestro programa y aquí colocaremos los pasos que debe seguirnuestro programa en el orden adecuado.Para indicar todos los pasos que pertenecen a Main() necesitamos colocarlos aden-tro de su bloque de código. Un bloque de código se define entre llaves { }. To-do lo que se encuentre en ese bloque de código pertenece a Main(), lo que se en-cuentre afuera de él, no pertenece.Es importante que notemos que la clase también tiene un bloque de código y Main()se encuentra adentro de él. De igual forma, el namespace también tiene su propiobloque de código y la clase se encuentra adentro, aunque por ahora sólo nos con-centraremos en el bloque de código de Main().Un error común cuando se crean bloques de código es olvidar cerrarlos. Como re-comendación, una vez que abrimos un bloque de código con {, inmediatamente de-bemos de colocar el cierre con } y luego programar su contenido. De esta forma, no

2. LOS ELEMENTOS BÁSICOS DE UN PROGRAMA

34 www.redusers.com

Cuando colocamos un valor con decimales en C# automáticamente se lo interpreta como de tipo

double. Sin embargo, si necesitamos colocar ese valor en una variable de tipo float, debemos

usar el sufijo f. Éste le dice a C# que use ese valor como flotante. Ejemplo:

resultado = a * 3.57f;.

ASIGNACIÓN DE VALORES FLOTANTES

02_C#2010.qxd 8/6/10 8:16 PM Page 34

Page 37: C# aprenda a programar

olvidaremos cerrarlo. Dentro de Main() encontramos los pasos de nuestro algorit-mo. En este momento nos pueden parecer extraños, pero aprenderemos qué signi-fican. Tenemos que recordar que debemos aprender el idioma de la computadora yéstas son una de sus primeras frases.Lo que encontramos adentro de la función Main() es una serie de sentencias. Lassentencias nos permiten colocar instrucciones que nuestro programa pueda eje-cutar, que son utilizadas para mostrar un mensaje en la pantalla. El mensaje quenosotros queremos mostrar en la pantalla se muestra al invocar el método WriteLine(). Los métodos son similares a las funciones, existen adentro de las cla-ses y nos permiten hacer uso de las funcionalidades internas. Este método perte-nece a la clase Console, y en esa clase encontraremos todo lo necesario para quepodamos trabajar con la consola, ya sea colocando mensajes o leyendo la infor-mación proporcionada por el usuario. Como WriteLine() pertenece a Consolecuando queremos utilizarlo, debemos escribir:

Console.WriteLine(“Hola”);

WriteLine() necesita cierta información para poder trabajar. Esta información es elmensaje que deseamos mostrar. A los métodos se les pasa la información que nece-sitan para trabajar por medio de sus parámetros. Los parámetros necesarios se co-locan entre paréntesis(). WriteLine() necesitará un parámetro de tipo cadena.Una cadena es una colección de caracteres, es decir, letras, números y signos. La ca-dena se delimita con comillas dobles “. En el ejemplo, el mensaje que queremosque se muestre es: Hola. Por eso pasamos el parámetro de tipo cadena “Hola”.Las sentencias se finalizan con punto y coma ;. Esto es importante y no debemosolvidarlo ya que este carácter en particular es reconocido por C# para indicar quela sentencia escrita hasta allí, ha finalizado.En cada una de las sentencias invocadas hasta aquí por nuestro programa, hemosenviado un mensaje tras otro con cada paso necesario para cocinar nuestro pas-tel o nuestra torta. Por último, sólo resta que ejecutemos el programa escrito yveamos el resultado que aparece en la pantalla.

Los lenguajes de programación

35www.redusers.com

Cuando se invoca un método es necesario no solamente colocar su nombre, sino que también

se deben poner los paréntesis. Éstos se deben poner aun cuando el método no necesite

parámetros. No hay que olvidar usar el paréntesis de cierre ). Si olvidamos colocar los

paréntesis, el compilador nos marcará errores y no podremos ejecutar el programa.

PROBLEMAS CON LOS MÉTODOS

02_C#2010.qxd 8/6/10 8:16 PM Page 35

Page 38: C# aprenda a programar

Figura 1. Podemos observar los mensajes

que enviamos a la pantalla por medio del método WriteLine().

Podemos observar que la ejecución ha mostrado los mensajes en el orden en elque los hemos puesto. Ahora podemos hacer un pequeño experimento. Cambia-remos el orden de las sentencias y observaremos qué es lo que sucede. El progra-ma quedará de la siguiente forma:

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la funcion principal del programa// Aqui inicia la aplicacionstatic void Main(string[] args){

Console.WriteLine(“1- Precalentar el horno”);

2. LOS ELEMENTOS BÁSICOS DE UN PROGRAMA

36 www.redusers.com

02_C#2010.qxd 8/6/10 8:16 PM Page 36

Page 39: C# aprenda a programar

Console.WriteLine(“2- Batir margarina con azucar”);Console.WriteLine(“6- Hornear por 40 minutos”);Console.WriteLine(“5- Agregar a la mezcla y leche”);Console.WriteLine(“7- Decorar y comer”);Console.WriteLine(“3- Agregar huevos”);Console.WriteLine(“4- Cernir harina”);

}}

}

Ejecutémoslo y veamos qué ocurre.

Figura 2. Aquí vemos que los mensajes se colocan en el orden

en que se encuentran en la función main() y no en el orden en que esperábamos.

Podemos observar que cuando se ejecuta, las sentencias se ejecutan en el mismoorden como están en el código del programa, no se ejecutan como nosotros sa-bemos que se deben de ejecutar. Este punto es importante, ya que nos muestraque colocar las sentencias del programa en el orden de ejecución correcto es res-ponsabilidad del programador. La computadora no puede leernos la mente y sa-ber qué es lo que realmente deseamos, ésta sólo ejecuta fielmente las sentencias

Los lenguajes de programación

37www.redusers.com

02_C#2010.qxd 8/6/10 8:16 PM Page 37

Page 40: C# aprenda a programar

en el orden en que las colocamos. Si en la vida real primero horneamos y luegobatimos, no podemos esperar obtener un pastel o una torta. Por lo tanto, si enla computadora no ponemos las sentencias del programa en el orden adecuado,no podemos esperar tener un programa funcional.

Errores en los programasUna parte importante de la programación es reconocer los errores que podemostener con el fin de corregirlos y permitir que el programa trabaje correctamente.Podemos tener dos tipos de errores: los errores de sintaxis y los errores de lógi-ca. Los errores de sintaxis son fáciles de corregir y se deben a que escribimos en elorden incorrecto las sentencias del programa. Estos errores se muestran cuando elprograma se compila, y de esa forma se pueden buscar fácilmente para corregirlos.Los errores de lógica se deben a que hemos creado nuestro algoritmo en forma erró-nea y aunque todas las sentencias estén correctas, el programa no lleva a cabo loque deseamos. Estos errores son más difíciles de corregir y la mejor forma de evi-tarlos es por medio de un análisis previo adecuado del problema a resolver. Másadelante aprenderemos cómo llevar a cabo este análisis.

Empecemos a reconocer los errores de sintaxis y los mensajes que da el compila-dor cuando los tenemos. El reconocer estos mensajes y cómo fueron ocasionadosnos permitirá resolverlos rápidamente en el futuro. Para esto empezaremos a ha-cer unos experimentos. En el código de nuestro programa, en cualquiera de lassentencias, eliminamos el punto y coma que se encuentra al final, y luego lo com-pilamos para ver qué sucede. Debido a que hemos eliminado el punto y coma, te-nemos un error de sintaxis y el compilador nos dice que el programa no se hacompilado exitosamente.Dentro de nuestro compilador se mostrará la ventana de lista de errores. En estaventana se colocan los errores encontrados por el compilador. Siempre es conve-niente solucionar el problema que se encuentra en la parte superior de la lista y noel último, debido a que muchas veces, solucionando el primero, quedan soluciona-dos otros que arrastraban su problema. El mensaje que vemos nos indica que se es-peraba punto y coma, tal y como se ve en la figura 3.

2. LOS ELEMENTOS BÁSICOS DE UN PROGRAMA

38 www.redusers.com

Algunas veces sucede que olvidamos colocar la cadena entre comillas o que solamente se ha

colocado la comilla del inicio. Es importante no olvidar colocar las cadenas siempre entre las

dos comillas. Si no lo hacemos de esta forma, el compilador no puede encontrar correctamente

la cadena o dónde finaliza. La sentencia nos marcará un error de compilación.

ERROR COMÚN DE LAS CADENAS

02_C#2010.qxd 8/6/10 8:16 PM Page 38

Page 41: C# aprenda a programar

Figura 3. Podemos ver la ventana con la lista

de errores y el error de sintaxis encontrado por el compilador.

La lista de errores nos da una descripción del error y también nos permite ver el nú-mero de línea donde se encuentra el error. Una forma sencilla de llegar a éste es sim-plemente hacer doble clic sobre la descripción del error, así el entorno C# nos lle-vará directamente a dónde se encuentra éste. Coloquemos nuevamente el punto ycoma en el lugar donde estaba en un principio y compilemos. En esta ocasión, elprograma puede compilar y ejecutar sin problemas, en base a la correción que he-mos realizado con antelación. El error se encuentra solucionado. La solución quenos brinda C# para corregir errores es práctica y sencilla de implementar.Ahora experimentemos otro error. A la primera sentencia le borramos el paréntesisde cierre y luego compilamos para ver qué ocurre:

Los lenguajes de programación

39www.redusers.com

Un error común que los principiantes hacen cuando nombran sus variables es que olvidan cómo

nombraron a la variable y la escriben a veces con minúscula y a veces con mayúscula. Esto hace

que se produzcan errores de lógica o de sintaxis. Para evitarlo, podemos utilizar una tabla que

contenga la información de las variables de nuestro programa.

ERRORES CON LOS NOMBRES DE VARIABLES

02_C#2010.qxd 8/6/10 8:16 PM Page 39

Page 42: C# aprenda a programar

Figura 4. Aquí vemos el mensaje de error generado por no cerrar el paréntesis.

Figura 5. Ahora nuestra lista de errores muestra tres errores en el programa.

2. LOS ELEMENTOS BÁSICOS DE UN PROGRAMA

40 www.redusers.com

02_C#2010.qxd 8/6/10 8:16 PM Page 40

Page 43: C# aprenda a programar

Corrijamos el error y compilemos de nuevo. Todo debe de estar bien. Pero lo queharemos ahora es borrar las comillas de cierre de la cadena en la primera sentencia.Este error nos presenta un escenario más interesante y nos conviene entender quées lo que sucede. Compilemos el programa y veamos nuestra lista de errores. Éstaserá mucho más extensa que las anteriores:Aquí ha sucedido algo interesante, a pesar de que solamente hemos creado unerror: en la lista de errores aparecen tres errores. Esto se debe a que un error pue-de ocasionar errores extras en el código siguiente. Al no cerrar la cadena, el com-pilador no sabe dónde termina la sentencia y cree que el paréntesis de cierre y elpunto y coma forman parte de la cadena. Por eso también nos muestra que fal-tan el paréntesis y el punto y coma.Debido a que los errores pueden ser en cadena, como en este ejemplo, siempre ne-cesitamos corregir el error que se encuentra en primer lugar. Si nosotros intentára-mos corregir primero el error del punto y coma, no resultaría evidente ver cuál esel error en esa línea, ya que veríamos que el punto y coma sí está escrito.A veces sucede que nuestro programa muestra muchos errores, pero cuando corre-gimos el primer error, la gran mayoría desaparece. Esto se debe a factores similaresa los que acabamos de ver.

La diferencia entre los métodos Write() y WriteLine()Hemos visto que el método WriteLine() nos permite mostrar un mensaje en la con-sola, pero existe un método similar que se llama Write(). La diferencia es muy sen-cilla. Después de escribir el mensaje WriteLine() inserta un salto de línea, por lo quelo próximo que se escriba aparecerá en el renglón siguiente. Por su parte, el méto-do Write() no lleva a cabo ningún salto de línea y lo siguiente que se escriba será enla misma línea. Veamos todo esto en el siguiente ejemplo:

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la funcion principal del programa// Aqui inicia la aplicacionstatic void Main(string[] args){

Console.Write(“Mensaje 1 “);

Los lenguajes de programación

41www.redusers.com

02_C#2010.qxd 8/6/10 8:16 PM Page 41

Page 44: C# aprenda a programar

Console.Write(“Mensaje 2 “);Console.WriteLine(“Mensaje 3 “);Console.WriteLine(“Mensaje 4 “);Console.Write(“Mensaje 5 “);

}}

}

Al ejecutarlo, vemos cómo en efecto después de usar Write() lo siguiente que se es-cribe se coloca en el mismo renglón, pero al usar WriteLine() lo siguiente apareceen el renglón siguiente. Esto es un ejemplo claro de lo explicado anteriormente:

Figura 6. Podemos observar la diferencia entre los métodos Write() y WriteLine().

Las variablesLas computadoras no solamente escriben mensajes en la pantalla, sino que debenhacer cosas útiles y para poder hacerlas necesitan información. La información de-be almacenarse y manipularse de alguna forma.Cuando queremos guardar algo en la vida cotidiana podemos utilizar cajas, porlo que cualquier cosa que deseamos almacenar puede ser colocada en una caja de

2. LOS ELEMENTOS BÁSICOS DE UN PROGRAMA

42 www.redusers.com

02_C#2010.qxd 8/6/10 8:16 PM Page 42

Page 45: C# aprenda a programar

cartón, por ejemplo. Sin embargo, el tamaño de la caja dependerá de lo que de-seamos almacenar. Unos zapatos pueden caber en una caja pequeña, pero enesa caja no podemos colocar un televisor. Si empezamos a almacenar muchas co-sas en cajas, pronto tendremos demasiadas y será difícil poder encontrar lo quehemos guardado. Entonces, una forma de solucionar esto es por medio de eti-quetas. A cada caja le ponemos una etiqueta con el contenido y de esta forma po-demos encontrar rápidamente lo que buscamos.Las variables en la computadora funcionan de manera similar a nuestras cajas dealmacenaje. Las podemos imaginar como pequeñas cajas que existen en la memo-ria de la computadora y su tamaño dependerá de la información que deben guar-dar. Esto se conoce como tipo de la variable. Para poder acceder a esa caja o varia-ble le ponemos un nombre que sería la etiqueta con la que la identificamos.Para hacer uso de una variable, lo primero que tenemos que hacer es declararla.La declaración de éstas es algo muy sencillo. Como primer paso tenemos que co-locar el tipo y luego el nombre. Las variables en C# deben nombrarse de acuerdocon unas recomendaciones sencillas:

• Los nombres de las variables deben empezar con letra.• Es posible colocar números en los nombres de las variables, pero no empezar el

nombre con ellos.• Los nombres de las variables no pueden llevar signos a excepción del guión bajo _ .• Las variables no pueden llevar acentos en sus nombres.

Cuando nombramos las variables, hay que tener en cuenta que C# es sensible a lasmayúsculas y minúsculas, por lo que una variable llamada costo no es la mismaque otra variable llamada COSTO u otra llamada Costo.Es recomendable nombrar a las variables con nombres que hagan referencia a la in-formación que guardarán. Si nos acostumbramos a hacer esto desde que empeza-mos a programar, evitaremos muchos problemas en el futuro y será mucho más sen-cillo corregir nuestros programas cuando tengan errores.Veamos un ejemplo de cómo podemos declarar una variable que guarde valores nu-méricos enteros. El tipo que guarda estos valores se conoce como int.

Los lenguajes de programación

43www.redusers.com

Es importante conocer los tipos y la información que pueden guardar, ya que esto nos permitirá

guardar la información necesaria y utilizar la menor cantidad de memoria. Podemos aprender

los rangos de los tipos o imprimir una tabla y tenerla a mano. Con la práctica podremos utilizar

los tipos sin tener que verificar los rangos constantemente.

SELECCIÓN DEL TIPO

02_C#2010.qxd 8/6/10 8:16 PM Page 43

Page 46: C# aprenda a programar

int costo;

Vemos que al final de la sentencia hemos colocado el punto y coma. Si necesitamosdeclarar más variables lo podemos hacer de la siguiente forma:

int costo;int valor;int impuesto;

Pero también es posible declarar las variables en una sola línea. Para esto simple-mente separamos los nombres de las variables con comas. No hay que olvidar co-locar el punto y coma al final de la sentencia.

int costo, valor, impuesto;

C# nos provee de muchos tipos para poder usar con nuestras variables, que pode-mos conocer en la siguiente tabla:

TIPO INFORMACIÓN QUE GUARDA

bool Es una variable booleana, es decir que solamente puede guardar los valores verdadero o falso

(true o false) en términos de C#.

byte Puede guardar un byte de información. Esto equivale a un valor entero positivo entre 0 y 255.

sbyte Guarda un byte con signo de información. Podemos guardar un valor entero con signo

desde –128 hasta 127.

char Puede guardar un carácter de tipo Unicode.

decimal Este tipo puede guardar un valor numérico con decimales. Su rango es desde ±1.0 ? 10?28

hasta ±7.9 ? 1028.

double También nos permite guardar valores numéricos que tengan decimales. El rango aproximado

es desde ±5.0 ? 10?324 hasta ±1.7 ? 10 308.

2. LOS ELEMENTOS BÁSICOS DE UN PROGRAMA

44 www.redusers.com

Un punto importante a tener en cuenta es que la asignación siempre se lleva a cabo de derecha

a izquierda. Esto quiere decir que el valor que se encuentra a la derecha del signo igual se le

asigna a la variable que se encuentra a la izquierda del signo igual. Si no lo hacemos de esta

forma, el valor no podrá ser asignado o será asignado a la variable incorrecta.

FORMA CORRECTA DE HACER UNA ASIGNACIÓN

02_C#2010.qxd 8/6/10 8:16 PM Page 44

Page 47: C# aprenda a programar

TIPO INFORMACIÓN QUE GUARDA

float Otro tipo muy utilizado para guardar valores numéricos con decimales. Para este tipo el rango

es desde ±1.5 ? 10?45 hasta ±3.4 ? 1038.

int Cuando queremos guardar valores numéricos enteros con signo, en el rango de -2,147,483,648

hasta 2,147,483,647.

uint Para valores numéricos enteros positivos, su rango de valores es desde 0 hasta 4,294,967,295.

long Guarda valores numéricos enteros realmente grandes con un rango

desde –9,223,372,036,854,775,808 hasta 9,223,372,036,854,775,807.

uling Guarda valores numéricos enteros positivos. Su rango de valores varía desde 0

hasta 18,446,744,073,709,551,615.

short Guarda valores numéricos enteros, pero su rango es menor y varía desde -32,768 hasta 32,767.

ushort Puede guardar valores numéricos enteros positivos con un rango desde 0 hasta 65,535.

string Este tipo nos permite guardar cadenas.

Tabla 1. Ésta es la tabla de los tipos más utilizados en C#.

Es útil para seleccionar el tipo adecuado para las variables.

Una vez que hemos declarado la variable, debemos inicializarla. Inicializar una va-riable es asignarle un valor por primera vez. Esto nos permite darle un valor inicialque puede ser útil en la ejecución de nuestro programa (no sólo podemos asignarlea una variable un valor fijo, sino también puede ser desde un texto ingresado por elusuario o desde el registro de una base de datos).Para asignarle un valor a una variable, ya sea durante la inicialización o durante eltranscurso del programa, usamos un operador de asignación, el signo igual. Veamos a continuación un ejemplo de cómo asignar valores:

costo = 50;valor = 75;impuesto = 10;

En este caso, la variable costo almacena el valor de 50, la variable valor almacena el75, y la variable impuesto guarda el valor 10 .

Los lenguajes de programación

45www.redusers.com

Los comentarios solamente nos sirven a nosotros como seres humanos para facilitarnos a

comprender el código del programa. El compilador ignora todos los comentarios y no los toma

en cuenta en el momento de la compilación. Los comentarios no hacen el programa ni más lento

ni más rápido. Sin embargo, sí son muy útiles cuando nosotros vemos el código.

LOS COMENTARIOS Y EL COMPILADOR

02_C#2010.qxd 8/6/10 8:16 PM Page 45

Page 48: C# aprenda a programar

Una asignación no válida sería la siguiente:

50 = costo;

En este caso nada queda asignado a la variable costo. Siempre la variable que recibeel valor se coloca a la izquierda del signo igual.Si lo necesitamos, es posible inicializar la variable al momento de declararla. Esto esmuy cómodo y si lo hacemos así evitamos olvidar la inicialización de la variable. Pa-ra hacerlo colocamos el tipo de la variable seguido del nombre a usar en la variablee inmediatamente con el operador de asignación colocamos el valor.

int costo = 50;

Comentarios en el programaLos programas de computadora pueden ser muy grandes, por lo que es necesariocolocar comentarios de codigo en el programa. Los comentarios sirven para docu-mentar las partes del programa, explicar lo que hace cierta parte del código o sim-plemente colocar un recordatorio. Podemos hacer comentarios de una sola línea, que se colocan por medio de la do-ble barra // seguido del texto del comentario. El texto que se encuentre a partir dela doble barra // y hasta el fin del renglón es ignorado por el compilador. Algunosejemplos de comentarios pueden ser:

// Declaro mis variablesint ancho, alto;

int tarea; // Esta variable guarda el área calculada.

// La siguiente sentencia nunca se ejecuta// Console.WriteLine(“Hola”);

Si llegáramos a necesitar colocar mucha información en nuestros comentarios, pue-de ser útil explayarla en varios renglones, es decir, hacer un bloque de comenta-rios. Para esto, abrimos nuestro bloque de comentarios con una barra seguida deun asterisco, /*, y finalizamos éste con un asterisco en primer lugar, seguido de unabarra */. Todo lo que se encuentre entre estos delimitadores será tomado como uncomentario y el compilador lo pasará por alto.Veamos un ejemplo de un comentario de múltiples líneas:

2. LOS ELEMENTOS BÁSICOS DE UN PROGRAMA

46 www.redusers.com

02_C#2010.qxd 8/6/10 8:16 PM Page 46

Page 49: C# aprenda a programar

/* La siguiente sección calcula el área y usa las variablesalto – para guardar la altura del rectánguloancho – para guardar la base del rectángulo*/

Así vemos cómo los comentarios colocados en varios renglones, se toman como unsolo comentario. Esto es algo muy útil para recordatorios futuros.

Mostrar los valores de las variables en la consolaYa que podemos guardar valores, también nos gustaría poder mostrarlos cuando seanecesario. Afortunadamente, por medio del método WriteLine() o el método Write()podemos hacerlo. En este caso no usaremos la cadena como antes, lo que usaremoses una cadena de formato y una lista de variables. La cadena de formato nos per-mite colocar el mensaje a mostrar e indicar qué variable usaremos para mostrar sucontenido y también en qué parte de la cadena queremos que se muestre. En la lis-ta de variables simplemente colocamos las variables que queremos mostrar.La cadena de formato se trata como una cadena normal, pero agregamos {} dondedeseamos que se coloque el valor de una variable. Adentro de {} debemos colocar elíndice de la variable en nuestra lista. Los índices inician en cero. Si queremos quese muestre el valor de la primera variable en la lista colocamos {0}, si es la segundaentonces colocamos {1} y así sucesivamente. La lista de variables simplemente se co-loca después de la cadena, separando con comas las diferentes variables.

Por ejemplo, podemos mostrar el valor de una variable de la siguiente forma:

Console.WriteLine(“Se tiene {0} en la variable”, costo);

Como solamente tenemos una variable en nuestra lista de variables entonces colo-camos {0}. Pero también podemos mostrar el valor de dos variables o más, como lomuestra el siguiente ejemplo:

Console.WriteLine(“La primera es {0} y la segunda es {1}”, costo, valor);

Ahora veamos un ejemplo con lo que hemos aprendido.

using System;using System.Collections.Generic;

Los lenguajes de programación

47www.redusers.com

02_C#2010.qxd 8/6/10 8:16 PM Page 47

Page 50: C# aprenda a programar

using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la función principal del programa// Aquí inicia la aplicaciónstatic void Main(string[] args){

// Declaramos variablesint costo;int valor, precio;

// Inicializamos las variablescosto = 50;valor = 75;precio = 125;

// Declaramos e inicializamosint impuesto = 10;

// Mostramos un valorConsole.WriteLine(“El valor adentro de costo es {0}”, costo);

// Varias variablesConsole.WriteLine(“Valor es {0} y precio es {1}”, valor,

precio);

// Dos veces la misma variableConsole.WriteLine(“Valor es {0} y precio es {1} con valor de

{0}”, valor, precio);

/* No olvidemosmostrar el valorde la variable impuesto*/

Console.WriteLine(“Y el valor que nos faltaba mostrar {0}”,impuesto);

2. LOS ELEMENTOS BÁSICOS DE UN PROGRAMA

48 www.redusers.com

02_C#2010.qxd 8/6/10 8:16 PM Page 48

Page 51: C# aprenda a programar

Los lenguajes de programación

49

}}

}

Una vez que hemos compilado la aplicación, obtendremos el resultado que mos-tramos en la figura a continuación.

Figura 7. En la consola observamos que los valores guardados

en las variables fueron desplegados de acuerdo con lo colocado en la cadena de formato.

Operaciones aritméticasPoder guardar la información es muy importante, pero es mucho más importanteque podamos recuperar y manipular esa información para hacer algo útil con ella.Para esto, debemos comenzar a realizar las operaciones aritméticas básicas: suma,resta, multiplicación y división, algo muy común en cualquier sistema informático.

Cuando queremos o necesitamos realizar una operación aritmética debemos ha-cer uso de un operador. Cada operación tiene su propio operador, que es el en-cargado de procesar los números, realizando el determinado cálculo, para luegodevolvernos el resultado deseado.

www.redusers.com

02_C#2010.qxd 8/6/10 8:16 PM Page 49

Page 52: C# aprenda a programar

OPERADOR DESCRIPCIÓN

= Asignación. Este operador ya es conocido por nosotros.

+ Suma. Nos permite sumar los valores de las variables o los números

- Resta. Para restar los valores de las variables o los números.

* Multiplicación. Multiplica los valores de las variables o los números.

/ División. Divide los valores de las variables o los números.

% Módulo. Nos da el residuo de la división.

Tabla 2. Ésta es la tabla de operadores aritméticos en C#.

Veamos algunos ejemplos de cómo utilizar estos operadores. Imaginemos que ya he-mos declarado e inicializado las variables. Para guardar en la variable resultado la su-ma de dos números, hacemos lo siguiente:

resultado = 5 + 3;

Como hemos visto, la expresión a la derecha se le asigna a la variable, por lo queen este caso la expresión 5 + 3 se evalúa y su resultado que es 8 es almacenado enla variable resultado. Al finalizar esta sentencia, la variable resultado tiene un va-lor de 8, que podrá ser utilizado dentro de la misma función o en el procedi-miento donde fue declarado.Las operaciones también se pueden realizar con las variables y los números. Suponga-mos que la variable a ha sido declarada y se le ha asignado el valor de 7.

resultado = a – 3;

De nuevo se evalúa primero la expresión a-3, como el valor adentro de a es 7, en-tonces la evaluación da el valor de 4, que se le asigna a la variable resultado.Si queremos podemos trabajar únicamente con variables. Ahora supondremos quela variable b ha sido declarada y que le hemos asignado el valor 8.

resultado = a * b;

Entonces, se evalúa la expresión a*b que da el valor 56, que queda asignado a la va-riable resultado al finalizar la expresión.Si lo que deseamos es la división, podemos hacerla de la siguiente forma:

resultado = a / b;

2. LOS ELEMENTOS BÁSICOS DE UN PROGRAMA

50 www.redusers.com

02_C#2010.qxd 8/6/10 8:16 PM Page 50

Page 53: C# aprenda a programar

En este caso, se divide el valor de a por el valor de b. El resultado es 0,875. Como elnúmero tiene valores decimales, debemos usar variables de algún tipo que nos per-mita guardarlos como float o double.

Y por último nos queda el módulo.

resultado = a % b;

En este caso recibimos en resultado el valor del residuo de dividir a por b.

Veamos un pequeño programa donde se muestra lo aprendido en esta sección.

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la función principal del programa// Aquí inicia la aplicaciónstatic void Main(string[] args){

// Declaramos las variables, ahora de tipo flotantefloat a, b, resultado;

// Inicializamos las variablesa = 7;b = 8;

Los lenguajes de programación

51www.redusers.com

Los errores más comunes en las expresiones matemáticas son olvidar el punto y coma, hacer

la asignación errónea, escribir mal el nombre de la variable y agrupar incorrectamente las

operaciones. Utilizar los paréntesis para agrupar ayuda mucho a reducir errores.

CÓMO EVITAR ERRORES EN LAS EXPRESIONES MATEMÁTICAS

02_C#2010.qxd 8/6/10 8:16 PM Page 51

Page 54: C# aprenda a programar

resultado = 0;

// SumasConsole.WriteLine(“Sumas”);

resultado = 3 + 5;Console.WriteLine(“Resultado = {0}”,resultado);

resultado = a + 3;Console.WriteLine(“Resultado = {0}”, resultado);

resultado = a + b;Console.WriteLine(“Resultado = {0}”, resultado);

// RestasConsole.WriteLine(“Restas”);

resultado = a - b;Console.WriteLine(“Resultado = {0}”, resultado);

resultado = b - 5;Console.WriteLine(“Resultado = {0}”, resultado);

resultado = b - a; // A la variable b se le resta aConsole.WriteLine(“Resultado = {0}”, resultado);

// MultiplicacionesConsole.WriteLine(“Multiplicaciones”);

resultado = a * 5;Console.WriteLine(“Resultado = {0}”, resultado);

resultado = a * 3.5f;Console.WriteLine(“Resultado = {0}”, resultado);

resultado = a * b;Console.WriteLine(“Resultado = {0}”, resultado);

// DivisionesConsole.WriteLine(“Divisiones”);

2. LOS ELEMENTOS BÁSICOS DE UN PROGRAMA

52 www.redusers.com

02_C#2010.qxd 8/6/10 8:16 PM Page 52

Page 55: C# aprenda a programar

resultado = a / 3;Console.WriteLine(“Resultado = {0}”, resultado);

resultado = a / b;Console.WriteLine(“Resultado = {0}”, resultado);

resultado = b / 2.5f;Console.WriteLine(“Resultado = {0}”, resultado);

// ModuloConsole.WriteLine(“Modulo”);

resultado = a % b;Console.WriteLine(“Resultado = {0}”, resultado);

}}

}

Podemos ver la ejecución en la siguiente figura:

Figura 8. Vemos los resultados de las operaciones aritméticas sobre nuestras variables.

Los lenguajes de programación

53www.redusers.com

02_C#2010.qxd 8/6/10 8:16 PM Page 53

Page 56: C# aprenda a programar

Precedencia de operadoresHasta el momento hemos utilizado expresiones aritméticas sencillas, pero en la vi-da real se pueden necesitar expresiones más complicadas. Entonces, si estas expre-siones no se colocan adecuadamente, esto nos puede ocasionar problemas.

Por ejemplo, veamos la siguiente expresión.

resultado = 3 * 5 + 2;

Esta expresión presenta un problema para nosotros en este momento. No sabemossi primero hace 3*5 y le suma 2, que da como resultado 17, o si suma 5+2 y luegolo multiplica por 3, lo que da como resultado 21. ¿Cuál es la respuesta correcta?La forma de saberlo es por medio de la precedencia de operadores. Ésta nos in-dica el orden en el que se llevan a cabo las operaciones. Este orden depende deltipo de operador que se utiliza. Algunos operadores tienen más precedencia queotros, es decir, se ejecutan primero.La siguiente tabla muestra la precedencia de los operadores que hemos visto hastael momento en C#. Se encuentran listados de mayor a menor precedencia.

OPERADOR DESCRIPCIÓN

* Multiplicación

/ División

% Módulo

+ Adición

- Sustracción

Tabla 3. Esta tabla nos muestra la precedencia de operadores

en C#. La multiplicación tiene más precedencia y se ejecuta primero.

Esto quiere decir que cuando tenemos una expresión aritmética como la del ejem-plo, primero se llevaría a cabo la multiplicación y luego la suma, entonces con estopodemos deducir cómo C# evaluaría la expresión.Pero algunas veces sería mejor si nosotros pudiéramos organizar nuestra expresióncon el fin de hacerla más fácil de leer para nosotros o para que podamos indicar deforma precisa cómo hacer la operación. Para que podamos organizar una expresiónhacemos uso de los paréntesis. Cada sección que tengamos en los paréntesis se eva-lúa como una expresión y el resultado se pasa al resto de la expresión. Supongamosque tenemos la siguiente expresión:

resultado = (3*5) + 2;

2. LOS ELEMENTOS BÁSICOS DE UN PROGRAMA

54 www.redusers.com

02_C#2010.qxd 8/6/10 8:16 PM Page 54

Page 57: C# aprenda a programar

Vemos que por medio de los paréntesis se ha agrupado una parte de la expresión,por lo que se evalúa y equivale a:

resultado = 15 + 2;

Lo que al final evalúa en:

resultado = 17;

Veamos otro ejemplo de cómo podemos usar los paréntesis para indicar cómo de-seamos que se evalúe la expresión.

resultado = 3 * (5+2);

Lo primero que sucede es que se evalúa la expresión contenida en el paréntesis.

resultado = 3 * 7;

Que nos da el valor:

resultado = 21;

Veamos un ejemplo un poco más complicado.

resultado = (3+7) * (36 + 4 *(2+5));

Veamos qué sucede:

resultado = 10 * (36 + 4 * 7);

Luego se continúa evaluando:

resultado = 10 * (36 + 28);

Los lenguajes de programación

55www.redusers.com

02_C#2010.qxd 8/6/10 8:16 PM Page 55

Page 58: C# aprenda a programar

Lo que da como resultado:

resultado = 10 * 64;

Y al final obtenemos:

resultado = 640;

Afortunadamente, C# hace todas estas evaluaciones y todos estos cálculos por no-sotros, pero ahora sabemos cómo sucede y sabemos que podemos usar los parénte-sis para organizar nuestras expresiones aritméticas.

Cómo pedirle datos al usuarioHemos utilizado variables para guardar valores y con los operadores aritméticoshemos podido realizar cálculos matemáticos. Sin embargo, todos los valores quehemos usado se encuentran colocados directamente en el código del programa.Esto no es muy cómodo, ya que si deseamos hacer un cálculo con diferentes va-lores, es necesario modificar el código y compilar nuevamente. Sería más útil sipudiéramos hacer que el usuario colocara los valores que necesita cuando el pro-grama se ejecuta. Para esto, C# nos provee de un método que pertenece a la cla-se Console. El método se llama ReadLine(). Éste no necesita ningún parámetro,por lo que sus paréntesis permanecerán vacíos, y nos regresa una cadena que con-tiene lo que escribió el usuario con el teclado.Ésta es una forma sencilla para pedirle información al usuario. Supongamos que dese-amos pedirle al usuario su nombre, que utilizaremos a posteriori para saludarlo. Paraeso colocamos el siguiente código:

string entrada = ” ”;

2. LOS ELEMENTOS BÁSICOS DE UN PROGRAMA

56 www.redusers.com

Un error común con expresiones grandes es olvidar cerrar un paréntesis en forma adecuada. En

Visual Studio es fácil ver cuáles paréntesis son pareja ya que al seleccionar uno de ellos su

pareja se ilumina. Para cada paréntesis de apertura forzosamente debe de existir un paréntesis

de cierre. Cuando esto no se logra se denomina desbalance de paréntesis.

AGRUPACIÓN DE LOS PARÉNTESIS

02_C#2010.qxd 8/6/10 8:16 PM Page 56

Page 59: C# aprenda a programar

Console.WriteLine(“Escribe tu nombre”);entrada=Console.ReadLine();

Console.WriteLine(“Hola {0}, como estas?”,entrada);

En este fragmento de programa es importante notar cómo el valor obtenido porReadLine() se le asigna a la variable de tipo cadena entrada. Si no colocamos unavariable que recibe el valor de lo escrito por el usuario, éste se perderá. Cuandousemos ReadLine() debemos hacerlo como se muestra. Una vez que recibimos laentrada del usuario podemos trabajar con ella sin problemas.

Conversión de variablesEl método de ReadLine() nos presenta una limitación en este momento ya que só-lo regresa el valor como cadena, pero no podemos utilizar una cadena en operacio-nes aritméticas o asignarla directamente a una variable numérica.Lo que debemos hacer es convertir ese dato numérico guardado como cadena a unvalor numérico útil para nuestros propósitos. C# nos provee de una clase que per-mite hacer conversiones entre los diferentes tipos de variables. Esta clase se cono-ce como convert y tiene una gran cantidad de métodos para la conversión. Aquísólo veremos cómo convertir a enteros y flotantes, ya que son los tipos con los quetrabajaremos en este libro principalmente. Sin embargo, los demás métodos se usande forma similar y podemos encontrar la información necesaria sobre éstos enMSDN (MicroSoft Developer Network).Si queremos convertir del tipo string al tipo int usaremos el método ToInt32(). És-te necesita un parámetro, que es la cadena que deseamos convertir. El método re-gresa un valor de tipo int, por lo que es necesario tener una variable que lo reciba.

Un ejemplo de esto es:

a = Convert.ToInt32(entrada);

Los lenguajes de programación

57www.redusers.com

MSDN es un sitio web donde encontraremos información técnica sobre todas las clases y

funciones, y todos los métodos que conforman los lenguajes que componen Visual Studio.

También es posible encontrar ejemplos y descripciones de los errores de compilación. Tiene un

buen sistema de búsquedas que resulta muy útil. La dirección es www.msdn.com.

MSDN

02_C#2010.qxd 8/6/10 8:16 PM Page 57

Page 60: C# aprenda a programar

De forma similar podemos convertir la cadena a una variable de tipo float. En estecaso usaremos el método ToSingle(). Éste también necesita un parámetro, que es lacadena que contiene el valor a convertir. Como regresa un valor flotante, entoncesdebemos tener una variable de tipo float que lo reciba.

valor = Convert.ToSingle(entrada);

Ya que tenemos los valores convertidos a números, entonces podemos hacer uso deellos. Veamos un ejemplo donde le pedimos información al usuario.

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la función principal del programa// Aquí inicia la aplicaciónstatic void Main(string[] args){

// Declaramos variablesstring entrada = “”;int a = 0, b = 0, resultado = 0;

// Leemos una cadenaConsole.WriteLine(“Escribe tu nombre”);entrada = Console.ReadLine();

Console.WriteLine(“Hola {0}, como estas?”, entrada);

// Leemos dos valores y los sumamos.

Console.Write(“Dame un entero:”);entrada = Console.ReadLine();

// Convertimos la cadena a enteroa = Convert.ToInt32(entrada);

2. LOS ELEMENTOS BÁSICOS DE UN PROGRAMA

58 www.redusers.com

02_C#2010.qxd 8/6/10 8:16 PM Page 58

Page 61: C# aprenda a programar

Console.Write(“Dame otro numero entero:”);entrada = Console.ReadLine();

// Convertimos la cadena a enterob = Convert.ToInt32(entrada);

// Sumamos los valoresresultado = a + b;

// Mostramos el resultadoConsole.WriteLine(“El resultado es {0}”, resultado);

}}

}

Ahora compilemos y ejecutemos la aplicación. Para introducir los datos, simplemen-te los escribimos con el teclado y al finalizar oprimimos la tecla ENTER o RETURN.

Figura 9. Éste es el resultado de la ejecución, donde vemos

que la suma se lleva a cabo con los valores introducidos por el usuario.

Los lenguajes de programación

59www.redusers.com

02_C#2010.qxd 8/6/10 8:16 PM Page 59

Page 62: C# aprenda a programar

Cómo resolver problemas en la computadoraYa que conocemos algunos elementos del lenguaje, ahora es importante apren-der cómo resolver los problemas en la computadora. Existen diferentes metodo-logías para hacerlo, pero como éste es un libro dirigido a gente sin experienciaen programación aprenderemos un método sencillo. Como ya hemos mencio-nado, C# es un lenguaje orientado a objetos. Sin embargo, primero aprendere-mos una metodología estructurada, lo que nos permitirá tener experiencia en laresolución de problemas y luego podremos aprender la metodología orientada aobjetos de manera más sencilla.La metodología que aprendemos se basa en el concepto de subdivisión de problemas.Es decir que tomamos el problema general y luego lo dividimos en problemas máspequeños y si es necesario, dividimos estos subproblemas en problemas más peque-ños, hasta que podamos resolver el subproblema directamente.Para resolver cualquier problema, lo primero que tenemos que hacer es entenderlo.Hay que entender de forma precisa qué es lo que se pide. Los problemas tendráninformación. En muchos casos, el problema nos da directamente la información. Aeste tipo de información se lo conoce como información explícita. Pero tambiéna veces sucede que el problema no nos da directamente la información, por eso esimportante entenderlo bien. En este caso nosotros debemos inferir la informaciónde otros datos que nos proporciona o buscarla en algún otro lugar. A este tipo deinformación se lo conoce como información implícita. Afortunadamente, la in-formación implícita en muchos casos es fácil de encontrar o forma parte de los co-nocimientos generales de cualquier persona.Ya que tenemos el problema subdividido y los datos reconocidos, procedemos a re-alizar el algoritmo. Recordemos que el algoritmo es la serie de pasos necesarios pa-ra resolver el problema. Además, éste puede definirse por medio de un diagrama deflujo o escribirse en algo que denominaremos pseudocódigo. El programador pue-de crear el algoritmo con su método de preferencia.Cuando se ha terminado el algoritmo, procedemos a probarlo. En esta etapa pode-mos probar en el papel si todo funciona bien. Si hubiera algún resultado erróneo,entonces se puede corregir el algoritmo y el proceso se repite hasta que tengamosun algoritmo que funcione adecuadamente.

2. LOS ELEMENTOS BÁSICOS DE UN PROGRAMA

60 www.redusers.com

Tambien es posible convertir de números a cadenas. Para esto se usa el método ToString(), que

está disponible en todos los tipos numéricos de C#. De esta forma podemos utilizar la

información de las variables numéricas en funciones o métodos que trabajen con cadenas. El

método no cambia el tipo, simplemente regresa una cadena que contiene el texto de ese valor.

CONVERSIÓN DE NÚMEROS A CADENAS

02_C#2010.qxd 8/6/10 8:16 PM Page 60

Page 63: C# aprenda a programar

El último paso consiste en pasar el algoritmo a programa de computadora. Si to-do se ha realizado correctamente, el programa deberá ejecutarse al primer inten-to. Mucha gente se sorprende que para hacer un programa de computadora, el úl-timo paso sea colocarlo en la computadora, pero ésta es la forma correcta. Algu-nos programadores no profesionales intentan hacer el programa directamente enla computadora, pero esto acarrea muchos errores de lógica y datos, y el tiempoen que resuelve el mismo problema es mayor y es difícil que se ejecute correcta-mente al primer intento. Aunque la metodología que acabamos de presentar pa-rece larga, en realidad puede ahorrar hasta un 50% del tiempo de resolución encomparación con alguien que programe directamente en la computadora. Ahoraque empezamos, es bueno adquirir hábitos correctos de programación desde elinicio. En el futuro, en especial cuando los problemas que se resuelvan sean com-plicados, se apreciarán los beneficios.

Elementos de un diagrama de flujoEs momento de aprender los componentes básicos de un diagrama de flujo. Conestos diagramas podemos representar el algoritmo y son fáciles de hacer y entender.Otra ventaja que tienen es que son independientes del lenguaje, lo que nos da la fle-xibilidad de resolver el problema y usar nuestra solución en cualquier lenguaje.El diagrama de flujo es una representación gráfica del algoritmo y tiene diferentescomponentes. Cada componente es una figura y ésta representa un tipo de actividad.En el interior de la figura colocamos una descripción del paso que está sucediendo ahí.Por medio de flechas indicamos cuál es el paso siguiente y nos da la idea del flujogeneral del algoritmo. En algunas ocasiones, a las flechas les agregamos informaciónextra, pero esto lo veremos más adelante. Aunque en este momento no utilizaremostodos los componentes del diagrama de flujo, sí conoceremos los más importantes,ya que en los capítulos posteriores los utilizaremos.El primer componente tiene forma de ovalo y se lo conoce como terminador. És-te nos sirve para indicar el inicio o el final del algoritmo. Al verlo podemos saberinmediatamente dónde inicia el algoritmo y poder continuar a partir de ahí. Hayque recordar que los algoritmos deben tener un final para que sean válidos. Si el ter-minador es de inicio, colocamos en su interior el mensaje: Inicio. Si el terminadorindica dónde se acaba el algoritmo, entonces se coloca el mensaje: Final.

Figura 10. En esta figura podemos observar el terminador tanto

en su papel como punto de inicio como punto final del algoritmo.

Inicio Final

Los lenguajes de programación

61www.redusers.com

02_C#2010.qxd 8/6/10 8:16 PM Page 61

Page 64: C# aprenda a programar

El siguiente elemento se conoce como proceso. Éste tiene la forma de un rectán-gulo y nos sirve para indicar que precisamente un proceso debe llevarse a cabo enese lugar. La descripción del proceso se indica en su interior.

Figura 11. El proceso se indica por medio

de un rectángulo. En su interior indicamos lo que se tiene que procesar.

Similar al proceso, tenemos el proceso predefinido. Su forma también es un rec-tángulo, pero éste tiene dos franjas a los lados. Se usa para indicar que haremos usode un proceso que ya ha sido definido en otra parte. Un ejemplo de esto sería unmétodo, como los que ya hemos usado. Principalmente lo usaremos para indicarllamadas a funciones o métodos definidos por nosotros mismos. En un capítulo pos-terior aprenderemos cómo hacer nuestros propios métodos.

Figura 12. Éste es el símbolo usado para el proceso predefinido.

Nuestro próximo elemento es conocido como condición. Utilizaremos este ele-mento cuando aprendamos cómo hacer que el programa tome sus propias

Tolnt32()

A = b + c

2. LOS ELEMENTOS BÁSICOS DE UN PROGRAMA

62 www.redusers.com

Algunas veces necesitaremos variables que nos apoyen para resolver algún cálculo o proceso.

A éstas las llamaremos datos de trabajo. Los datos de trabajo se descubren cuando hacemos el

análisis del problema. Si llegamos a omitir alguno durante el análisis siempre es posible

agregarlo durante el desarrollo, pero esto debe ser la excepción a la regla.

DATOS DE TRABAJO

02_C#2010.qxd 8/6/10 8:16 PM Page 62

Page 65: C# aprenda a programar

decisiones. Básicamente, sirve para hacer una selección entre las posibles rutas deejecución del algoritmo, que dependerá del valor de la expresión evaluada. Suforma es la de un rombo y a partir de las esquinas de éste surgirán las flechas ha-cia las posibles rutas de ejecución del algoritmo.

Figura 13. La decisión se representa con un rombo.

Luego nos encontramos con un componente conocido como datos. Su forma esla de un paralelogramo y podemos usarlo para indicar la salida o la entrada delos datos. Un ejemplo de esto sería cuando llevamos a cabo la petición de un va-lor al usuario o cuando mostramos un valor en pantalla. Adentro de él indica-mos qué dato se pide o se presenta.

Figura 14. En este caso usamos el dato

para indicar la petición del valor de una variable.

Hemos visto los elementos principales del diagrama de flujo. Ahora podemos hacerun ejercicio que muestre la solución de un problema en la computadora.

Pedir A

A > B

Los lenguajes de programación

63www.redusers.com

Es una versión gratuita de C# con las herramientas básicas para programar en este lenguaje.

Esta versión nos provee todo lo necesario para los temas que aprenderemos en este libro.

Aunque la versión es gratuita, es necesario registrarla para poder utilizarla por más de treinta

días. La podemos descargar de http://msdn2.microsoft.com/en-us/express/aa700756.aspx.

C# EXPRESS...

02_C#2010.qxd 8/6/10 8:16 PM Page 63

Page 66: C# aprenda a programar

Resolución de problemas en la computadoraEmpecemos por un problema sencillo y fácil de entender. Para este problema se-guiremos todos los pasos que hemos mencionado hasta llegar al programa de cóm-puto final. En primer lugar, tenemos la descripción del problema.Hacer un programa de cómputo que calcule el área y el perímetro de un rectángulodados sus lados. Una vez que tenemos el problema y lo hemos entendido, entoncesprocedemos a subdividirlo en problemas más pequeños que sean fáciles de resolver.Esta subdivisión puede ser hecha por medio de un diagrama y para esto hay que re-cordar que si alguno de los problemas aún continua siendo difícil, lo podemos seguirsubdividiendo. A modo de ejemplo exageraremos un poco la subdivisión en este ca-so. El problema quedaría subdividido como se muestra en la siguiente figura.

Figura 15. Aquí tenemos nuestro problema

subdividido en problemas menores y fáciles de resolver.

Ya que conocemos el problema y lo hemos subdividido en varios subproblemas, po-demos identificar de manera más clara los datos que nos hacen falta para poder tra-bajar en él. La descripción del problema nos proporciona dos datos explícitos: el

Calcular área y perímetro

del rectángulo

Calcular áreaPedir datos

Pedir

ancho

Pedir

alto

Mostrar

área

Mostrar

perímetro

Mostrar

resultados

Calcular

perímetro

2. LOS ELEMENTOS BÁSICOS DE UN PROGRAMA

64 www.redusers.com

Si queremos encontrar información sobre cualquier clase o método de C#, el lugar apropiado

para hacerlo es el sitio web MSDN que nos provee Microsoft. Cuando realicemos la búsqueda

debemos filtrar para buscar únicamente contenidos del lenguaje C# y así evitar confusiones con

información de otros lenguajes. La dirección es www.msdn.com.

MSDN

02_C#2010.qxd 8/6/10 8:16 PM Page 64

Page 67: C# aprenda a programar

área y el perímetro. Pero también reconocemos inmediatamente dos datos implíci-tos que son necesarios: el alto y el ancho del rectángulo.Nosotros sabemos que necesitamos una cadena para recibir el valor escrito por elusuario, pero como tal, esta cadena no forma parte del problema. Sin embargo, nosayuda a resolverlo, por lo que la cadena será un dato de trabajo. Los datos que he-mos identificados serán colocados en una tabla de la siguiente forma:

NOMBRE TIPO VALOR INICIAL

área Float 0.0

perímetro Float 0.0

ancho Float 1.0

alto Flota 1.0

valor String “”

Tabla 4. Tabla de variables para el programa que estamos resolviendo.

Hemos decidido usar el tipo float, ya que podemos tener valores decimales en el cál-culo del perímetro. Como un rectángulo con ancho o alto de 0 no tiene sentido,hemos seleccionado como valor inicial para estas variables a 1.Ahora viene el paso más importante: la creación del algoritmo. Sin embargo, si ob-servamos la forma como subdividimos el problema, podemos ver que nos da unaindicación de los pasos que son necesarios colocar en el algoritmo.

Figura 16. La subdivisión nos muestra una lista

de los pasos posibles necesarios en la subdivisión del algoritmo.

Con esta información creamos el algoritmo con el diagrama de flujo. En éste apare-ce la secuencia de pasos en el orden correcto. Veamos cómo queda el diagrama.

Calcular área y perímetro

del rectángulo

Calcular áreaPedir datos

Pedir

ancho

Pedir

alto

Mostrar

área

Mostrar

perímetro

Mostrar

resultados

Calcular

perímetro

Los lenguajes de programación

65www.redusers.com

02_C#2010.qxd 8/6/10 8:16 PM Page 65

Page 68: C# aprenda a programar

Figura 17. El diagrama de flujo muestra el algoritmo.

Las diferentes figuras nos indican el tipo de actividad que se realiza.

Podemos observar cómo hemos utilizado el trapezoide cuando es necesario pedirleo mostrarle un dato al usuario. Los cálculos con la fórmula correspondiente estánen los rectángulos, ya que son procesos, y el inicio y fin del algoritmo están re-presentados por los terminadores.

Pedir ancho

Pedir alto

Mostrar área

Mostrar

perímetro

Área = ancho • alto

Perímetro =

(ancho + alto) • 2

Inicio

Fin

2. LOS ELEMENTOS BÁSICOS DE UN PROGRAMA

66 www.redusers.com

02_C#2010.qxd 8/6/10 8:16 PM Page 66

Page 69: C# aprenda a programar

El código de nuestra aplicaciónYa tenemos todo lo necesario para poder crear el código del programa. Para esto ha-remos uso de la aplicación base que ya tenemos. Como creamos una tabla de datos,ya conocemos todas las variables necesarias para la aplicación. Entonces tomamosesta tabla y colocamos los datos como variables.

// Declaramos las variables que necesitamosfloat area = 0.0f;float perimetro = 0.0f;float ancho = 1.0f;float alto = 1.0f;string valor = ””;

Con las variables definidas, entonces procedemos a codificar cada uno de los pasosdel algoritmo. Recorremos paso por paso y en el mismo orden en que se encuen-tran, y vemos que lo primero es pedir el ancho del rectángulo.

Console.Write(“Dame el ancho del rectángulo: “);valor = Console.ReadLine();

ancho = Convert.ToSingle(valor); // Convertimos a flotante

Lo siguiente que hace el algoritmo es pedir el alto del rectángulo, entonces el códi-go necesario es el siguiente.

Console.Write(“Dame el alto del rectángulo: “);valor = Console.ReadLine();

alto = Convert.ToSingle(valor); // Convertimos a flotante

Los lenguajes de programación

67www.redusers.com

Aprender a programar requiere de mucha práctica y mucha experimentación. Es bueno probar

con los programas y ver qué es lo que sucede. No debemos temer en cometer errores cuando

estamos aprendiendo. También es bueno verificar la documentación para las funciones, las

clases y los métodos ya que es posible encontrar utilidades en éstas para el futuro.

EXPERIMENTANDO

02_C#2010.qxd 8/6/10 8:16 PM Page 67

Page 70: C# aprenda a programar

Una vez que hemos obtenido todos los datos de entrada, podemos decir que ya te-nemos un proceso. Este proceso será el encargado de calcular el área que ocupa elrectángulo. Veamos el ejemplo a continuación:

area = ancho * alto;

En el próximo proceso que tenemos se calcula el perímetro.

perimetro = (ancho + alto) * 2;

Si vemos con detenimiento el algoritmo y también su paso siguiente, encontra-remos que volvemos a trabajar con datos nuevamente, pero en este último casosólo mostramos en pantalla el valor de área calculado.Veamos para comprender mejor de qué hablamos.

Console.WriteLine(“El área es : {0} unidades cuadradas”, area);

Como último paso del algoritmo que se está ejecutando, sólo queda que mostre-mos en nuestra aplicación de consola, el valor calculado del perímetro.A continuación escribamos el último código necesario en nuestra aplicación:

Console.WriteLine(“El perímetro es : {0} unidades”, perimetro);

Hemos visto hasta aquí una forma completa y compleja de cómo manejar desdeuna aplicación de consola, la manipulación de datos, variables y operaciones ma-temáticas, con un claro ejemplo estudiado paso a paso. Con esto ya hemos fina-lizado el código de la aplicación. Ahora lo podemos compilar y probar, y todo de-be funcionar correctamente, si no hemos olvidado de colocar nada en él.

2. LOS ELEMENTOS BÁSICOS DE UN PROGRAMA

68 www.redusers.com

Un sitio web que nos presenta diferentes recursos de C# y cuyo contenido está en idioma inglés

es: www.csharphelp.com. Aquí podremos encontrar información cuando tengamos algún

problema con el lenguaje o deseemos aprender cómo se realiza algo en particular. También hay

información para programar con formas de Windows.

SITIO CON RECURSOS SOBRE C#

02_C#2010.qxd 8/6/10 8:16 PM Page 68

Page 71: C# aprenda a programar

Figura 18. Aquí podemos ver la ejecución de nuestro

programa, la forma como pide los datos y los resultados calculados.

Los lenguajes de programación

69www.redusers.com

… RESUMEN

Para programar software para computadoras necesitamos conocer un lenguaje de

programación. Uno de estos lenguajes es C#. Los programas deben ser ordenados e

indicar paso a paso lo que se debe hacer, y para esto hacemos uso de los algoritmos. La

información se guarda en variables y el tipo indica la información que puede tener en su

interior por lo que es posible mostrar datos en la consola y también pedírselos al usuario.

Los operadores aritméticos nos permiten llevar a cabo operaciones matemáticas, siempre

que usemos una metodología correcta de resolución de problemas.

02_C#2010.qxd 8/6/10 8:16 PM Page 69

Page 72: C# aprenda a programar

70 www.redusers.com

TEST DE AUTOEVALUACIÓN

1 ¿Qué es un algoritmo?

2 ¿Qué características tienen los

algoritmos?

3 ¿Qué es una sentencia?

4 ¿Cómo se finalizan las sentencias?

5 ¿Cuál es la diferencia entre Write() y

WriteLine()?

6 ¿Qué es una cadena?

7 ¿Qué es una variable?

8 ¿Cómo mostramos el valor de una

variable?

9 ¿Cómo le solicitamos un dato al usuario?

10¿Cómo se convierte una cadena a un valor

numérico?

11¿Qué son los operadores aritméticos?

12¿De qué forma podemos agrupar

operaciones aritméticas?

ACTIVIDADES

EJERCICIOS PRÁCTICOS

1 Hacer un programa que calcule el

perímetro de cualquier polígono regular.

2 Generar en este proyecto un error

a propósito y ver cómo se comporta

el compilador.

3 Hacer un programa que transforme de

grados a radianes.

4 Hacer un programa que transforme de

grados centígrados a grados Fahrenheit.

5 Hacer un programa que transforme entre

dólares y euros y que también pida el tipo

de cambio del día.

02_C#2010.qxd 8/6/10 8:17 PM Page 70

Page 73: C# aprenda a programar

El programa

toma

decisiones

La toma de decisiones 72Expresiones relacionales 72El uso de if 76El uso de else 84Cómo usar if anidados 89Escalera de if-else 92Expresiones lógicas 96El uso de switch 105

Resumen 109Actividades 110

Capítulo 3

En los programas creados hasta ahora,

hemos visto que los algoritmos tenían

un solo sentido de resolución. En este

capítulo aprenderemos otras formas

diferentes de hacer que nuestros

programas tomen decisiones en base

al análisis de diversos parámetros,

y también aprenderemos a crear

algoritmos con diferentes rutas

de ejecución para poder solucionar

problemas en base a un previo análisis.

C#

SERVICIO DE ATENCIÓN AL LECTOR: [email protected]

03_C#2010_AJUSTADO.qxd 8/11/10 9:46 AM Page 71

Page 74: C# aprenda a programar

LA TOMA DE DECISIONES

No todos los problemas se resuelven linealmente, a veces es necesario tener quetomar una decisión o ejecutar determinadas acciones cuando una condición secumple, y otras cuando no lo hace. Supongamos que nuestro problema consisteen mantener la temperatura de un balde con agua tibia. Para hacerlo nosotros po-demos agregar agua caliente o agua fría. En este problema necesitaríamos tomaruna decisión sobre qué tipo de agua agregar. De igual forma, hay muchos pro-blemas en los que para poder resolverlos necesitamos conocer una condición otomar una decisión. En C# es sencillo poder lograr esto, ya que el lenguaje nosprovee diferentes herramientas para poder lograrlo. Tendremos que utilizar ex-presiones y éstas se evaluarán. En este caso usaremos expresiones relacionales yexpresiones lógicas, que se evaluarán, y dependiendo del resultado de esa eva-luación, se llevarán a cabo ciertos pasos del algoritmo u otros.Empecemos por conocer las expresiones que necesitamos.

Expresiones relacionalesLas expresiones relacionales se usan para expresar la relación que existe entre dosvalores. Los valores pueden estar contenidos adentro de variables o ser colocadosexplícitamente. Estas expresiones, al igual que las expresiones aritméticas, tienensus propios operadores. La expresión será evaluada, pero el resultado de la evalua-ción tendrá únicamente dos valores posibles: true o false.Ambos valores son de tipo bool y true es usado para indicar que la expresión eva-luada es verdadera. El valor de false por su parte se utiliza para indicar que laexpresión evaluada es falsa.Empecemos por conocer primero a los operadores relacionales y luego veremosejemplos de expresiones relacionales con su resolución.

Operadores relacionalesEn la tabla 1 podemos apreciar los operadores relacionales en C#. La forma como es-tán escritos sus signos es la forma como debemos colocarlos en nuestro programa.

3. EL PROGRAMA TOMA DECISIONES

72 www.redusers.com

Un error muy común que sucede cuando se empieza a programar en C# es el de confundir el

operador de igualdad con el de asignación. Si se obtiene un error en una expresión, hay que

verificar esto. No olvidemos que la asignación lleva un signo igual y la igualdad doble signo igual.

ERROR MUY COMÚN CON LA IGUALDAD

03_C#2010_AJUSTADO.qxd 8/6/10 8:31 PM Page 72

Page 75: C# aprenda a programar

SIGNO OPERADOR

== Igualdad

!= No igual

> Mayor que

< Menor que

>= Mayor que igual

<= Menor que igual

Tabla 1. Esta tabla nos muestra los diferentes operadores relacionales de C#.

El operador de igualdad se representa con dos signos igual juntos y sin espacio. Co-locar un solo signo igual, indica que el operador será de asignación. Esto puede de-rivar en errores de lógica, porque una asignación siempre evalúa a verdadero, perouna igualdad no. Este operador es el más sencillo. Supongamos que ya tenemos lasvariables y las inicializamos con los siguientes valores:

int a = 5;int b = 7;int c = 5;int d = 4;

Ahora crearemos nuestra primera expresión y la evaluaremos:

a == c

Como el valor contenido en a es 5 y el valor contenido en c también es 5, vemos quese cumple 5 igual a 5, por lo que la expresión se evalúa como true.Veamos qué sucede en la siguiente expresión:

a == d

En este caso el valor contenido en d es 4, por lo que la expresión 5 igual a 4 nose cumple y el valor de la expresión es false. En el lado derecho y en el lado iz-quierdo de la expresión podemos colocar cualquier valor, variable o expresión.Si colocásemos una expresión, primero se evaluaría ésta y luego se procedería aevaluar la expresión relacional principal.

a == (3 + 2)

La toma de decisiones

73www.redusers.com

03_C#2010_AJUSTADO.qxd 8/6/10 8:31 PM Page 73

Page 76: C# aprenda a programar

En este caso 3 + 2 se evalúa como 5 y luego 5 igual a 5, lo que nos da como valorfinal de la expresión true. Otro ejemplo es el siguiente:

(b – 2) == d

Al evaluar b - 2 obtenemos 5, entonces la expresión es 5 igual a 4, lo que evidente-mente nos da como resultado final false.Ésta es la forma como se evalúan las expresiones relacionales y ahora veremos másejemplos con otros operadores. También tenemos al operador de desigualdad, quese crea por medio de un signo de admiración y luego el signo de igual.

a != 7

En este caso tenemos 5 no es igual a 7, lo cual es cierto, y obtenemos el valor truecomo resultado de la evaluación.

a != c

Para esta expresión tenemos 5 no es igual a 5, y se evalúa la expresión como falsa,lo que nos da false como valor final. El operador > sirve para evaluar una relacióndel tipo mayor que. Si el valor del lado izquierdo es mayor que el valor del lado de-recho, regresará true, en caso contrario regresará false.

b > a

Esto es 7 mayor que 5 y da como resultado true.

a > b

En este caso 5 mayor que 7 es falso y el resultado de la expresión es false.

b > b

Este expresión nos da 6 mayor que 6, lo cual, si analizamos todos los pasos hastaaquí, nos indica que es falso también y obtenemos false como resultado.

3. EL PROGRAMA TOMA DECISIONES

74 www.redusers.com

03_C#2010_AJUSTADO.qxd 8/6/10 8:31 PM Page 74

Page 77: C# aprenda a programar

En el operador < evaluamos una relación del tipo menor que. Ésta da true comoresultado si el valor del lado izquierdo es menor que el valor que encontramos en ellado derecho. Si esto no se cumple, entonces el valor regresado será false.

d < a

Tenemos 4 menor que 5, lo que resulta cierto y el resultado es true.

d < (a - 3)

La expresión a evaluar es 4 menor que 2, y se tiene false como resultado de laexpresión.

d < d

Esta expresión también da como resultado false, ya que 4 menor que 4 no es ver-dadera. Para poder evaluar si un valor es mayor que o igual a otro valor usamos eloperador >=. Su forma de trabajo es similar a la de los otros operadores.

b >= a

Para esta expresión tenemos 7 mayor que igual a 5, es cierta y da true de resultado.

b >= (a + c)

En este caso obtendríamos 7 mayor que igual a 10, lo cual sabemos que es falso yy, por lo cual, como resultado obtendríamos false.

La toma de decisiones

75www.redusers.com

Los operadores que se escriben con dos signos deben escribirse correctamente. No es lo mismo

>= que =>. Esto puede llevarnos a errores de sintaxis, pero al escribirlos en la forma correcta se

verán corregidos. También debemos recordar que se escriben sin espacios entre los signos, ya

que esto nos lleva a otro error de sintaxis.

COLOCAR LOS OPERADORES ADECUADAMENTE

03_C#2010_AJUSTADO.qxd 8/6/10 8:31 PM Page 75

Page 78: C# aprenda a programar

b >= b

Aquí comparamos la diferencia de resultado con relación a usar >= en lugar de >. Pa-ra esta expresión evaluamos 7 mayor que igual a 7. Esto es verdadero y el resultadofinal es true. De igual manera tenemos al operador <=, pero éste evalúa a la inversa.

a <= b

La expresión a evaluar es 5 menor que igual a 7, y obtenemos true como resultado.

(a + c) <= b

En este caso tenemos 10 menor que igual a 7 y resulta falso.

(a + 2)<= b

En esta última expresión 7 menor que igual a 7 es verdadero y nuevamente obte-nemos true como resultado.

El uso de ifYa aprendimos a usar las expresiones relacionales y el tipo de valor devuelto. Es elmomento de hacer algo práctico con ellas. Este tipo de expresiones se usa endiferentes casos, pero generalmente en las estructuras selectivas o repetitivas.Las estructuras selectivas serán estudiadas en este capítulo, las repetitivas en un capí-tulo posterior. Las estructuras selectivas son aquellas que nos permiten hacer unaselección entre dos o varias rutas de ejecución posibles. La selección se llevará a cabosegún el valor de una expresión. Esta expresión puede ser una expresión relacional.Nuestra primera estructura selectiva se conoce como if, que es un si condicional. Si tal cosa sucede, entonces haz tal cosa. El uso del if es sencillo:

if(expresión)Sentencia a ejecutar

El uso de if requiere que coloquemos una expresión a evaluar entre paréntesis. Si elresultado de esta expresión es true, entonces la sentencia a ejecutar se lleva a cabo.

3. EL PROGRAMA TOMA DECISIONES

76 www.redusers.com

03_C#2010_AJUSTADO.qxd 8/6/10 8:31 PM Page 76

Page 79: C# aprenda a programar

Si el resultado de la evaluación es false, entonces la sentencia a ejecutar nunca se lle-va a cabo, o dicho de otra forma, es ignorada.En el diagrama de flujo if se representa por medio de un rombo. En el interior delrombo colocamos la expresión a evaluar, de las esquinas sacamos una ruta de ejecu-ción en el caso de que sí se cumpla la condición o en el caso de que no se cumpla.

Figura 1. Este rombo simboliza a if con la expresión en su interior.

Veamos un primer ejemplo donde nos puede servir if y las expresiones. Crearemosun programa que le pida al usuario un número, y la computadora debe decir si elnúmero es positivo o negativo. Para ver el algoritmo de este programa, creamos sudiagrama de flujo e incluimos los if necesarios.

Figura 2. Éste es el diagrama de flujo del algoritmo para resolver

el problema. Podemos observar que tenemos dos rutas de ejecución en cada if.

Mostrar "El número

es positivo"

Pedir número

Inicio

Fin

Número>=0 SI

NO

NO Mostrar "El número

es negativo"

Número>0 SI

Expresión

SI NO

La toma de decisiones

77www.redusers.com

03_C#2010_AJUSTADO.qxd 8/6/10 8:31 PM Page 77

Page 80: C# aprenda a programar

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{class Program

{// Esta es la función principal del programa// Aquí inicia la aplicaciónstatic void Main(string[] args)

{int numero = 0; // Donde guardamos el númerostring valor = “”; // Para guardar la cadena dada por el usuario

// Pedimos el númeroConsole.Write(“Dame un numero entero:”);Valor = Console.ReadLine();numero = Convert.ToInt32(valor); // Convertimos la cadena a entero

// Hacemos uso de if con la expresión para el caso de los positivosif (numero >= 0)Console.WriteLine(“El numero {0} es positivo”, numero); // se ejecuta si se

cumple numero>=0

// Hacemos uso de if con la expresión para el caso de los negativos if (numero < 0)Console.WriteLine(“El numero {0} es negativo”, numero); // se ejecuta si se

cumple numero<0

}

3. EL PROGRAMA TOMA DECISIONES

78 www.redusers.com

Cuando hacemos uso de if, nunca debemos colocar punto y coma después del paréntesis ya que

hacerlo no es un error de sintaxis sino de lógica. El compilador interpreta esto como si deseamos

que se ejecute una sentencia vacía cuando if se cumple. Si vemos que la sentencia if siempre se

cumple sin importar cómo se evalúa la expresión, es posible que tengamos este error.

EL USO CORRECTO DE LA SENTENCIA CON IF

03_C#2010_AJUSTADO.qxd 8/6/10 8:31 PM Page 78

Page 81: C# aprenda a programar

}}

La primera parte el programa es de muy fácil comprensión. Luego de ésta, nos encon-tramos con la primera sentencia if. Para este if se tiene la expresión numero >= 0. Si esaexpresión se evalúa como true, entonces la siguiente sentencia se ejecuta, de lo con-trario será ignorada y continuará el programa.Supongamos que el valor guardado en numero es 3, entonces la expresión relacio-nal regresa un valor de true. Al obtener true, if lleva a la ejecución y el mensaje quedice que se ejecuta un número positivo.Luego se continúa con el siguiente if. Para éste, la expresión es numero < 0, co-mo en este ejemplo numero vale 3, entonces la expresión se evalúa como false,por lo que, mientras el valor de la expresión sea false, if no ejecutará en ningúnmomento el mensaje que dice que el número es negativo. Esto es exactamente loque deseamos que realice desde un principio este programa.

Figura 3. Éste es el resultado de la ejecución

cuando pasamos un número positivo al programa.

Éste es un buen momento para comenzar a experimentar en nuestros desarrollos,cambiando los valores, tanto negativos como positivos, incluido el cero y ver có-mo responderá nuestro programa.

La toma de decisiones

79www.redusers.com

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 79

Page 82: C# aprenda a programar

Figura 4. En este caso damos un número negativo

y podemos observar el comportamiento del programa.

Bloque de código con ifComo vimos, if efectivamente puede sernos de mucha utilidad para que el progra-ma lleve a cabo la decisión correcta, sin embargo, solamente ha podido ejecutar unasentencia. Con frecuencia nos encontraremos con el caso cuando necesitamos quese ejecute más de una sentencia si la condición se cumple. Una buena opción pararesolver este inconveniente encontrado es colocarle un bloque de código a if. Eneste caso, el bloque de código se ejecutará siempre que la expresión dentro de if seaevaluada como true, y el bloque de código completo será ignorado siempre que laexpresión sea evaluada como false.El bloque de código es un conjunto de sentencias agrupadas y debe ser abierto con{ y cerrado con }, quedará compuesto de la siguiente forma:

if(expresión){

Sentencia 1;Sentencia 2;…Sentencia n;

}

3. EL PROGRAMA TOMA DECISIONES

80 www.redusers.com

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 80

Page 83: C# aprenda a programar

Veamos un ejemplo donde hacemos uso de esto. Sabemos que la división entrecero no está definida, entonces debemos hacer un programa que le pregunte alusuario el dividendo y el divisor, pero que cuando el divisor sea cero no lleve acabo la división. Como siempre, primero hacemos nuestro análisis y creamos elalgoritmo en forma de diagrama de flujo.

Figura 5. Éste es el diagrama de flujo del algoritmo. Podemos pensar que

lo que hemos agrupado es lo que se encuentra adentro del bloque de código de if.

El programa queda de la siguiente forma:

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{class Program

{// Esta es la función principal del programa

Pedir dividendo

Pedir divisor

Mostrar resultado

Inicio

Fin

Resultado =

dividendo/divisor

Divisor!=0SÍ

NO

La toma de decisiones

81www.redusers.com

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 81

Page 84: C# aprenda a programar

// Aquí inicia la aplicaciónstatic void Main(string[] args)

{// Variables necesariasfloat dividendo = 0.0f;float divisor = 1.0f;float resultado = 0.0f;string valor = “”;

// Pedimos el dividendoConsole.WriteLine(“Dame el dividendo:”);valor = Console.ReadLine();dividendo = Convert.ToInt32(valor);

// Pedimos el divisorConsole.WriteLine(“Dame el divisor:”);valor = Console.ReadLine();divisor = Convert.ToInt32(valor);

// Si el divisor es válido, entonces hacemos la divisiónif (divisor != 0.0f)

{// Hacemos la operaciónresultado = dividendo / divisor;

// Mostramos el resultadoConsole.WriteLine(“El resultado de la división es {0}”,

resultado);}

}}

}

Podemos observar que hemos colocado un bloque de código para if. Si la expresión dedivisor != 0.0f es verdadera, entonces se ejecuta el bloque de código donde tenemos laoperación y el desplegado del resultado. Si la expresión se evalúa como falsa, todo elbloque de código es ignorado y no ejecutan las sentencias que están en su interior.Ahora podemos compilar el programa y dar valores para hacer pruebas y observarel comportamiento. Vemos que efectivamente cuando el divisor tiene un valor decero, la operación y el mensaje no se ejecutan.

3. EL PROGRAMA TOMA DECISIONES

82 www.redusers.com

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 82

Page 85: C# aprenda a programar

Figura 6. En este caso visto aquí, es ejecutada

la división y a continuación se muestra el resultado.

Figura 7. Como hemos colocado el valor

de cero en el divisor, la división no se lleva a cabo.

La toma de decisiones

83www.redusers.com

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 83

Page 86: C# aprenda a programar

El uso de elseCon los programas anteriores con los que estuvimos trabajando, donde utilizamosla sentencia if, hemos visto que podemos indicar que determinada sentencia seejecute cuando deseamos que una condición se cumpla. Sin embargo, puede ocu-rrir que a veces necesitamos que una sentencia se ejecute cuando se cumple la con-dición y que otra sentencia se ejecute cuando esa condición no se cumpla. Si nosencontramos en este caso, una forma de resolverlo sería colocar un if con una con-dición y luego otro if con una condición que sea complemento de la primera. Es-to ya lo hemos hecho anteriormente en el programa de los números positivos ynegativos. Sin embargo, existe otra forma más sencilla que la utilizada en este pro-grama para hacerlo. Esta forma puede sernos de mucha utilidad para simplificarla lógica y que no nos veamos obligados de tener que colocar tantos if dentro deuna sentencia. Para lograr esto haremos uso de else. Siempre utilizaremos else a continuación de una sentencia if, ya que else no se pue-de usar sólo. Tenemos que colocar nuestro código de la siguiente forma:

if(condición)Sentencia1;

elseSentencia2;

Si la condición es evaluada como verdadera, entonces se ejecuta la sentencia 1,en cambio, cuando la condición se evalúa como falsa, se ejecuta la sentencia 2. A continuación analizaremos cómo hacer uso de este caso para simplificarnuestro código. Para esto elegimos para representar este ejemplo el programade los números positivos y negativos.Lo primero que tenemos para analizar es el gráfico del diagrama de flujo, y, co-mo utilizamos una estructura o sentencia de tipo if-else, una de las salidas delrombo corresponde al código que se ejecuta cuando la expresión es evaluada co-mo verdadera (if) y la otra salida es la que utilizamos para la sentencia que se eje-cuta cuando la expresión es evaluada como falsa (else).

3. EL PROGRAMA TOMA DECISIONES

84 www.redusers.com

Siempre es conveniente verificar la ejecución del programa y colocar valores que puedan

provocar problemas con el fin de detectar cualquier error de lógica. Podemos probar valores

positivos, negativos, el cero, fraccionarios, etcétera. Si encontramos problemas con los valores,

podemos hacer uso del if para validar los valores antes de usarlos.

VERIFICAR EL PROGRAMA

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 84

Page 87: C# aprenda a programar

Figura 8. Aquí vemos claramente la ruta de if y la ruta de else.

El código de nuestro programa quedaría compuesto de la siguiente forma:

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{class Program

{// Esta es la función principal del programa// Aquí inicia la aplicaciónstatic void Main(string[] args)

Pedir número

Inicio

Fin

Mostrar

"El número es

positivo"

Mostrar

"El número es

negativo"

Número>=0SÍ NO

La toma de decisiones

85www.redusers.com

Cuando tenemos una estructura del tipo if-else, solamente la sentencia if o la sentencia else se

ejecutará. En ningún caso se ejecutarán las dos sentencias. Solamente una de ellas puede

ejecutarse. Es importante tener esto en cuenta para evitar errores de lógica y no olvidar que else

siempre requiere de un if.

LAS SENTENCIAS EN IF-ELSE

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 85

Page 88: C# aprenda a programar

{int numero = 0; // Donde guardamos el númerostring valor = “”; // Para guardar la cadena dada por el

usuario// Pedimos el numeroConsole.Write(“Dame un número entero:”);valor = Console.ReadLine();numero = Convert.ToInt32(valor); // Convertimos la cadena a

entero// Hacemos uso de if con la expresión para el caso de los

positivos if (numero >= 0)Console.WriteLine(“El número {0} es positivo”, numero); // se

ejecuta si se cumple numero>=0elseConsole.WriteLine(“El numero {0} es negativo”, numero); // se

ejecuta si NO se cumple numero>=0

}}

}

Podemos ver que el programa es más sencillo, se ha simplificado la lógica y esto lohace más fácil de leer y mantener. Esto no significa que siempre debamos usar if-else. Hay que hacer uso de él cuando tenemos algo que deseamos ejecutar cum-pliendo previamente la condición especificada, y algo que deseamos ejecutar cuan-do ésta no se cumpla. Abusar de if-else o usarlo sin sentido complicará la lógica delprograma, pero usarlo bien nos ayuda.

El uso de else con bloque de códigoAl igual que con if, nosotros podemos colocar un bloque de código en else. Estonos permitiría que más de una sentencia se ejecute cuando no se cumple la con-dición del if. No debemos olvidar colocar el bloque de código empezando conuna llave, {, y finalizándolo con la llave de cierre }. Adentro del bloque de códi-go podemos colocar cualquier sentencia válida de C#.Por ejemplo, podemos modificar el programa de la división para hacer uso de lasentencia else. En este caso, lo que haremos será que, cuando el divisor sea iguala cero enviaremos a la consola un mensaje de error y cuando no lo sea, llevare-mos a cabo la división. Primero veamos cómo es el diagrama de flujo con estoscambios. Es fácil notar la ruta de else.

3. EL PROGRAMA TOMA DECISIONES

86 www.redusers.com

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 86

Page 89: C# aprenda a programar

Figura 9. Aquí podemos ver el diagrama de flujo con las

dos rutas de ejecución posibles, una para if y la otra para else.

El código del programa se modifica de la siguiente forma:

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{class Program

{// Esta es la función principal del programa// Aquí inicia la aplicaciónstatic void Main(string[] args)

{// Variables necesariasfloat dividendo = 0.0f;

Pedir dividendo

Pedir divisor

Mostrar resultado

Inicio

Fin

Mostrar

"Divisor no válido"

Resultado =

dividendo/divisor

Divisor==0NOSÍ

La toma de decisiones

87www.redusers.com

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 87

Page 90: C# aprenda a programar

float divisor = 1.0f;float resultado = 0.0f;string valor = “”;

// Pedimos el dividendoConsole.WriteLine(“Dame el dividendo:”);valor = Console.ReadLine();dividendo = Convert.ToInt32(valor);

// Pedimos el divisorConsole.WriteLine(“Dame el divisor:”);valor = Console.ReadLine();divisor = Convert.ToInt32(valor);

if (divisor == 0)Console.WriteLine(“El divisor no es válido”);

else{// Hacemos la operacionresultado = dividendo / divisor;

// Mostramos el resultadoConsole.WriteLine(“El resultado de la división es {0}”,

resultado);}

}}

}

De esta forma podemos manejar dos opciones, una para el divisor con el valor decero y otra para cuando el divisor es válido.

3. EL PROGRAMA TOMA DECISIONES

88 www.redusers.com

Cuando hacemos uso de if-else, cualquiera de los dos o ambos pueden tener una sentencia o un

bloque de código. No es necesario que ambos sean iguales. La selección entre la sentencia o el

bloque de código nos la da el algoritmo y las necesidades de lógica que tengamos. Algunos

programadores colocan el bloque de código por costumbre, aunque éste sólo tenga una sentencia.

BLOQUES DE CÓDIGO CON IF-ELSE

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 88

Page 91: C# aprenda a programar

La toma de decisiones

89

Cómo usar if anidadosLa sentencia o el bloque de código que ejecuta if puede ser cualquier sentencia válidao bloque de código válido en C#, esto incluye a otro if. Esto significa que nosotrospodemos colocar if adentro del código a ejecutar de un if anterior. Cuando hacemosesto hay que ser cuidadosos para evitar errores de lógica. Esto se conoce como ifanidados. Veamos un ejemplo de esto. Tenemos que hacer un programa que pediráel tipo de operación aritmética que deseamos ejecutar y luego los dos números con losque llevar a cabo la operación. El resultado se desplegará en la pantalla.El programa tendrá el siguiente código:

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{class Program

{// Esta es la función principal del programa// Aqui inicia la aplicacionstatic void Main(string[] args)

{// Variables necesariasfloat a = 0.0f;float b = 0.0f;float resultado = 0.0f;string valor = “”;int opcion = 0;

// Mostramos el menuConsole.WriteLine(“1- Suma”);Console.WriteLine(“2- Resta”);Console.WriteLine(“3- División”);Console.WriteLine(“4- Multiplicación”);Console.Write(“Que operación deseas hacer: “);valor=Console.ReadLine();opcion = Convert.ToInt32(valor);

// Pedimos el primer númeroConsole.Write(“Dame el primer numero:”);

www.redusers.com

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 89

Page 92: C# aprenda a programar

valor = Console.ReadLine();a = Convert.ToSingle(valor);// Pedimos el segundo númeroConsole.Write(“Dame el segundo numero:”);valor = Console.ReadLine();b = Convert.ToSingle(valor);// Verificamos para sumaif (opcion == 1)

resultado = a + b;// Verificamos para restaif (opcion == 2)

resultado = a - b;// Verificamos para divisionif (opcion == 3)

if (b != 0) // este if esta anidado resultado = a / b;

else // Este else pertenece al segundo ifConsole.WriteLine(“Divisor no valido”);

// Verificamos para la multiplicacionif (opcion == 4)

resultado = a * b;// Mostramos el resultadoConsole.WriteLine(“El resultado es: {0}”, resultado);

}}

}

El programa es sencillo, solamente necesitamos if para cada operación, pero para elcaso de la división necesitaremos colocar otro if para verificar que el divisor no sea ce-ro. Es decir que para la división tendremos if anidados. El diagrama de flujo de la apli-cación se muestra en la siguiente figura.

3. EL PROGRAMA TOMA DECISIONES

90 www.redusers.com

Cuando colocamos un if adentro del código que puede ejecutar un if anterior, estamos diciendo

que tenemos if anidados. Este tipo de estructura es muy útil y puede ayudarnos a optimizar los

programas, pero debemos tener cuidado de usarla correctamente para evitar errores de lógica.

Cuando se codifica hay que hacerlo en forma ordenada.

UN IF ADENTRO DE OTRO IF

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 90

Page 93: C# aprenda a programar

Figura 10. Éste es el diagrama de flujo.

Es fácil observar en la división el anidamiento de if.

0

Mostrar Men˙

Resultado = a + b

Resultado = a - b

Resultado = a/b

Resultado = a ï b

Mostrar "Divisor

no v· lido"

Pedir opciÛn

Pedir b

Mostrar resultado

Pedir a

Inicio

Fin

OpciÛn==1

OpciÛn==2

OpciÛn==3

OpciÛn==4

B!= 0SÍ

NO NO

NO

NO

NO

NO

NO

NO

La toma de decisiones

91www.redusers.com

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 91

Page 94: C# aprenda a programar

En el programa anterior observamos cómo se ha usado if anidado para la división,sólo tenemos que ser cuidadosos con else para poder saber a qué if pertenece. Si ennuestros programas hacemos uso de la indentación, es decir colocar espacios antesde la sentencia, podemos facilitar reconocer qué parte del código pertenece a quésección. Algunos editores de código hacen esto por nosotros de forma automática yvisualmente es más fácil reconocer el código.

Escalera de if-elseOtra estructura que se puede utilizar es la escalera de if-else. Una de sus funcionesprincipales es optimizar la ejecución del código. Algunas veces son necesarias por-que así lo requiere la lógica del programa. Al igual que con los if anidados, no hayque utilizarlos sin planeación, ya que al no programarlos correctamente, nos puedellevar a errores de lógica que pueden resultar difíciles de solucionar. Ahora aprendamos cómo los podemos usar para que nuestro código se vuelvamás eficiente. Si observamos el programa de las operaciones matemáticas, tene-mos un if para cada operación. Esto significa que cuando nuestro programa seejecuta, sin importar si se ha seleccionado la suma o la multiplicación, siemprese tienen que ejecutar al menos cuatro if. Los if pueden ser operaciones costosasya que se tienen que evaluar expresiones.La forma de optimizar esto es con una cadena de if-else. El concepto es sencillo yconsiste en colocar un if en la sentencia del else.

Esto quedaría como muestra el siguiente código:

if(expresión 1)Sentencia 1

else if(expresión 2)Sentencia 2

else if(expresión 3)Sentencia 3

3. EL PROGRAMA TOMA DECISIONES

92 www.redusers.com

A veces sucede que cuando tenemos anidamiento, uno o varios de los if pueden tener else y

luego no sabemos a quién pertenece. Else siempre pertenecerá al if más cercano que ya no

tenga un else asignado. La mejor forma de evitar problemas con esto es hacer uso de bloques

de código, aunque solamente tengamos una sentencia en el bloque.

¿A QUIÉN LE PERTENECE ELSE?

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 92

Page 95: C# aprenda a programar

Como podemos ver se genera una figura que parece una escalera y por eso su nom-bre. Modifiquemos el programa de las operaciones matemáticas. En primer lugar sudiagrama de flujo queda de la forma que se muestra en la figura.

Figura 11. En este diagrama de flujo

podemos observar nuestra escalera de if-else.

Mostrar Menú

Resultado = a + b

Resultado = a - b

Resultado = a/b

Resultado = a • b

Mostrar "Divisor

no válido"

Pedir opción

Pedir b

Mostrar resultado

Pedir a

Inicio

Fin

Opción==1

Opción==2

Opción==3

Opción==4

B!= 0SÍ

NO SÍ

NONO

NO

NO

La toma de decisiones

93www.redusers.com

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 93

Page 96: C# aprenda a programar

Modifiquemos el código del programa, colocándolo de la siguiente manera:

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la función principal del programa// Aquí inicia la aplicaciónstatic void Main(string[] args){

// Variables necesariasfloat a = 0.0f;float b = 0.0f;float resultado = 0.0f;string valor = “”;int opcion = 0;

// Mostramos el menuConsole.WriteLine(“1- Suma”);Console.WriteLine(“2- Resta”);Console.WriteLine(“3- División”);Console.WriteLine(“4- Multiplicación”);Console.Write(“Que operación deseas hacer: “);valor = Console.ReadLine();opcion = Convert.ToInt32(valor);

// Pedimos el primer numeroConsole.Write(“Dame el primer numero:”);valor = Console.ReadLine();a = Convert.ToSingle(valor);

// Pedimos el segundo númeroConsole.Write(“Dame el segundo número:”);valor = Console.ReadLine();b = Convert.ToSingle(valor);

3. EL PROGRAMA TOMA DECISIONES

94 www.redusers.com

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 94

Page 97: C# aprenda a programar

// Verificamos para sumaif (opcion == 1)

resultado = a + b;

// Verificamos para restaelse if (opcion == 2)

resultado = a - b;

// Verificamos para divisionelse if (opcion == 3)

if (b != 0) // este if esta anidado

resultado = a / b;else // Este else pertenece al segundo if

Console.WriteLine(“Divisor no válido”);

// Verificamos para la multiplicacionelse if (opcion == 4)

resultado = a * b;

// Mostramos el resultadoConsole.WriteLine(“El resultado es: {0}”, resultado);

}}

}

Si ejecutamos el programa, veremos que hace exactamente lo mismo que la versiónanterior. ¿Pero dónde está la optimización? Si observamos el código, podemos en-contrarla. Supongamos que el usuario ha seleccionado la opción 1, es decir la suma.

La toma de decisiones

95www.redusers.com

Si la escalera if-else parece difícil de leer, podemos utilizar bloques de código para agrupar las

secciones. Esto hará que entender y leer la lógica de la aplicación sea más fácil. La aplicación

se puede resolver con if normales, no es forzoso utilizarlos. Se pueden utilizar cuando

empezamos a tener más experiencia.

FACILITAR LA LECTURA DE NUESTRO CÓDIGO

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 95

Page 98: C# aprenda a programar

Con esto se cumple la condición del primer if y se ejecuta la operación de suma. Pe-ro nosotros sabemos que se ejecuta if o else, nunca ambos. Si observamos, vemos quetodas las demás operaciones están en la ruta de else, por lo que son ignoradas. Antes teníamos que hacer cuatro if siempre, ahora solamente se hizo uno y los demás seevitaron, ahí es donde está la optimización. En otras palabras, en el programa anteriorsiempre eran cuatro if y en el nuevo, en el mejor de los casos tenemos un solo if, peroen el peor de los casos tenemos cuatro. Así es cómo se llevo a cabo la optimización.

Expresiones lógicasAl igual que las expresiones aritméticas y relacionales, las expresiones lógicas tienen suspropios operadores. Éstos son: y, o y no. En inglés los conocemos como: and, or y not.

OPERADOR SIGNIFICADO

&& y

|| o

! no

Tabla 2. Aquí tenemos los operadores lógicos utilizados en C#.

El uso de la conjunciónEmpecemos a conocerlos. El primer operador es y, conocido como ccoonnjjuunncciióónn. Parausar este operador es necesario tener dos expresiones. Una expresión a la iizzqquuiieerrddaa yla otra a la ddeerreecchhaa. Las expresiones se evalúan devolviendo valores true o false. Conla conjunción, la expresión se evalúa como verdadera únicamente cuando aammbbaass eexx--pprreessiioonneess ssoonn vveerrddaaddeerraass. La siguiente es la tabla de verdad para este operador:

P Q P&&Q

true true true

false true false

true false false

false false true

Tabla 3. La tabla de verdad de la conjunción.

3. EL PROGRAMA TOMA DECISIONES

96 www.redusers.com

Recordar la conjunción es fácil, únicamente es verdadera cuando ambas expresiones son

verdaderas. Podemos recordar la regla o simplemente tener una impresión de la tabla a mano.

Debemos recordar que se necesitan dos operandos, uno a la derecha y el otro a la izquierda. Con

un solo operando no es posible hacerlo.

RECORDAR LA CONJUNCIÓN

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 96

Page 99: C# aprenda a programar

Supongamos que tenemos que decidir si debemos llenar el tanque de gasolina delvehículo. Esto lo hacemos si el tanque tiene menos del 50% y si la distancia a re-correr es de más de 200 km. Como vemos, tenemos que usar la conjunción ya quetenemos dos condiciones y ambas se deben cumplir para que suceda la carga de lagasolina. Si colocamos esto como expresión quedaría:

if(tanque < 50 && distancia > 200)Cargar gasolina

Supongamos que tanque es 25 y distancia es 350, al evaluar 25 < 50 y 350 > 200 te-nemos lo siguiente.

if(true && true)Cargar gasolina

En nuestra tabla sabemos que cuando ambas expresiones son verdaderas, entoncesse cumple la conjunción y la expresión lógica nos evalúa a true.

if(true)Cargar gasolina

Por lo que cargaremos gasolina.

Ahora supongamos que tanque tiene el valor de 90 y distancia es nuevamente 350.Las primeras evaluaciones nos darían:

if(false && tue)Cargar gasolina

La toma de decisiones

97www.redusers.com

Es fácil recordar la tabla de verdad de la disyunción. Ésta es verdadera cuando cualquiera de las

expresiones es verdadera. Ya que si una es verdadera o la otra es verdadera, entonces la

expresión total es verdadera. También es bueno que tengamos esta tabla a mano hasta que

aprendamos la disyunción de memoria.

RECORDAR LA DISYUNCIÓN

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 97

Page 100: C# aprenda a programar

Al ver nuestra tabla, vemos que false y true se evalúan como false, por lo que no re-alizaremos la carga de gasolina.

El uso de la disyunciónPara la disyunción hacemos uso del operador o. Éste también necesita dos ex-presiones, una en el lado derecho y otra en el lado izquierdo. Esta disyunción tie-ne la siguiente tabla de verdad:

P Q P||Q

true true true

false true true

true false true

false false false

Tabla 4. La tabla de verdad de la disyunción.

Veamos un ejemplo con la disyunción. Tenemos que tomar la sombrilla si llueve osi hay mucho sol. La expresión podría quedar de la siguiente manera:

if(lluvia == true || muchosol == true)Tomar sombrilla

Supongamos que hay lluvia pero no hay sol, tendríamos la expresión:

if(true || false)Tomar sombrilla

En este caso, si vemos la tabla de verdad, podemos observar que el resultado de eva-luar la expresión nos da true, por lo que sí debemos tomar la sombrilla.

Ahora veamos qué sucede si no hay lluvia y no hay sol. La expresión quedaría como:

3. EL PROGRAMA TOMA DECISIONES

98 www.redusers.com

La negación simplemente intercambia true por false y false por true. Resulta fácil recordarla. Se

invierte el valor del operando del lado derecho. No debemos olvidar que este operador

solamente necesita un operando y siempre se encuentra del lado derecho. No hacerlo así puede

originar problemas con nuestro programa.

RECORDAR LA NEGACIÓN

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 98

Page 101: C# aprenda a programar

if(false || false)Tomar sombrilla

En este caso, la expresión se evalúa como false y no se toma la sombrilla.

El uso de la negaciónNos falta conocer un operador más, el de la negación. Ese operador es muy sencillo ysolamente necesita hacer uso de un operando del lado derecho. Con estas condicionesdadas, esta expresión será negada por el operador.

p Negación

true false

false true

Tabla 5. La tabla de verdad de la negación.

Esto quiere decir que si el operando del lado derecho es true, el operador regresafalse. Y si el operando del lado derecho es false, el operador regresa true.

Veamos un ejemplo para poder comprender mejor esto.Tenemos una habitación con una bombilla eléctrica y supongamos que tenemosque prender la luz del cuarto cuando no es de día. Entonces nuestra expresiónqueda de la siguiente forma:

if(!dia == true)Prender la luz

Veamos qué sucede cuando la expresión dia tiene como valor verdadero. La ex-presión dia == true se evalúa como true y luego éste se niega, lo que al final nosda como resultado un valor false. Como if recibe el valor false, se ejecutará laorden o el método prender la luz.Pero si dia es false, entonces la expresión dia == true se evalúa como false, que esnegado e if recibe true. Como if recibe true, se ejecuta prender la luz.Ahora podemos analizar un ejemplo de cómo hacer uso de una expresión lógica. Es-to podemos aplicarlo en nuestro programa de las operaciones matemáticas. Pode-mos observar que la división se debe hacer cuando el usuario ha seleccionado entrelas opciones presentadas, la número 3, y el divisor tiene un valor diferente de cero.Éste es un caso en el que podemos hacer uso de la conjunción. Si procedemos a mo-dificar la aplicación para realizar esto, nuestro diagrama de flujo debería modificar-se, quedando similar a la forma que vemos a continuación:

La toma de decisiones

99www.redusers.com

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 99

Page 102: C# aprenda a programar

Figura 12. Podemos observar cómo la expresión lógica

se encuentra dentro del rombo en la condición de la división.

El código del programa quedaría de la siguiente forma:

using System;using System.Collections.Generic;using System.Text;

Mostrar Menú

Resultado = a + b

Resultado = a - b

Resultado = a/b

Resultado = a • b

Pedir opción

Pedir b

Mostrar resultado

Pedir a

Inicio

Fin

Opción==1

Opción==2

Opción==3

&& B!=0

Opción==4

NO SISSÍ

NO

NO

NO

3. EL PROGRAMA TOMA DECISIONES

100 www.redusers.com

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 100

Page 103: C# aprenda a programar

namespace AplicacionBase{

class Program{

// Esta es la función principal del programa// Aquí inicia la aplicaciónstatic void Main(string[] args){

// Variables necesariasfloat a = 0.0f;float b = 0.0f;float resultado = 0.0f;string valor = “”;int opcion = 0;

// Mostramos el menúConsole.WriteLine(“1- Suma”);Console.WriteLine(“2- Resta”);Console.WriteLine(“3- División”);Console.WriteLine(“4- Multiplicación”);Console.Write(“Que operación deseas hacer: “);valor = Console.ReadLine();opcion = Convert.ToInt32(valor);

// Pedimos el primer númeroConsole.Write(“Dame el primer numero:”);valor = Console.ReadLine();a = Convert.ToSingle(valor);

// Pedimos el segundo númeroConsole.Write(“Dame el segundo numero:”);valor = Console.ReadLine();b = Convert.ToSingle(valor);

// Verificamos para sumaif (opcion == 1)

resultado = a + b;

// Verificamos para restaelse if (opcion == 2)

La toma de decisiones

101www.redusers.com

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 101

Page 104: C# aprenda a programar

resultado = a - b;

// Verificamos para divisiónelse if (opcion == 3 && b!=0) // Aquí usamos una expresión

lógicaresultado = a / b;

// Verificamos para la multiplicaciónelse if (opcion == 4)

resultado = a * b;

// Mostramos el resultadoConsole.WriteLine(“El resultado es: {0}”, resultado);

}}

}

Veamos otro ejemplo. Supongamos que tenemos que hacer un programa que nos in-dique si una persona puede conducir un automóvil, y las condiciones para que lo con-duzca son que tenga más de 15 ó 18 años y que tenga permiso de sus padres. Si ob-servamos el problema vemos que necesitamos dos variables, una para la edad y otra pa-ra el permiso de los padres. La expresión lógica podría quedar de la siguiente forma:

if(edad > 18 || (edad > 15 && permiso == true))Puede conducir

Vemos que en este caso usamos una expresión más compleja y al igual que con lasexpresiones aritméticas, hemos utilizado los paréntesis para ayudarnos y hacer que

3. EL PROGRAMA TOMA DECISIONES

102 www.redusers.com

Cuando tenemos expresiones complejas, para evitar errores es útil hacer una tabla de verdad

de la expresión y probar todos sus casos. De esta forma podemos ver si funciona tal y como lo

esperábamos. La tabla de verdad debe ser similar a las que hemos utilizado y nos podemos

apoyar en ella para encontrar el valor final de la expresión.

EXPRESIONES COMPLEJAS

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 102

Page 105: C# aprenda a programar

la lógica sea más fácil de leer. Nuestra expresión es una disyunción, en el lado iz-quierdo del or tenemos edad > 18, en el lado derecho tenemos una expresión(edad > 15 && permiso == true). La segunda expresión es una conjunción y de-berá evaluarse primero. El resultado que se obtenga será usado por la disyunción.Ahora podemos hacer el programa de ejemplo para esta expresión.Primero, observemos el diagrama de flujo a continuación:

Figura 13. Al igual que en el caso anterior, debemos

colocar la expresión dentro del rombo sin importar su complejidad.

El programa podría quedar de la siguiente manera:

using System;using System.Collections.Generic;using System.Text;

Mostrar "No es

posible conducir"

Pedir edad

Pedir permiso

Inicio

Fin

NO

Edad> 18 || (edad> 15

&& permiso==true

Mostrar "Es posible

conducir"

La toma de decisiones

103www.redusers.com

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 103

Page 106: C# aprenda a programar

namespace AplicacionBase{

class Program{

// Esta es la función principal del programa// Aquí inicia la aplicaciónstatic void Main(string[] args){

// Variables necesariasint edad = 0;bool permiso = false;string valor = “”;

// Obtenemos los datosConsole.Write(“Dame la edad: “);valor = Console.ReadLine();

edad = Convert.ToInt32(valor);

Console.Write(“Tiene permiso de los padres (true/false): “);

valor = Console.ReadLine();

permiso = Convert.ToBoolean(valor);

// Verificamos que se cumpla la reglaif(edad > 18 || (edad > 15 && permiso == true))

Console.WriteLine(“Es posible conducir”);else

Console.WriteLine(“No puedes conducir”);

3. EL PROGRAMA TOMA DECISIONES

104 www.redusers.com

Con switch nosotros podemos comparar una variable contra diferentes valores. La variable

puede ser de tipo entero o cadena. El valor del caso debe ser apropiado para que funcione

correctamente. De nuestro análisis conocemos los posibles valores para cada caso. El tipo de

variable de comparación dependerá del algoritmo en particular.

TIPOS DE DATOS PARA EL SWITCH

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 104

Page 107: C# aprenda a programar

}}

}

Ahora aprenderemos a usar otra estructura selectiva.

El uso de switchEn uno de los ejemplos anteriores, en los que realizamos las operaciones mate-máticas, hemos observado que para cada operación debemos utilizar un if. Estoes correcto, y en varias ocasiones veremos que es necesario tomar diferentes op-ciones dependiendo del valor de una variable.Como esto puede ocurrir frecuentemente, tenemos una estructura selectiva quenos ayuda y nos permite colocar el código para estos casos con facilidad. Esta es-tructura se conoce como switch. Para ésta necesitamos una variable y varios casos.Por ejemplo, en el programa de las operaciones, cada una de ellas es un caso. Elvalor de la variable se compara con un valor para cada caso. Si el valor coincide,entonces se empieza a ejecutar el código a partir de esa línea.Cuando usamos switch es necesario colocar entre paréntesis la variable que utilizare-mos para llevar a cabo las comparaciones. Luego tenemos que crear un bloque de có-digo y colocar adentro de él los casos y el código a ejecutar para cada caso. Para indi-car un caso, usamos case seguido del valor de comparación y dos puntos. Existe un caso llamado default, que podemos utilizar si lo deseamos. Este caso siem-pre debe ser el último caso definido. Cuando la variable de comparación no ha en-contrado su valor en ninguno de los casos, entonces se ejecuta el código del caso de-fault. En los casos podemos colocar cualquier código C# que sea válido.Para indicar dónde termina el código de un caso debemos hacer uso de break, quenos permitirá salir de la ejecución de una estructura selectiva o repetitiva. Esto loveremos con más detalle en otro capítulo. Si no hacemos uso de break y el caso es-tá vacío, entonces el programa continuará ejecutando el código del próximo caso yasí sucesivamente hasta el final del bloque del código que pertenece al switch.

La toma de decisiones

105www.redusers.com

Para evitar errores en el switch debemos recordar que todos los casos deben terminar con

break o return. Si no lo hacemos así, el compilador nos puede dar problemas. El uso de

return lo aprenderemos en el capítulo de funciones. Es bueno tener bien definidos los casos

para evitar problemas de lógica.

EVITAR ERRORES EN EL SWITCH

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 105

Page 108: C# aprenda a programar

Switch puede ser representado en el diagrama de flujo por medio del rombo. Ensu interior colocamos la variable de comparación y de las esquinas o los lados po-demos sacar las diferentes rutas de ejecución que puede tener. Como ejemplomodificaremos el programa de las operaciones aritméticas para que haga uso delswitch. La variable de comparación será la variable opción, ya que el valor de és-ta será comparado para cada operación.

Figura 14. En este caso las diferentes rutas de ejecución

del switch salen de los lados y las esquinas del rombo.

El código del programa quedará de la siguiente manera:

Mostrar menú

Resultado =

a + b

Resultado =

a - b

Resultado =

a/b

Mostrar "Divisor

no válido"

Mostrar "Opción

no válida"

Pedir opción

Pedir b

Mostrar resultado

Pedir a

Inicio

Fin

Opción

B!= 0

NO

3 4 Default1 2

Resultado =

a • b

3. EL PROGRAMA TOMA DECISIONES

106 www.redusers.com

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 106

Page 109: C# aprenda a programar

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la función principal del programa// Aquí inicia la aplicaciónstatic void Main(string[] args){

// Variables necesariasfloat a = 0.0f;float b = 0.0f;float resultado = 0.0f;string valor = “”;int opcion = 0;

// Mostramos el menúConsole.WriteLine(“1- Suma”);Console.WriteLine(“2- Resta”);Console.WriteLine(“3- División”);Console.WriteLine(“4- Multiplicación”);Console.Write(“Que operación deseas hacer: “);valor = Console.ReadLine();opcion = Convert.ToInt32(valor);

// Pedimos el primer númeroConsole.Write(“Dame el primer numero:”);valor = Console.ReadLine();

La toma de decisiones

107www.redusers.com

Es posible encontrar diferentes programas de computadora que nos permitan crear diagramas

de flujo. Estos programas nos pueden ayudar a hacer nuestros programas más rápido. Un

programa que hace esto es Visio de Microsoft, pero también se pueden encontrar programas

gratuitos en varios sitios web en Internet como www.download.com.

DIAGRAMAS DE FLUJO

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 107

Page 110: C# aprenda a programar

a = Convert.ToSingle(valor);

// Pedimos el segundo númeroConsole.Write(“Dame el segundo numero:”);valor = Console.ReadLine();b = Convert.ToSingle(valor);

switch (opcion){

// Verificamos para sumacase 1:

resultado = a + b;break;

// Verificamos para restacase 2:

resultado = a - b;break;

// Verificamos para divisióncase 3:

if (b != 0) // este if esta anidado resultado = a / b;

else // Este else pertenece al segundo ifConsole.WriteLine(“Divisor no valido”);

break;

// Verificamos para la multiplicacióncase 4:

resultado = a * b;break;

// Si no se cumple ninguno de los casos anteriores

default:Console.WriteLine(“Opción no valida”);break;

}

3. EL PROGRAMA TOMA DECISIONES

108 www.redusers.com

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 108

Page 111: C# aprenda a programar

// Mostramos el resultadoConsole.WriteLine(“El resultado es: {0}”, resultado);

}}

}

Con esto hemos visto las estructuras selectivas básicas en C# y cómo podemos usarlas.

La toma de decisiones

109www.redusers.com

… RESUMEN

Las estructuras selectivas nos sirven para llevar a cabo la toma de decisiones. Tenemos

varias de estas estructuras: if, if-else y switch. Podemos hacer uso de las expresiones

relacionales y lógicas en if. Esto nos permite indicar de forma precisa la condición que se

debe cumplir para que se ejecute determinado código. El uso de else nos permite tener

código que se puede ejecutar cuando la condición no se cumple. Para comparar una

variable contra diferentes valores y ejecutar un código en particular cuando su contenido

es igual a un determinado valor hacemos uso del switch. Es importante no olvidar el uso

del break al finalizar el código de cada caso.

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 109

Page 112: C# aprenda a programar

110 www.redusers.com

TEST DE AUTOEVALUACIÓN

1 ¿Qué son las estructuras selectivas?

2 ¿Cuándo se ejecuta la sentencia de if?

3 ¿Qué colocamos entre paréntesis en if?

4 ¿Qué es una expresión relacional?

5 ¿Cuáles son los operadores de una

expresión relacional?

6 ¿A qué valores posibles puede evaluar una

expresión relacional o lógica?

7 ¿Qué es una expresión lógica?

8 ¿Cuáles son los operadores de las

expresiones lógicas?

9 ¿Qué operador solamente necesita un

operando?

10¿Cómo funciona el switch?

11¿Qué es la variable de comparación y

cómo se coloca?

12¿Cómo definimos los casos y cómo

usamos break?

ACTIVIDADES

EJERCICIOS PRÁCTICOS

1 Hacer un programa que le pida al usuario

un número y la computadora responda si

es par o impar.

2 Hacer un programa que transforme de

grados a radianes o de radianes a grados

dependiendo de lo que necesite el

usuario.

3 Hacer un programa que calcule el

impuesto de un producto, pero coloque

un impuesto del 0% si el producto es

medicina.

4 Hacer un programa que le pida al usuario

un número del 1 al 7 y escriba el nombre

del día que corresponde ese número en la

semana.

5 Hacer una programa que pueda calcular

el perímetro y el área de cualquier

polígono regular, pero que le pregunte al

usuario qué desea calcular.

03_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 110

Page 113: C# aprenda a programar

Creación

de ciclos

El ciclo for 112El valor de inicio 117El límite de conteo del ciclo 119Control del incremento 121Ejemplos con el ciclo for 128El ciclo do while 134El ciclo while 141

Resumen 145Actividades 146

Capítulo 4

En la vida real a veces repetimos

la misma actividad muchas veces.

También en los programas

de computadora veremos

que es necesario repetir algo un número

de veces. Para esto haremos uso

de los ciclos, que harán que nuestro

código sea más sencillo al mismo tiempo

que podemos repetir una actividad

cuantas veces sea necesario.

C#

SERVICIO DE ATENCIÓN AL LECTOR: [email protected]

04_C#2010_AJUSTADO.qxd 8/11/10 9:47 AM Page 111

Page 114: C# aprenda a programar

EL CICLO FOR

El primer ciclo que aprenderemos en este capítulo se llama ciclo for, pero para po-der entenderlo mejor necesitamos ver un problema donde sea necesario utilizarlo.Imaginemos que tenemos que crear un programa para una escuela, y este programadebe sacar el promedio de las calificaciones para tres alumnos. Si recordamos, elpromedio se calcula al sumar todas las cantidades y el resultado de la suma se divi-de por la cantidad de cantidades que hemos sumado. El programa es sencillo, de-bido a que en el salón de clases solamente hay tres alumnos.El diagrama para resolver este programa es el que se muestra en la siguiente figura:

Figura 1. Podemos observar que el programa es muy sencillo.

El código fuente queda de la siguiente manera:

using System;

Inicialización

Inicio

Fin

Condición

NO Código

Incremento

4. CREACIÓN DE CICLOS

112 www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 112

Page 115: C# aprenda a programar

using System.Collections.Generic;using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la función principal del programa// Aquí inicia la aplicaciónstatic void Main(string[] args){

// Variables necesariasfloat cal1 = 0.0f, cal2 = 0.0f, cal3 = 0.0f;float promedio = 0.0f;string valor = “”;

// Pedimos los datosConsole.WriteLine(“Dame la primera calificación:”);valor = Console.ReadLine();cal1 = Convert.ToSingle(valor);

Console.WriteLine(“Dame la segunda calificación:”);valor = Console.ReadLine();cal2 = Convert.ToSingle(valor);

Console.WriteLine(“Dame la tercera calificación:”);valor = Console.ReadLine();cal3 = Convert.ToSingle(valor);

// Calculamos el promediopromedio = (cal1 + cal2 + cal3) / 3;

El ciclo for

113www.redusers.com

La variable de control que usamos en el ciclo for puede ser declarada antes del ciclo, pero

en algunos casos es posible declararla e inicializarla en la sección de inicialización del ciclo.

Si la declaramos ahí, hay que tomar en cuenta que el ámbito de la variable es solamente el

ciclo y no se conocerá por afuera de él.

DECLARACIÓN DE LA VARIABLE DE CONTROL

04_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 113

Page 116: C# aprenda a programar

// Mostramos el promedioConsole.WriteLine(“El promedio es {0}”, promedio);

}}

}

Vemos que el programa es muy sencillo. Pedimos tres valores y calculamos elpromedio. Al final simplemente desplegamos el resultado. No hay ningún pro-blema con el programa, de hecho es correcto. Sin embargo, nuestro programatiene un defecto: es poco flexible. Ahora imaginemos que la escuela desea el promedio para un grupo con cinco alum-nos. Al parecer esto no es difícil, simplemente podríamos agregar dos peticiones de va-riables más y modificar la fórmula. Esto no parece problemático. ¿Pero qué sucede siel grupo es de quince alumnos? Esta solución de agregar más peticiones, aunque es via-ble, no es cómoda. ¿Si nos piden el promedio para toda la escuela con 2500 alumnos?Entonces es evidente que no podemos seguir con este tipo de solución. Sin embargo, de este problema podemos observar algo. Todas las peticiones de ca-lificaciones se hacen de la misma forma y pedir las calificaciones es algo que tene-mos que repetir un número de veces. Cuando tenemos código que se debe repetirun número de veces podemos utilizar el ciclo for. Éste nos permite repetir la ejecu-ción de un código un número determinado de veces.Antes de resolver nuestro problema con el ciclo for, lo primero que tenemos quehacer es aprender a utilizar el ciclo. La sentencia del ciclo se inicia con la palabraclave for seguida de paréntesis. Adentro de los paréntesis colocaremos expresionesque sirven para controlar el ciclo. El ciclo for tiene cuatro partes principales:

for( inicializacion; condicion; incremento)código

El ciclo for necesitará una o varias variables de control, aunque en la mayoría de loscasos usaremos únicamente una variable. Veamos las diferentes partes del ciclo for.En primer lugar encontramos la inicialización. En esta sección le damos a la variablede control su valor inicial. El valor inicial se lleva a cabo por medio de una asigna-ción normal, tal y como las que hemos trabajado. La segunda sección lleva una con-dición en forma de una expresión relacional. Ésta nos sirve para controlar cuándo ter-mina el ciclo y generalmente aquí indicamos la cantidad de vueltas que da el ciclo. Luego tenemos el código. En esta sección colocamos la parte del código que dese-amos que se repita. Esta sección puede ser una sentencia o un bloque de código. Por

4. CREACIÓN DE CICLOS

114 www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 114

Page 117: C# aprenda a programar

último, se ejecuta la sección del incremento. Aquí indicamos cómo se modificaráel valor de la variable de control para cada vuelta del ciclo.Cuando se ejecuta el ciclo for, lo primero que se lleva a cabo es la inicialización y luego la condición. Si la condición es verdadera, entonces se pasa al código ydespués al incremento. Seguido del incremento vamos nuevamente a la condicióny se repite el proceso. Si la condición no se cumple, entonces decimos que el ci-clo finaliza, se salta al código y continúa la ejecución del programa con lo que seaque encontremos después del ciclo.Esto lo podemos apreciar mejor en el siguiente diagrama de flujo.

Figura 2. Este diagrama de flujo nos muestra los pasos de la ejecución del ciclo for.

El poder comprender el ciclo for requiere de mucha experimentación, por lo queharemos varias pruebas para conocer sus características principales. Empecemos con un programa sencillo. Usaremos el ciclo para mostrar un mensaje,que únicamente imprimirá el valor de la variable de control del ciclo. Para saber cuáles el trabajo que realiza el ciclo, colocaremos un mensaje antes y después del ciclo.

Inicialización

Inicio

Fin

Condición

NO Código

Incremento

El ciclo for

115www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 115

Page 118: C# aprenda a programar

Para iniciar con facilidad, queremos que el ciclo se lleve a cabo diez veces. Primeroveamos el programa y luego analicemos cada una de las partes del ciclo.Nuestro programa queda de la siguiente forma:

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la función principal del programa// Aquí inicia la aplicaciónstatic void Main(string[] args){

// Variables necesariasint n = 0; // variable de control

Console.WriteLine(“—- Antes del ciclo —-”);

for (n = 1; n <= 10; n = n + 1)Console.WriteLine(“{0}”, n);

Console.WriteLine(“—- Después del ciclo —-”);}

}}

Antes de ejecutar el programa, veamos cómo está construido. En primer lugar de-claramos nuestra variable de control. Ésta se llama n. El programa imprimirá los nú-meros del 1 al 10 y n cambiará su valor según se repita el ciclo.Adentro del ciclo for encontramos inmediatamente que a n se le asigna el valor 1.Esto quiere decir que nuestro conteo empezará con el número 1. Si deseáramos ini-ciar en otro valor, en esta parte es dónde lo asignaríamos. Luego tenemos la condi-ción. La condición limita hasta donde contaremos con n. En este caso es hasta 10.Mientras n tenga un valor menor o igual a 10 el mensaje se muestra.Como en este caso 1 <= 10 se cumple, ya que n vale 1, entonces el mensaje se escri-be. El mensaje es muy sencillo ya que simplemente muestra el valor contenido en lavariable n. Después de esto, vamos al incremento. El incremento aumenta el valor

4. CREACIÓN DE CICLOS

116 www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 116

Page 119: C# aprenda a programar

de n en uno. Después del primer incremento n valdrá 2. Esto se repite y se incre-menta en 1 el valor de n cada vez que se repite el ciclo. En el último incremento, ntendrá el valor de 11 y en este caso la condición ya no se cumplirá y se termina conel ciclo. Veamos la ejecución del programa y observaremos cómo n cambia de valory efectivamente el ciclo se lleva a cabo solamente 10 veces.

Figura 3. Aquí podemos observar cómo el ciclo

se repitió y el valor de n fue modificado en cada vuelta.

El valor de inicioAhora ya podemos empezar a experimentar con el ciclo. Lo primero que haremosserá colocar el valor de inicio del ciclo y ver cómo se modifica la ejecución del

El ciclo for

117www.redusers.com

En C# veremos que en muchos casos tenemos estructuras con índice cero. Esto quiere decir que

su primer elemento se considera en la posición 0, no en la posición 1. Aunque nos parezca

extraño empezar a contar desde cero, en la computadora es muy común que esto ocurra, por lo

que nos conviene acostumbrarnos a hacer ciclos de esta forma.

CICLOS QUE EMPIEZAN EN CERO

04_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 117

Page 120: C# aprenda a programar

programa. Esto es útil ya que no siempre es necesario empezar a contar a partirde 1, a veces necesitamos empezar a contar a partir de otros números.

Supongamos que ahora tenemos que contar del 3 al 10. Para lograr esto, simple-mente modificamos el valor de inicio en la sección de inicialización del ciclo:

for (n = 3; n <= 10; n = n + 1)Console.WriteLine(“{0}”, n);

Ejecutemos el programa.

Figura 4. Éste es el resultado. Efectivamente, la variable de control

empieza con 3. Desde luego, el número de repeticiones es menor.

Es posible que la variable de control tenga un valor negativo en la inicialización. Es-to es útil cuando necesitamos contar desde un número negativo. Modifiquemos elcódigo del ciclo for de la siguiente manera:

for (n = -10 n <= 10; n = n + 1)Console.WriteLine(“{0}”, n);

4. CREACIÓN DE CICLOS

118 www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 118

Page 121: C# aprenda a programar

La ejecución nos da el resultado que observamos en la siguiente figura.

Figura 5. Podemos ver que el recorrido inicia en -10. No hay que pasar

por alto que la variable de control también pasa por el valor de cero.

El límite de conteo del cicloTambién podemos tener un control de hasta qué número contar. Veamos nues-tro código para realizar el conteo del 1 al 10.

for (n = 1; n <= 10; n = n + 1)Console.WriteLine(“{0}”, n);

En este ejemplo pudimos ver que el límite de conteo está siendo controlado en lacondición y que no hay una única forma de escribirla. Podemos ver que la siguien-te condición n <= 10 también podría ser escrita como n < 11 sin que se afecte en lomàs mínimo la ejecución del ciclo.

for (n = 1; n <11; n = n + 1)Console.WriteLine(“{0}”, n);

El ciclo for

119www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 119

Page 122: C# aprenda a programar

Veamos el resultado de este cambio en la figura a continuación.

Figura 6. Podemos observar que aunque

la condición es diferente, aún se cumple lo que deseamos.

Esto hay que tenerlo en cuenta para evitar confusiones en el futuro, en especialcuando veamos código de otras personas que utilicen un estilo diferente al nues-tro. Ahora modifiquemos el ciclo para que cuente del 1 al 15, en este caso usa-remos el operador < en lugar de <=.

for (n = 1; n < 16; n = n + 1)Console.WriteLine(“{0}”, n);

4. CREACIÓN DE CICLOS

120 www.redusers.com

Uno de los problemas más comunes con el ciclo for es equivocar la cantidad de repeticiones

necesarias. Algunas veces sucede que el ciclo da una vuelta más que las que deseamos. Si esto

ocurre, lo primero que debemos revisar es la condición. Una condición mal escrita hará que no se

produzcan las repeticiones deseadas. Otro problema puede ser el colocar ; al final de for.

PROBLEMAS CON EL CICLO FOR

04_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 120

Page 123: C# aprenda a programar

Ejecutemos el programa y veamos su comportamiento.

Figura 7. En este caso hemos incrementado el rango del ciclo.

Control del incrementoAhora que ya sabemos cómo colocar el rango del ciclo for desde su valor de iniciohasta el valor al que contará, podemos empezar a aprender cómo hacer uso del in-cremento. Nuestro incremento ha sido de uno en uno. Sin embargo, podemos ha-cer que el conteo sea de dos en dos, de tres en tres o de cualquier otro valor.Para lograr esto, simplemente tenemos que modificar el incremento e indicar cómose incrementaría nuestra variable de control. El valor del incremento puede ser unvalor colocado explícitamente o el valor que se encuentra adentro de una variable.Por ejemplo, hagamos que nuestro ciclo avance de dos en dos.

for (n = 1; n <16; n = n + 2)Console.WriteLine(“{0}”, n);

Como vemos, ahora hemos colocado n = n + 2. Con esto indicamos que se sumará2 al valor de n con cada vuelta del ciclo. Esto es más fácil de entender si vemos laejecución del programa y vemos el desplegado de los valores de n.

El ciclo for

121www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 121

Page 124: C# aprenda a programar

Figura 8. Podemos observar que efectivamente el valor

de n se incrementa de dos en dos por cada vuelta del ciclo.

Los ciclos que hemos utilizado siempre han contado de manera progresiva, es de-cir del menor valor al valor más alto, pero también es posible hacer un ciclo regre-sivo. Por ejemplo, podríamos hacer que el ciclo cuente del 10 al 1. Para esto nece-sitamos modificar no solamente el incremento sino que también es necesario colo-car las expresiones correctas en la inicialización y la condición.

Veamos cómo lograr esto con la siguiente sentencia:

for (n = 10; n>=1; n = n - 1)

4. CREACIÓN DE CICLOS

122 www.redusers.com

Si llevamos a cabo la declaración e inicialización de una variable adentro del bloque de código

de un ciclo, la variable será inicializada cada vez que se repita el ciclo y no conservará su valor

entre vueltas del ciclo. Este detalle también nos puede llevar a errores de lógica, por lo que hay

que decidir bien dónde se declara la variable.

INICIALIZACIÓN DE VARIABLES EN CICLOS

04_C#2010_AJUSTADO.qxd 8/6/10 8:32 PM Page 122

Page 125: C# aprenda a programar

Console.WriteLine(“{0}”, n);

Figura 9. Aquí podemos observar cómo el valor de n se decrementa de uno en uno.

El contador y el acumuladorAhora aprenderemos dos conceptos nuevos. Existen dos categorías de variables de-pendiendo de cómo guardan la información, en primer lugar tenemos elcontador. El contador es una variable que será incrementada o disminuirá su valorde uno en uno. En la mayoría de los ejemplos anteriores n ha funcionado como con-tador. Por su parte, el acumulador es una variable que puede incrementar o dis-minuir su valor en cualquier número.Aún no hemos hecho uso de un acumulador, pero lo veremos cuando debamos re-solver el problema de los promedios de los alumnos.Por el momento, veamos un pequeño ejemplo de estas dos clasificaciones de va-riables explicadas hasta aquí:

using System;using System.Collections.Generic;using System.Text;

El ciclo for

123www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 123

Page 126: C# aprenda a programar

namespace AplicacionBase{

class Program{

// Esta es la función principal del programa// Aquí inicia la aplicaciónstatic void Main(string[] args){

// Variables necesariasint n = 0; // variable de controlint contador = 0, acumulador = 0;

Console.WriteLine(“—- Antes del ciclo —-”);

for (n = 10; n >= 1; n = n - 1){

contador = contador + 1;acumulador = acumulador + contador;

Console.WriteLine(“{0}, {1}”, contador, acumulador);}

Console.WriteLine(“—- Después del ciclo —-”);}

}}

Hemos creado dos variables: contador y acumulador. La variable contador incrementasu valor de uno en uno. Por su parte, la variable acumulador incrementará el valoren base al número contenido en contador. A continuación, para comprender mejor lo explicado, ejecutemos el programa yveamos el funcionamiento de las dos variables:

4. CREACIÓN DE CICLOS

124 www.redusers.com

Si llevamos a cabo la declaración de una variable adentro del bloque de código del ciclo, ésta

únicamente puede ser usada en ese ciclo. Si tratamos de utilizarla después del ciclo, no será

reconocida por el programa. Si éste fuera el caso, lo mejor es declarar la variable al inicio de la

función para que sea conocida en ella.

PROBLEMAS CON VARIABLES EN LOS CICLOS

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 124

Page 127: C# aprenda a programar

Figura 10. Vemos cómo cambian los valores de las variables con cada vuelta del ciclo.

Incrementos y decrementosCuando trabajamos el C# con el ciclo for es muy común que tengamos que incre-mentar o disminuir siempre de uno en uno. Para facilitarnos esto, tenemos opera-dores nuevos que son el operador de incremento y el operador de decremento.

OPERADOR SIGNO

Incremento ++

Decremento —

Tabla 1. Este tipo de operadores

nos permiten cambiar el valor de la variable en 1.

Estos operadores pueden ser usados como sufijos o prefijos en la variable. En el ca-so de los sufijos lo escribimos como variable++ y para el prefijo como ++variable. Elvalor contenido en la variable en ambos casos se incrementará en uno. Lo que cam-bia es cómo se evalúa la expresión que contienen los operadores.Cuando tenemos el caso del sufijo, se evalúa la expresión con el valor actual de lavariable y luego se incrementa a la variable. En el caso del prefijo, se incrementa pri-mero el valor de la variable y posteriormente se evalúa la expresión.Quizás esto no quede muy claro en la primer explicación, pero no debemos preo-cuparnos por ello. Para poder entender esto, veremos un ejemplo a continuación:

El ciclo for

125www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 125

Page 128: C# aprenda a programar

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la función principal del programa// Aquí inicia la aplicaciónstatic void Main(string[] args){

int numero = 5;

Console.WriteLine(“Valor inicial {0}”, numero);

// incrementamosnumero++;

Console.WriteLine(“Después del incremento {0}”, numero);

// Decrementamosnumero—;

Console.WriteLine(“Después del decremento {0}”, numero);

// Incremento en la sentenciaConsole.WriteLine(“Incremento en la sentencia {0}”, numero++);

Console.WriteLine(“Valor después de la sentencia {0}”, numero);

// Incremento en la sentencia como prefijoConsole.WriteLine(“Incremento en la sentencia {0}”, ++numero);

Console.WriteLine(“Valor después de la sentencia {0}”, numero);

}}

}

4. CREACIÓN DE CICLOS

126 www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 126

Page 129: C# aprenda a programar

Podemos ejecutar el código escrito y ver qué es lo que ha ocurrido, y la razón porla que obtenemos esos valores desplegados.

Figura 11. Aquí vemos los valores obtenidos por los

operadores y la diferencia en usarlos como sufijos o prefijos.

Empezamos con una variable llamada numero a la que le asignamos el valor inicialde cinco. Desplegamos su valor en la pantalla. Luego usamos el operador e incre-mentamos el valor de la variable. En este caso vale 6, ya que el incremento es en uno.Esto lo comprobamos al imprimir el valor de la variable. Después llevamos a cabo eldecremento. En este caso, numero guarda el valor de 5, ya que lo hemos decremen-tado en uno. La impresión del mensaje nos muestra que estamos en lo correcto.Ahora que ya hemos visto cómo funciona, podemos tratar de colocar el operador aden-tro de una sentencia. La sentencia será el mismo mensaje que deseamos mostrar conel fin de observar cómo se evalúa y las diferencias entre el uso como sufijo y prefijo.No olvidemos que el último valor en numero es 5. Empezamos por colocar el incre-mento adentro de la sentencia y lo usamos como sufijo. Esto incrementa el valor a 6,pero si vemos la ejecución del programa, el valor que aparece es 5. ¿Por qué? La razónya la conocemos: cuando se usa como sufijo, se evalúa la expresión con el valor actualy luego se incrementa. La siguiente impresión del valor de la variable nos muestra có-mo efectivamente la variable sí fue incrementada después de la sentencia anterior. Aho-ra podemos experimentar con el sufijo. Nuestro valor actual es de 6 e ingresamos la

El ciclo for

127www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 127

Page 130: C# aprenda a programar

sentencia. En este caso, primero se incrementa el valor y tenemos 7 en la variablenúmero y luego la imprimimos. Por eso, en este caso obtenemos 7 en la pantalla.Con esto ya hemos visto el comportamiento de estos operadores y podemos inte-grarlos en nuestro ciclo for. En el caso de incremento:

for (n = 1; n <16; n++)Console.WriteLine(“{0}”, n);

O para decrementar decrementar su valor:

for (n = 10; n>=1; n—)Console.WriteLine(“{0}”, n);

Existen otros operadores que también podemos utilizar cuando deseamos calcularun valor con la variable y guardar el mismo valor en la variable.

OPERADOR EJEMPLO EQUIVALE A

+= numero+=5 numero=numero+5

-= numero-=5 numero=numero-5

*= numero*=5 numero=numero*5

/= numero/=5 numero=numero/5

Tabla 2. Estos operadores también nos permiten modificar el valor de la variable.

Es bueno conocer estos operadores ya que los veremos y deberemos utilizar frecuen-temente en muchos programas de cómputo. Por ejemplo, para hacer el incrementode cinco en cinco en un ciclo for, realizamos lo siguiente:

for (n = 1; n <16; n+=5)Console.WriteLine(“{0}”, n);

Ejemplos con el ciclo forAhora ya podemos resolver el problema sobre el cálculo del promedio. Sabemos quees lo que se debe repetir y la cantidad de veces que debemos hacerlo. En este caso,lo que se debe repetir es pedir la calificación del alumno y hacer una suma de estascalificaciones. La cantidad de veces que se tiene que repetir depende de la cantidadde alumnos. Esta suma de las calificaciones puede hacerse con la variable acumula-dor. El promedio final se calcula dividiendo el acumulador entre la cantidad de

4. CREACIÓN DE CICLOS

128 www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 128

Page 131: C# aprenda a programar

alumnos y éste se presenta en la pantalla. Veamos el diagrama de flujo de nuestroalgoritmo para resolver este problema.

Figura 12. Podemos observar fácilmente

el ciclo for y lo que se realiza adentro de él.

Pedimos cantidad

Pedir calif

Mostrar promedio

Inicio

Fin

N<cantidad

NO

NO

Nº 1

Suma=+calif

N++

Promedio=

Suma/calif

El ciclo for

129www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 129

Page 132: C# aprenda a programar

Ahora podemos ver cómo queda el código del programa:

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la función principal del programa// Aquí inicia la aplicaciónstatic void Main(string[] args){

// Variables necesariasint n = 0; // Control cicloint cantidad; // Cantidad alumnosfloat calif = 0.0f; // Calificación del alumnofloat suma = 0.0f; // Sumatoria de calificacionesfloat promedio = 0.0f; // Promedio finalstring valor = “”;

Console.WriteLine(“Dame la cantidad de alumnos:”);valor = Console.ReadLine();cantidad = Convert.ToInt32(valor);

// Ciclo para la captura de calificacionesfor (n = 1; n <= cantidad; n++){Console.WriteLine(“Dame la calificacion del alumno”);

valor = Console.ReadLine();calif = Convert.ToSingle(valor);

// Llevamos a cabo la suma de calificacionessuma += calif;

}

// Calculamos el promediopromedio = suma / cantidad;

4. CREACIÓN DE CICLOS

130 www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 130

Page 133: C# aprenda a programar

// Mostramos el promedioConsole.WriteLine(“El promedio es {0}”,promedio);

}}

}

Si ejecutamos el programa obtenemos la salida que se muestra en la siguiente figura.

Figura 13. Vemos cómo la petición

de la calificación se repite el número de veces indicado.

Un punto importante sobre este programa, en comparación al primer intento quehicimos al inicio del capítulo, es que puede funcionar con cualquier cantidad dealumnos. No importa si son 5, 10 ó 5000, el programa llevará a cabo su cometido.Vemos cómo el uso del ciclo no solamente nos da flexibilidad, sino que tambiénevita que tengamos que repetir mucho código.Veamos otro ejemplo. Podemos utilizar el ciclo for en cualquier problema que ne-cesite algo que se repita: una operación, un conteo, algún proceso. Pero también elnúmero de repeticiones debe ser conocido, ya sea por medio de un valor colocadoexplícitamente o un valor colocado adentro de una variable.

El ciclo for

131www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 131

Page 134: C# aprenda a programar

Ahora tenemos que calcular el factorial de un número. Por ejemplo, el factorial de5 es 5*4*3*2*1 que da 120. De igual forma, debemos calcular el valor factorial decualquier número dado por el usuario. Si observamos el problema y cómo se re-suelve, podemos apreciar que hay un ciclo y este ciclo es con conteo regresivo. Po-demos resolver fácilmente con un ciclo for que lleve a cabo la multiplicación con lavariable de control como producto.

Figura 14. Éste es el diagrama de flujo

del algoritmo para calcular el factorial de un número.

Pedimos número

Mostrar factorial

Inicio

Fin

N>=1

NO

N=número

Factorial*=número

N--

4. CREACIÓN DE CICLOS

132 www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 132

Page 135: C# aprenda a programar

El código del programa queda de la siguiente forma:

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la función principal del programa// Aquí inicia la aplicaciónstatic void Main(string[] args){

// Variables necesariasint n = 0; // Variable de controlint numero = 0; // Número al que sacamos factorialint factorial = 1; // Factorial calculadostring valor = “”;

// Pedimos el numeroConsole.WriteLine(“Dame el número al que se le saca el

factorial:”);valor = Console.ReadLine();

numero = Convert.ToInt32(valor);

// Calculamos el factorial en el ciclofor (n = numero; n >= 1; n—)

factorial *= n;

// Mostramos el resultadoConsole.WriteLine(“El factorial de {0} es {1}”,numero,

factorial);}

}}

Cuando ejecutamos el programa, nos encontramos con que podemos llevar a caboel cálculo factorial sin problema alguno.

El ciclo for

133www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 133

Page 136: C# aprenda a programar

Figura 15. El factorial del número es calculado adecuadamente.

El ciclo do whileHemos visto que el ciclo for es muy útil para repetir algo cuando sabemos el nú-mero de repeticiones previamente. Sin embargo, algunas veces no es posible saberel número de repeticiones que tendremos. Pensemos que una carpintería nos ha con-tratado para hacer un programa que transforme de pies y pulgadas a centímetros,ya que ellos lo usan para calcular el tamaño de las tablas. El programa es muy sen-cillo, pero no podemos dejarlo así ya que sería muy incómodo para ellos ejecutar elprograma cada vez que necesitan hacer un corte. Pensamos que esto se puede resolver con un ciclo for. ¿De cuántas vueltas el ciclo? Sicolocamos 10 vueltas podemos pensar que es suficiente. Pero hay días que necesitan15 conversiones y es necesario ejecutar el programa dos veces. Y los días que sólo ne-cesitan 5 conversiones tienen que escribir 5 más tan sólo para finalizar el programa.Podemos deducir del problema que efectivamente necesitamos un ciclo. Sin embargo,no sabemos el número de repeticiones previamente, por lo que el ciclo for no es ade-cuado. Necesitamos un ciclo que pueda ser controlado por una condición, y la eva-luación de esta condición dependerá del estado del programa en un momento dado.El ciclo do while nos permite hacer esto. Permite que cierto código se repita mien-tras una condición se evalúe como verdadera. El valor de la evaluación dependerádel estatus del programa en un momento dado.

4. CREACIÓN DE CICLOS

134 www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 134

Page 137: C# aprenda a programar

El ciclo do while se codifica de la siguiente manera:

do {Código

}(condición);

Si observamos el diagrama de flujo de la figura 16, podemos ver el funcionamien-to interno del ciclo do while de una manera simple y clara.

Figura 16. Éste es el diagrama del ciclo do while.

Podemos observar su comportamiento interno.

Empecemos a recorrer el ciclo. En primer lugar encontramos el código que hay quellevar a cabo. Este código es definido adentro de un bloque de código aunque seasolamente una sentencia. Generalmente, en el código se modificará de alguna for-ma el valor de la variable o las variables que usamos para la expresión en la condi-ción. Esta modificación de valor puede llevarse a cabo por medio de un cálculo, pro-ceso o incluso una petición al usuario. Después tenemos la condición a evaluar. Enla condición colocamos una expresión lógica o relacional. Si al evaluarse la condi-ción obtenemos el valor true, entonces se repite el código. En caso de que la con-dición del valor de false ya no se repite y se continúa con el programa. Hay que te-ner en cuenta que a veces sucede que la condición se evalúa como falsa desde la pri-mera vez. En este caso, solamente se habrá ejecutado el código una vez.Veamos un ejemplo. Crearemos el programa para la carpintería y usaremos el ciclodo while para que el programa se repita el número de veces necesarias, aun sin sa-ber cuántas veces son. Para lograr esto tenemos que pensar bien en nuestra condi-ción y cuál es el estado del programa que evaluaremos en ella.

Condición

NO

Código

El ciclo for

135www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 135

Page 138: C# aprenda a programar

La forma más sencilla de hacerlo es preguntarle al usuario si desea hacer otra con-versión. Si lo afirma, se repite el código para convertir. En caso de que el usuariono lo desee, el programa finaliza. De esta forma, es controlada la repetición del ci-clo pudiéndola repetir, aun sin saber cuántas veces hay que hacerlo.Nuestro programa tendrá el siguiente diagrama de flujo.

Figura 17. Aquí podemos observar el programar y distinguir el ciclo do while.

Pedimos los pies

Pedimos pulgadas

Mostramos centímetros

Mostramos centímetros

Inicio

Fin

Respuesta==SÍ

NO

centímetros =

[(pies * 12) + pulgadas] * 2.54

Pedimos

otra conversación

4. CREACIÓN DE CICLOS

136 www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 136

Page 139: C# aprenda a programar

El programa quedará de la siguiente manera:

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la función principal del programa// Aquí inicia la aplicaciónstatic void Main(string[] args){

// Variables necesariasfloat pies = 0.0f; // Cantidad de piesfloat pulgadas = 0.0f; // Cantidad de pulgadasfloat centimetros = 0.0f; // Resultado en centímetrosstring respuesta = “”; // Respuesta para otro cálculostring valor = “”;

do{

// Pedimos los piesConsole.WriteLine(“Cuántos pies:”);valor = Console.ReadLine();pies = Convert.ToSingle(valor);

// Pedimos las pulgadasConsole.WriteLine(“Cuántas pulgadas:”);valor = Console.ReadLine();pulgadas = Convert.ToSingle(valor);

// Convertimos a centimetroscentímetros = ((pies * 12) + pulgadas) * 2.54f;

// Mostramos el resultadoConsole.WriteLine(“Son {0} centímetros”, centimetros);

// Preguntamos si otra conversión

El ciclo for

137www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 137

Page 140: C# aprenda a programar

Console.WriteLine(“Deseas hacer otra conversión (si/no)?”);

respuesta = Console.ReadLine();

} while (respuesta == “si”);

}}

}

Ejecutemos el programa.

Figura 18. En la ejecución podemos verificar

que tenemos un ciclo, pero puede terminar cuando lo deseemos.

Podemos observar que hemos colocado adentro del ciclo la parte de conversión depies y pulgadas a centímetros. Después de mostrar el resultado le preguntamos alusuario si desea realizar otra conversión. En caso afirmativo, repetimos el ciclo. Siel usuario no desea hacer otra conversión, el ciclo finaliza. Esto nos permite que aveces se repita cinco veces, cuando sea necesario diez, y así dependiendo de las ne-cesidades del usuario. Hemos resuelto el problema.

4. CREACIÓN DE CICLOS

138 www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 138

Page 141: C# aprenda a programar

El ciclo do while nos da flexibilidad extra, pero siempre es necesario usar el tipo deciclo adecuado al problema que tenemos.Veamos otro ejemplo donde podemos utilizar este ciclo. En uno de los progra-mas anteriores le preguntábamos al usuario qué operación deseaba realizar y lue-go los operandos. El programa tal y como está solamente se ejecuta una vez, pe-ro si usamos el ciclo do while y colocamos una nueva opción en el menú,entonces el usuario puede realizar las operaciones que sean necesarias o solamenteuna como se usaba anteriormente. Este tipo de comportamiento es muy útil yfácil de implementar con el ciclo do while.Si modificamos el programa quedará de la siguiente manera:

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la función principal del programa// Aquí inicia la aplicaciónstatic void Main(string[] args){

// Variables necesariasfloat a = 0.0f;float b = 0.0f;float resultado = 0.0f;string valor = “”;int opcion = 0;

// Tenemos el ciclodo{

// Mostramos el menúConsole.WriteLine(“1- Suma”);Console.WriteLine(“2- Resta”);Console.WriteLine(“3- División”);Console.WriteLine(“4- Multiplicación”);Console.WriteLine(“5- Salir”);

El ciclo for

139www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 139

Page 142: C# aprenda a programar

Console.Write(“Que operación deseas hacer: “);valor = Console.ReadLine();opcion = Convert.ToInt32(valor);

if (opcion != 5){

// Pedimos el primer númeroConsole.Write(“Dame el primer número:”);valor = Console.ReadLine();a = Convert.ToSingle(valor);

// Pedimos el segundo númeroConsole.Write(“Dame el segundo número:”);valor = Console.ReadLine();b = Convert.ToSingle(valor);

switch (opcion){

// Verificamos para sumacase 1:

resultado = a + b;break;

// Verificamos para restacase 2:

resultado = a - b;break;

// Verificamos para divisióncase 3:

if (b != 0) // este if esta anidado resultado = a / b;

else // Este else pertenece al segundo ifConsole.WriteLine(“Divisor no válido”);

break;

// Verificamos para la multiplicacióncase 4:

resultado = a * b;break;

4. CREACIÓN DE CICLOS

140 www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 140

Page 143: C# aprenda a programar

// Si no se cumple ninguno de los casos anteriores

default:Console.WriteLine(“Opción no válida”);

break;

}

// Mostramos el resultadoConsole.WriteLine(“El resultado es: {0}”,

resultado);}

} while (opcion != 5);

}}

}

El ciclo whileHabiendo comprendido el ciclo Do While, estamos en condiciones de ver otro tipode ciclo. Este ciclo se conoce como while y en cierta forma se asemeja al anterior, pe-ro tiene sus propias características que debemos conocer para utilizarlo correctamente.El ciclo while también puede ser utilizado cuando tenemos algo que se debe repetirpero no conocemos el número de repeticiones previamente. La repetición del ciclotiene que ver con el cumplimiento de una condición. A diferencia del ciclo do while,este ciclo puede no ejecutarse ni siquiera una vez. Su estructura es la siguiente:

while(condicion) {Código

}

El ciclo for

141www.redusers.com

En el programa de las operaciones matemáticas hemos agregado un ciclo do while. Sin

embargo, nuestro trabajo no termina ahí. Tenemos que ejecutarlo para ver si se comporta de la

forma deseada. Por eso fue necesario que adicionáramos un if, ya que de lo contrario nos pediría

los operadores aun cuando lo que deseáramos fuera salir.

VERIFICAR CAMBIOS EN UN PROGRAMA

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 141

Page 144: C# aprenda a programar

Para comprender cómo funciona, veamos el diagrama de flujo.

Figura 19. Este ciclo inicia con una condición y esto

lo debemos de tener en cuenta en nuestros algoritmos.

Si observamos el diagrama de flujo lo primero que encontramos es una condición.Adentro de esta condición colocaremos una expresión lógica o relacional. Si la con-dición se evalúa como verdadera, entonces se procede a ejecutar el código. Despuésdel código se regresa a la condición. Si la condición no se cumple, entonces no seejecuta el código y se continúa con el resto del programa.El tener la condición al inicio del ciclo nos lleva a un punto importante. Si la con-dición no se cumple desde el inicio, entonces el ciclo nunca se lleva a cabo. Si nues-tro algoritmo está bien diseñado, esto es deseable.Ahora podemos hacer un ejemplo de programa que utilice el ciclo while. En esteejemplo utilizaremos la característica del ciclo que puede repetirse o no repetirse nisiquiera una vez. Imaginemos que tenemos que hacer un programa de control paraenfriar una caldera. La caldera debe ser enfriada a 20 grados centígrados.El ciclo while será usado para reducir la temperatura de uno en uno para cada vueltadel ciclo hasta que lleguemos a 20 grados centígrados. La ventaja que nos da este ciclo

Condición

NO Código

4. CREACIÓN DE CICLOS

142 www.redusers.com

Algunos programadores usan el ciclo while y para garantizar su ejecución les asignan valores a

las variables de forma tal que la condición se cumpla al inicio. Esto es recomendable en pocos

casos. Si necesitamos un ciclo que garantice la entrada es mejor hacer uso de do while en lugar

de forzar nuestra lógica con while.

GARANTIZAR LA EJECUCIÓN DEL CICLO WHILE

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 142

Page 145: C# aprenda a programar

es que si la temperatura es menor a 20 grados, ni siquiera se entra al ciclo y no se llevaa cabo ningún enfriamiento. En este caso, aprovechamos las propiedades del ciclo.Veamos el código de este programa:

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la función principal del programa// Aquí inicia la aplicaciónstatic void Main(string[] args){

// Variables necesariasint temperatura = 0;string valor = “”;

// Pedimos la temperaturaConsole.WriteLine(“Dame la temperatura actual:”);valor = Console.ReadLine();

temperatura = Convert.ToInt32(valor);

// El ciclo reduce la temperaturawhile (temperatura > 20){

// Disminuimos la temperaturatemperatura—;

El ciclo for

143www.redusers.com

Al igual que con los if, es posible tener ciclos anidados. Como adentro de los ciclos podemos

colocar cualquier código válido, entonces también podemos colocar otro ciclo. Cuando un ciclo

se encuentra adentro de otro, decimos que están anidados. Hay que tener mucho cuidado con

las variables de control y las condiciones para evitar problemas de lógica.

CICLOS ANIDADOS

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 143

Page 146: C# aprenda a programar

Console.WriteLine(“Temperatura->{0}”, temperatura);

}

// Mostramos la temperatura final

Console.WriteLine(“La temperatura final es {0}”, temperatura);

}}

}

Para comprobar que efectivamente el ciclo actúa como hemos dicho, debemos correrel programa dos veces. La primera vez colocaremos la temperatura en valor mayor a20°C. Esto debe hacer que el ciclo se lleve a cabo. La segunda vez colocaremos un va-lor menor que 20. En este caso, el programa no deberá entrar al ciclo.

Veamos el resultado de la primera ejecución:

Figura 20. Podemos observar que se ha entrado al ciclo

y que se lleva a cabo mientras la temperatura es mayor a 20°.

4. CREACIÓN DE CICLOS

144 www.redusers.com

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 144

Page 147: C# aprenda a programar

Si llevamos a cabo la segunda ejecución obtenemos lo siguiente:

Figura 21. En este caso no se entra al ciclo en la ejecución del programa.

Con esto hemos visto los tres ciclos principales disponibles en C# y de qué formapodemos utilizarlos dentro de nuestros desarrollos.

El ciclo for

145www.redusers.com

… RESUMEN

Los ciclos nos permiten repetir la ejecución de cierto código. El ciclo for es usado para repetir

algo un número determinado de veces. Este ciclo necesita de una variable de control con valor

inicial, una condición y un incremento. El ciclo do while nos permite repetir cierto código un

número de veces desconocido y se ejecuta al menos una vez. El número de veces depende de

una condición. El ciclo while también nos permite repetir el código un número desconocido de

veces, pero en este caso el ciclo puede o no puede ejecutarse dependiendo de su condición.

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 145

Page 148: C# aprenda a programar

146 www.redusers.com

TEST DE AUTOEVALUACIÓN

1 ¿Qué es un ciclo?

2 ¿Cuáles son las partes del ciclo for?

3 ¿Cómo colocamos el valor inicial de

conteo en un ciclo for?

4 ¿Cómo colocamos el valor final de conteo

en un ciclo for?

5 ¿Cómo se lleva a cabo el incremento en

un ciclo for?

6 ¿Cómo funciona el ciclo do while?

7 ¿Por qué el ciclo while se lleva a cabo al

menos una vez?

8 ¿Se necesita punto y coma al finalizar el

ciclo do while?

9 ¿Cómo funciona el ciclo while?

10¿Cuántas veces se puede repetir el ciclo

while?

11¿Qué tipo de condición podemos colocar

en el ciclo while?

12¿Se coloca un bloque de código en el ciclo

while?

ACTIVIDADES

EJERCICIOS PRÁCTICOS

1 Hacer un programa que muestre la tabla

de multiplicar del 1 al 10 de cualquier

número.

2 Hacer un programa que calcule el

resultado de un número elevado a

cualquier potencia.

3 Hacer el diagrama de flujo del programa

para reducir la temperatura de la caldera.

4 Hacer un programa que encuentre los

números primos que existen entre el 1 y

el 1000.

5 Hacer un programa que calcule el

promedio de edad de un grupo de

personas y diga cuál es la de edad más

grande y cuál es la más joven.

04_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 146

Page 149: C# aprenda a programar

Funciones

y métodos

Las funciones 148Funciones que ejecutancódigo 150Funciones que regresan un valor 156Funciones que reciben valores 159Funciones que reciben parámetros y regresan un valor 163Optimizar con funciones 171Paso por copia y paso por referencia 178Uso de parámetros de default 183

Resumen 185Actividades 186

Capítulo 5

Las funciones y los métodos

son elementos muy importantes

de programación. En C# estaremos

utilizándolos frecuentemente, en especial

cuando avancemos hacia la programación

orientada a objetos. Las funciones

nos dan muchas ventajas y nos permiten

desarrollar de forma más rápida

y más ordenada nuestras aplicaciones.

C#

SERVICIO DE ATENCIÓN AL LECTOR: [email protected]

05_C#2010_AJUSTADO.qxd 8/11/10 9:49 AM Page 147

Page 150: C# aprenda a programar

LAS FUNCIONES

Empecemos a conocer las funciones. Veamos un ejemplo de un problema y luego laforma cómo la utilización de la función nos puede ayudar. La función es un elementodel programa que contiene código y se puede ejecutar, es decir, lleva a cabo una ope-ración. La función puede llamarse o invocarse cuando sea necesario y entonces el có-digo que se encuentra en su interior se va a ejecutar. Una vez que la función terminade ejecutarse el programa continúa en la sentencia siguiente de donde fue llamada.

Figura 1. Podemos observar cómo la ejecución del programa se dirige

a la función y luego regresa a la sentencia siguiente de donde fue invocada.

Las funciones, para que sean útiles, deben estar especializadas. Es decir que cadafunción debe hacer solamente una cosa y hacerla bien. Nosotros ya hemos utiliza-do una función, es la función Main() y podemos crear más funciones conforme lasnecesitemos. Dentro de la programación orientada a objetos las clases tienen códi-go y este código se encuentra adentro de funciones llamadas métodos. Por ejemplo,cuando hemos convertido de cadena a un entero, hacemos uso de una función lla-mada ToIn32() que se encuentra adentro de la clase Convert.

Las funciones constan de cinco partes:

modificador tipo Nombre(parámetros){

código}

Veremos ahora las cinco partes, pero conforme estudiemos a las funciones sabremoscómo son utilizadas. Las funciones pueden regresar información y esta información

Sentencia 1

Sentencia 2

...

...

Función()

...

...

Sentencia n

Sentencia 1

Sentencia 2

...

Sentencia n

Main()

Función()

5. FUNCIONES Y MÉTODOS

148 www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 148

Page 151: C# aprenda a programar

puede ser cadena, entero, flotante o cualquier otro tipo. En la sección de tipo te-nemos que indicar precisamente la clase de información que regresa. Si la funciónno regresa ningún valor entonces tenemos que indicar a su tipo como void.Todas las funciones deben identificarse y lo hacemos por medio de su nombre. Lasfunciones que coloquemos adentro de las clases deben de tener un nombre único.El nombre también es utilizado para invocar o ejecutar a la función.

Las funciones pueden necesitar de datos o información para poder trabajar. No-sotros le damos esta información por medio de sus parámetros. Los parámetros noson otra cosa que una lista de variables que reciben estos datos. Si la función no ne-cesita usar a los parámetros, entonces simplemente podemos dejar los paréntesis va-cíos. Nunca debemos olvidar colocar los paréntesis aunque no haya parámetros.El código de la función se sitúa adentro de un bloque de código. En esta secciónpodemos colocar cualquier código válido de C#, es decir, declaración de variables,ciclos, estructuras selectivas e incluso invocaciones a funciones.Las funciones al ser declaradas pueden llevar un modificador antes del tipo. Losmodificadores cambian la forma como trabaja la función. Nosotros estaremos uti-lizando un modificador conocido como static. Este modificador nos permite usar ala función sin tener que declarar un objeto de la clase a la que pertenece.

Tenemos cuatro tipos básicos de funciones: las que solo ejecutan código, las que re-ciben parámetros, las que regresan valores y las que reciben parámetros y reciben va-lores. Durante este capítulo iremos conociéndolas.Ahora que ya conocemos los elementos básicos de las funciones, podemos ver unejemplo de donde su uso sería adecuado. Supongamos que tenemos un programa enel cual en diferentes secciones tenemos que escribir el mismo código, pero debido asu lógica no podemos usar un ciclo, ya que está en diferentes partes del programa.En este caso nuestra única solución hasta el momento sería simplemente escribir nue-vamente el código. Otra forma de resolverlo y que nos evitaría tener código repeti-do es usar la función. El código que se va a utilizar repetidamente se coloca adentrode la función, y cada vez que necesitemos usarlo, simplemente se invoca a la función. En nuestro ejemplo del carpintero, el cual analizamos en el capítulo anterior, nos

Las funciones

149www.redusers.com

Es importante seleccionar correctamente el nombre de la función. El nombre debe hacer refe-

rencia al tipo de trabajo que lleva a cabo la función; en muchos casos podemos hacer uso de ver-

bos. El nombre de la variable puede llevar números, pero debe empezar con una letra.

EL NOMBRE DE LA FUNCIÓN

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 149

Page 152: C# aprenda a programar

encargamos de realizar conversiones de pies y pulgadas a centímetros. La conver-sión se hacía con una fórmula sencilla pero un poco larga. Si ahora nuestro car-pintero necesita un programa para transformar las medidas de una mesa completaa centímetros, entonces tendríamos que usar la fórmula adecuada en varios luga-res. Para no copiar el mismo código varias veces, lo más conveniente sería colocarla fórmula en una función y simplemente invocarla donde fuera necesario. Empe-cemos a conocer cómo programar e invocar a las funciones.

Funciones que ejecutan códigoEl primer tipo de funciones que vamos a conocer son las que ejecutan código. Es-tas funciones no reciben datos y no regresan ningún dato. Solamente llevan a caboalguna operación. Aunque en este momento no parecen muy útiles, sí lo son.Para poder utilizar la función, debemos declararla. La declaración se debe haceradentro del bloque de código correspondiente a una clase. Para los ejemplos anali-zados en este libro, estamos usando la clase denominada Program. Nuestra funciónMain() se encuentra también adentro de esta clase.En este momento tomaremos una estrategia de programación, que aún no pertene-ce a la programación estructurada, en el futuro veremos las técnicas orientadas a ob-jetos. En esta técnica usamos a la función Main() como administradora de la lógicay la mayor parte del proceso se llevará a cabo en las funciones.Crearemos una aplicación y le colocaremos cada uno de los tipos de funciones quevamos a aprender, dejando a Main() como nuestra administradora del programa. Elprograma va a ser conceptualmente sencillo, ya que lo que nos interesa es com-prender el funcionamiento de las funciones.El programa simplemente se encargará de preguntarle al usuario el tipo de opera-ción aritmética que queremos llevar a cabo y luego la realizará con los datos dadosque le proporcionemos. Este programa ya fue resuelto anteriormente, pero en estecaso será implementado agregando el uso de las funciones.En el diagrama de flujo indicamos a la función por medio de un rectángulo que tienedos franjas a los lados. Cuando lo veamos, sabemos que tenemos que ir a la función yejecutar su código. Veamos cómo quedaría el diagrama de flujo de la aplicación.

5. FUNCIONES Y MÉTODOS

150 www.redusers.com

Las funciones no pueden ser declaradas adentro de otra función. Esto nos lleva a un error de

sintaxis y de lógica que debe ser corregido lo antes posible. Es importante mantener las funcio-

nes ordenadas y tener cuidado de no desbalancear los { } cuando se creen nuevas funciones.

Hay que recordar que deben ir adentro de una clase.

PROBLEMAS AL DECLARAR LAS FUNCIONES

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 150

Page 153: C# aprenda a programar

Figura 2. Aquí podemos ver el diagrama de flujo

y encontrar los lugares donde se invocan a las funciones.

Vemos que nuestro diagrama es muy sencillo y también podemos localizar inme-diatamente el lugar donde invocamos a las funciones. Cada una de las operacionestendrá su propia función. En este momento no programaremos todo, iremos ha-ciendo crecer el programa poco a poco.Empecemos por construir el programa, dejando la administración de la lógica aMain(), tal y como aparece en el diagrama de flujo.

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase

Mostrar menú

Suma

Resta

Pedir opción

Inicio

Fin

Opción==1

Opción==1SÍ

NO

NO

Multiplicación

División

Opción==1

Opción==1SÍ

NO

NO

Las funciones

151www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 151

Page 154: C# aprenda a programar

{class Program{

// Esta es la funcion principal del programa// Aqui inicia la aplicacionstatic void Main(string[] args){

// Variables necesariasint opcion = 0;string valor = “”;

// Mostramos el menuConsole.WriteLine(“1-Suma”);Console.WriteLine(“2-Resta”);Console.WriteLine(“3-Multiplicacion”);Console.WriteLine(“4-Division”);

// Pedimos la opcionConsole.WriteLine(“Cual es tu opcion:”);valor = Console.ReadLine();opcion = Convert.ToInt32(valor);

// Checamos por la sumaif (opcion == 1){}

// Checamos por la restaif (opcion == 2){}

// Checamos por la multiplicacionif (opcion == 3){}

// Checamos por la division

5. FUNCIONES Y MÉTODOS

152 www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 152

Page 155: C# aprenda a programar

if (opcion == 4){}

}}

}

Como vemos en nuestra función Main() tenemos la lógica principal del programa.Hemos dejado en este momento los bloques de código de los if vacíos para ir colo-cando el código correspondiente según vallamos avanzando.Empecemos a crear la función para la suma. Como esta función no va a recibir da-tos ni a regresar valores, todo se llevará a cabo en su interior. Será responsable depedir los operandos, realizar la suma y mostrar el resultado. Entonces colocamos ladeclaración de la función. Esto lo hacemos después de la función Main(), hay querecordar tener cuidado con los { }. También les debemos crear su diagrama de flu-jo y resolverlas de la forma usual. El diagrama de flujo es el siguiente.

Figura 3. Éste es el diagrama de flujo de la función, también debemos hacerlos.

Nuestra función queda de la siguiente forma:

static void Suma()

R=a+b

Pedimos b

Mostramos r

Pedimos a

Inicio

Fin

Las funciones

153www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 153

Page 156: C# aprenda a programar

{// Variables necesariasfloat a=0;float b=0;float r=0;string numero=””;

// Pedimos los valoresConsole.WriteLine(“Dame el primer numero”);numero = Console.ReadLine();a = Convert.ToSingle(numero);

Console.WriteLine(“Dame el segundo numero”);numero = Console.ReadLine();b = Convert.ToSingle(numero);

// Calculamos el resultador = a + b;

// Mostramos el resultadoConsole.WriteLine(“El resultado es {0}”,r);

}

Observamos que la función es static. Como la función no regresa ningún valor sutipo es void, el nombre de la función es Suma. Escogemos este nombre porque des-cribe la actividad que lleva a cabo la función. Como no recibe ningún dato del pro-grama principal no colocamos ningún parámetro y los paréntesis están vacíos. Enel código tenemos todos los pasos para resolver la suma y ya los conocemos. Como podemos observar es posible declarar variables. Debemos saber que las va-riables que se declaran adentro de la función se conocen como variables locales y

5. FUNCIONES Y MÉTODOS

154 www.redusers.com

Un error muy común cuando se empieza a programar las funciones es equivocarse al escribir el

nombre de la función de forma diferente durante la invocación. Por ejemplo, si nuestra función

se declara como Suma() cuando la invocamos no podemos usar suma(). La invocación debe usar

el nombre de la función exactamente como fue declarado.

NOMBRE EN LA INVOCACIÓN

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 154

Page 157: C# aprenda a programar

solamente serán conocidas adentro de esa función, de esta forma solo podrán ser in-vocadas dentro de la función correspondiente.Con esto la función está lista, sin embargo, si ejecutamos el programa nada dife-rente sucede. Esto se debe a que no hemos invocado la función. Cuando invocamosa la función su código se ejecuta. Para invocar a una función que solamente ejecu-ta código simplemente colocamos su nombre seguido de () y punto y coma en ellugar donde queremos que se ejecute. En nuestro caso sería el bloque de código delif para la suma, de la siguiente manera:

// Checamos por la suma

if(opcion==1){

Suma();}

Ahora si ejecutamos el programa y seleccionamos la opción de suma, veremos queefectivamente se ejecuta el código propio de la función.

Figura 4. En la ejecución observamos

cómo se está ejecutando el código de la función.

Las funciones

155www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 155

Page 158: C# aprenda a programar

Funciones que regresan un valorNuestro siguiente tipo de función puede regresar un valor. Esto significa que cuan-do la función es invocada va a llevar a cabo la ejecución de su código. El código vaa calcular un valor de alguna manera y este valor calculado por la función será re-gresado a quien haya invocado a la función. La invocación puede haber sido hechapor la función Main() o algún otra función.Como la función va a regresar un valor, necesitamos indicar su tipo. El tipo va adepender del valor devuelto. Si el valor es un entero, entonces el tipo de la funciónes int. Si el valor es un flotante, la función tendrá tipo float y así sucesivamente. Lafunción puede regresar cualquiera de los tipos definidos en el lenguaje y también ti-pos definidos por el programador y objetos de diferentes clases.La función va a utilizar un comando especial para regresar el valor, este comandose conoce como return y se usa de la siguiente manera:

return variable;

En cuanto la ejecución del programa encuentra un return, la función es finalizadaaun si no ha llegado a su fin. Al mismo tiempo que finaliza la función el valor co-locado después del return es regresado a quien hizo la invocación. El valor puedeser colocado con una variable o explícitamente con un valor en particular. No hayque olvidar colocar el punto y coma al finalizar la sentencia. La finalización de lafunción se lleva a cabo aunque tengamos código escrito después del return.Como la función regresa un valor, del lado del invocador necesitamos tener alguienque pueda recibir el valor regresado. Generalmente usaremos una variable, pero enalgunos casos puede ser una expresión que será evaluada con el valor regresado porla función. Supongamos que nuestra función regresa un valor entero. Entonces po-demos tener un código como el siguiente.

int n;

n=función();

De esta forma el valor regresado por la función queda guardado en la variable n ypodemos hacer uso de él. El código lo entendemos de la siguiente forma. Tenemosuna variable entera n. Luego tenemos una asignación para n. Si recordamos, la asig-nación siempre se lleva a cabo de derecha a izquierda. Se evalúa la expresión y lafunción se ejecuta y calcula un valor, el cual es regresado por medio de return. Es-te valor se considera como la evaluación de la expresión y es asignado a n. A partirde este momento podemos usar el valor según lo necesitemos.

5. FUNCIONES Y MÉTODOS

156 www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 156

Page 159: C# aprenda a programar

Ahora ya podemos empezar a usar este tipo de funciones en nuestra aplicación. Pa-ra la operación de la resta haremos uso de ella. El código en la parte del Main() noserá tan sencillo, ya que no solamente necesitamos una invocación, debemos de re-cibir un valor y hacer algo con él. De esta forma en el if para la resta, obtendremosel valor regresado por la función y luego lo presentaremos al usuario. La funciónResta() tiene el siguiente diagrama de flujo.

Figura 5. Podemos observar la forma cómo se crea

el diagrama de esta función, no hay que olvidar el retorno del valor.

El código de la función queda de la siguiente manera:

static float Resta()

{

R=a-b

Pedimos b

Regresamos R

Pedimos a

Inicio

Fin

Las funciones

157www.redusers.com

Es importante que la variable que recibe el valor de regreso de la función tenga el mismo tipo

que la función. Si no es así podemos tener desde problemas de compilación hasta perdida de

precisión en valores numéricos. En algunos casos si los tipos son diferentes será necesario lle-

var a cabo conversiones entre los tipos.

CUIDADO CON EL TIPO DE RETORNO

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 157

Page 160: C# aprenda a programar

// Variables necesariasfloat a=0;float b=0;float r=0;string numero=””;

// Pedimos los valoresConsole.WriteLine(“Dame el primer numero”);numero = Console.ReadLine();a = Convert.ToSingle(numero);

Console.WriteLine(“Dame el segundo numero”);numero = Console.ReadLine();b = Convert.ToSingle(numero);

// Calculamos el resultador = a - b;

// Retornamos el resultadoreturn r;

}

Podemos observar que la función Resta() es de tipo float y al final hemos colocadoel return indicando la variable cuyo valor deseamos regresar, en nuestro caso r.Pero no solamente debemos adicionar la función, también es necesario colocar nue-vo código en el if que corresponde a la resta.

// Checamos por la restaif(opcion==2){

5. FUNCIONES Y MÉTODOS

158 www.redusers.com

No es estrictamente necesario que el return se ubique al final de la función, aunque general-

mente lo encontraremos ahí. También es posible tener varios return escritos, por ejemplo uno

en cada caso de una escalera de if. Lo que no debemos olvidar es que cuando la ejecución en-

cuentra el return, la función finaliza.

LA POSICIÓN DE RETURN EN LA FUNCIÓN

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 158

Page 161: C# aprenda a programar

// Variable para nuestro resultadofloat resultado=0;

// Invocamos y obtenemos el resultadoresultado=Resta();

// Mostramos el resultadoConsole.WriteLine(“El resultado de la resta es

{0}”,resultado);}

Ejecutemos el programa. Podemos observar que la función actúa como se esperaba.

Figura 6. Vemos cómo el valor regresado por la función

es desplegado en quien lo invocó, en nuestro caso Main().

Funciones que reciben valoresHasta el momento las funciones que hemos utilizado piden directamente al usua-rio los valores que necesitan para trabajar. Sin embargo, las funciones también

Las funciones

159www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 159

Page 162: C# aprenda a programar

pueden recibir valores en el momento que son invocadas. De esta forma trabaja-rán con los valores pasados por el programa en lugar de pedirlos al usuario. Estosvalores son conocidos como parámetros. Los parámetros pueden ser de cualquiertipo, ya sea de los tipos nativos de C# como entero, flotante, cadena o de tiposdefinidos por el programador como clases y estructuras.

Los parámetros deben llevar su tipo y su nombre. El nombre nos permite accedera los datos que contiene y de hecho van a trabajar como si fueran variables loca-les a la función. Adentro de la función los usamos como variables normales. Losparámetros se definen en la declaración de la función. Adentro de los paréntesisde la función los listamos. La forma de listarlos es colocando primero en tipo se-guido del nombre. Si tenemos más de un parámetro para la función, entonces de-bemos separarlos por medio de comas.

La invocación de la función es muy sencilla, simplemente debemos colocar elnombre de la función y, entre los paréntesis, los datos que vamos a enviar co-mo parámetros. Los datos pueden ser situados por medio de variables o un va-lor colocado explícitamente.Podemos hacer ahora la función que se encargará de la multiplicación. Esta funciónrecibirá los operandos desde Main() por medio de los parámetros, realizará el cál-culo y lo mostrará al usuario. Como la función Main() manda la información, en-tonces será responsabilidad de ella pedirlos a los usuarios.El diagrama de flujo de la función Multiplicacion() se muestre a continuación.

Figura 7. La función Multiplicacion()es más sencilla, pues no pide los datos directamente al usuario.

R=a*b

Mostramos R

Inicio

Fin

5. FUNCIONES Y MÉTODOS

160 www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 160

Page 163: C# aprenda a programar

El código de la función es el siguiente:

static void Multiplicacion(float a, float b){

// Variables necesariasfloat r;

// Calculamos el valorr=a*b;

// Mostramos el resultadoConsole.WriteLine(“El resultado es {0}”,r);

}

Como podemos observar la función va a tener dos parámetros. Los parámetros sonde tipo flotante y se llaman a y b. No olvidemos que están separados por una co-ma. Los parámetros a y b funcionarán como variables y su contenido serán los va-lores pasados en la invocación.El otro lugar donde debemos de adicionar código es la función Main(), en este ca-so el if para la multiplicación.

// Checamos por la multiplicacionif(opcion==3){

// Variables necesariasfloat n1=0;float n2=0;string numero=””;

Las funciones

161www.redusers.com

Durante la invocación de la función los parámetros deben colocarse en el mismo orden en el cual

fueron declarados. No hacerlo así puede llevarnos a que los parámetros reciban datos equivo-

cados. Éste es uno de los puntos que debemos cuidar. También es bueno nombrar a los pará-

metros de tal manera que su nombre nos recuerde la información que va a colocársele.

ORDEN DE LOS PARÁMETROS

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 161

Page 164: C# aprenda a programar

// Pedimos los valoresConsole.WriteLine(“Dame el primer numero”);numero = Console.ReadLine();n1 = Convert.ToSingle(numero);

Console.WriteLine(“Dame el segundo numero”);numero = Console.ReadLine();n2 = Convert.ToSingle(numero);

// Invocamos a la funcionMultiplicacion(n1, n2);

}

En el interior del if creamos dos variables flotantes y le pedimos al usuario los va-lores con los que vamos a trabajar. Estos valores quedan guardados adentro de lasvariables n1 y n2. Veamos ahora la invocación de la función. Como la función fuedefinida para recibir parámetros entonces debemos de pasar datos en su invocación.Los parámetros son colocados entre los paréntesis. De la forma como lo tenemos elparámetro a recibirá una copia del valor contenido en n1 y el parámetro b recibiráuna copia del valor contenido en n2. Ya con esto la función puede llevar a cabo sutrabajo. Las variables usadas en la invocación no necesitan llamarse igual que los pa-rámetros declarados en la función. Si lo necesitáramos la invocación podría llevarun valor colocado explícitamente, por ejemplo:

// Invocamos a la funcionMultiplicacion(n1, 4.0f);

Cuando la función se invoca el parámetro a recibe una copia del valor contenido enn1 y el parámetro b recibe el valor de 4. Veamos cómo funciona.

5. FUNCIONES Y MÉTODOS

162 www.redusers.com

Los datos que enviamos deben de ser compatibles con los tipos que la función espera recibir co-

mo parámetros y de ser posible del mismo tipo. Podemos hacer uso de conversiones antes de

enviar el dato hacia la función. Con datos no compatibles tendremos problemas de compilación,

en datos compatibles, pero no del mismo tipo, tendremos problemas de perdida de precisión.

TIPOS DE LOS PARÁMETROS

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 162

Page 165: C# aprenda a programar

Figura 8. Vemos que la función imprime el resultado correcto,

lo que nos muestra que está recibiendo la información pasada en los parámetros.

Funciones que reciben parámetros y regresan un valorYa hemos visto tres tipos diferentes de funciones, y seguramente ya hemos com-prendido cómo funcionan y podemos fácilmente imaginar lo que hará este tipo defunción. Esta función va a recibir de quien la invoque información. La informaciónes pasada por medio de parámetros. La función lleva a cabo alguna acción o cálcu-lo y obtiene un valor que va a ser regresado. El valor regresado es recibido en el lu-gar donde se invocó a la función y se puede trabajar con él.Los parámetros serán usados como variables y los declaramos adentro de los parén-tesis de la función. Tenemos que indicar el tipo que va a recibir seguido de su nom-bre, si tenemos más de un parámetro, entonces debemos de separarlos por comas.Como la función regresa un valor, es necesario indicar su tipo en la declaración. Lavariable que va a recibir el valor retornado deberá tener de preferencia el mismo ti-po que la función o cuando menos un tipo que sea compatible o posible de conver-tir. Como siempre haremos uso de return para poder regresar el valor calculado. Dehecho este tipo de función utiliza todas las partes de las que consiste una función.En este momento debemos programar la función que lleva a cabo la división. Lafunción recibirá dos valores flotantes, verificará que no llevemos a cabo la divisiónentre cero, realiza el cálculo y regresa el valor.

Las funciones

163www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 163

Page 166: C# aprenda a programar

Si pasamos el diagrama de flujo a código, encontraremos algo interesante:

static float Division(float a, float b){

// Variables necesariasfloat r=0;

// Verificamos por division entre ceroif(b==0){

Console.WriteLine(“No es posible dividir entre cero”);

return 0.0f;}else

{r=a/b;return r;

}}

Adentro de la función tenemos dos return. ¿Esto significa que vamos a regresar dosvalores? En realidad no. Únicamente podemos regresar un valor con este tipo defunciones. Lo que sucede es que cada uno de nuestros return se encuentra en unaruta de ejecución diferente. Observemos que una se lleva a cabo cuando el if se cum-ple y el otro se ejecuta cuando el if no se cumple. Para la función, solamente unode ellos podrá ser ejecutado. También podemos notar que uno de los return está re-gresando un valor colocado explícitamente, en este caso 0.0. Si colocamos valoresde retorno explícitos, éstos deben de ser del mismo tipo que el tipo de la función.Éste es un concepto importante que nos da flexibilidad en nuestro código. Pode-mos regresar bajo diferentes condiciones, siempre y cuando solamente tengamos unreturn por ruta de ejecución. Si nuestra función debe regresar valores y tenemos va-rias rutas de ejecución, por ejemplo, varios if o if anidados, entonces debemos decolocar un return en cada ruta. No es posible dejar una ruta sin la posibilidad de re-gresar un valor. Debemos tomar en cuenta estas características para evitar proble-mas de lógica dentro de nuestro programa.En el lado de la función Main() también debemos adicionar código. El código locolocaremos en el bloque de código que corresponde al if de la división.

5. FUNCIONES Y MÉTODOS

164 www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 164

Page 167: C# aprenda a programar

// Checamos por la divisionif(opcion==4){

// Variables necesariasfloat n1=0.0f;float n2=0.0f;float resultado=0.0f;string numero=””;

// Pedimos los valoresConsole.WriteLine(“Dame el primer numero”);numero = Console.ReadLine();n1 = Convert.ToSingle(numero);

Console.WriteLine(“Dame el segundo numero”);numero = Console.ReadLine();n2 = Convert.ToSingle(numero);

// Invocamos a la funcionresultado=Division(n1, n2);

// Mostramos el resultadoConsole.WriteLine(“El resultado es

{0}”,resultado);}

Al igual que en casos anteriores, primero declaramos las variables necesarias y pedi-mos los valores. Luego invocamos a la función. En la invocación pasamos como pa-rámetros a nuestras variables n1 y n2. Se lleva a cabo la ejecución de la función yrecibimos de regreso un valor. Este valor es asignado a la variable resultado y luegoutilizado por Main() al mostrar el resultado.

Las funciones

165www.redusers.com

El ambiente de desarrollo .NET nos permite ver las funciones o métodos que tiene una clase en

particular. Cuando se escribe el nombre del objeto de dicha clase seguido del operador punto

nos aparece una lista de ellas. Esto lo podemos hacer con la clase Console. El investigar estas

funciones nos permite aprender más sobre .NET y lo que podemos hacer con él.

PARA CONOCER LAS FUNCIONES

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 165

Page 168: C# aprenda a programar

Figura 10. La división se lleva a cabo y el valor

de regreso es utilizado para mostrar el resultado.

Con esto ya tenemos el programa completo.

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la funcion principal del programa// Aqui inicia la aplicacionstatic void Main(string[] args){

// Variables necesariasint opcion = 0;string valor = “”;

5. FUNCIONES Y MÉTODOS

166 www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 166

Page 169: C# aprenda a programar

// Mostramos el menuConsole.WriteLine(“1-Suma”);Console.WriteLine(“2-Resta”);Console.WriteLine(“3-Multiplicacion”);Console.WriteLine(“4-Division”);

// Pedimos la opcionConsole.WriteLine(“Cual es tu opcion:”);valor = Console.ReadLine();opcion = Convert.ToInt32(valor);

// Checamos por la sumaif (opcion == 1){

Suma();}

// Checamos por la restaif (opcion == 2)

{// Variable para nuestro resultadofloat resultado = 0;

// Invocamos y obtenemos el resultadoresultado = Resta();

// Mostramos el resultadoConsole.WriteLine(“El resultado de la resta es

{0}”, resultado);}

// Checamos por la multiplicacionif (opcion == 3){

// Variables necesariasfloat n1 = 0;float n2 = 0;

Las funciones

167www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 167

Page 170: C# aprenda a programar

string numero = “”;

// Pedimos los valoresConsole.WriteLine(“Dame el primer numero”);numero = Console.ReadLine();n1 = Convert.ToSingle(numero);

Console.WriteLine(“Dame el segundo numero”);numero = Console.ReadLine();n2 = Convert.ToSingle(numero);

// Invocamos a la funcionMultiplicacion(n1, n2);

}

// Checamos por la divisionif (opcion == 4){

// Variables necesariasfloat n1 = 0.0f;float n2 = 0.0f;

float resultado = 0.0f;string numero = “”;

// Pedimos los valoresConsole.WriteLine(“Dame el primer numero”);numero = Console.ReadLine();n1 = Convert.ToSingle(numero);

Console.WriteLine(“Dame el segundo numero”);numero = Console.ReadLine();n2 = Convert.ToSingle(numero);

// Invocamos a la funcionresultado = Division(n1, n2);

// Mostramos el resultadoConsole.WriteLine(“El resultado es {0}”,

resultado);

5. FUNCIONES Y MÉTODOS

168 www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 168

Page 171: C# aprenda a programar

}

} // Cierre de Main

static void Suma(){

// Variables necesariasfloat a = 0;float b = 0;float r = 0;string numero = “”;

// Pedimos los valoresConsole.WriteLine(“Dame el primer numero”);numero = Console.ReadLine();a = Convert.ToSingle(numero);

Console.WriteLine(“Dame el segundo numero”);numero = Console.ReadLine();b = Convert.ToSingle(numero);

// Calculamos el resultador = a + b;

// Mostramos el resultadoConsole.WriteLine(“El resultado es {0}”, r);

}

static float Resta(){

// Variables necesariasfloat a = 0;float b = 0;float r = 0;string numero = “”;

// Pedimos los valoresConsole.WriteLine(“Dame el primer numero”);

Las funciones

169www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 169

Page 172: C# aprenda a programar

numero = Console.ReadLine();a = Convert.ToSingle(numero);

Console.WriteLine(“Dame el segundo numero”);numero = Console.ReadLine();b = Convert.ToSingle(numero);

// Calculamos el resultador = a - b;

// Retornamos el resultadoreturn r;

}

static void Multiplicacion(float a, float b){

// Variables necesariasfloat r = 0;

// Calculamos el valor

r = a * b;

// Mostramos el resultadoConsole.WriteLine(“El resultado es {0}”, r);

}

static float Division(float a, float b){

// Variables necesariasfloat r = 0;

// Verificamos por division entre ceroif (b == 0){

Console.WriteLine(“No es posible dividir entre cero”);return 0.0f;

}

5. FUNCIONES Y MÉTODOS

170 www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 170

Page 173: C# aprenda a programar

else{

r = a / b;return r;

}}

}}

Optimizar con funcionesYa conocemos cómo utilizar los diferentes tipos de funciones y ahora aprenderemoscómo podemos optimizar un programa haciendo uso de ellas. En el programa an-terior podemos pensar que hemos utilizado todas las funciones que son necesarias.Pero nosotros sabemos que una buena oportunidad para hacer uso de las funcioneses cuando tenemos código que se repite constantemente. Si observamos nuestro pro-grama, podemos observar que esto ocurre.

En nuestro programa tenemos algo que sucede ocho veces. Se piden los valores autilizar al usuario en varios lugares del programa. Cada vez que lo pedimos usamostres líneas de código y la forma cómo se pide es muy similar entre ellas.

Cuando tenemos estos casos hay que llevar a cabo un poco de análisis. Lo prime-ro que nos preguntamos es: ¿qué función lleva a cabo este código? La respuesta espedir un valor flotante. Luego nos tenemos que preguntar si la función necesitade algún dato o datos para poder trabajar.

En una primera vista parece que no, ya que el usuario es el que va a introducir eldato. Sin embargo, si observamos mejor veremos que en realidad sí necesitamos undato. La petición se lleva a cabo por medio de un mensaje y este mensaje puede serdiferente en cada caso. Podemos tener como dato el mensaje a mostrar por el usua-rio. Este va a entrar como parámetro en nuestra función. La última pregunta quenos debemos hacer es: ¿necesita la función regresar algo? En este caso es muy fácildeducir que sí. Lo que necesitamos regresar es el valor que el usuario nos ha dado.

Ya con esta información podemos construir nuestra función. Si la función fuera máscomplicada necesitaríamos hacer el diagrama de flujo correspondiente. Afortuna-damente nuestra función es muy sencilla y queda de la siguiente manera:

Las funciones

171www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 171

Page 174: C# aprenda a programar

static float PideFlotante(string mensaje)

{// Variables necesariasfloat numero=0.0f;string valor=””;

// Mostramos el mensajeConsole.WriteLine(mensaje);

// Obtenemos el valorvalor = Console.ReadLine();numero = Convert.ToSingle(valor);

// Regresamos el datoreturn numero;

}

Empecemos a ver cómo trabaja esta función que hemos creado.El nombre es PideFlotante ya que como sabemos el nombre de la función tiene queindicar una referencia al tipo de trabajo que realiza. Como nuestra función regresaun valor de tipo flotante, entonces colocamos como su tipo a float. La función tiene un único parámetro que es el mensaje que deseamos mostrar alusuario en la petición. Como es un mensaje de texto entonces el tipo que más con-viene usar es string. A nuestro parámetro le nombramos mensaje.En el interior de la función declaramos dos variables. Una es el número que vamosa recibir del usuario y la otra variable es la cadena que usamos con ReadLine(). Lue-go mostramos el mensaje de petición. De la forma habitual obtenemos el valor da-do por el usuario. Ya para finalizar simplemente regresamos el número.Para invocar a esta función, lo haremos de la siguiente manera:

n1 = PideFlotante(“Dame el primer numero”);

Ahora vemos que en lugar de utilizar las tres líneas de código por petición, simple-mente hacemos una invocación a nuestra función. Pero este no es el único cambioque tenemos que hacer. En el programa original habíamos colocado variables de tra-bajo para apoyarnos en la petición del valor, pero ya no son necesarias.Si cambiamos el programa para hacer uso de nuestra nueva función quedará comoen el ejemplo que vemos a continuación:

5. FUNCIONES Y MÉTODOS

172 www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 172

Page 175: C# aprenda a programar

using System;using System.Collections.Generic;using System.Text;namespace AplicacionBase{

class Program{

// Esta es la funcion principal del programa// Aqui inicia la aplicacionstatic void Main(string[] args){

// Variables necesariasint opcion = 0;string valor = “”;

// Mostramos el menuConsole.WriteLine(“1-Suma”);Console.WriteLine(“2-Resta”);Console.WriteLine(“3-Multiplicacion”);Console.WriteLine(“4-Division”);

// Pedimos la opcionConsole.WriteLine(“Cual es tu opcion:”);valor = Console.ReadLine();opcion = Convert.ToInt32(valor);

// Checamos por la sumaif (opcion == 1){

Suma();}

// Checamos por la restaif (opcion == 2){

// Variable para nuestro resultadofloat resultado = 0;

// Invocamos y obtenemos el resultado

Las funciones

173www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 173

Page 176: C# aprenda a programar

resultado = Resta();

// Mostramos el resultadoConsole.WriteLine(“El resultado de la resta es

{0}”, resultado);}

// Checamos por la multiplicacionif (opcion == 3){

// Variables necesariasfloat n1 = 0;float n2 = 0;

// Pedimos los valoresn1 = PideFlotante(“Dame el primer numero”);n2 = PideFlotante(“Dame el segundo numero”);

// Invocamos a la funcion

Multiplicacion(n1, n2);}

// Checamos por la divisionif (opcion == 4){

// Variables necesariasfloat n1 = 0.0f;float n2 = 0.0f;float resultado = 0.0f;

// Pedimos los valoresn1 = PideFlotante(“Dame el primer numero”);n2 = PideFlotante(“Dame el segundo numero”);

// Invocamos a la funcionresultado = Division(n1, n2);

// Mostramos el resultadoConsole.WriteLine(“El resultado es {0}”,

5. FUNCIONES Y MÉTODOS

174 www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 174

Page 177: C# aprenda a programar

resultado);}

} // Cierre de Main

static void Suma(){

// Variables necesariasfloat a = 0;float b = 0;float r = 0;

// Pedimos los valoresa = PideFlotante(“Dame el primer numero”);b = PideFlotante(“Dame el segundo numero”);

// Calculamos el resultador = a + b;

// Mostramos el resultado

Console.WriteLine(“El resultado es {0}”, r);}static float Resta(){

// Variables necesariasfloat a = 0;float b = 0;float r = 0;

// Pedimos los valoresa = PideFlotante(“Dame el primer numero”);b = PideFlotante(“Dame el segundo numero”);

// Calculamos el resultador = a - b;

// Retornamos el resultadoreturn r;

Las funciones

175www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 175

Page 178: C# aprenda a programar

}

static void Multiplicacion(float a, float b){

// Variables necesariasfloat r = 0;

// Calculamos el valorr = a * b;

// Mostramos el resultadoConsole.WriteLine(“El resultado es {0}”, r);

}

static float Division(float a, float b){

// Variables necesarias

float r = 0;

// Verificamos por division entre ceroif (b == 0){

Console.WriteLine(“No es posible dividir entre cero”);return 0.0f;

}else{

r = a / b;return r;

}}

static float PideFlotante(string mensaje){

// Variables necesariasfloat numero = 0.0f;string valor = “”;

5. FUNCIONES Y MÉTODOS

176 www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 176

Page 179: C# aprenda a programar

// Mostramos el mensajeConsole.WriteLine(mensaje);

// Obtenemos el valorvalor = Console.ReadLine();numero = Convert.ToSingle(valor);

// Regresamos el datoreturn numero;

}

}}

Si observamos el código, podemos notar que es más fácil de leer y luce más orde-nado. También hemos reducido los lugares donde podemos tener un error de sin-taxis o lógica. Ejecutemos el programa para verificar si trabaja correctamente. Po-demos seleccionar cualquier operación.

Figura 11. El programa se ejecuta correctamente

con nuestra función para pedir flotantes al usuario.

Las funciones

177www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 177

Page 180: C# aprenda a programar

Otro punto que debemos de tener en cuenta es que las funciones están invocandoa nuestra función sin problema. Las funciones pueden invocar a las funciones.

Paso por copia y paso por referenciaTenemos que aprender un concepto importante sobre los parámetros y las funciones.La mejor forma de hacerlo es por medio de un experimento sencillo. Ya anteriormentehemos comentado dos conceptos. El primero es que las variables tienen ámbito, esdecir que las partes del programa donde se pueden utilizar depende de donde fuerondeclaradas. El otro concepto es que cuando invocamos a una función y pasamos pa-rámetros, una copia del valor del parámetro es pasada a la función. Empecemos connuestro experimento. Vamos a crear un programa con el siguiente código.

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la funcion principal del programa// Aqui inicia la aplicacionstatic void Main(string[] args){

// Variables necesariasint numero = 5;

// Valor antes de funcionConsole.WriteLine(“Valor antes de funcion {0}”, numero);

// Invocamos funcionCambiar(numero);

// Valor despues de funcionConsole.WriteLine(“Valor despues de funcion {0}”, numero);

}static void Cambiar(int numero){

// Cambiamos el valor

5. FUNCIONES Y MÉTODOS

178 www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:33 PM Page 178

Page 181: C# aprenda a programar

numero = 17;}

}}

En el programa tenemos dos funciones, la función Main() y la función Cambiar().En Main() estamos declarando una variable y le asignamos el valor de 5. Luego im-primimos un mensaje que muestra el valor de nuestra variable antes de invocar a lafunción. En seguida invocamos a la función y después de ésta imprimimos otro men-saje que nos muestra el valor de la variable.Esto lo hacemos para poder verificar si la variable se ve afectada por la función. Lafunción es muy sencilla, simplemente recibe un parámetro y le asigna un nuevo va-lor. Este programa podría parecer que presentaría un valor diferente antes y despuésde la función, pero ejecutémoslo y veamos qué ocurre.

Figura 12. El valor de la variable es el mismo

antes y después de la ejecución de la función.

Al ejecutar notamos que el valor de la variable es igual antes y después de invocar ala función. Es decir que la función no alteró el valor de la variable, aunque parecíaque lo iba a hacer. Veamos la razón de esto.

Las funciones

179www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 179

Page 182: C# aprenda a programar

La primera razón de por qué esto sucede es que la variable fue declarada en la fun-ción Main(), es decir que solamente esta función la conoce y puede utilizarla direc-tamente. Main() es el ámbito de la variable. Luego tenemos que cuando el paráme-tro se pasa de esta forma, en realidad no es la variable lo que se está pasando, sinouna copia del valor de ella. Por eso cuando nuestra función trata de cambiar el va-lor, cambia a la copia y no a la variable original.Cuando pasamos los parámetros de esta forma decimos que pasan por copia. Peroexiste otra forma de pasar los parámetros y se conoce como paso por referencia.Cambiemos nuestro programa para que quede de la siguiente manera:

using System;using System.Collections.Generic;using System.Text;namespace AplicacionBase{

class Program{

// Esta es la funcion principal del programa// Aqui inicia la aplicacionstatic void Main(string[] args){

// Variables necesariasint numero = 5;

// Valor antes de funcionConsole.WriteLine(“Valor antes de funcion {0}”,

numero);

// Invocamos funcionCambiar(ref numero);

// Valor despues de funcionConsole.WriteLine(“Valor despues de funcion {0}”, numero);

}

static void Cambiar(ref int numero){

// Cambiamos el valornumero = 17;

5. FUNCIONES Y MÉTODOS

180 www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 180

Page 183: C# aprenda a programar

}}

}

Ejecutemos primero el programa y luego veamos qué ocurre.

Figura 13. En este caso el valor de la variable

si es cambiado. Esto se debe a que se pasó la referencia a la variable.

En este caso estamos pasando el parámetro por referencia. Cuando esto sucede,en lugar de pasar una copia del valor, lo que pasamos es una referencia al lugardonde se encuentra la variable en memoria. De esta forma cualquier asignación ala variable se realiza sobre la variable original y su valor puede ser cambiado aun-que haya sido definida en otro ámbito.Para poder indicar que un parámetro necesita pasarse por referencia es necesario usarla instrucción ref, tanto en la invocación de la función como en su declaración. Po-demos tener más de una variable pasada por referencia en una función.El paso por referencia es muy útil, en especial para casos cuando es necesario queuna función regrese más de un valor. Como sabemos, return solamente puede re-gresar un valor, pero al usar referencias podemos tener una función que regrese másde un valor por medio de la modificación de las variables pasadas.

Las funciones

181www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 181

Page 184: C# aprenda a programar

Veamos un ejemplo de esto. Vamos a crear una función que permita intercambiarlos valores de dos variables. Esto problema puede parecer sencillo, pero sin el usode las referencias es imposible resolverlo con una sola función. A continuación ve-remos cómo queda nuestra programa.

using System;

using System.Collections.Generic;using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la funcion principal del programa// Aqui inicia la aplicacionstatic void Main(string[] args){

// Variables necesariasint a = 5;int b = 3;

// Valor antes de funcionConsole.WriteLine(“Valores antes de funcion a={0},

b={1}”, a,b);

// Invocamos funcionCambiar(ref a, ref b);

// Valor despues de funcion

Console.WriteLine(“Valores despues de funcion a={0}, b={1}”, a, b);

}

static void Cambiar(ref int x, ref int y){

// Variable de trabajoint temp = 0;

182 www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 182

Page 185: C# aprenda a programar

// Cambiamos el valortemp = x;x = y;y = temp;

}

}}

Si lo ejecutamos, obtenemos lo siguiente:

Figura 14. Los valores han sido intercambiados por la función.

Como vemos, hacemos uso de una variable de trabajo para ayudarnos en el inter-cambio de los valores. El paso por referencia nos permite modificar ambas variables.

Uso de parámetros de defaultUna de las características nuevas que encontramos en la última versión de C# es eluso de parámetros de default en las funciones. Con las funciones que hemos estadoutilizando es necesario proveer a la función de todos los parámetros con los que fuedeclarada. Es decir, si la función tiene dos parámetros, cuando la invocamos debe-mos darle dos valores para que trabaje con ella.

Las funciones

183www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 183

Page 186: C# aprenda a programar

Con los parámetros de default es posible colocar un valor predeterminado al pará-metro, de tal forma que si en la invocación de la función no se da explícitamente elvalor, entonces se usa el valor predeterminado. Esto puede resultar útil cuando te-nemos parámetros que en la gran mayoría de los casos usan el mismo valor. De es-ta forma cuando invocamos a la función lo hacemos usando solamente los valoresque cambien, lo cual nos permite escribir menos y solamente cuando es necesariocolocamos el valor en el parámetro.Esto lo podemos ver en el siguiente ejemplo. El cual tiene una función con parámetrosde default y es invocada de forma tradicional y luego haciendo uso del parámetro dedefault. Cuando hace uso del parámetro de default impuesto usa el valor de 0.16.

using System;using System.Collections.Generic;using System.Linq;using System.Text;

namespace Cap5_5{

class Program{

static void Main(string[] args){

double costo = 50.0;double imp = 0.0;double total = 0.0;

// Hacemos uso de la funcion de manera tradicional

imp = CalculaImpuesto(costo, 0.25);total = costo + imp;

// Imprimimos resultadoConsole.WriteLine(“El total es ${0}”, total);

// Hacemos uso de la funcion con parametro de default// Hay que notar que solamente pasamos un parametro, el otro usa

// el valor predeterminado

5. FUNCIONES Y MÉTODOS

184 www.redusers.com

05_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 184

Page 187: C# aprenda a programar

imp = CalculaImpuesto(costo);total = costo + imp;

// Imprimimos resultadoConsole.WriteLine(“El total es ${0}”, total);

}

public static double CalculaImpuesto(double cantidad, double impuesto = 0.16f)

{double impuestoCalculado;

impuestoCalculado = cantidad * impuesto;return impuestoCalculado;

}}

}

Con esto hemos visto los principios y los usos fundamentales de las funciones. Lasfunciones son muy útiles y las continuaremos utilizando frecuentemente.

Las funciones

185www.redusers.com

… RESUMEN

Las funciones nos permiten tener secciones especializadas de código en nuestra aplicación,

reducir la cantidad de código necesario y reutilizar el código de manera eficiente. Las

funciones constan de cinco partes y hay cuatro tipos de ellas. La función puede recibir

información por medio de los parámetros y regresar información por medio de return. Es

posible pasar los parámetros por copia o por referencia.

05_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 185

Page 188: C# aprenda a programar

186 www.redusers.com

TEST DE AUTOEVALUACIÓN

1 ¿Qué son las funciones?

2 ¿Qué es invocar una función?

3 ¿Cuáles son las partes de las funciones?

4 ¿Para qué nos sirve el modificador static?

5 ¿Cuáles son los cuatro tipos de funciones?

6 Cuando la función no regresa un valor,

¿cuál es su tipo?

7 ¿Qué tipos de valores pueden regresar las

funciones?

8 ¿Para que sirve return?

9 ¿Cómo se colocan los parámetros?

10¿Cómo podemos usar las funciones para

optimizar nuestro programa?

11¿Qué es el paso por copia?

12¿Qué es el paso por referencia?

ACTIVIDADES

EJERCICIOS PRÁCTICOS

1 Hacer una función para transformar de

grados a radianes.

2 Hacer una función para transformar de

grados centígrados a grados Fahrenheit.

3 Hacer una función que calcule el

perímetro de cualquier polígono regular

dando el número de lados y sus

dimensiones.

4 Hacer una función que calcule el factorial

de un número.

5 Hacer una función que dado un número

nos regrese una cadena donde se

encuentre escrito en palabras.

05_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 186

Page 189: C# aprenda a programar

Los arreglos

Los arreglos 188Declaración de los arreglos de una dimensión 189Asignación y uso de valores 191Arreglos de dos dimensiones 196Arreglos de tipo jagged 205Los arreglos como parámetros a funciones 212

Resumen 215Actividades 216

Capítulo 6

En los capítulos anteriores hemos

utilizado las variables. Colocamos

información en éstas para luego

procesarlas. Nuestros programas pueden

tener muchas variables, en especial

cuando la cantidad de información

a guardar es mucha. Los aarrrreeggllooss

nos brindan una forma de poder

administrar la información fácilmente,

y son especialmente útiles cuando

necesitamos muchas variables

y el trabajo que se realiza sobre ellas

es el mismo.

C#

SERVICIO DE ATENCIÓN AL LECTOR: [email protected]

06_C#2010_AJUSTADO.qxd 8/11/10 9:53 AM Page 187

Page 190: C# aprenda a programar

LOS ARREGLOS

Pensemos en un problema donde los arreglos nos pueden ser útiles. En el Capítu-lo 4 creamos un programa donde se calculaba el promedio de un grupo de alum-nos. En él usamos un ciclo for, mediante el cual se pedía la calificación constante-mente. Para la calificación siempre se usaba la misma variable. Pensemos ahora, quenos encontramos con la necesidad de que nuestro programa no solamente muestreel promedio, sino también la calificación más alta y más baja del salón. Estos cál-culos requieren ser utilizados en diferentes partes del programa, por lo que no es po-sible colocar todo adentro del ciclo for con el que fue diseñado en un principio.El problema al que nos estamos enfrentando es que, como sólo hemos hecho usode una variable para las calificaciones, cuando necesitemos procesar nuevamen-te la información desde nuestro software, ya no tendremos almacenado el valorde la calificación anterior en la variable, sólo tendremos la última calificacióncapturada. ¿Cómo podemos resolver esto? Una forma de hacerlo sería crear y uti-lizar muchas variables como: calif1, calif2, calif3…, etcétera.Al principio esta idea puede parecer correcta, pero manejar muchas variables deforma independiente, luego de un tiempo puede tornarse engorroso, y también po-dremos encontrar un caso en el que no sabemos cuántas variables necesitaremos.Sin embargo, esto nos puede dar una idea sobre lo que necesitamos.Si observamos el nombre de las variables, vemos que todas llevan en su nombre calif,es decir que todas se refieren a la calificación. Podemos pensar que están conceptual-mente agrupadas para la calificación. Otro punto que notamos es que las variables es-tán numeradas, como si tuvieran un índice que nos sirve para identificarlas.Los arreglos son similares a estos conceptos ya que son grupos de variables y estasvariables serán referenciadas por el mismo nombre. Para poder acceder a una varia-ble del arreglo usaremos un número de índice, ya que todas las variables adentro deun arreglo serán de un mismo tipo. Un punto muy importante que no debemos ol-vidar cuando trabajemos con los arreglos es que éstos están basados en índice cero,esto quiere decir que el primer elemento del arreglo se encuentra en la posición 0,no en la posición 1 como podríamos pensar. No olvidar este punto nos evitará mu-chos problemas de lógica en el futuro.

6. LOS ARREGLOS

188 www.redusers.com

En un arreglo es conveniente colocar la cantidad correcta de elementos, ya que una vez creado,

no puede crecer a menos que utilicemos una función especial. Si hacemos lo último en forma

constante, esto indica que nuestro programa tiene problemas de diseño. En el próximo capítulo

veremos estructuras que permiten variar la cantidad de elementos a guardar.

EL TAMAÑO DEL ARREGLO

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 188

Page 191: C# aprenda a programar

Figura 1. En esta figura vemos la comparación

entre tener varias variables y un arreglo.

Declaración de los arreglos de una dimensiónLos arreglos pueden tener diferentes dimensiones, y si el arreglo se parece a unasimple lista, como la lista de calificaciones que tenemos, entonces decimos que esde una dimensión. Estos arreglos también se conocen como monodimensionaleso unidimensionales. Si el arreglo es como una tabla con varios renglones y variascolumnas, entonces es un arreglo de dos dimensiones o bidimensional. Primerotrabajaremos con los arreglos de una dimensión y luego pasaremos a arreglos de dosdimensiones o más. Para poder trabajar un arreglo, primero es necesario declarar-lo. En la declaración nosotros indicamos su tipo, su nombre y su tamaño.

tipo[] nombre = new tipo[tamaño];

0a0

a1

a2

a3

1

2

3

a

Los arreglos

189www.redusers.com

Los arreglos tienen una cantidad finita de elementos y ésta se indica en el momento en que se

declaran. Cuando intentamos acceder a uno de sus elementos debemos colocar un valor de

índice válido y que no exceda el tamaño del arreglo. Un error común con los arreglos es intentar

acceder a elementos más allá de los que tiene.

CUIDADO CON EL RANGO DEL ARREGLO

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 189

Page 192: C# aprenda a programar

La declaración puede parecer un poco extraña, por lo que a continuación haremosun ejemplo más claro y real, y lo explicaremos a fondo.

float[] calificaciones= new float[10];

En C# los arreglos son objetos, y deberemos usar new al declararlos. El arreglo se-rá de tipo flotante, y usaremos [ ] para indicar su declaración. Luego debemos co-locar el nombre con el que lo identificaremos. En nuestro ejemplo se llama: cali-ficaciones. Del lado derecho de la sentencia tenemos la instanciación del arreglo.Indicaremos entre [ ] la cantidad de elementos que deseamos tener. La cantidadpuede ser colocada de forma explícita, tal como está en el ejemplo, o por mediodel contenido de una variable. Podemos ejemplificar esto de la siguiente forma:

int n = 10;

float[] calificaciones = new float[n];

En este caso se tendrá la cantidad de elementos igual al valor guardado en la variable n.En algunas ocasiones podemos conocer los valores que colocaremos adentro del arre-glo, por lo que podemos declararlo y asignarle sus valores en la misma sentencia.Esto lo hacemos indicando primero el tipo y los [ ] seguidos del nombre del arre-glo y en el lado derecho de la sentencia colocamos entre { } los elementos que se ledesean asignar al arreglo. Estos elementos deberán estar separados por comas.Veámoslo ejemplificado de manera más clara:

float[] valores = { 1.5f, 3.78f, 2.1f };

En este caso hemos creado un arreglo llamado valores y tendrá tres elementos conlos valores colocados. La siguiente figura nos muestra cómo quedaría.

6. LOS ARREGLOS

190 www.redusers.com

La cantidad de datos debe ser un valor válido. No podemos colocar números negativos, ni un

tamaño de cero ya que no tendría sentido. Si la cantidad de elementos a crear se pasará por

medio de una variable, ésta debe de ser de tipo entera. No tener en cuenta esto traerá

problemas al compilar la aplicación.

COLOCAR EL TAMAÑO CORRECTAMENTE

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 190

Page 193: C# aprenda a programar

Figura 2. El arreglo tiene tres elementos con los índices 0, 1 y 2.

Asignación y uso de valoresYa hemos visto cómo declarar el arreglo. Ahora tenemos que aprender cómo podercolocar información en su interior y hacer uso de ésta.Para poder asignarle un valor a alguno de los elementos del arreglo necesitamos ha-cer uso del índice del elemento que queremos utilizar, y como dijimos antes, no de-bemos olvidar que el primer elemento se encuentra en la posición 0.Supongamos que queremos asignarle la calificación 8.5 al tercer alumno.

calificaciones[2] = 8.5f;

Lo primero es usar el nombre del arreglo, tal y como con las variables, pero entre [ ]colocamos el índice del elemento al que se lo queremos asignar. El tercer alumno seencuentra en el índice 2. Esto se debe a que empezamos a contar desde cero: 0, 1, 2.Luego del lado derecho de la asignación colocamos el valor a asignar. El control delíndice también se puede hacer por medio de una variable de tipo entero. El valor con-tenido en la variable será usado para acceder al elemento del arreglo.

calificaciones[indice] = 8.5f;

Para el índice, tener la capacidad de utilizar una variable es muy útil, ya que estonos permitirá recorrer el arreglo con alguno de los ciclos estudiados en los primeroscapítulos del libro. Los valores contenidos adentro del arreglo pueden usarse comovariables normales, por ejemplo en un cálculo.

impuesto = costo[n] * 01.5f;

0- 1.5

1- 3.78

2- 2.1

valores

Los arreglos

191www.redusers.com

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 191

Page 194: C# aprenda a programar

Y el desplegado es igualmente fácil.

Console.Write(“El valor es {0}”, costo[n]);

Ahora que ya tenemos los conceptos básicos de los arreglos podemos hacer nuestroprograma, donde se pedirá la cantidad de alumnos y las calificaciones. El programaencontrará el promedio, la calificación más alta y la calificación más baja. Para de-mostrar que los datos no se pierden al ser guardados en el arreglo haremos cada cál-culo en un ciclo diferente, y para comprender mejor esto, veamos a continuación eldiagrama de flujo correspondiente:

Figura 3. El diagrama nos muestra las diferentes

partes donde usamos la información del arreglo.

using System;using System.Collections.Generic;

n = 0 n = 0 n = 0

Mostrarpromedio

mínima máxima

Pedimoscantidad de

alumnos

Creamosarreglo

Pedimoscalificación

Inicio

Fin

NO

NO

n = 0

suma+=calif[n]

Calif[n]<mínima

mínima=calif[n]

máxima=calif[n]

n<cantidadPromedio=

suma/cantidad

NOCalif[n]>máxima

NO

NO

NO

NO

Í NO

n<cantidad

NO

n<cantidad

NO

SÍ n<cantidad

6. LOS ARREGLOS

192 www.redusers.com

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 192

Page 195: C# aprenda a programar

using System.Text;namespace AplicacionBase{

class Program{

// Esta es la función principal del programa// Aquí inicia la aplicacionstatic void Main(string[] args){

// Variables necesariasint cantidad = 0; // Cantidad de alumnosint n = 0; // Variable de control de ciclostring valor = “”;

// Variables para el promediofloat suma = 0.0f;float promedio = 0.0f;

float minima = 10.0f;// Variable para la calificación mínima

float máxima = 0.0f; // Variable para la calificación maxima

// Pedimos la cantidad de alumnosConsole.WriteLine(“Dame la cantidad de alumnos”);valor = Console.ReadLine();cantidad = Convert.ToInt32(valor);

// Creamos el arreglofloat[] calif = new float[cantidad];

// Capturamos la informaciónfor (n = 0; n < cantidad; n++){

Console.Write(“Dame la calificación “);valor = Console.ReadLine();calif[n] = Convert.ToSingle(valor);

}

// Encontramos el promedio

Los arreglos

193www.redusers.com

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 193

Page 196: C# aprenda a programar

for (n = 0; n < cantidad; n++){

suma += calif[n];}

promedio = suma / cantidad;

// Encontramos la calificación mínimafor (n = 0; n < cantidad; n++){

if (calif[n] < minima)minima = calif[n];

}

// Encontramos la calificación maximafor (n = 0; n < cantidad; n++){

if (calif[n] > maxima)máxima = calif[n];

}

// Desplegamos los resultadosConsole.WriteLine(“El promedio es {0}”, promedio);Console.WriteLine(“La calificación mínima es {0}”, minima);Console.WriteLine(“La calificación máxima es {0}”, maxima);

} // Cierre de main

} // Cierre de la clase}

Inicialmente declaramos las variables que necesitará la aplicación. Sin embargo, aúnno hemos declarado el arreglo. Esto se debe a que el tamaño del arreglo dependeráde la cantidad de alumnos. Una vez que tenemos esa cantidad creamos el arreglo.Luego, por medio de un ciclo for capturamos la información. Debemos notar que elciclo inicia en 0. Esto se debe a que el primer elemento del arreglo se encuentra enel índice 0. El ciclo se recorre tantas veces como elementos tenga el arreglo. Para cal-cular el promedio, recorremos el arreglo de nuevo por medio de un ciclo for con lavariable suma para obtener la sumatoria de todas las calificaciones. Luego simple-mente calculamos el promedio, dividiendo la suma entre la cantidad de alumnos.

6. LOS ARREGLOS

194 www.redusers.com

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 194

Page 197: C# aprenda a programar

Para poder calcular la calificación menor declaramos una variable llamada minima.A esta variable la inicializamos con el valor más alto posible para las calificaciones(la razón de esto tendrá sentido enseguida). Creamos nuevamente un ciclo for y re-corremos el arreglo. Para cada elemento del arreglo comparamos su valor con el va-lor de nuestra variable. Si el valor del elemento del arreglo es menor que minima,eso significa que hemos encontrado un valor menor, por lo que minima se actuali-za con este nuevo valor menor. Esto se repite hasta que hemos terminado con to-dos los elementos del arreglo y minima en cada caso tendrá el valor más pequeñoencontrado hasta esa vuelta del ciclo.De igual forma encontramos la calificación más alta del arreglo pero en este ca-so creamos una variable llamada máxima. Esta variable se inicializa con el valormás pequeño que puede tener una calificación. Hacemos un ciclo y recorremostodo el arreglo, y a cada elemento contenido en éste lo comparamos con el valorde máxima. Si es mayor eso significa que hemos encontrado un nuevo máximo,por lo que actualizamos la variable. Si lo anterior se cumple, al finalizar el ciclotendremos la calificación más grande para ese grupo de alumnos.Para finalizar el programa, simplemente mostramos en la consola o línea de co-mandos, los resultados que hemos obtenido.Ejecutemos y probemos cómo funciona la teoría hasta aquí explicada.

Figura 4. El programa guarda la información

en un arreglo y podemos utilizarla cuando sea necesario.

Los arreglos

195www.redusers.com

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 195

Page 198: C# aprenda a programar

Arreglos de dos dimensionesHasta aquí hemos visto que los arreglos nos ayudan a guardar información y a tra-bajar de una manera más cómoda con ella. Cuando tenemos mucha informaciónque almacenar es más fácil manipular un arreglo que muchas variables. Los arre-glos que vimos son similares a una lista, pero no todos los problemas se pueden re-solver con este esquema, y veamos por qué. Supongamos que ahora debemos ha-cer un nuevo programa para una fábrica que produce automóviles y desea tener lainformación de las unidades producidas a diario. La información será procesadapor semana, con el promedio semanal de vehículos producidos. Hasta el momen-to el problema sería muy similar al anterior. Podríamos crear un arreglo de 7 ele-mentos llamado semana y estaría resuelto, pero ahora también desean la informa-ción por mes. El mes tiene cuatro semanas, por lo que podemos pensar en tenercuatro arreglos, uno que se corresponda con cada semana, pero en realidad existeuna forma mejor de solucionar este problema.Si pensamos un poco más en el problema veremos que podemos guardar la infor-mación en una tabla, cada columna sería una semana y cada renglón representaríaun día. Esto se conoce como matriz, y es un arreglo de dos dimensiones. En losarreglos de dos dimensiones tenemos que utilizar dos índices. Uno controlará el ren-glón y el otro la columna. Con la creación de estos dos índices es posible que acce-damos a cualquier celda ubicada dentro de la matriz.

Figura 5. El diagrama nos muestra un arreglo de dos dimensiones

y cómo podemos localizar una celda por medio de su renglón y de su columna.

Al igual que con los arreglos de una sola dimensión, los índices están basados en 0.Esto es tanto para los renglones como para las columnas.

(1,1)

Renglones

Columnas

6. LOS ARREGLOS

196 www.redusers.com

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 196

Page 199: C# aprenda a programar

Declaración de los arreglos de dos dimensionesLa declaración es similar al arreglo de una dimensión, pero indicamos la cantidadde elementos en cada dimensión.

float[,] tabla = new float[5,3];

En este caso, hemos creado una matriz de valores flotantes llamada tabla. Hay quenotar que hemos colocado una coma entre los [ ] para indicar que serán dos di-mensiones. En el lado derecho indicamos el tamaño de cada dimensión. Para esteejemplo tenemos cinco columnas y tres renglones. También es posible declarar la matriz por medio de variables.

float[,] tabla = new float[n, m];

Acceso a un arreglo de dos dimensiones

La utilización del arreglo de dos dimensiones es muy sencilla, podemos acceder ala información si indicamos el renglón y la columna de la celda que nos interesa.Por ejemplo, si deseamos hacer uso del valor que se encuentra almacenado en lacelda (3, 2) hacemos lo siguiente:

impuesto = producto[3,2] * 0.15;

En este caso se toma el valor de la celda (3,2) del arreglo producto, se multiplicapor 0.15 y el valor resultante se asigna a impuesto. De igual forma podemos hacer la asignación al arreglo.

producto[3,2] = 17.50;

Para mostrar el valor en la consola hacemos lo siguiente:

Console.WriteLine(“El costo es {0}”,producto[3,2]);

No debemos olvidar que los índices siempre se inician en cero, y que no es posiblecolocar índices más grandes que la cantidad de elementos contenidos en el arreglo.Con este conocimiento podemos comenzar a trabajar en un ejemplo. Tomaremos

Los arreglos

197www.redusers.com

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 197

Page 200: C# aprenda a programar

el código del ejemplo de la escuela y ahora haremos posible que trabaje para variossalones. Para este caso pediremos la cantidad de salones y la cantidad de alumnos.Cada columna representará el salón y los renglones guardarán la información de losalumnos. De esta forma podemos capturar toda la información de la escuela y cal-cular el promedio, y la calificación mínima y máxima de toda la escuela.Para que este programa funcione de forma eficiente utilizaremos la sentencia for ytambién un tipo de ciclo mencionado en un capítulo anterior. Éstos son los ciclosenlazados, o simplemente, un ciclo dentro de otro ciclo. La forma de utilizarlo esla siguiente: tendremos un ciclo para recorrer cada uno de los salones y dentro deéste tendremos otro ciclo que se dedicará a recorrer los estudiantes. De esta formapodemos cubrir todos los salones y todos los estudiantes de cada salón.A continuación un ejemplo práctico de ciclos enlazados.

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la función principal del programa// Aquí inicia la aplicacionstatic void Main(string[] args){

// Variables necesariasint n = 0; // Ciclo exteriorint m = 0; // Ciclo interior

// Ciclos enlazadosfor (n = 0; n < 3; n++){

for (m = 0; m < 5; m++){

Console.WriteLine(“Ciclo exterior {0}, ciclo interior {1}”, n, m);

} // fin del ciclo m

} // fin del ciclo n

6. LOS ARREGLOS

198 www.redusers.com

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 198

Page 201: C# aprenda a programar

}}

}

Compilemos y ejecutemos el programa.

Figura 6. Vemos cómo se recorren los ciclos. Para cada

paso del ciclo exterior tenemos una vuelta completa del ciclo interior.

Al primer ciclo lo llamaremos ciclo exterior y al ciclo que se coloca adentro lollamaremos ciclo interior. Cada vez que el ciclo exterior avanza un paso, el ci-clo interior da una vuelta completa. Este tipo de comportamiento es el que nos

Los arreglos

199www.redusers.com

Los arreglos tienen un método conocido como Array.Clear(). Este método limpia el arreglo y al

hacerlo coloca todos sus elementos en 0, false o null dependiendo del tipo del arreglo. El

método tiene tres parámetros. El primero es el arreglo a borrar. Luego debemos colocar el

índice a partir de donde deseamos borrar y por último la cantidad de elementos a limpiar.

EL MÉTODO CLEAR()

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 199

Page 202: C# aprenda a programar

permite recorrer toda la tabla. Para cada columna recorremos todos los renglo-nes. Veamos en el diagrama de flujo del programa cómo sería:

Figura 7. El diagrama muestra cómo podemos localizar los ciclos enlazados fácilmente.

Nuestro programa queda constituido de la siguiente manera:

using System;using System.Collections.Generic;

n = 0 n = 0 n = 0 Pedimos

cantidad de salones

Mostrar promedio

mínima máxima

Pedimos cantidad de

alumnos

Creamos arreglo

Pedimos calificación

Inicio

Fin

NO

m = 0

n = 0

m = 0

suma+= calif[n,m]

Calif[n,m] <mínima

mínima= calif[n,m]

máxima= calif[n,m]

m<cantidad

n<salones Promedio=

suma/ cantidad

NOCalif[n,m] >máxima

m = 0 m = 0

NO

NO

NO

NO

NO

NO

Í

NO

m<cantidad

n<salones

NO

Í

NO

Í

m<cantidad

n<salones

NO

NO

Í

m<cantidad

n<salones

6. LOS ARREGLOS

200 www.redusers.com

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 200

Page 203: C# aprenda a programar

using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la función principal del programa// Aquí inicia la aplicacionstatic void Main(string[] args){

// Variables necesariasint cantidad = 0; // Cantidad de alumnosint salones = 0; // Cantidad de salonesint n = 0; // Variable de control de ciclo salonesint m = 0; // Variable de control del ciclo alumnosstring valor = “”;

// Variables para el promediofloat suma = 0.0f;float promedio = 0.0f;

float minima = 10.0f;// Variable para la calificación mínimafloat máxima = 0.0f; // Variable para la calificación maxima

// Pedimos la cantidad de salonesConsole.WriteLine(“Dame la cantidad de salones”);valor = Console.ReadLine();salones = Convert.ToInt32(valor);

// Pedimos la cantidad de alumnos

Los arreglos

201www.redusers.com

Podemos tener arreglos de más de dos dimensiones. El mecanismo para declararlos y

utilizarlos es el mismo. Simplemente debemos tener cuidado con el manejo de los índices para

cada dimensión y si el arreglo es de tres dimensiones necesitaremos tres índices, si es de

cuatro, cuatro índices y así sucesivamente.

ARREGLOS DE MÁS DIMENSIONES

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 201

Page 204: C# aprenda a programar

6. LOS ARREGLOS

202

Console.WriteLine(“Dame la cantidad de alumnos por salon”);valor = Console.ReadLine();cantidad = Convert.ToInt32(valor);

// Creamos el arreglofloat[,] calif = new float[salones, cantidad];

// Capturamos la informaciónfor (n = 0; n < salones; n++) // Ciclo salones

{Console.WriteLine(“Salon {0}”, n);for (m = 0; m < cantidad; m++) // Ciclo alumnos{

Console.Write(“Dame la calificación “);valor = Console.ReadLine();calif[n, m] = Convert.ToSingle(valor);

}}

// Encontramos el promediofor (n = 0; n < salones; n++) // Ciclo salones{

for (m = 0; m < cantidad; m++) // Ciclo alumnos{

suma += calif[n, m];}

}promedio = suma / (cantidad * salones);

// Encontramos la calificación mínima

www.redusers.com

Aunque no parezca, cuando usamos arreglos de muchas dimensiones la cantidad de

memoria necesaria para guardarlos puede crecer rápidamente sin notarlo. Un arreglo de

tres dimensiones de enteros con un tamaño de 256x256x256 no puede parecer mucho, pero

necesita 67,108,864 bytes de memoria.

CRECIMIENTO DE LA MEMORIA USADA POR LOS ARREGLOS

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 202

Page 205: C# aprenda a programar

for (n = 0; n < salones; n++) // Ciclo salones{

for (m = 0; m < cantidad; m++) // Ciclo alumnos{

if (calif[n, m] < minima)minima = calif[n, m];

}}

// Encontramos la calificación maximafor (n = 0; n < salones; n++) // Ciclo salones{

for (m = 0; m < cantidad; m++) // Ciclo alumnos{

if (calif[n, m] > maxima)máxima = calif[n, m];

}}

// Desplegamos los resultadosConsole.WriteLine(“El promedio es {0}”, promedio);Console.WriteLine(“La calificación mínima es {0}”, minima);Console.WriteLine(“La calificación máxima es {0}”,

maxima);

} // Cierre de main

}}

Lo primero que necesitamos es obtener las dimensiones de nuestra matriz. Para es-to debemos saber cuántos salones o cuántas columnas y qué cantidad de alumnoso renglones necesitaremos. Como podemos observar, en el código tenemos los ci-clos enlazados. Un ciclo recorre los salones y el otro recorre los alumnos. Cuandohacemos la petición de la información, es posible asignarla a la celda adecuada pormedio de las variables m y n. De esta forma capturamos toda la información y que-da guardada en las celdas del arreglo.Teniendo esta información, podemos procesarla. Como trabajamos sobre toda la ta-bla, nuevamente usamos los ciclos anidados, desplegando al final sólo los resultados.Ejecutemos el programa y veamos cómo funciona:

Los arreglos

203www.redusers.com

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 203

Page 206: C# aprenda a programar

Figura 8. Observemos que capturamos la información y luego

la procesamos en diferentes partes del programa para obtener los resultados finales.

Es posible que nosotros hayamos procesado una columna en particular. Para estosimplemente mantenemos fijo el valor de la columna y recorremos los renglones conun ciclo. Un ejemplo de esto sería el siguiente:

for (n = 0; n < 10; n++){Console.WriteLine(“El valor es {0}”, producto[5,n]);

}

En este caso recorremos la columna 5 de la matriz producto. El índice del renglónes colocado por la variable de control del ciclo.También es posible mantener fijo el renglón y recorrer todas las columnas. Para es-to nuevamente es necesario un solo ciclo.

for (n = 0; n < 10; n++){

6. LOS ARREGLOS

204 www.redusers.com

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 204

Page 207: C# aprenda a programar

Console.WriteLine(“El valor es {0}”, producto[n,3]);

}

En el caso anterior recorrimos todas las columnas del renglón 3.

Arreglos de tipo jaggedEn el ejemplo anterior todas las columnas tienen la misma cantidad de renglones, esdecir, que todos los salones tendrían la misma cantidad de alumnos, sin embargo, enla práctica esto no sucederá. Tendremos salones con diferentes cantidades de alum-nos, y los arreglos que hemos visto hasta el momento no permiten tener columnas condiferente cantidad de renglones. Esto puede ser una limitación, y puede significar quetengamos renglones sin utilizar en varias columnas. Esto nos lleva a desperdiciar me-moria. Una solución podría ser tener un arreglo que nos permita lograr esto. Para ha-cerlo tenemos que crear un arreglo de arreglos. Esto se conoce como arreglo jagged.En lugar de usar una matriz, lo que haremos es crear un arreglo, pero cada elementode este arreglo será a su vez otro arreglo. Así podemos controlar de forma indepen-diente la cantidad de renglones en cada arreglo. Estos arreglos son más flexibles quelos tradicionales, pero requieren que seamos más cuidadosos con ellos.La siguiente figura nos muestra cómo está constituido un arreglo jagged.

Figura 9. Tenemos un arreglo y cada elemento del arreglo es a su vez otro arreglo.

Renglones

Columnas

Los arreglos

205www.redusers.com

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 205

Page 208: C# aprenda a programar

Al arreglo que contiene los demás arreglos lo llamaremos arreglo contenedor paraque podamos reverenciarnos a él fácilmente.

Declaración de un arreglo jaggedLa declaración de los arreglos jagged es ligeramente más complicada que la de lostradicionales. Cuando los declaramos debemos declarar en primer lugar el arreglocontendor y luego cada uno de los arreglos independientes que tiene.Veamos un primer ejemplo de declaración:

// Declaramos arreglo contenedorint[][] Costos = new int[3][];

// Declaramos los arreglosCostos[0] = new int[15];Costos[1] = new int[20];Costos[2] = new int[10];

Lo que declaramos es un arreglo jagged de tipo entero que se llamará Costos. Comoobservamos, junto al int tenemos [ ][ ]. Esto indica que es un arreglo de arreglos y nouna matriz. En el lado derecho de la asignación tenemos algo similar. Aquí indicamosque nuestro arreglo tiene 3 columnas, pero inmediatamente dejamos [ ] vacíos. Estoes lo que nos permite tener la flexibilidad de darle un tamaño propio a cada renglón. Ya tenemos inicializado el arreglo contenedor. Ahora necesitamos inicializar cadauno de los arreglos internos. Primero indicamos cuál es la columna a inicializar. Enel ejemplo tenemos Costos[0], es decir, que inicializaremos el arreglo que se en-cuentra en la primera columna. Del lado derecho está int[15], con lo que indica-mos que tendrá quince elementos, es decir, 15 renglones para la columna 0.De forma similar la columna 1 tendrá 20 renglones y la columna 2 tendrá 10 ren-glones. Podemos ver que ahora tenemos diferente cantidad de renglones para ca-da columna. Al igual que con los arreglos tradicionales, la cantidad de elemen-tos que tendrá el arreglo puede ser colocada de forma explícita o por medio de

6. LOS ARREGLOS

206 www.redusers.com

Como en un arreglo de tipo jagged nosotros podemos tener diferente cantidad de renglones, es

necesario tener un mecanismo que nos permita saber cuántos renglones tenemos, ya que de lo

contrario corremos el riesgo de colocar índices indebidos que provocarán errores de lógica. Estos

errores pueden ser difíciles de corregir, por lo que es mejor estar preparados antes de utilizarlos.

ADMINISTRAR LOS ARREGLOS JAGGED

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 206

Page 209: C# aprenda a programar

una variable. Si conocemos con anterioridad la información que tendrá el arre-glo jagged podemos hacer lo siguiente:

int[][] valores = new int[3][];valores[0] = new int[] { 9, 3, 1, 7, 2, 4 };valores[1] = new int[] { 2, 9 };valores[2] = new int[] { 3, 5, 2, 9 };

En este caso creamos un arreglo jagged de tres columnas y luego, al momento decrear cada uno de los arreglos internos, los instanciamos colocando los valores di-rectamente. En este caso cada columna tendrá la cantidad de renglones según la can-tidad de valores utilizados en su instanciación. La columna 0 tendrá seis renglones,la columna 1 tendrá dos renglones y la columna 2 tendrá cuatro renglones.A continuación se muestra otra forma para inicializar este tipo de arreglos cuandoconocemos previamente los elementos que utilizaremos adentro de él:

int[][] valores = new int[][]{

new int[] { 9, 3, 1, 7, 2, 4 },new int[] { 2, 9 },new int[] { 3, 5, 2, 9 }

};

En el ejemplo listado no indicamos directamente la cantidad de columnas. C# en-contrará este valor dependiendo de la cantidad de arreglos que se declaren adentro delbloque de código. En este caso declaramos tres arreglos internos, por lo que la canti-dad de columnas es de tres. Al igual que en el caso anterior, la cantidad de renglonespor columnas dependerá de la cantidad de elementos que declaramos en cada inicia-lización, entonces tendremos las mismas cantidades que en el ejemplo anterior.

Acceder a un arreglo jaggedPara acceder a los elementos guardados adentro de un arreglo jagged también ne-cesitamos utilizar índices. Un índice será aplicado para indicar cuál elemento delarreglo contenedor utilizaremos, es decir el número de columna. El otro índice en-tonces nos indicará el elemento del arreglo interno que queremos acceder.Por ejemplo, para asignar un valor realizamos lo siguiente:

productos[6][7] = 5.7f;

Los arreglos

207www.redusers.com

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 207

Page 210: C# aprenda a programar

En este ejemplo vemos que se selecciona el elemento 6 del arreglo contenedor, o silo preferimos la columna 6. Adentro de esa columna seleccionamos el elemento 7 yahí es dónde se coloca el valor 5.7. Si lo que necesitamos es mostrar el contenido deun elemento, el esquema es similar a lo que ya conocemos.

Console.WriteLine(“El valor es {0}”, productos[5][n]);

Ahora modificaremos algunas partes del programa de la escuela para usar el arreglode tipo jagged. Lo que haremos es tener salones con diferente cantidad de alumnosy luego simplemente mostraremos las calificaciones de cada salón.El diagrama es el siguiente:

Figura 10. Hemos agregado un ciclo para

la creación de cada uno de los arreglos internos.

El código del programa quedará de la siguiente forma:

n = 0 n = 0 Pedimos salones

Creamos arreglo

Creamos arreglo

Pedimos alumnos

Pedimos calificación

Inicio

Fin

m = 0

n = 0

m = 0

NO

NO

NO

NO

NO

NO

Ín<salones

NO

Í

NO Í

m<tamaño arreglo

Despliega calificación

NO

SÍ m<tamaño arreglo

n<salones

NOÍ

n<salones

6. LOS ARREGLOS

208 www.redusers.com

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 208

Page 211: C# aprenda a programar

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la función principal del programa// Aquí inicia la aplicacionstatic void Main(string[] args){

// Variables necesariasint cantidad=0; // Cantidad de alumnosint salones=0; // Cantidad de salonesint n=0; // Variable de control de ciclo

salonesint m=0; // Variable de control del ciclo

alumnosstring valor=””;

// Variables para el promediofloat suma=0.0f;float promedio=0.0f;

float minima=10.0f; //Variable para la calificación

mínimafloat maxima=0.0f; //Variable para la calificación

maxima

// Pedimos la cantidad de salonesConsole.WriteLine(“Dame la cantidad de salones”);valor=Console.ReadLine();salones=Convert.ToInt32(valor);

// Creamos el arreglofloat[][] calif= new float [salones][];

// Pedimos los alumnos por salon

Los arreglos

209www.redusers.com

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 209

Page 212: C# aprenda a programar

for(n=0;n<salones;n++) // Ciclo salones{

Console.WriteLine(“Dame la cantidad de alumnos

para el salon {0}”,n);valor=Console.ReadLine();cantidad=Convert.ToInt32(valor);

// Instanciamos el arreglocalif[n]=new float[cantidad];

}

// Capturamos la informaciónfor(n=0;n<salones;n++) // Ciclo salones{

Console.WriteLine(“Salon {0}”,n);for(m=0;m<calif[n].GetLength(0);m++) //

Ciclo alumnos

{Console.Write(“Dame la calificación “);

valor=Console.ReadLine();calif[n][m]=Convert.ToSingle(valor);

}}

// Desplegamos la informaciónConsole.WriteLine(“—— Información ——”);for (n = 0; n < salones; n++) // Ciclo salones{

Console.WriteLine(“Salon {0}”, n);for (m = 0; m < calif[n].GetLength(0); m++) // Ciclo

alumnos{Console.WriteLine(“El alumno {0} tiene {1} “, m,

calif[n][m]);

}

6. LOS ARREGLOS

210 www.redusers.com

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 210

Page 213: C# aprenda a programar

}}

}}

Podemos observar que como primera medida hemos creado el arreglo contenedorde acuerdo con la cantidad de salones que tendremos, luego, por medio de un ci-clo, recorremos cada uno de los salones preguntando en cada uno la cantidad dealumnos, entonces ahí creamos el arreglo interno con el tamaño obtenido. Debe-mos tener cuidado y prestar mucha atención en el uso de la sintaxis para proce-sar cada arreglo que manejaremos.Veamos que del lado derecho de la sentencia tenemos el índice del arreglo quecrearemos y en el lado izquierdo indicamos el tamaño. De esta forma, quedarácreado un arreglo de ese tamaño en tal posición del arreglo contenedor.Ya creado el arreglo jagged procedemos a colocar la información en su interior.Al igual que antes usamos ciclos enlazados, y solamente deberemos cambiar laasignación de acuerdo con la sintaxis del arreglo jagged. Lo mismo ocurre cuandoqueremos imprimir los contenidos de arreglo jagged en la consola.

Figura 11. Podemos observar que efectivamente

cada salón tiene un número diferente de alumnos.

Los arreglos

211www.redusers.com

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 211

Page 214: C# aprenda a programar

Para verificar que efectivamente podemos crear columnas con diferentes tamañoscada vez, ejecutemos el programa de nuevo con otros valores.

Figura 12. En esta ocasión hemos creado un arreglo jagged de diferente tamaño.

Los arreglos como parámetros a funcionesAprendimos a usar los arreglos. Hasta el momento han sido utilizados adentro dela función Main(). A medida que nuestros programas sean más grandes y especiali-zados, tendremos que usar funciones y éstas necesitarán procesar la información con-tenida en los arreglos. Al igual que con las variables, es posible pasar un arreglo co-mo parámetro. De esta forma podremos encargarnos de enviar la información des-de el arreglo hacia la función correspondiente.

6. LOS ARREGLOS

212 www.redusers.com

Cuando enviamos un arreglo como parámetro a una función, contemplemos los siguientes factores.

El primero es que el arreglo enviado y el arreglo del parámetro deben ser el mismo tipo de dato, el

segundo es que deben tener las mismas dimensiones, es decir ambos son como lista o como matriz,

y el último es que ambos deben ser del mismo estilo: normal o jagged.

LOS ARREGLOS COMO PARÁMETROS

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 212

Page 215: C# aprenda a programar

Nuestra función debe estar definida de forma similar, como se muestra a continuación:

static void Imprime(int[] arreglo){

...

}

Como podemos ver, en la lista de parámetros indicamos que el parámetro es unarreglo al colocar [ ] y es de tipo int. El nombre del parámetro en este caso es arre-glo y lo podremos utilizar internamente dentro de la función como variable local.

La invocación se llevaría a cabo de la siguiente forma:

int[] numeros = new int[5];......Imprime(numeros);

Vemos que tenemos un arreglo de enteros que se llama números. En el momentode invocar la función lo hacemos por medio del nombre de la función y coloca-mos como parámetro solamente el nombre del arreglo, es decir, pasamos el arre-glo pero sin colocarle [ ]. Esto se debe a que pasamos un arreglo completo y nosolamente un elemento que se encuentra adentro del arreglo. Ahora veremos unejemplo donde podamos hacer uso de esto. En la función Main() crearemos unarreglo y capturaremos los datos necesarios. Luego tendremos una función espe-cializada en imprimir los contenidos del arreglo.

Nuestro código queda de la siguiente forma:

using System;using System.Collections.Generic;using System.Text;

namespace AplicacionBase{

class Program{

Los arreglos

213www.redusers.com

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 213

Page 216: C# aprenda a programar

// Esta es la función principal del programa// Aquí inicia la aplicacionstatic void Main(string[] args){

// Variables necesariasint[] numeros = new int[5];int n = 0;string valor = “”;

// Pedimos los numerosfor (n = 0; n < 5; n++){

Console.Write(“Dame un numero “);valor = Console.ReadLine();numeros[n] = Convert.ToInt32(valor);

}

// Invocamos a la funcionImprime(numeros);

}

// Esta es la función de impresionstatic void Imprime(int[] arreglo){

int n = 0;

for (n = 0; n < 5; n++){

Console.WriteLine(“El numero es {0}”, arreglo[n]);

}

}}

}

Vemos que es muy sencillo llevar a cabo el paso del arreglo como parámetro y lafunción Imprime() puede usar la información que contiene sin problemas.

6. LOS ARREGLOS

214 www.redusers.com

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 214

Page 217: C# aprenda a programar

Si compilamos y ejecutamos la aplicación obtendremos el siguiente resultado.

Figura 13. Podemos observar que la información

capturada efectivamente es pasada a la función y ésta la utiliza.

Con esto hemos visto los puntos más importantes de los arreglos y cómo utilizarlos.

Los arreglos

215www.redusers.com

… RESUMEN

Los arreglos nos permiten guardar información adentro de un grupo de variables que son

todas del mismo tipo y a las que se puede acceder por un nombre en común. Para acceder a un

elemento en particular necesitamos usar su número de índice. En los arreglos el índice está

basado en cero, es decir que el primer elemento se encuentra en la posición cero, a diferencia

de los arreglos, que pueden tener varias dimensiones dependiendo de nuestras necesidades.

Los arreglos de tipo jagged en realidad son arreglos de arreglos. Éstos nos permiten tener

columnas con diferente cantidad de renglones. Al ser clases, los arreglos tienen funciones de

apoyo que nos facilitan su uso y pueden ser pasados como parámetros a funciones.

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 215

Page 218: C# aprenda a programar

216 www.redusers.com

TEST DE AUTOEVALUACIÓN

1 ¿Qué son los arreglos?

2 ¿Cómo se declara un arreglo?

3 ¿Qué es el índice cero?

4 ¿Cómo se accede a un arreglo?

5 ¿Cómo se declara un arreglo de dos

dimensiones?

6 ¿Qué relación hay entre la cantidad de

índices y la cantidad de dimensiones?

7 ¿Qué sucede si le ponemos un índice

mayor al tamaño del arreglo?

8 ¿Qué es un arreglo de tipo jagged?

9 ¿Cuántas formas de declarar un arreglo

jagged existen?

10¿Cómo declaramos una función para que

reciba un arreglo?

11¿Cómo invocamos una función para que

procese un arreglo?

12¿Qué sucede si intento indexar un arreglo

jagged con la sintaxis de un arreglo

tradicional?

ACTIVIDADES

EJERCICIOS PRÁCTICOS

1 Agregar el cálculo del promedio para el

programa con arreglo jagged.

2 Agregar el cálculo de la menor

calificación para el programa con arreglo

jagged.

3 Agregar el cálculo de la mayor

calificación para el programa con arreglo

jagged.

4 Modificar el programa de la escuela para

que utilice funciones.

5 Crear un programa que pase un arreglo

jagged como parámetro a una función.

06_C#2010_AJUSTADO.qxd 8/6/10 8:34 PM Page 216

Page 219: C# aprenda a programar

Las

colecciones

Las colecciones más importantes 218

El ArrayList 218El Stack 232El Queue 241El Hashtable 249

Resumen 253Actividades 254

Capítulo 7

Hemos aprendido a utilizar los arreglos

para guardar grupos de información

y trabajar más fácilmente. Si bien

los arreglos son muy útiles y sencillos

de usar, en algunas ocasiones están

limitados en su funcionamiento

y son poco flexibles para guardar grupos

de datos dinámicos. En este capítulo

aprenderemos a utilizar las colecciones.

Éstas nos brindan muchos

de los beneficios de los arreglos

y nos dan la flexibilidad necesaria para

guardar datos dinámicos.

C#

SERVICIO DE ATENCIÓN AL LECTOR: [email protected]

07_C#2010_AJUSTADO.qxd 8/11/10 9:56 AM Page 217

Page 220: C# aprenda a programar

LAS COLECCIONES MÁS IMPORTANTES

Las colecciones son estructuras de datos que nos permiten guardar en su interiorcualquier tipo de información. Existen diferentes tipos de colecciones y la forma co-mo se guarda, se accede y se elimina la información en cada una de ellas es distinta.En los arreglos nosotros teníamos que indicar la cantidad de elementos que el arre-glo debía tener. En las colecciones esto no es necesario, ya que es posible agregarelementos dinámicamente. Esto quiere decir que cuando el programa se está eje-cutando podemos adicionar o borrar sus elementos.En otros lenguajes de programación cuando se desea tener este tipo de estructurasgeneralmente es necesario programarlas antes de poder usarlas. Sin embargo C# nosprovee de las colecciones más importantes y podemos utilizarlas directamente sintener que hacer ningún tipo de desarrollo previo.Las coleccione que aprenderemos en este capítulo son: ArrayList, Hashtable,Queue, y Stack. También aprenderemos un nuevo tipo de ciclo que nos facilita-rá la utilización de estas colecciones.

El ArrayListLa primera colección que aprenderemos se conoce como ArrayList, que guarda lainformación como si fuera una lista. Y sobre esta lista es posible realizar diferentesactividades con los elementos almacenados. Entendemos al ArrayList como un arre-glo que puede cambiar su tamaño según lo necesitemos.Puede guardar cualquier tipo de dato, por lo que lo podemos usar para enteros,cadenas, flotantes o incluso para tipos definidos por nosotros mismos. ArrayListes una clase en C#, por lo que va a tener métodos o funciones que nos permiti-rán trabajar con los datos.El ArrayList tiene una propiedad que llamamos capacidad, que indica el tamañoque ocupa la lista. También tenemos el conteo, el cual nos dice cuántos elementosestá guardando en su interior.Para entender cómo funciona ArrayList crearemos una pequeña aplicación y en ellarealizaremos las operaciones más importantes.

7. LAS COLECCIONES

218 www.redusers.com

Para poder utilizar las colecciones necesitamos que nuestro programa utilice el namespace de

System.Collections. Sin este namespace las colecciones no serán reconocidas y tendremos pro-

blemas al compilar el programa. Hay que recordar que los namespace a utilizar se colocan al

inicio del programa antes de nuestro código.

EL NAMESPACE DE LAS COLECCIONES

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 218

Page 221: C# aprenda a programar

Declaración de un ArrayListEn nuestro programa podemos tener tantos ArrayList como sean necesarios, pero esnecesario declararlos primero. La declaración se lleva a cabo de la siguiente manera:

ArrayList datos = new ArrayList();

Lo primero que necesitamos es indicar ArrayList, ya que éste es el nombre de la cla-se. Luego colocamos el nombre que va a tener, en nuestro caso es datos. Posterior-mente pasamos a la instanciación, la cual se lleva a cabo por medio de new. En es-te ejemplo el constructor de la clase no recibe ningún parámetro.Si bien el ArrayList aumenta su tamaño dinámicamente, es posible instanciar el arre-glo con algún valor de capacidad inicial. Esto es útil si sabemos inicialmente cuan-tos elementos puede contener el ArrayList. para hacerlo simplemente colocamos lacapacidad inicial entre los paréntesis de la siguiente forma:

ArrayList datos = new ArrayList(32);

Aquí, datos tiene una capacidad inicial de 32, aunque se encuentre vacío.

Adición de informaciónNosotros podemos adicionar cualquier tipo de información al ArrayList. Hacerlo esmuy sencillo y requiere que usemos un método conocido como Add().

Figura 1. Aquí podemos ver cómo el nuevo

elemento es colocado al final del ArrayList existente.

4

5

3

10

7 4

5

3

10

7

Antes Elemento a insertar Después de inserción

Las colecciones más importantes

219www.redusers.com

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 219

Page 222: C# aprenda a programar

Siempre que se adiciona un elemento al ArrayList, este nuevo elemento se agrega alfinal. Si incorporamos otro elemento, se colocará después del anterior. La adiciónsiempre se lleva a cabo después del último elemento que se encuentre en el ArrayList.

El método Add() va a necesitar de un único parámetro y este es el dato que queremosguardar. Por ejemplo para guardar un dato de tipo entero podemos hacer lo siguiente

datos.Add(7);

El dato a guardar también puede ser pasado por medio de una variable:

datos.Add(n);

Si quisiéramos guardar una cadena, se puede hacer de la siguiente manera:

palabras.Add(“Hola”);

El uso de foreachEn la programación orientada a objetos existe un patrón conocido como iterador oiterator, según su sintaxis en el idioma inglés. La principal característica del itera-dor es permitirnos realizat un recorrido por todos los elementos que existen en unaestructura de datos. El recorrido lo hace de forma sequencial, uno por uno. Esto re-sulta muy útil cuando sabemos que debemos recorrer todos los elementos de la es-tructura, como un ArrayList, y hacer algo con ellos. En C# encontramos un iterador en el foreach. Con él es posible que recorramos loselementos, luego ejecutamos alguna acción con ellos y finalizamos cuando la colec-ción ya no tiene más elementos que entregarnos.

La sintaxis es la siguiente:

7. LAS COLECCIONES

220 www.redusers.com

En varias ocasiones vamos a encontrar que la capacidad del ArrayList es mayor que su conteo, pe-

ro nunca menor. La capacidad tiende a ser mayor para que las operaciones de inserción de datos

sean rápidas. El arreglo guarda los datos hasta que llega a su capacidad y si la cantidad de datos

pasa cierto límite, el arreglo crece en su capacidad dejando espacio libre para nuevas inserciones.

LA CAPACIDAD Y EL CONTEO

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 220

Page 223: C# aprenda a programar

foreach (tipo identificador in expresión) sentencia

El tipo está relacionado con la clase de información que guarda la colección. Si nues-tra colección guarda enteros, entonces el tipo debe de ser int y así sucesivamente pa-ra cada tipo de dato. Luego tenemos que tener una variable que represente al elementoque se encuentra en la lista, esta variable es el identificador y luego por medio de es-ta variable identificador podremos hacer algo con la información de ese elemento.

La expresión simplemente es la colección o el arreglo que vamos a recorrer con el ci-clo. La sentencia es el código que se va a repetir para cada vuelta del ciclo. La senten-cia puede ser sencilla o se puede colocar un bloque de código en caso de ser necesario.Como ya conocemos bien los arreglos, veamos cómo podemos utilizar este ciclopara mostrar los contenidos de un arreglo. Supongamos que tenemos un arreglode enteros que se llama costo y al que hemos introducido valores. Para mostrar-lo con este ciclo, haremos lo siguiente:

foreach(int valor in costo){

Console.WriteLine(“El valor es {0}”, valor);}

En este caso estamos indicando que el tipo de dato con el que vamos a trabajar esentero. La variable valor cambiará su contenido dependiendo del elemento del arre-glo que estemos recorriendo en ese momento. Luego simplemente indicamos queel arreglo a recorrer es costo. Adentro del ciclo mostramos un mensaje indicando elcontenido de valor para esa vuelta del ciclo.

Ahora es posible continuar nuestro aprendizaje sobre C#, más especificamente se-guiremos revisando las características de las colecciones.

Las colecciones más importantes

221www.redusers.com

El método Add() regresa un valor de tipo entero. Este valor indica el índice donde fue guardado

un nuevo elemento. Muchas veces ignoramos este valor, pero en algunos casos puede resultar-

nos útil. Hay que recordar que el índice en el cual se encuentra un elemento puede variar, ya que

es posible eliminar elementos del ArrayList también.

EL ÍNDICE DEL NUEVO ELEMENTO

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 221

Page 224: C# aprenda a programar

Cómo acceder a la información de un ArrayListLa colección ArrayList nos permite acceder a sus elementos por medio de un índice,algunas colecciones no lo permiten, pero ArrayList sí. Esto es bueno, pues podemostrabajarla de forma similar a un arreglo, pero con la flexibilidad de ser dinámica.Si tenemos un ArrayList llamado datos y deseamos imprimir el elemento 2, lo po-demos hacer de la siguiente manera:

Console.WriteLine(“El dato es {0}”,datos[2]);

De igual forma podemos utilizar el valor del elemento en una expresión:

impuesto = datos[2] * 0.15f;

Y podemos también asignar un valor determinado:

datos[2] = 5;

Cómo obtener la cantidad de elementos en un ArrayListEn muchas ocasiones es útil saber cuántos elementos tenemos en el ArrayList. Adiferencia del arreglo tradicional, éste puede cambiar su tamaño durante la eje-cución de la aplicación y conocer el tamaño nos evita problemas con los valoresde los índices al acceder el arreglo.

Afortunadamente es muy sencillo hacerlo, simplemente tenemos que leer el valorde la propiedad count del ArrayList. Esta propiedad es un valor entero.

elementos = datos.Count;

En este caso la variable elementos tendrá la cantidad de elementos en el arreglo datos.No debemos olvidar que si elementos tiene el valor de 5, los índices irán de 0 a 4.

Insertar elementosHemos visto que podemos adicionar elementos y que éstos son colocados al finaldel ArrayList, sin embargo también es posible llevar a cabo una inserción. La inser-ción permite colocar un elemento nuevo en cualquier posición válida del arreglo. Para lograr esto usamos el método Insert(). Este método necesita de dos pará-metros, el primer parámetro es el índice donde deseamos insertar el elemento y

7. LAS COLECCIONES

222 www.redusers.com

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 222

Page 225: C# aprenda a programar

el segundo parámetro es el elemento a insertar. La figura que se muestra a con-tinuación, se encarga de mostrar cómo trabaja la inserción.

Figura 2. Podemos observar cómo se lleva a cabo la inserción

del elemento, debemos notar cómo algunos elementos cambian de índice.

Por ejemplo, si deseamos insertar el valor de 5 en el índice 2, hacemos lo siguiente:

datos.Insert(2, 5);

El ArrayList crecerá su tamaño según sea necesario.

Para eliminar un elementoEs posible eliminar cualquier elemento del ArrayList y hacerlo de forma muy sen-cilla. Lo único que necesitamos es conocer el índice del elemento a eliminar. El

4

5

3

10

7 4

5

7

3

10

Elemento a insertar Después de inserción

Las colecciones más importantes

223www.redusers.com

Si en alguna de nuestras aplicaciones necesitáramos saber cuál es la capacidad del ArrayList,

es posible hacerlo al leer el valor de propiedad Capacity. Esta propiedad es de tipo entero. Si lo

que deseamos es reducir la capacidad del ArrayList, se puede usar el método TrimToSize(), pe-

ro debemos tener cuidado para no perder información útil.

LA CAPACIDAD DEL ARRAYLIST

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 223

Page 226: C# aprenda a programar

índice es un valor entero y debe ser válido. El método que se encarga de llevar acabo la eliminación es RemoveAt().

Figura 3. Al eliminar el elemento, desaparece del ArrayList.Los demás elementos se reorganizan y sus índices pueden modificarse.

Este método solamente necesita de un parámetro, que es el índice del objeto quedeseamos eliminar. Por ejemplo si queremos eliminar el elemento que se encuentraen el índice 7, podemos hacer lo siguiente:

datos.RemoveAt(7);

Para encontrar un elementoCon los ArrayList es posible saber si un elemento en particular se encuentra aden-tro de él. Para lograr esto hacemos uso del método IndexOf(). Este método requie-re de un solo parámetro que es el objeto a buscar adentro del ArrayList. El métodonos regresa un valor entero.

Este valor es el índice donde se encuentra la primera ocurrencia del elemento, esto esdebido a que podemos tener el elemento guardado en diferentes posiciones. Si el ele-mento no se encuentra en el ArrayList, entonces simplemente recibimos el valor de -1.

Si lo que deseamos es buscar el índice donde se encuentra el elemento 7 en nuestroArrayList, hacemos lo siguiente:

4

5

3

10

74

5

7

3

10

Elemento a eliminar Después de eliminación

7. LAS COLECCIONES

224 www.redusers.com

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 224

Page 227: C# aprenda a programar

índice = datos.IndexOf(7);

Ahora la variable índice tiene la locación donde se encuentra el elemento 7.

Ejemplo con ArrayListAhora podemos construir un ejemplo que use el ArrayList y los diferentes métodosque es posible usar con él. Empecemos por declarar nuestras variables y colocar lonecesario para crear el ArrayList y adicionar unos datos inicialmente.

static void Main(string[] args){

// Variables necesariasint indice=0;int cantidad=0;

// Declaramos el ArrayListArrayList datos = new ArrayList();

// Adicionamos valores al ArrayListdatos.Add(7);datos.Add(5);datos.Add(1);

Console.WriteLine(“Tenemos inicialmente los datos:”);

Imprime(datos);

}

Para que nuestra aplicación muestre el arreglo crearemos una pequeña función lla-mada Imprime. Esta función recibe el ArrayList a imprimir y hace uso del foreachpara mostrar cada elemento del ArrayList.

static void Imprime(ArrayList arreglo){

foreach (int n in arreglo)

Las colecciones más importantes

225www.redusers.com

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 225

Page 228: C# aprenda a programar

Console.Write(“ {0},”,n);

Console.WriteLine(“\n—————————————”);}

Si ejecutamos la aplicación obtendremos lo siguiente:

Figura 4. Podemos observar cómo se han mostrado los elementos del ArrayList.

Vamos a experimentar un poco y haremos crecer al arreglo insertando tres nuevosvalores. Para el último valor obtendremos el índice donde fue colocado.

// Hacemos crecer el ArrayListdatos.Add(4);datos.Add(5);

// Obtenemos el indiceindice=datos.Add(10);

Console.WriteLine(“Despues de hacerlo crecer:”);

7. LAS COLECCIONES

226 www.redusers.com

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 226

Page 229: C# aprenda a programar

Imprime(datos);Console.WriteLine(“El ultimo elemento tiene el

indice {0}”,indice);Console.WriteLine(“\n—————————————”);

Ejecutemos el programa y veremos el siguiente resultado.

Figura 5. Podemos verificar que el ArrayList ha crecido

y vemos cómo hemos obtenido el índice de la última inserción.

Ahora utilizaremos el índice para leer el valor de un elemento y modificar el valorde otro. En este caso la sintaxis es muy similar a la de los arreglos.

// Imprimimos un elemento en particularConsole.WriteLine(“El valor en el indice 2 es

{0}”,datos[2]);Console.WriteLine(“\n—————————————”);

// Modificamos un datodatos[3]=55;

Las colecciones más importantes

227www.redusers.com

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 227

Page 230: C# aprenda a programar

Console.WriteLine(“Despues de la modificacion:”);Imprime(datos);

Si compilamos este ejemplo, podremos observar cómo se llevó a cabo el cambio delelemento adentro del arreglo correspondiente.

Figura 6. Hemos obtenido el contenido de un elemento y modificado otro.

En este momento obtendremos la cantidad de elementos que contiene el arreglo yla desplegaremos en la pantalla.

// Obtenemos la cantidad

7. LAS COLECCIONES

228 www.redusers.com

Cuando hacemos uso de las Hashtable, cada elemento que coloquemos debe de tener un key úni-

co. El key no se debe repetir, si lo hacemos podemos experimentar problemas con nuestro progra-

ma. La razón de esto es que el key es usado para encontrar la posición en el Hashtable del elemento

y una repetición crearía conflicto al tener dos elementos diferentes en la misma posición.

PROBLEMAS CON LOS KEY DE LAS HASHTABLE

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 228

Page 231: C# aprenda a programar

cantidad=datos.Count;Console.WriteLine(“La cantidad de elementos es

{0}”,cantidad);Console.WriteLine(“\n—————————————”);

Figura 7. Hemos obtenido la cantidad de elementos en el ArrayList.

Si deseamos insertar un elemento en alguna posición en particular es posible hacerlo.

// Insertamos un elementodatos.Insert(2,88);

Las colecciones más importantes

229www.redusers.com

Al igual que con los arreglos tradicionales, a ArrayList le debemos tener cuidado cuando lo ac-

cedamos por medio de un índice ya que si intentamos acceder a un elemento con un índice ine-

xistente obtendremos un error al ejecutar el programa. No debemos usar índices negativos ni

mayores a la cantidad de elementos que se tienen. Los índices también están basados en cero.

CUIDADO CON EL RANGO

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 229

Page 232: C# aprenda a programar

Console.WriteLine(“Despues de la insercion:”);Imprime(datos);

Al ejecutar el programa podemos ver que fue insertado en el lugar de adicionado.

Figura 8. La inserción puede llevarse a cabo

en cualquier lugar del ArrayList, la adición solo al final.

Si lo que necesitamos es eliminar un elemento lo hacemos de la siguiente manera:

// Eliminamos un elemento

7. LAS COLECCIONES

230 www.redusers.com

El método Pop() tomó el elemento que se encuentra en la parte superior del Stack y lo regresa

al exterior, pero el elemento ya no pertenece al Stack. Hay otro método conocido como Peek()

que lee el valor del elemento en la parte superior del Stack y lo regresa al exterior, pero no eli-

mina el elemento del Stack.

OTRA FORMA DE TOMAR EL ELEMENTO

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 230

Page 233: C# aprenda a programar

datos.RemoveAt(4);Console.WriteLine(“Despues de la eliminacion:”);Imprime(datos);

Figura 9. El elemento ha desaparecido del ArrayList.

Lo último que nos falta en la generación de nuestra aplicación, es dotarla de la ca-pacidad de encontrar el índice donde se encuentra un elemento en particular. Paraello debemos agregar el código que se muestra a continuación.

// Encontramos el indice donde se encuentra el primer 5

indice=datos.IndexOf(5);Console.WriteLine(“Elprimer 5 se encuentra en

{0}”,indice);Console.WriteLine(“\n—————————————”);

Luego de agregar el trozo de código propuesto en el bloque anterior, nuestra apli-cación será capaz de encontrar el índice; y como ya se halla completa lucirá similaral ejemplo que podemos ver en la imagen mostrada a continuación:

Las colecciones más importantes

231www.redusers.com

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 231

Page 234: C# aprenda a programar

7. LAS COLECCIONES

232

Figura 10. La primera ocurrencia del valor de 5 es en el índice 1.

El StackAhora empezaremos a conocer otro tipo de colección. A esta colección se la cono-ce como Stack o pila, nos permite guardar elementos y cambia su tamaño de for-ma dinámica, sin embargo trabaja en forma diferente al arreglo y al ArrayList.El Stack es una estructura de tipo LIFO. LIFO es el acrónimo en inglés para Last-in-first-out, es decir el primero que entra, el último que sale. Para entender su fun-cionamiento podemos imaginar una pila de platos. El primer plato que colocamosqueda hasta la base, el siguiente se colocará encima y así sucesivamente. Como elprimer plato queda hasta abajo, no lo podemos sacar directamente pues la pila sederrumbaría. Al sacar los platos, debemos tomar el que se encuentre hasta arribade la pila primero y así continuar.

www.redusers.com

El Stack al igual que el ArrayList tiene una capacidad y ésta crece dinámicamente. Cuando ins-

tanciamos el Stack adquiere la capacidad de default. Si necesitamos crear un Stack con deter-

minada capacidad, la forma de hacerlo es colocando el valor de capacidad entre los paréntesis

del constructor al momento de instanciarlo.

LA CAPACIDAD DEL STACK

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 232

Page 235: C# aprenda a programar

El efecto de colocar nuevos elementos en la parte superior del Stack se conoce co-mo Push. Esto se muestra en la siguiente figura:

Figura 11. Podemos observar cómo Push inserta nuevos elementos en la parte superior.

Cuando tomamos un elemento de la parte superior del Stack se conoce como Pop.En la figura podemos observar cómo esto sucede.

Figura 12. Pop toma el elemento que se encuentra en la parte superior del Stack.

4

5

3

10

7 7

4

5

3

10

Antes Elemento de Pop Después de Pop

4

5

3

10

7 7

4

5

3

10

Antes Push Después de Push

Las colecciones más importantes

233www.redusers.com

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 233

Page 236: C# aprenda a programar

Debido a este comportamiento con Push y Pop podemos entender cómo el primerobjeto que se coloca adentro del Stack es el último en poder salir.

Como crear el StackComo cualquier otra colección el Stack necesita ser instanciado para poderlo utili-zar. C# nos provee de la clase Stack y adentro de esta clase encontramos todos losmétodos necesarios para trabajar con él. La instanciación simplemente será la crea-ción de un objeto de esta clase. Si deseamos crear un Stack hacemos lo siguiente:

Stack miPila = new Stack();

Hemos creado un Stack llamado miPila. Nosotros podemos usar cualquier nombreque sea válido. Una vez instanciado podemos empezar a colocar información en él.

Cómo introducir información al StackPara introducir información al Stack usamos el método Push(). Este método colo-ca el nuevo elemento en la parte superior del Stack. El método necesita únicamen-te de un parámetro que es el elemento que deseamos insertar. Podemos utilizar elmétodo Push() cuantas veces sea necesario para colocar la información.

miPila.Push(7);miPila.Push(11);miPila.Push(8);

En este ejemplo se introduce primero el elemento 7 y luego sobre él se coloca el ele-mento 11. En seguida se coloca un nuevo elemento en la parte superior, que en es-te caso es 8. El Stack resultante se muestra en la siguiente figura:

Figura 13. El Stack resultante nos muestra como el elemento 7 ha quedado en la base.

8

11

7

7. LAS COLECCIONES

234 www.redusers.com

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 234

Page 237: C# aprenda a programar

Cómo obtener información del StackSi lo que necesitamos es obtener la información que está contenida en el Stack lopodemos hacer al tomar el elemento que se encuentra en la parte superior del Stack.Para lograr esto hacemos uso del método Pop(). Este método no necesita ningúnparámetro y regresa el elemento correspondiente.Por ejemplo, si deseamos tomar el elemento de nuestro Stack:

int valor = 0;…valor = (int)miPila.Pop();

Siguiendo el ejemplo anterior la variable valor ahora tendrá en su interior 8. Esto lovemos en la siguiente figura:

Figura 14. Se ha tomado el elemento de la parte superior

del Stack. Hay que notar que el elemento no continúa siendo parte de él.

Uso de foreach para recorrer el StackSi necesitamos recorrer el Stack, es posible hacerlo por medio del uso de foreach. Eluso de esta alternativa es similar al del ArrayList.

8

11

7

11

7

Antes Después

Las colecciones más importantes

235www.redusers.com

Existe una clase a partir de la cual descienden todas las demás clases en C#, esta clase se co-

noce como Object. Muchos métodos regresan objetos de tipo Object, por lo que es necesario in-

dicar el tipo correcto bajo el cual debemos de usarlo. Para hacer esto hacemos uso del casting.

Por ejemplo para hacer un casting a entero hacemos lo siguiente: Valor = (int)fila.Dequeue();

EL CASTING

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 235

Page 238: C# aprenda a programar

foreach( int n in miPila)Console.WriteLine(“{0}”,n);

Podemos usar el foreach, generalmente recorreremos el Stack por medio de Pop().

Para obtener la cantidad de elementos del StackEs posible conocer la cantidad de elementos que tiene el Stack y hacerlo es muy sen-cillo. Debemos leer la propiedad Count del Stack. Esta propiedad nos regresa un va-lor entero con la cantidad de elementos. El uso es equivalente al del ArrayList.

cantidad = miPila.Count;

Para limpiar los contenidos del StackSi deseamos eliminar todos los elementos del Stack de forma rápida lo podemos ha-cer al usar el método Clear(). Este método no necesita de ningún parámetro y sola-mente debe ser usado cuando sepamos que debemos borrar los elementos del Stack.

miPila.Clear();

Para saber si el Stack tiene un elementoSi deseamos saber si adentro del Stack se encuentra un elemento en particular, po-demos hacer uso del método Contains(). Este método necesita de un parámetro quees el objeto a encontrar adentro del Stack. El método regresa un valor de tipo bool.Si el objeto se encuentra el valor es true, pero si no se encuentra es false.

bool enStack = false;…enStack = miPila.Contains(7);

Creación de una aplicaciónPodemos hacer un programa que muestre como usar los métodos del Stack. Para es-to crearemos una aplicación que presente las operaciones del Stack. El contenido semostrará para ver los cambios que se tienen debidos al Push y al Pop.

static void Main(string[] args){

7. LAS COLECCIONES

236 www.redusers.com

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 236

Page 239: C# aprenda a programar

// Variables necesarias

int opcion=0;string valor=””;int numero=0;bool encontrado=false;

// Creamos el stack

Stack miPila= new Stack();

do {

// Mostramos menuConsole.WriteLine(“1- Push”);Console.WriteLine(“2- Pop”);Console.WriteLine(“3- Clear”);Console.WriteLine(“4- Contains”);Console.WriteLine(“5- Salir”);Console.WriteLine(“Dame tu opcion”);valor=Console.ReadLine();opcion=Convert.ToInt32(valor);

if(opcion==1){

// Pedimos el valor a introducirConsole.WriteLine(“Dame el valor a

introducir”);valor=Console.ReadLine();numero=Convert.ToInt32(valor);

// Adicionamos el valor en el stackmiPila.Push(numero);

}

if(opcion==2){

// Obtnemos el elementonumero=(int)miPila.Pop();

Las colecciones más importantes

237www.redusers.com

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 237

Page 240: C# aprenda a programar

// Mostramos el elementoConsole.WriteLine(“El valor obtenido

es: {0}”,numero);}

if(opcion==3){

// Limpiamos todos los contenidos del stack

miPila.Clear();}

if(opcion==4){

// Pedimos el valor a encontrarConsole.WriteLine(“Dame el valor a

encontrar”);valor=Console.ReadLine();numero=Convert.ToInt32(valor);

// Vemos si el elemento estaencontrado=miPila.Contains(numero);

// Mostramos el resultadoConsole.WriteLine(“Encontrado -

{0}”,encontrado);}

// Mostramos la informacion del stackConsole.WriteLine(“El stack tiene {0}

elementos”,miPila.Count);foreach(int n in miPila)

Console.Write(“ {0},”, n);

Console.WriteLine(“”);Console.WriteLine(“————”);

}while(opcion!=5);}

7. LAS COLECCIONES

238 www.redusers.com

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 238

Page 241: C# aprenda a programar

}}

El programa es muy sencillo, en primer lugar declaramos las variables necesarias. Unavariable es para la opción seleccionada por el usuario. Otra variable llamada numeroserá usada para los casos en los que tengamos que obtener o colocar un valor numé-rico en el Stack. La variable llamada encontrado es de tipo bool y tendrá el valor de trueo false dependiendo si el elemento a buscar se encuentra o no en el Stack. Como siem-pre tenemos una variable de trabajo de tipo cadena que nos ayuda a obtener el valordado por el usuario. Luego simplemente creamos un Stack llamado miPila.Tenemos un ciclo do que estará repitiéndose hasta que el usuario decida finalizar elprograma. En el ciclo lo primero que hacemos es mostrar el menú con las posiblesacciones que podemos hacer con el Stack. Luego de acuerdo a cada opción mani-pulamos el Stack. Después de la opción hacemos uso del foreach para mostrar loscontenidos del Stack y poder verificar los cambios realizados. También aprovecha-mos para mostrar la cantidad de elementos que existen en el Stack. Compilemos yejecutemos la aplicación. Lo primero que haremos es insertar algunos valores en elStack, para esto seleccionaremos la opción 1. Coloquemos los valores 5, 7, 3.

Figura 15. Podemos observar cómo el último valor introducido

se encuentra al inicio del Stack, el primer valor se encuentra al final.

Las colecciones más importantes

239www.redusers.com

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 239

Page 242: C# aprenda a programar

Si en este momento hacemos un Pop, el Stack debe de regresarnos el elemento quese encuentra en la parte superior del Stack, en nuestro ejemplo debe ser 3.

Figura 16. Vemos que el valor obtenido

es 3 y el Stack ahora solamente tiene dos elementos.

Ahora podemos ver si el Stack tiene un elemento en particular. Para realizar estaoperación, nos encargaremos de seleccionar la opción número 4 y para continuartendremos que preguntar por el elemento número 9.

Si ahora preguntamos por el elemento 5 obtendremos una respuesta diferente y lavariable encontrado deberá tener el valor true. Lo último que nos queda por haceres limpiar el Stack y para esto seleccionamos la opción 3.

7. LAS COLECCIONES

240 www.redusers.com

Nosotros podemos utilizar el constructor de default del Queue el cual no necesita de ningún pa-

rámetro, sin embargo, es buena idea consultar MSDN para conocer otros constructores. Por

ejemplo tenemos una versión que nos permite colocar la capacidad inicial del Queue y otros que

nos pueden resultar útiles en nuestras aplicaciones.

EL CONSTRUCTOR DEL QUEUE

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 240

Page 243: C# aprenda a programar

Figura 17. El Stack nos regresa el valor de false

en la variable encontrado pues el elemento no se halla en el Stack.

El QueueLa siguiente colección que aprenderemos se conoce como Queue, algunas veces tam-bién denominada cola. Al igual que en el Stack, nosotros ya no necesitamos progra-marla, pues C# nos provee una clase con toda la funcionalidad necesaria para poderutilizarla. La clase que debemos de utilizar para poder tener una cola es Queue.La forma como trabaja es diferente al Stack, ya que el Queue es una estructura de ti-po FIFO. Su comportamiento es diferente al Stack. Para entender el Queue, pode-mos imaginar una fila para comprar los boletos o las entradas al cine. La primerapersona en llegar se coloca junto a la taquilla y conforme van llegando otras perso-

Las colecciones más importantes

241www.redusers.com

Cuando nosotros trabajamos con una estructura de datos que funcione bajo el esquema de FIFO

debemos tomar en cuenta su comportamiento. FIFO es el acrónimo para First In First Out, que en

español significa: Primero en Entrar, Primero en Salir. En estas estructuras el primer elemen-

to que colocamos, es el primer elemento que podemos extraer.

EL COMPORTAMIENTO DE FIFO

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 241

Page 244: C# aprenda a programar

nas se colocan atrás de ella y así sucesivamente. Sin embargo, en cuanto se habré lataquilla, la primera persona en pasar es la primera que se encuentra en la fila.Esto nos indica que cuando insertamos elementos en el Queue, éstos se colocan atrásdel último elemento insertado o en la parte posterior de éste. Al momento de leerelementos, se toma el que se encuentre en la parte superior del Queue. Esto lo po-demos ver más fácilmente en la siguiente figura:

Figura 18. Aquí podemos observar el proceso de adición

de un elemento y también qué es lo que sucede cuando se extrae un elemento.

El proceso por medio del cual nosotros insertamos un elemento nuevo al Queuese conoce como Enqueue y no debemos olvidar que lo hace al final. El acto deextraer un elemento del Queue se llama Dequeue y siempre toma el elemento quese encuentra en la parte superior.

Declaración del QueuePara utilizar el Queue, lo primero que debemos hacer es crear una instancia de la cla-se Queue. El nombre de la instancia puede ser cualquier nombre válido de variableen C#. Si deseamos crear un Queue llamado fila, haremos lo siguiente:

Queue fila = new Queue();

Una vez instanciado ya es posible hacer uso de fila y también de los métodos quenos provee la clase correspondiente para trabajar con él.

4

5

3

10

4 5

3

10

7

7 4

5

3

10

7

Antes Enqueue Dequeue Final

7. LAS COLECCIONES

242 www.redusers.com

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 242

Page 245: C# aprenda a programar

Adición de elementos al QueueNosotros podemos adicionar elementos al Queue en cualquier momento que lo ne-cesitemos. El tamaño del Queue se modificará dinámicamente por lo que no debe-mos de preocuparnos por él. Siempre que se adiciona un elemento, este elementose coloca al final o en la parte baja del Queue.

Para poder hacer esto debemos utilizar el método Enqueue(), el cual pertenece ala clase Queue de C#. Este método es muy sencillo, ya que solamente requiere deun parámetro. En el parámetro colocamos el elemento que deseamos añadir, es-te método no regresa ningún valor.

Por ejemplo, si deseamos añadir el elemento 7 a nuestro Queue llamado fila, será ne-cesario que escribamos el código que se muestra a continuación:

fila.Enqueue(7);

Otra altrenativa posible es colocar variables en el parámetro adecuado, si realizamosesto, una copia del valor se ubicará en el Queue.

Cómo extraer un elemento del QueueAl igual que podemos colocar un elemento, también es posible extraerlo. Sin em-bargo, la extracción se lleva a cabo de acuerdo a las reglas del Queue. Cuando ex-traemos un elemento, el elemento que recibimos es el que se encuentra en la partesuperior o al inicio del Queue. Debemos recordar que no es posible la extracción delos elementos que se encuentren en otras posiciones.Para llevar a cabo la extracción tenemos que usar un método de la clase Queue quese llama Dequeue(). El método no necesita de ningún parámetro y regresa el ele-mento correspondiente. Es importante tener una variable que reciba al elemento ouna expresión que haga uso de él. Si lo que deseamos es extraer un elemento del Queue, podremos agregar el códigoque se muestra en el siguiente bloque:

Las colecciones más importantes

243www.redusers.com

Algunos tipos de datos, en especial los numéricos, pueden llegar a ser compatibles entre sí.

Pero debemos tener algo en cuenta. Cuando convertimos de un tipo mayor a uno menor, por

ejemplo de double a float, es posible que tengamos perdida de información. Esto se debe a que

el tipo menor no puede guardar tantos dígitos como el mayor.

PÉRDIDA DE PRECISIÓN

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 243

Page 246: C# aprenda a programar

int valor = 0;……valor = fila.Dequeue();

Para observar un elemento del QueueCuando hacemos uso del método Dequeue(), el elemento es extraído y deja de en-contrarse adentro del Queue después de esa operación. Sin embargo, podemos ob-servar el elemento. En este caso recibimos el valor del elemento, pero éste no es eli-minado del Queue después de ser leído.

Para llevar a cabo la observación hacemos uso del método Peek(). Este método nonecesita de ningún parámetro y regresa el elemento observado. Al igual que con De-queue() debe de existir una variable o una expresión que reciba este valor.

Un ejemplo de su uso puede ser:

int valor = 0;……valor = fila.Peek();

Para saber si el Queue tiene determinado elementoAlgunas veces podemos necesitar saber si en el interior del Queue se guarda un ele-mento en particular. Esto es posible hacerlo gracias a un método conocido comoContains(). Para usar este método, necesitamos pasar como parámetro el elementoque queremos determinar. El método regresará un valor de tipo bool. Si el elemen-to existe adentro del Queue, el valor regresado será true. En el caso de que el ele-mento no exista en el interior del Queue el valor regresado será false. Necesitamostener una variable o una expresión que reciba el valor del método Contains().

7. LAS COLECCIONES

244 www.redusers.com

Las clases tienen un método especial llamado constructor. Este método es invocado automáti-

camente en el momento que un objeto de esa clase se instancia. Los constructores pueden o no

recibir parámetros y siempre se nombran igual que la clase, se usan principalmente para ini-

cializar correctamente al objeto.

EL CONSTRUCTOR DE LA CLASE

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 244

Page 247: C# aprenda a programar

Por ejemplo, si deseamos saber si el elemento 7 existe, podemos hacer lo siguiente:

if(miFila.Contains(7) == true)Console.WriteLine(“El elemento si existe”);

Para borrar los contenidos del QueueSi necesitamos eliminar todos los contenidos del Queue, es sencillo de hacer por me-dio del método Clear(). Este método ya es conocido por nosotros de colecciones quepreviamente hemos estudiado. Su utilización es muy sencilla ya que no necesita deningún parámetro. Solamente debemos tener cuidado, ya que si lo utilizamos en unmomento inadecuado, perderemos información que todavía puede ser útil.Para eliminar todos los elementos del Queue, colocamos lo siguiente:

miFila.Clear();

Para conocer la cantidad de elementos que tiene el QueueEs conveniente saber la cantidad de elementos que contiene el Queue, especialmen-te antes de llevar a cabo algunas operaciones sobre éste. Cuando deseamos saber lacantidad de elementos existentes, debemos utilizar la propiedad de Count. Esta pro-piedad corresponde a un valor de tipo entero.La podemos utilizarla de la siguiente manera:

int cantidad = 0;……cantidad = miFila.Count;

Si queremos aprovecharla para hacer una operación en particular y evitar algún errorcon el Queue, puede ser algo como lo siguiente:

if(miFila.Count>0)valor = (int)miFila.Dequeue();

Para recorrer los elementos del QueueSi necesitamos recorrer los elementos del Queue, por ejemplo, para mostrarlos o im-primirlos lo que nos conviene usar es un ciclo foreach. Su utilización es muy senci-lla y similar a lo que hemos usado con otras colecciones.

Las colecciones más importantes

245www.redusers.com

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 245

Page 248: C# aprenda a programar

foreach( int n in miFila)Console.WriteLine(“{0}”,n);

Ahora podemos ver un ejemplo que haga uso del Queue. En este ejemplo llevaremosa cabo las operaciones más comunes sobre éste. Mostraremos al usuario un menú ydependiendo de la opción seleccionada será la operación a realizar.

using System;using System.Collections;using System.Text;

namespace AplicacionBase{

class Program{

// Esta es la funcion principal del programa// Aqui inicia la aplicacionstatic void Main(string[] args){

// Variables necesarias

int opcion=0;string valor=””;int numero=0;bool encontrado=false;

// Creamos el Queue

Queue miFila= new Queue();

7. LAS COLECCIONES

246 www.redusers.com

Si el Queue se encuentra vacío, es decir, sin elementos; cuando intentemos hacer una operación

como Dequeue() o Peek() se generará un error. Una forma de evitar esto, es llevar a cabo es-

tas operaciones solamente cuando la cantidad de elementos sea mayor que cero. Un simple if

nos puede ayudar con esto y evitar que el programa ocasione problemas.

OPERACIONES INVÁLIDAS

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 246

Page 249: C# aprenda a programar

do {

// Mostramos menuConsole.WriteLine(“1- Enqueue”);Console.WriteLine(“2- Dequeue”);Console.WriteLine(“3- Clear”);Console.WriteLine(“4- Contains”);Console.WriteLine(“5- Salir”);Console.WriteLine(“Dame tu opcion”);

valor=Console.ReadLine();opcion=Convert.ToInt32(valor);

if(opcion==1){

// Pedimos el valor a introducir

Console.WriteLine(“Dame el valor a introducir”);

valor=Console.ReadLine();numero=Convert.ToInt32(valor);

// Adicionamos el valor en el queuemiFila.Enqueue(numero);

}

if(opcion==2){

// Obtnemos el elementonumero=(int)miFila.Dequeue();

Las colecciones más importantes

247www.redusers.com

Existe otro estilo de colecciones que son funcionalmente equivalentes a las colecciones que he-

mos visto, pero que proveen mejor desempeño y más seguridad en el manejo de los tipos de los

elementos. Estas colecciones utilizan tipos genéricos para los elementos y se encuentran en el

namespace System.Collections.Generics

OTRO ESTILO DE COLECCIONES

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 247

Page 250: C# aprenda a programar

// Mostramos el elementoConsole.WriteLine(“El valor obtenido

es: {0}”,numero);}

if(opcion==3){

// Limpiamos todos los contenidos del Queue

miFila.Clear();}

if(opcion==4){

// Pedimos el valor a encontrarConsole.WriteLine(“Dame el valor a

encontrar”);valor=Console.ReadLine();numero=Convert.ToInt32(valor);

// Vemos si el elemento estaencontrado=miFila.Contains(numero);

// Mostramos el resultadoConsole.WriteLine(“Encontrado - {0}”,encontrado);

}

// Mostramos la informacion del stackConsole.WriteLine(“El Queue tiene {0}

elementos”,miFila.Count);foreach(int n in miFila)

Console.Write(“ {0},”, n);

Console.WriteLine(“”);Console.WriteLine(“————”);

}while(opcion!=5);

7. LAS COLECCIONES

248 www.redusers.com

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 248

Page 251: C# aprenda a programar

}

}}

El HashtableLa última colección que aprenderemos en este capítulo se conoce como Hashtable.Es una estructura de datos un poco compleja de implementar, pero afortunadamenteC# nos provee de una clase que nos da toda la funcionalidad necesaria y podemosutilizarla tan fácilmente como las colecciones anteriores.El Hashtable es una colección indexada. Es decir que vamos a tener un índice y unvalor referenciado a ese índice. Sin embargo, la indexación no se lleva a cabo comoen el arreglo o el ArrayList. El lugar adentro del Hashtable donde se coloca el ele-mento va a depender de un valor conocido como key o llave. El valor contenidoen key es usado para calcular la posición del elemento en el Hashtable. El elementoque vamos a colocar se conoce como value.

En el Hashtable siempre utilizaremos una pareja de key y value para trabajar con él.La forma como trabaja el Hashtable puede parecer extraña, pero en realidad es unaestructura muy eficiente al momento de leer la información. El comprender el fun-cionamiento interno del Hashtable pertenece a un libro de nivel más avanzado, porlo que no tocaremos este tema aquí.La clase se llama Hashtable y pertenece al igual que las demás colecciones al na-mespace System.Collections.

Declaración del HashtableLa declaración del Hashtable es muy sencilla y similar a la declaración de las otrascolecciones. Para hacerlo, simplemente creamos una instancia de la clase Hashtabley después podemos hacer uso de las operaciones de la colección por medio de losmétodos que nos provee.

Las colecciones más importantes

249www.redusers.com

Tenemos otras colecciones que no veremos en el capítulo pero resultan interesantes y útiles de

aprender. El conocer cómo trabajan otras colecciones puede ahorrarnos mucho código y tiempo ya

que posiblemente existe lo que estamos tratando de hacer. Para poder conocerlas, como siempre,

es recomendable visitar MSDN. Algunas de estas colecciones son: BitArray, Dictionary y SortedList.

OTRAS COLECCIONES

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 249

Page 252: C# aprenda a programar

Si lo que deseamos es declarar e instanciar un Hashtable llamado miTabla, es posi-ble realizarlo prosiguiendo de la siguiente manera:

Hashtable miTabla = new Hashtable();

El nombre del Hashtable puede ser cualquier nombre válido de variable para C#.Ahora ya podemos aprender a utilizarlo.

Adición de elementos al HashtableNosotros podemos adicionar cualquier cantidad de elementos al Hashtable. Hacer-lo es tan sencillo como con las otras colecciones, pero debemos tomar en cuenta laforma cómo el Hashtable indexa su información. Para insertar un elemento usamos el método Add(). Este método a diferencia delos de las otras colecciones, va a necesitar de dos parámetros. En el primer pará-metro colocamos el key que será usado para indexar al elemento. Este key pue-de ser de cualquier tipo, pero generalmente se utilizan cadenas. El segundo pa-rámetro será el valor o elemento a insertar, también puede ser de cualquier tipo.Hay que recordar que cuando hagamos uso de esta colección siempre trabajamosla información en parejas key-value.Por ejemplo, podemos usar el Hashtable para guardar un producto con su costo. Elnombre del producto puede ser el key y su costo será el value. Si deseamos insertaralgunos elementos, quedará de la siguiente forma:

miTabla.Add(“Pan”, 5.77);miTabla.Add(“Soda”, 10.85);miTabla.Add(“Atun”, 15.50);

El lugar donde quedaron colocados estos elementos adentro del Hashtable dependedel algoritmo de hashing que se use. Realmente a nosotros no nos interesa, ya quecualquier acceso que necesitemos lo haremos por medio de key.

7. LAS COLECCIONES

250 www.redusers.com

Para el ArrayList un índice se considera válido si no es menor que cero y es menor que la can-

tidad de elementos que contiene el ArrayList. Si se coloca un índice fuera de este rango se pro-

ducirá un error. Si estos errores no se manejan adecuadamente, podemos tener pérdida de in-

formación o la finalización inesperada de la aplicación. Lo mejor es evitarlos.

ÍNDICES VÁLIDOS

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 250

Page 253: C# aprenda a programar

Recorriendo el HashtablePara poder recorrer el Hashtable, haremos uso del ciclo foreach. Si queremos obtenerla pareja key-value, nos apoyaremos en una clase conocida como DictionaryEntry. Eldiccionario también guarda parejas de datos. Por ejemplo, si deseamos proseguir con la impresión de los contenidos del Hashta-ble, podemos colocar el código que se muestra a continuación:

foreach(DictionaryEntry datos in miTabla)

Console.WriteLine(“Key – {0}, Value –{1}”, datos.Key, datos.Value);

Si lo deseamos podemos extraer solamente los valores y colocar una copia de ellosen una colección. Esto nos permitiría trabajar con los valores de una forma más pa-recida a lo que hemos aprendido anteriormente.

ICollection valores = miTabla.Values;……foreach(double valor in valores)

Console.WriteLine(“El valor es {0}”,valor);

ICollection es una interfase usada para implementar las colecciones, de tal forma quevalores puede actuar como cualquier colección válida que tengamos, en este caso lacolección que representa los valores extraídos del Hashtable.

Para obtener un elemento del HashtableSi deseamos leer un elemento en particular del Hashtable, es posible que lo hagamospor medio de su propiedad Item. Para utilizarla, simplemente tenemos que colocarcomo índice el key que corresponde al valor que queremos leer en el momento. De-bemos tener en cuenta que es posible que necesitemos hacer un type cast para de-jar el valor correspondiente en el tipo necesario.

float valor;…

…valor = (float)miTabla.Item[“Pan];

Las colecciones más importantes

251www.redusers.com

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 251

Page 254: C# aprenda a programar

Para borrar los contenidos del HashhtableTodos los elementos guardados adentro del Hashtable pueden ser borrados al utili-zar el método Clear(). Este método no necesita de ningún parámetro.

miTabla.Clear();

Para encontrar si ya existe un keyComo no podemos repetir el mismo key para dos elementos, es necesario poder sa-ber si ya existe determinado key en el Hashtable. Poder hacerlo es fácil, pues C# nosprovee del método Contains(). Este método necesita de un único parámetro que esel key a buscar y regresa un valor de tipo bool. Si el valor regresado es true significaque el key ya existe, y si es false que no se encuentra en el Hashtable.

bool exsite;……existe = miTabla.Contains(“Pan”);

Para encontrar si ya existe un valueIgualmente podemos buscar adentro del Hashtable por un value en particular. Eneste caso, usaremos el método ContainsVale(). Como parámetro colocaremos el va-lor a buscar y el método regresará un bool. Si el valor regresado es true, el value exis-te en el Hashtable y el valor de false nos indica que no se encuentra.

bool existe;……existe = miTabla.ContainsValue(17.50);

Para conocer la cantidad de parejas en el HashtableSi deseamos saber cuantas parejas key-value existen adentro de nuestro Hashtable,podemos usar la propiedad de Count. No hay que olvidar que el valor regresado esun entero que dice el número de parejas.

int cantidad;……

7. LAS COLECCIONES

252 www.redusers.com

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 252

Page 255: C# aprenda a programar

cantidad = miTabla.Count;

Para eliminar un elemento del HashtableEn el Hashtable no solamente podemos adicionar elementos, también podemos eli-minarlos. Al eliminarlos removemos la pareja key-value del Hashtable. Para poderllevar a cabo la eliminación, necesitamos conocer el key del valor a eliminar y utili-zar el método Remove(). Este método necesita de un solo parámetro que es el keydel elemento a borrar.

miTabla.Remove(“Pan”);

Con esto finalizamos los métodos principales del Hashtable y las colecciones másusadas en C#.

Las colecciones más importantes

253www.redusers.com

… RESUMEN

Las colecciones nos permiten guardar elementos, a diferencia de los arreglos, éstas son

dinámicas y pueden modificar su tamaño según sea necesario. Las colecciones tienen diferentes

comportamientos, según la estructura de datos en la que estén basadas. Las que hemos

aprendido en este capitulo son: ArrayList, Stack, Queue y Hashtable. Cada colección tiene su

propia clase y necesitamos instanciarla para poder utilizarla. También nos proveen de diversos

métodos para poder llevar a cabo las operaciones necesarias con los elementos a guardar.

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 253

Page 256: C# aprenda a programar

254 www.redusers.com

TEST DE AUTOEVALUACIÓN

1 ¿Qué son las colecciones?

2 ¿Cómo funciona ArrayList?

3 ¿Cómo introducimos un elemento en el

ArrayList?

4 ¿Cómo funciona el ciclo foreach?

5 ¿Cómo funciona el Stack?

6 ¿Qué hace la operación Push?

7 ¿Qué hace la operación Pop?

8 ¿Para que sirve la propiedad Count?

9 ¿Cómo funciona el Queue?

10¿Cómo funciona la operación Enqueue?

11¿Cómo funciona la operación Dequeue?

12¿Cómo funciona el Hashtable?

ACTIVIDADES

EJERCICIOS PRÁCTICOS

1 Hacer el programa que calcula el

promedio, calificación máxima y mínima

de un salón de clases usando el ArrayList.

2 Hacer un programa que funcione como un

diccionario, con palabra y definición,

usando el Hashtable.

3 Hacer un programa que simule un

sistema de atención a clientes, donde el

cliente que llega primero es atendido

primero.

4 Hacer un programa que muestre la suma

de los gastos ocurridos durante el mes, y

que los muestre en orden cronológico

descendente.

5 Hacer un programa que funcione como

una agenda telefónica y que guarde el

nombre de la persona y su número

telefónico.

07_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 254

Page 257: C# aprenda a programar

Las cadenas

El uso de las cadenas 256Cómo declarar la cadena 256El método ToString() 256Cómo convertir y formatear fechas a cadenas 257Para darles formato a valores numéricos 259Cómo concatenar cadenas 260Uso de StringBuilder 261Comparación de cadenas 263Para encontrar una subcadena 264Para obtener una subcadena 265Para determinar si una cadena finaliza en una subcadena 266Cómo copiar una parte de la cadena 267Cómo insertar una cadena 268Para encontrar la posición de una subcadena 269Justificación del texto 270Para eliminar caracteresde la cadena 271Cómo reemplazar una subcadena 271Cómo dividir la cadena 272Intercambiar mayúsculas y minúsculas 273Cómo podar la cadena 275

Resumen 277Actividades 278

Capítulo 8

Las cadenas son un elemento

muy importante en la programación

de software, ya que nos permiten

guardar y manipular información escrita.

Algunos lenguajes no tienen un tipo

de cadena predefinido, pero C#

nos da una clase con diversos métodos

que nos ayudan a trabajar con ellas.

C#

SERVICIO DE ATENCIÓN AL LECTOR: [email protected]

08_C#2010_AJUSTADO.qxd 8/11/10 9:59 AM Page 255

Page 258: C# aprenda a programar

El uso de las cadenas

En los capítulos anteriores hemos trabajado con cadenas. Las utilizamos por ejem-plo, cuando necesitamos mandarle mensajes al usuario. Sin embargo, las cadenastienen mucha más funcionalidad que eso. Si necesitamos guardar cualquier infor-mación de tipo alfanumérica las podemos utilizar. También son utilizadas paraguardar nombres, direcciones, etcétera.Para poder utilizar cadenas necesitamos hacer uso de la clase String, que nos da to-do lo necesario para poder trabajar con ellas. En su interior la cadena se guarda co-mo una colección y cada carácter es un elemento. En este capítulo aprenderemos autilizarlas y conoceremos los métodos más importantes.

Cómo declarar la cadenaDeclarar una cadena es muy sencillo. De hecho, ya lo hemos llevado a cabo variasveces. Cuando necesitamos declararla, creamos una instancia de la clase String y leasignamos el valor que contendrá. Este valor deberá estar colocado entre comillas.Podemos declarar la variable y asignarle una cadena vacía.

String miCadena = “Hola a todos”;String dato = “”;

En este caso la variable miCadena contendrá la frase “Hola a todos” y la variabledato contendría una cadena vacía.Siempre representaremos las cadenas entre comillas. Podemos imaginarlas como semuestra en la Figura 1. Esto hace fácil poder visualizarlas y entender las operacionesque podemos realizar sobre ellas.

Figura 1. Una cadena puede ser representada

de esta forma y se puede ver cada uno de sus elementos.

El método ToString()Un método común para muchas clases que existen en C# y .NET es ToString(). És-te es usado para convertir el tipo de dato o su representación a una cadena y es muyútil cuando necesitamos desplegar esa información para que el usuario la pueda leer.

'H' 'o' 'l' 'a' '' 't' 'ó' 'd' 'o' 's'

8. LAS CADENAS

256 www.redusers.com

08_C#2010_AJUSTADO.qxd 8/9/10 11:22 AM Page 256

Page 259: C# aprenda a programar

Si nosotros hacemos nuestras propias clases también lo podemos implementar. Elmétodo siempre regresará una cadena, que puede ser formateada para nuestras ne-cesidades. Imaginemos que tenemos una variable de tipo entero llamada valor y que-remos desplegársela al usuario. Para esto podemos convertir la cadena agregando elcódigo que se muestra a continuación:

String Cadena = valor.ToString();

Cómo convertir y formatear fechas a cadenasUno de los usos más comunes de las cadenas es el de poder formatear informa-ción, que puede ser de cualquier tipo. Uno bastante común que no hemos utili-zado hasta el momento es el de las fechas. Para utilizar la fecha y la hora, lo ha-remos mediante una clase conocida como DateTime. Esta clase provee todos loselementos necesarios para poder trabajar con la información relacionada con eltiempo, como son la fecha y las horas del día. Si deseamos tener un objeto de es-te tipo y que tenga la hora actual de la máquina en el momento en que se ins-tanció podemos hacerlo de la siguiente manera:

DateTime miTiempo = DateTime.Now;

La propiedad Now de DateTime contiene el tiempo actual del sistema en su interior.Ahora lo único que necesitamos es poder pasar esa información a un formato útily práctico de trabajar para nosotros. Podemos hacer uso del método Format() deString. Este método nos permite reemplazar los contenidos de la cadena por una ca-dena con un formato en particular.Para llevar a cabo un formato debemos usar los especificadores de formato.DateTime contiene un conjunto de estos especificadotes.A continuación veamos los más importantes de estos, presentados en la tabla 1de una forma clara de leer y comprender.

El uso de las cadenas

257www.redusers.com

Es importante visitar MSDN y obtener más información sobre la clase String. Una de las cosas

que podemos descubrir es que tiene muchas sobrecargas a su constructor, lo que nos permite

tener un control muy preciso sobre la forma y las características con las que será creada la

cadena a utilizar. En este libro usaremos la forma más sencilla.

EL CONSTRUCTOR DE LA CADENA

08_C#2010_AJUSTADO.qxd 8/9/10 11:22 AM Page 257

Page 260: C# aprenda a programar

ESPECIFICADOR DESCRIPCIÓN

d Día del mes.

dd Día del mes, pero los primeros días se representan con 01, 02, 03, etcétera.

ddd Presenta el nombre del día abreviado.

dddd Presenta el nombre del día completo.

h Hora en el rango de 1 a 12.

hh Hora en el rango de 1 a 12. Las primeras horas se presentan como 01, 02, 03, etcétera.

H Hora en el rango de 0 a 23.

HH Hora en el rango de 0 a 23. Las primeras horas se presentan como 01, 02, 03, etcétera.

m Minuto.

mm Minuto. Los primeros minutos se muestran como 01, 02, 03, etcétera.

M Mes.

MM Mes. Los primeros meses se presentan como 01, 02, 03, etcétera.

MMM Nombre del mes abreviado.

MMMM Nombre del mes completo.

s Segundos.

ss Segundos. Los primeros segundos se presentan como 01, 02, 03, etcétera.

t Despliega A o P según AM o PM.

tt Despliega AM o PM.

yyyy Muestra el año.

Tabla 1. Lista de los especificadores más importantes para DateTime. Una

vez que conocemos los especificadores simplemente debemos indicar el formato deseado

para que la información de DateTime quede guardada en nuestra cadena.

Por ejemplo, si deseamos tener una cadena en la que se muestre la información dela fecha de forma tal que primero esté escrito el día de la semana, seguido del añoy por último el mes en número, podemos hacerlo de la siguiente manera:

String formato;

formato=String.Format(“La fecha es: {0:dddd yyyy M}”,DateTime.Now);

8. LAS CADENAS

258 www.redusers.com

Nosotros podemos guardar información alfanumérica adentro de las cadenas. Este tipo de

información se refiere a los caracteres como letras, números y signos. Lo único que debemos

tener en cuenta es que se guardan como caracteres dentro de la cadena, no como valores de

otro tipo. Esto es especialmente importante con los números.

LA INFORMACIÓN ALFANUMÉRICA

08_C#2010_AJUSTADO.qxd 8/9/10 11:22 AM Page 258

Page 261: C# aprenda a programar

Adentro de Format colocamos la cadena de formato y como solamente debemos des-plegar un valor, hacemos uso de {0}, pero este valor tendrá un formato en particu-lar. Ponemos el formato al colocar : y los especificadores necesarios adentro de {}.De esta forma, ese valor tendrá el formato correspondiente. Nosotros podemos usarlos especificadores que queramos siempre y cuando sean válidos para el tipo que de-seamos formatear en la cadena.

Para darles formato a valores numéricosAl igual que con la información de la fecha y hora, es posible darles formato a losvalores numéricos que deseemos mostrar. Para éstos también tendremos una seriede especificadores que podemos utilizar.

ESPECIFICADOR DESCRIPCIÓN

# Dígito

. Punto decimal

, Separador de miles

% Porcentaje

E0 Notación científica

; Separador de secciones

Tabla 2. Éstos son los especificadores

de formato para los valores numéricos más importantes.

Cuando especificamos un formato podemos tener diferentes secciones. Por ejem-plo, podemos utilizar un formato en particular para cuando los números sean po-sitivos y otro formato para cuando los números sean negativos. Estas secciones seseparan por medio del carácter ;.Si usamos dos secciones, el formato colocado en la primera será utilizado paralos números positivos y el cero. El formato que coloquemos en la segunda sec-ción será el que se utilizará para los números negativos. En el caso que defina-mos tres secciones, el formato colocado en la primera sección será utilizado pa-ra los números positivos. En la segunda sección colocaremos el formato que se

El uso de las cadenas

259www.redusers.com

Si deseamos aprender más sobre la forma de utilizar los especificadores, el mejor lugar para

hacerlo es MSDN. En él podemos encontrar toda la documentación necesaria y ejemplos útiles

que usaremos como guía para nuestros propios programas. Dar formato no es complicado, pero

requiere de experimentación para aprenderlo correctamente.

FORMATO A VALORES NUMÉRICOS

08_C#2010_AJUSTADO.qxd 8/9/10 11:22 AM Page 259

Page 262: C# aprenda a programar

utilizará cuando el valor sea negativo. La tercera sección tendrá el formato usa-do para cuando el valor sea cero.Por ejemplo, podemos colocar el siguiente formato para un valor numérico:

Console.WriteLine(String.Format(“{0:$#,###0.00;Negativo $#,###0.00;Cero}”,

valor));

En este caso, si el número contenido adentro de valor es positivo se presentará nor-malmente y con un signo de moneda antes de él, pero si el valor es negativo apare-cerá con la palabra Negativo y el signo de moneda antes de él. Si el contenido devalor fuera cero, aparecería la palabra Cero.

Cómo concatenar cadenasOtra de las manipulaciones que podemos hacer es la concatenación, que en C# adiferencia de otros lenguajes es muy natural e intuitiva. Esto se debe a que pode-mos utilizar una función especializada para esto o aprovechar la sobrecarga del ope-rador + para la clase String. Si deseamos llevar a cabo la concatenación por mediodel operador + podemos hacerlo de la siguiente manera:

String nombre = “Juan”;String apellido = “Lopez”;String NombreCompleto = “”;NombreCompleto = nombre + “ “ + apellido;

De esta forma, obtendremos una cadena que tendrá en su interior “Juan Lopez”.Al hacer la concatenación, hemos incluido otra cadena. En este caso contiene unespacio. De no hacerlo, el nombre y el apellido hubieran quedado juntos y la ca-dena sería: “JuanLopez”.

8. LAS CADENAS

260 www.redusers.com

Cuando llevamos a cabo la concatenación por medio del operador +, puede suceder que muchas

cadenas se guarden en la memoria y algunas de ellas no sean necesarias, como en el caso de

las cadenas que insertan espacios. Para mejorar el uso de la memoria se puede utilizar

StringBuilder, una clase que nos da funcionalidades para facilitar la concatenación.

OPTIMIZAR LA CONCATENACIÓN

08_C#2010_AJUSTADO.qxd 8/9/10 11:22 AM Page 260

Page 263: C# aprenda a programar

Figura 2. Aquí vemos una representación

de la concatenación y la cadena resultante al final.

Otra forma de concatenar es hacer uso del método Concat(). Este método pertene-ce a String, es muy sencillo de utilizar y solamente requiere de dos parámetros, queserán las cadenas que deseamos concatenar. El método regresa una cadena, que esla cadena resultante de la concatenación de los parámetros.Veamos un ejemplo de cómo podemos concatenar:

NombreCompleto = String.Concat(nombre, apellido);

El método Concat() es estático, por eso es posible usarlo sin tener que declararun objeto de la clase String. Para llevar a cabo una concatenación múltiple, po-demos hacerlo de la siguiente manera:

NombreCompleto =String.Concat(nombre, String.Concat(“ “, apellido));

Uso de StringBuilderStringBuilder es una clase que provee .NET y podemos utilizar con C#. Nos permi-te construir cadenas de forma eficiente y a su vez podemos utilizarla en lugar de lasconcatenaciones si fuera necesario. Aquí sólo veremos los métodos más importantes.Invitamos a los lectores a investigar el resto de los métodos con la ayuda de MSDN.Su constructor tiene varias versiones. Podemos utilizar el constructor de default queno necesita de ningún parámetro. Hay una versión en la que podemos pasar comoparámetro una cadena con la que podemos inicializar el objeto StringBuilder.La clase tiene varias propiedades que podemos usar, como la propiedad Capacity,que nos indica la capacidad actual, que puede o no ser igual a la cantidad de carac-teres que tenemos guardados en su interior, aunque generalmente será mayor.Otra opción es la propiedad Chars, mediante la que podemos obtener o modificarun carácter en particular. La modificación se hace indicando el índice donde se en-cuentra ese carácter. Lo podemos hacer de la siguiente manera:

+ -'J'

'J' 'u' 'a' 'n' '' 'L' 'ó' 'p' 'e' 'z'

'u' 'a' +'n' '' 'L' 'ó' 'p' 'e' 'z'

El uso de las cadenas

261www.redusers.com

08_C#2010_AJUSTADO.qxd 8/9/10 11:22 AM Page 261

Page 264: C# aprenda a programar

StringBuilder sb = new StringBuilder(“Hola a todos”);......sb.Chars[6]=’o’;

Si leemos la propiedad de Length obtenemos la longitud que tiene el StringBuilder.Si colocamos un valor en esta propiedad entonces el StringBuilder tendrá el ta-maño que indicamos. Si el nuevo tamaño es menor que el actual, entonces setrunca el contenido del StringBuilder.Para llevar a cabo una concatenación, debemos usar el método Append(). Este mé-todo tiene muchas sobrecargas ya que no solamente puede concatenar cadenas. Elmétodo necesita solamente un parámetro y es el valor a concatenar en la cadena.Hay que recordar que Append() es eficiente.

StringBuilder sb = new StringBuilder(“Hola a todos”);......sb.Append(“ Hola mundo”);

En sb ahora tendremos el contenido de “Hola a todos Hola mundo”.También podemos agregar una cadena de formato construida de forma similar a laforma como trabajamos con los formatos de WriteLine(). Para esto usamos el mé-todo AppendFormat(). Este método necesitará dos parámetros, pero puede llevar mássi fuera necesario. En el primero colocamos la cadena de forma y en el segundo y/olos siguientes la lista de variables a utilizar. Por ejemplo:

StringBuilder sb = new StringBuilder();int valor = 5;......sb.AppendFormat(“El valor es {0}”, valor);

Un método importante en esta clase es ToString(), que permitirá convertir String-Builder en una cadena, y de esta manera poder utilizar los contenidos creados pormedio de esta clase. Para usarlo simplemente hacemos una asignación:

String cadena = “”;

8. LAS CADENAS

262 www.redusers.com

08_C#2010_AJUSTADO.qxd 8/9/10 11:22 AM Page 262

Page 265: C# aprenda a programar

cadena = sb.ToString();

De esta forma, la cadena tendrá en su interior la cadena creada por medio delStringBuilder. Existen otros métodos más que pertenecen a esta clase y pueden lle-gar a sernos útiles en el futuro.

Comparación de cadenasEn algunas de nuestras aplicaciones es posible que lleguemos a necesitar llevar a ca-bo una comparación entre algunas cadenas. Esto nos puede servir para determinarsi una cadena en especial ha sido introducida por el usuario. Pero la comparacióntambién nos puede ayudar a organizar alfabéticamente una serie de cadenas que no-sotros seleccionemos, o también, simplemente para resolver algún problema que re-quiera saber si una cadena es mayor, igual o menor que otra. La comparación de cadenas es una herramienta muy importante para solucionar di-versos problemas y lograr resultados que de otra forma serían muy complejos.La clase String nos da el método Compare(). Este método es estático, por lo que po-demos hacer uso de éste sin necesidad de declarar un objeto de tipo String. El mé-todo necesitará dos parámetros, que son las cadenas a comparar. Los llamaremos ennuestro ejemplo Cadena1 y Cadena2. El método regresará luego del análisis, un va-lor entero y el valor de este entero será el que se encargue de indicarnos la relaciónque existe entre las cadenas que acabamos de comparar.Si el valor regresado es igual a 0, esto significa que Cadena1 y Cadena2 son igua-les. En el caso de que el valor sea menor que 0, es decir, un número negativo, Ca-dena1 es menor que Cadena2. Si se recibe un número mayor que 0 significa queCadena1 es mayor que Cadena2.

A continuación veamos la forma utilizar este método:

int comparación=0;String nombre=”Juan”;......comparación=String.Compare(“Pedro”,nombre);

if(comparación==0)Console.WriteLine(“Los nombres son iguales”);

elseConsole.WriteLine(“Los nombres son diferentes”);

El uso de las cadenas

263www.redusers.com

08_C#2010_AJUSTADO.qxd 8/9/10 11:22 AM Page 263

Page 266: C# aprenda a programar

Figura 3. En este ejemplo P es mayor que J,

por lo que “Pedro” es más grande que “Juan”.

Otra forma que podemos utilizar para saber si dos cadenas son iguales es hacer usodel método Equals(), que solamente dirá si dos cadenas son iguales, no realiza nin-guna otra comparación. Existen varias sobrecargas del método Equals(), por lo quees conveniente aprender el resto con la ayuda de MSDN. La versión que veremosaquí es estática y requiere dos parámetros. Los parámetros son las cadenas a com-parar. El método regresa un bool con el valor de true si las cadenas son iguales y elvalor de false si son diferentes.

Podemos usarlo de la siguiente manera:

String cadena1 = “Hola”;String cadena2 = “Todos!”;......if( String.Equals(cadena1,cadena2) == true)

Console.WriteLine(“Las cadenas son iguales”);

Para encontrar una subcadenaLa cadena puede contener una frase con muchas palabras y para algunas aplicacio-nes necesitamos saber si determinada palabra se encuentra en esa cadena. Es decirque buscaremos una subcadena adentro de otra cadena. Esta subcadena es una ca-dena que queremos saber si se encuentra en la cadena principal.Esto puede servirnos en búsquedas o cuando necesitamos llevar a cabo determina-da lógica si se encuentra una palabra o frase en particular. El método que usaremosse llama Contains() y debe ser invocado por la cadena a la que se le realizará la bús-queda. Esto es importante y no debemos olvidarlo ya que la invocación de Con-tains() en la cadena incorrecta nos puede llevar a errores de lógica.

P>J

'P' 'e' 'd' 'r' 'o'

'J' 'u' 'a' 'n'

8. LAS CADENAS

264 www.redusers.com

08_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 264

Page 267: C# aprenda a programar

El método Contains() sólo necesita un parámetro. Este parámetro es la subcadena abuscar. Ésta puede ser dada explícitamente o por medio de una variable de tipoString que la contenga. El método regresa un bool. Si la subcadena se encontró, elvalor regresado es true y si no se encontró el valor regresado es false.

El uso de Contains() puede ser como se muestra a continuación:

String NombreCompleto = “Juan Pedro Lopez”;String NombreBuscar = “Pedro”;......if (NombreCompleto.Contains(NombreBuscar) == true)

Console.WriteLine(“El nombre se encuentra”);

Figura 4. Vemos cómo la subcadena es encontrada en la cadena original.

Para obtener una subcadenaAhora que ya tenemos una forma de saber si existe una subcadena, también pode-mos extraer una subcadena. Esto nos puede servir para los casos en los que necesite-mos tener solamente una parte de la cadena original. La forma cómo lo hacemos espor medio del medio del método Substring().

Cadena original

Cadena a buscar

'J' 'u' 'a' 'n' '' '''P' 'e' 'd' 'r' 'o'

'P' 'e' 'd' 'r' 'o'

'L' 'z''e''ó' 'p'

El uso de las cadenas

265www.redusers.com

Para evitar problemas de lógica debemos tener en cuenta puntos relacionados con Contains().

El primero es que una cadena vacía como “” siempre regresará true. Otro punto importante es

que la búsqueda que realiza Contains() es sensible a mayúsculas y minúsculas. Buscar “hola”

no es lo mismo que buscar “Hola”.

PARA EVITAR PROBLEMAS CON CONTAINS()

08_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 265

Page 268: C# aprenda a programar

Para poder usar este método necesitamos contar con dos parámetros, que son va-lores de tipo entero. El primero indica el índice adentro de la cadena originaldonde inicia la subcadena que nos interesa obtener y el segundo es la cantidadde caracteres que tiene la subcadena. El método regresa una cadena que contie-ne a la subcadena que hemos obtenido.El siguiente ejemplo nos muestra cómo podemos usar este método:

String cadena=”Hola mundo redondo”;String resultado=””;......resultado=cadena.Substring(5,5);

Ahora la cadena resultado tendrá en su interior a “mundo”, que es la subcadena quehemos obtenido de la variable cadena.

Figura 5. A partir del índice y la cantidad de caracteres se extrae la subcadena.

Para determinar si una cadena finaliza en una subcadenaEs posible saber si una cadena finaliza en una subcadena en particular.Por ejemplo, si analizamos la cadena, y ésta termina en punto, o si la cadena ter-mina en una palabra en particular.Al igual que en los casos anteriores, tenemos un método que nos permite llevar acabo esto. El método es EndsWith() y necesita un parámetro, que será la subca-dena que deseamos verificar en la terminación de la cadena principal. La funciónregresa un valor de tipo bool, si es true la cadena termina en la subcadena en ca-so contrario el valor regresado es de false.Un ejemplo de cómo podemos usar esta función es el siguiente:

String cadena1 = “Juan Pedro Lopez”;

5

5

'H' 'o' 'l' 'a' '' '''m' 'u' 'n' 'd' 'o'

'm' 'u' 'n' 'd' 'o'

'r' 'n''o''e' 'd' 'o''d'

8. LAS CADENAS

266 www.redusers.com

08_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 266

Page 269: C# aprenda a programar

String cadena2 = “Lopez”;......if(cadena1.EndsWith(cadena2) == true)

Console.WriteLine(“La cadena finaliza en Lopez”);

Figura 6. La búsqueda de la subcadena se hace al final de la cadena.

Cómo copiar una parte de la cadenaEn muchas aplicaciones es necesario obtener o copiar una parte en particular de unacadena, y si la cadena contiene una frase, podemos extraer una palabra en particular.Cuando necesitamos procesar cadenas es muy útil hacer esto.El método que usaremos se conoce como CopyTo() y aunque es un poco más com-plejo que los anteriores es fácil de utilizar ya que necesita el mismo de cuatro pará-metros. Antes de ver los parámetros es necesario comentar que la cadena extraídaserá colocada en un arreglo de tipo char. El método no regresa ningún valor.El primer parámetro es el índice adentro de la cadena principal desde donde se em-pezará a copiar. El segundo parámetro es la cadena de tipo char donde se colocarála cadena a extraer. El tercer parámetro es el índice del arreglo a partir de donde seempezarán a colocar los caracteres de la cadena copiada. Esto es útil ya que pode-mos hacer la copia en cualquier posición del arreglo, no solamente al inicio. Elcuarto parámetro indica la cantidad de caracteres a copiar. Con estos parámetrospodemos indicar sin problema cualquier sección a copiar.

Veamos un ejemplo de esto último a continuación:

char[] destino = new char[10];String cadena = “Hola a todos mis amigos”;...

Cadena original

Cadena a buscar al final

'J' 'u' 'a' 'n' '' '''P' 'e' 'd' 'r' 'o'

'L' 'ó' 'p' 'e' 'z'

'L' 'z''e''ó' 'p'

El uso de las cadenas

267www.redusers.com

08_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 267

Page 270: C# aprenda a programar

...cadena.CopyTo(7, destino, 0, 5);

En este caso hemos extraído la cadena “todos” y se ha guardado en el arreglo destino.

Figura 7. Los caracteres son copiados al arreglo a partir del índice indicado.

Cómo insertar una cadenaYa hemos visto una manera fácil de cómo podemos extraer una subcadena, sin em-bargo, también es posible llevar a cabo la inserción de una cadena en otra.Esto nos ayuda cuando necesitamos colocar información nueva en la cadena, peroya no es posible hacerlo por medio de concatenación o formato.Para poder hacer esto, recurriremos a utilizar al método Insert(), que nos brindaC#. Este método coloca la cadena dentro de la cadena principal. Este también ne-cesitará dos parámetros. El primero indicará el índice dentro de la cadena princi-pal donde se va a insertar la nueva cadena. Este valor debe de ser de tipo enteroy nunca podemos pasarle un valor negativo. El segundo parámetro es la cadenaque deseamos insertar, que puede ser colocada explícitamente o mediante una va-riable de tipo String.El método Insert() regresa un valor de tipo String. Este valor regresado sería la ins-tancia de la nueva cadena que ya contiene la inserción. Un ejemplo para llevar acabo la inserción sería de la siguiente forma:

5

0

Arreglo

5

'H' 'o' 'l' 'a' '' '''m' 'u' 'n' 'd' 'o'

'm' 'u' 'n' 'd' 'o'

'r' 'n''o''e' 'd' 'o''d'

8. LAS CADENAS

268 www.redusers.com

Si necesitamos llevar a cabo inserciones de cadenas debemos tener cuidado con los parámetros

para no tener problemas con nuestro programa. El índice donde se inserta la cadena nunca debe

ser negativo o tener un valor más grande que el tamaño de la cadena principal. La variable de la

cadena a insertar debe contener una cadena válida y no un valor null.

PARA EVITAR ERRORES CON EL MÉTODO INSERT()

08_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 268

Page 271: C# aprenda a programar

String cadena1 = “Hola a todos”;String cadena2 = “hola ”;String resultado = “”;......resultado = cadena1.Insert(5, cadena2);

Figura 8. En esta figura podemos ver la inserción de una cadena.

Para encontrar la posición de una subcadenaEn algunas situaciones necesitamos encontrar dónde se encuentra determinadasubcadena para poder llevar a cabo alguna operación en ese índice en particular.Para poder hacer esto hacemos uso del método LastIndexOf(). Un punto importantea tener en cuenta es que este método nos regresa el índice de la última posición en-contrada, es decir que si la cadena principal tiene dos repeticiones de esa cadena,nos da el índice de la segunda repetición. Este método tiene varias sobrecargas, pero la que veremos sólo necesita un paráme-tro y es la subcadena a encontrar. Como siempre la cadena puede ser dada de for-ma explícita o por medio de una variable de tipo String. El método regresa un valorde tipo entero que contiene el índice de la última ocurrencia de la subcadena.La forma para usar este método es la siguiente:

int índice = 0;String cadena = “Hola a todos. Hola”;......

Cadena original

Cadena a insertar

Cadena resultante

'H' 'o' 'l' 'a' '' 'o''a' '' 't' 'o' 'd'

'h' 'o' 'l' 'a' ''

's'

'H' 'o' 'l' 'a' '' 'a''h' 'o' 'l' 'a' '' '' 'o''d''t' 'o' 's'

El uso de las cadenas

269www.redusers.com

08_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 269

Page 272: C# aprenda a programar

8. LAS CADENAS

270

índice=cadena.LastIndexOf(“Hola”);

Justificación del textoHasta el momento hemos visto métodos para manipular las cadenas dentro de C#,pero no hemos hablado aún que la clase String, que nos provee de varios más. Acontinuación, veremos algunos que nos permiten hacer otras modificaciones.Si necesitamos justificar el texto hacia la derecha es posible hacerlo. La forma cómofunciona esto es la siguiente. Supongamos que tenemos una cadena de 10 caracte-res como “0123456789”. Para justificarla necesitamos saber el tamaño de la cadenaresultante con la justificación incluida. Supongamos que la cadena resultante seráde 25 caracteres. Esto nos daría 15 caracteres del que tenemos que insertar del ladoizquierdo para obtener “0123456789” que se encuentra justificada hacia la derecha. Para esto necesitamos un método que nos permita empotrar esos caracteres de es-pacio. El método PadLeft() se encarga de esto. Requiere de un parámetro que es lacantidad de caracteres de la cadena final. Éste es un valor entero y representa los ca-racteres originales más los espacios en blanco. Regresa la cadena final justificada.

Un ejemplo de uso sería el que vemos a continuación:

String cadena=”Hola”;String resultado=””;......resultado=cadena.PadLeft(10);

Figura 9. El texto ha sido justificado a la

derecha al insertar los espacios del lado izquierdo.

De forma similar, podemos hacer una justificación hacia la izquierda. En este caso,los caracteres en blanco serán insertados a la derecha de la cadena. Se insertarán tan-tos caracteres como sean necesarios hasta llegar al tamaño deseado.

Cadena original

Cadena resultante

'H' 'o' 'l' 'a'

'' '' '' '' '' '' 'H' 'o' 'l' 'a'

www.redusers.com

08_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 270

Page 273: C# aprenda a programar

Para esto usaremos un método equivalente a PadLeft(), pero hacia la derecha. Es-te método es conocido como PadRight(). El método necesita un parámetro, que esun valor entero que indica la cantidad total de caracteres de la cadena final. Estetotal debe ser igual a los caracteres de la cadena original más los caracteres vacíos.El método regresa la cadena justificada.

Para eliminar caracteres de la cadenaOtra manipulación que podemos hacer sobre la cadena es la eliminación de ca-racteres. Es posible borrar determinada parte de la cadena, según sea lo que ne-cesitemos en la lógica del programa.El método que podemos utilizar se conoce como Remove(). Este método está so-brecargado, pero veremos la versión que es más flexible. La eliminación de loscaracteres puede hacerse en cualquier parte de la cadena, sólo debemos tener cui-dado de no generar ningún error.El método Remove() necesita dos parámetros, ambos de valores enteros. El primer pa-rámetro se usa para indicar el índice a partir del cual se empezarán a eliminar los ca-racteres de la cadena, y en el segundo parámetro colocamos la cantidad de caracteres aeliminar. El método regresa una cadena, que es la cadena resultante de la eliminación.

Para poder eliminarla realicemos el siguiente ejercicio:

String cadena=”Hola mundo, hola a todos”;String resultado=””;......resultado=cadena.Remove(12,4);

Cómo reemplazar una subcadenaReemplazar una parte de la cadena principal con otra cadena puede ser un proce-so que toma tiempo programar. Esto se debe a que necesitamos encontrar la sub-cadena a eliminar, luego eliminarla y al final introducir los caracteres de la nuevacadena. Como siempre, la clase String nos provee de un método que nos facilita lamanipulación de la cadena para el reemplazo. Éste es el método Replace(). Existendos versiones del método Replace(), una de ellas funciona con caracteres y la queaprenderemos en esta ocasión hace uso de cadenas.Esto nos puede permitir reemplazar una palabra en particular contenida dentrode la cadena por otra palabra. El método llevará a cabo el reemplazo en todas lasocurrencias de la palabra que tengamos.

El uso de las cadenas

271www.redusers.com

08_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 271

Page 274: C# aprenda a programar

El método es sencillo de utilizar y necesita dos parámetros. El primero es la ca-dena que simboliza la palabra que deseamos reemplazar. El segundo es la cadenacon la que la reemplazaremos. El método regresa una cadena, que es la resultan-te con los reemplazos ya llevados a cabo.

Veamos un ejemplo de la utilización de este método:

String cadena1=”Hola a todos. Hola mundo”;String cadena2=”Adios”;String resultado=””;......resultado=cadena1.Replace(“Hola”,cadena2);

Por el ejemplo, vemos que es posible colocar el parámetro ya sea de forma explíci-ta o por medio de una variable.

Cómo dividir la cadenaOtro problema clásico con la manipulación de las cadenas es la subdivisión cuando seencuentra algún carácter en particular. Por ejemplo, si la cadena contiene un párrafode un texto, podemos dividirla en subcadenas, cada una de ellas delimitada por unsigno de puntuación. Para lograr esto necesitamos tener un arreglo de caracteres quecontenga los caracteres que tomaremos como delimitadores. Cada vez que el méto-do encuentre uno de estos caracteres, llevará a cabo el corte de la subcadena. El método que usaremos se conoce como Split(), éste sólo requiere de un pará-metro, que es el arreglo de caracteres delimitadores. El método regresará un arre-glo de tipo String. Cada uno de los elementos presentes en el arreglo regresado se-rá una de las subcadenas que se habrán recortado. Después debemos proceder ahacer uso de las cadenas en el arreglo y procesarlas o utilizarlas según sea necesa-rio en la aplicación que estamos desarrollando.

8. LAS CADENAS

272 www.redusers.com

No colocar valores adecuados en los parámetros puede traer problemas al momento de utilizar

el método Replace(). Esto puede suceder cuando el valor del parámetro se pasa por medio de

una variable y ésta no contiene un valor adecuado. El método puede ocasionar problemas

cuando el primer parámetro recibe null o una cadena vacía del tipo “”.

POSIBLES PROBLEMAS CON EL REEMPLAZO

08_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 272

Page 275: C# aprenda a programar

Un ejemplo de cómo podemos usar este método es el siguiente:

String cadena1=”Hola a todos. Este es un ejemplo, de lo que podemos hacer.”);

String resultado[] = cadena1.Split(new char[] { ‘,’, ‘.’, ‘;’ });

Como podemos ver en el ejemplo, usamos los caracteres punto, coma y punto ycoma como delimitadores. Adentro de resultado estarán las cadenas que han sidorecortadas de cadena1.

Figura 10. La cadena ha sido subdividida. Al ser

el delimitador, el espacio no aparece en las cadenas resultantes.

Intercambiar mayúsculas y minúsculasEn muchas ocasiones tendremos cadenas que estarán escritas con letras en ma-yúscula y minúscula mezcladas, pero puede suceder que para facilitar la lógica deaplicación debamos tener la cadena exclusivamente en mayúscula o minúscula.

'H' 'o' 'l' 'a'

'H' 'o' 'l' 'a'

'' '''m' 'u' 'n' 'd' 'o'

'm' 'u' 'n' 'd' 'o'

'r' 'n''o''e' 'd' 'o''d'

'r' 'n''o''e' 'd' 'o''d'

El uso de las cadenas

273www.redusers.com

Si necesitamos podar otros caracteres en lugar del espacio en blanco, es posible hacerlo. Para

esto tenemos que usar la versión sobrecargada de Trim(). Esta versión necesitará un

parámetro. En él colocamos un arreglo de caracteres. Este arreglo tendrá aquellos caracteres

a podar del inicio y fin de la cadena original.

PARA PODAR OTROS CARACTERES

08_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 273

Page 276: C# aprenda a programar

Esto nos puede ayudar a reducir la cantidad de comparaciones o búsquedas quenecesitamos hacer. Si lo que deseamos hacer es convertir la cadena a minúscula,entonces debemos hacer uso del método ToLower(). Este método no necesita nin-gún parámetro. La fuente de información para hacer la conversión es la mismacadena que lo invoca, pero en esta ocasión nos daremos cuenta de que el métodosí se encargará de regresar un valor, el valor que se devuelve será la cadena con-vertida totalmente a letras minúsculas.

Por ejemplo, podemos tener lo siguiente:

String cadena=”Hola Hola”;String resultado=””;......resultado=cadena.ToLower();

Al finalizar el código la variable resultado tendrá en su interior a la cadena “hola hola”.De forma similar, podemos pasar la cadena a mayúscula. La forma de hacer esto escon el método ToUpper(), que toma la cadena y pasa todas sus letras a mayúscula.El método no necesita ningún parámetro, ya que al igual que ToLower(), toma lainformación directamente de la cadena que lo invoca y regresa una cadena, que esla resultante con todas las letras en mayúscula.

Veamos un ejemplo de cómo aplicar esto:

String cadena=”Hola Hola”;String resultado=””;......resultado=cadena.ToUpper();

8. LAS CADENAS

274 www.redusers.com

Cuando usamos el método Split() es bueno conocer que ninguno de los caracteres que usamos

como delimitadores se copiarán a las subcadenas. Si la cadena no contiene ninguno de los

delimitadores, lo que obtendremos será un arreglo con un solo elemento que es la misma cadena.

Si el arreglo de delimitadores es null o está vacío, el carácter espacio será usado como delimitador.

PUNTOS IMPORTANTES SOBRE EL MÉTODO SPLIT()

08_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 274

Page 277: C# aprenda a programar

La variable resultado tendrá en su interior “HOLA HOLA”.Los dos métodos tienen otra versión que tiene en cuenta las reglas culturales para po-der llevar a cabo la conversión. En ese caso tendríamos que pasar como parámetro elidentificador de la cultura que se usará como base para convertir los caracteres.En MSDN podemos encontrar la información sobre los diferentes identificadoresde cultura que puede manejar .NET. Para hacer uso del identificador de culturadebemos usar un objeto de tipo CultureInfo. En su constructor debemos pasar el IDde la cultura correspondiente. Por ejemplo, para pasar a mayúscula con las reglas dela cultura en México podemos colocar lo siguiente:

String cadena=”Hola Hola”;String resultado=””;......resultado=cadena.ToUpper(new CultureInfo(“es-MX”));

Cómo podar la cadenaCuando trabajamos con las cadenas podemos encontrarnos con situaciones comocuando la cadena tiene exceso de espacios, ya sea al inicio o al final. Algunas vecesesto puede ser útil, como cuando justificamos, pero otras veces estos espacios extraspueden ser indeseados. Los espacios extras al inicio o al final pueden deberse a ope-raciones realizadas sobre la cadena o simplemente a entradas erróneas del usuario,y para librarnos de estos caracteres tenemos diferentes opciones. En primer lugarconoceremos un método que elimina los espacios en blanco extras tanto al iniciocomo al final de la cadena. Este método se conoce como Trim().El uso de Trim() es muy sencillo ya que no necesita ningún parámetro, simplementetrabajará sobre la cadena que lo invoca. Este método regresará una cadena nueva,que es la cadena original sin los espacios extras.Es necesario que tengamos en cuenta que la cadena original no se modifica, por es-ta razón recibiremos una cadena completamente nueva.

El uso de las cadenas

275www.redusers.com

Hay que tener cuidado cuando se guardan valores numéricos en las cadenas. No es lo mismo 54

que “54”. Cuando se guarda adentro de la cadena, no queda como un número sino como

carácter “5” seguido de carácter “4”, que es diferente. Si necesitamos pasar la cadena a una

variable que pueda contener números, debemos hacer uso de la clase Convert.

VALORES NUMÉRICOS EN LAS CADENAS

08_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 275

Page 278: C# aprenda a programar

Veamos un ejemplo de cómo poder utilizar este método:

String cadena=” Hola a todos. “;String resultado=””;......resultado=cadena.Trim();

En la cadena resultado tendremos “Hola a todos”, que es la cadena sin los espaciosextras. El método Trim() poda los espacios tanto del inicio como del final de la cade-na. Sin embargo, puede haber ocasiones en las que necesitemos podar únicamente elinicio de la cadena. El método para lograr esto es TrimStart(). Este método es un po-co más complejo que Trim() ya que necesita un parámetro. Este parámetro es un arre-glo de caracteres y en él tenemos que colocar los caracteres que nos interesa extraer delinicio de la cadena. El método regresará otra cadena, que es la resultante de la cadenaoriginal sin los caracteres podados a su inicio.Es posible que creemos el arreglo de caracteres o también que lo coloquemos explí-citamente. Es conveniente pensar bien cuáles serán los caracteres a podar para evi-tar la eliminación de caracteres que sí pueden ser útiles.

Veamos cómo podemos utilizar este método:

String cadena=”x x x x x x Hola a todos. “;String resultado=””;......resultado=cadena.TrimStart(‘ ‘, ‘x’);

En este ejemplo se podan los caracteres espacio y x. La cadena final resultante es“Hola a todos. “. Debemos notar que los caracteres al final no han sido po-dados, ya que solamente trabaja sobre los caracteres al inicio de la cadena.Si lo que necesitamos es podar el final de la cadena, entonces tenemos que usarel método TrimEnd(). Este método es equivalente a TrimStart(), pero funcionaúnicamente al final de la cadena.Recordemos que el método necesita un parámetro. El parámetro es un arreglo decaracteres. En este arreglo es necesario que coloquemos los caracteres que deseamoseliminar del final de la cadena con la que trabajamos. El método correspondientese encargará de regresar una cadena, está será el resultado sin los caracteres que fue-ron eliminados al final de la cadena original.

8. LAS CADENAS

276 www.redusers.com

08_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 276

Page 279: C# aprenda a programar

Veamos un ejemplo del uso de este método:

String cadena=”x x x x x x Hola a todos. “;String resultado=””;......resultado=cadena.TrimEnd(‘ ‘, ‘x’);

En la cadena de resultado tendremos “x x x x x x Hola a todos”, el espacio fue eli-minado al final ya que se encuentra dentro de la lista de caracteres a podar.Con esto hemos visto el uso y la manipulación de las cadenas, así como los méto-dos más importantes que nos permiten trabajar con ellas.

El uso de las cadenas

277www.redusers.com

… RESUMEN

En este capítulo hemos aprendido muchas cosas sobre las cadenas y su manipulación.

Aprendimos cómo obtener la hora y fecha del sistema y colocar esa información con formato

adentro de una cadena. También aprendimos cómo darles formato a los valores numéricos

que podemos presentarle al usuario. La concatenación nos sirve para unir dos cadenas o más

y tenemos varias formas de poder llevarla a cabo. StringBuilder es una clase que nos da apoyo

para la creación de cadenas. Podemos comparar las cadenas por medio del método Compare()

o Equals(). Podemos saber si una subcadena se encuentra adentro de la cadena principal y

también obtener una subcadena extraída de la cadena principal, la justificación del texto es

posible, así como su contraparte que consiste en eliminar espacios extras al inicio o al final

de la cadena. Es posible pasar la cadena enteramente a mayúscula o minúscula.

08_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 277

Page 280: C# aprenda a programar

278 www.redusers.com

TEST DE AUTOEVALUACIÓN

1 ¿Qué es una cadena?

2 ¿Qué clase se usa para obtener la fecha y

hora de la computadora?

3 ¿Cómo se les da el formato a la fecha y la

hora?

4 ¿Cómo se le da el formato a un valor

numérico?

5 ¿Qué es la concatenación?

6 ¿De qué forma nos ayuda StringBuilder?

7 ¿De qué manera se lleva a cabo la

comparación de cadenas?

8 ¿Cómo podemos obtener una parte de la

cadena?

9 ¿Cómo podemos saber si una palabra se

encuentra adentro de una cadena?

10¿Cómo podemos justificar una cadena a la

derecha?

11¿De qué forma podemos eliminar los

espacios extras al final de la cadena?

12¿De qué forma podemos colocar una

cadena totalmente en mayúscula?

ACTIVIDADES

EJERCICIOS PRÁCTICOS

1 Hacer un programa que le pida al usuario

una cadena y muestre cada una de las

palabras de la cadena en una línea.

2 Hacer un programa que le pida al usuario

una cadena y la forma de justificarla.

3 Hacer un programa que muestre la hora

del día en formato AM/FM seguida del

año, el día y el mes actual.

4 Hacer un programa que calcule sumas y

muestre los resultados negativos entre

paréntesis.

5 Hacer un programa que le solicite al

usuario dos cadenas y luego las muestre

en orden alfabético.

08_C#2010_AJUSTADO.qxd 8/9/10 11:23 AM Page 278

Page 281: C# aprenda a programar

Estructuras y

enumeraciones

Las estructuras 280Cómo definir una estructura 280Cómo crear una variable del nuevo tipo 282Cómo acceder a los campos de la estructura 283Cómo mostrar los campos de la estructura 283Creación de un constructor para la estructura 286Estructuras enlazadas 299Las enumeraciones 309

Resumen 315Actividades 316

Capítulo 9

En este capítulo aprenderemos un tema

muy útil. Empezaremos por cómo utilizar

los tipos definidos por el programador,

es decir, los tipos de datos definidos

por nosotros. Estos tipos nos darán

la flexibilidad de poder guardar

lo que nosotros necesitemos en nuestra

aplicación y poder utilizarlos de forma

similar a las variables.

C#

SERVICIO DE ATENCIÓN AL LECTOR: [email protected]

09_C#2010_AJUSTADO.qxd 8/11/10 10:00 AM Page 279

Page 282: C# aprenda a programar

Las estructuras

Las estructuras son tipos definidos por el programador y son un conjunto de datosagrupados. Supongamos que programamos una agenda telefónica. Desde luego, laagenda necesita guardar mucha información, por lo que ya hemos pensado en usararreglos. Pero también necesitamos pensar en los datos que debe contener como:nombre, edad, teléfono. Esto nos lleva a tener tres arreglos. Si necesitamos más da-tos, entonces más arreglos serán necesarios. Al final es posible que sea un poco com-plicado administrar tantos arreglos y esto reduce la flexibilidad de nuestro software.Lo mejor sería poder agrupar esa información, de forma tal que solamente tenga-mos que administrar un solo arreglo. La forma de poder agrupar la informaciónes por medio del uso de las estructuras.Cuando creamos una estructura, definimos un nuevo tipo y adentro de este tipopodremos colocar datos. Estos datos se conocen como campos. Cada campo estárepresentado por una variable, que puede ser de cualquier tipo. Luego que hemosterminado de definir la estructura podemos crear variables de esta estructura y guar-dar la información que necesitemos en ellas.

Figura 1. Ésta es una representación de una estructura y sus campos.

Cómo definir una estructuraDefinir una estructura es sencillo. Sin embargo, el primer paso no se lleva a cabo enla computadora. Lo primero que tenemos que hacer es encontrar cuáles son los cam-pos y el tipo que debe guardar la estructura. En el programa la definiremos utili-zando el código que comentamos en el siguiente bloque:

acceso struct nombre{

Agenda Nombre: String

Dirección: String

Teléfono: String

Edad: Int

9. ESTRUCTURAS Y ENUMERACIONES

280 www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 280

Page 283: C# aprenda a programar

acceso tipo campo1;...acceso tipo campoN;

}

El acceso indica si la estructura puede verse por afuera del ámbito donde ha sidodefinida o no. Si el acceso es de tipo público, se puede acceder a la estructura porafuera del ámbito. Para esto pondremos como acceso public. Si no deseamos queel exterior pueda acceder a la estructura, entonces la colocamos como privada.Para esto colocamos el acceso como private. En este libro siempre trabajaremoscon acceso de tipo public. Para indicar que definimos una estructura usamos structseguido del nombre de la estructura. Éste puede ser cualquier nombre válido enC#. No hay que confundir el nombre de la estructura con la o las variables queusaremos de ella. Con este nombre identificaremos el nuevo tipo. Luego tenemos que crear un bloque de código. Dentro de este bloque definiremoslos campos que necesitamos. Éstos se definen igual que las variables, pero es nece-sario colocar el acceso. En este libro utilizaremos un acceso de tipo public, de for-ma tal que podamos leer la información contenida adentro de la estructura.Por ejemplo, la estructura de nuestra agenda puede ser definida de la siguiente forma:

public struct Agenda{

public String Nombre;public int Edad;public String Telefono;

}

Así de sencilla es la definición. Ya tenemos una estructura llamada Agenda que con-tiene los campos: Nombre, Edad y Telefono.

Las estructuras

281www.redusers.com

El hacer un análisis correcto de los campos y los tipos que debe tener una estructura nos será

de mucha ayuda. Esto nos ahorra cambios que pueden ser muy costosos en tiempo y

mantenimiento de nuestro programa. La lista de campos surge de manera similar a la lista de

variables que hemos aprendido en el Capítulo 2.

SELECCIÓN ADECUADA DE LOS CAMPOS

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 281

Page 284: C# aprenda a programar

Nosotros podemos definir tantas estructuras como sean necesarias y también cadaestructura puede tener la cantidad necesaria de campos.

Cómo crear una variable del nuevo tipoYa que tenemos definida la estructura, es necesario poder definir sus variablespara guardar información. Como hemos realizado la declaración de un nuevo ti-po, entonces nos será posible crear variables de ésta, y la forma de hacer esto essimilar a la de cualquier otro tipo.Para definir la variable sólo deberemos poner el nombre del tipo seguido del nom-bre que le daremos a nuestra variable. No debemos olvidar colocar ; (punto y co-ma) al final de la sentencia. Supongamos que deseamos crear una variable cuyonombre será amigo y es del tipo agenda.

Agenda amigo;

Ahora, adentro del nuevo tipo de variable declarada llamada amigo, se encuentranlos campos Nombre, Edad y Telefono. Es posible declarar varias variables de Agenda.

Agenda amigo1, amigo2, amigo3;

En el caso de necesitar hacer uso de éste, podemos crear un arreglo de la estructu-ra. Este arreglo puede ser del tamaño que necesitemos para nuestra aplicación, y esentonces de esta forma que para la estructura agenda podemos tener un arreglodonde guardamos la información de los amigos, y otro arreglo donde se guardarála información de los clientes.

Agenda []amigos=new Agenda[15];Agenda []clientes=new Agenda[5];

9. ESTRUCTURAS Y ENUMERACIONES

282 www.redusers.com

Podemos definir una variable de la estructura de la forma tradicional, pero también podemos

hacerlo por medio new. Con ésta última es posible colocar un constructor adentro de la

estructura y facilitarnos la introducción de información. Si se define de forma tradicional

deberemos inicializar cada campo de la estructura manualmente.

CREACIÓN DE VARIABLES DE ESTRUCTURA

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 282

Page 285: C# aprenda a programar

Cómo acceder a los campos de la estructuraYa tenemos variables de la estructura y sabemos que adentro de éstas se encuen-tran los campos que guardarán la información. Tenemos que tener acceso a loscampos para poder guardar, leer o modificar los datos. El acceso al campo se lle-va a cabo de la siguiente manera:

VariableEstructura.Campo

Esto quiere decir que primero debemos indicar cuál es la variable con la que dese-amos trabajar. Luego necesitamos utilizar el operador punto y seguido de él coloca-mos el nombre del campo a acceder. Veamos un ejemplo de esto:

amigo.Edad = 25;

En este caso decimos que al campo Edad de la variable amigo le colocamos en suinterior el valor 25. Podemos utilizar los campos en cualquier tipo de expresión vá-lida, tal y como una variable:

if(amigo.Edad>18)...diasVividos=amigo.Edad * 365;...Console.WriteLine(“El nombre es {0}”,amigo.Nombre);

Cómo mostrar los campos de la estructuraAlgo que necesitaremos constantemente es presentar los campos de la estructura.La manera más evidente de hacerlo es con el método WriteLine(). Simplementemostramos el contenido del campo como si fuera otra variable del programa.

Las estructuras

283www.redusers.com

Es posible que tengamos una estructura y que sólo utilicemos determinados campos, sin embargo,

los demás campos continúan existiendo. Algunos de éstos pueden inicializarse automáticamente

a 0 o null si usamos new para crear la variable. Pero si se hace de forma tradicional y no se han

inicializado, entonces ese campo no tiene instancia y originará problemas si se intenta usar.

CAMPOS OLVIDADOS

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 283

Page 286: C# aprenda a programar

Console.WriteLine(“La edad es {0}”,amigo.Edad);

Esta forma es sencilla y útil en los casos en los que solamente necesitamos mostrarun campo de la estructura. Sin embargo, de necesitar mostrar todos los campos,deberemos colocar WriteLine() para cada campo, o uno solo con una cadena deformato larga. En cualquier caso resulta incómodo.La mejor forma de mostrar todos los datos contenidos en los campos sería median-te la conversión de la estructura a una cadena. Sabemos que existe un método lla-mado ToString() que hemos usado con las variables numéricas. Sin embargo, C# nose lo puede dar directamente a nuestra estructura porque no puede saber cuáles sonlos campos que contiene ni cómo los deseamos mostrar. Por esto, cae en nuestraresponsabilidad programar el método ToString() de nuestra estructura.

Veamos esto en el siguiente ejemplo:

public struct Agenda{

public String Nombre;public int Edad;public String Telefono;

public override String ToString(){

StringBuilder sb = new StringBuilder();sb.AppendFormat(“Nombre: {0}, Edad: {1},

Telefono: {2}”, Nombre, Edad, Telefono);

return (sb.ToString());}

}

Podemos observar que adentro del bloque de código de la estructura hemos colo-cado nuestra versión del método ToString(). El acceso debe ser público para que sepueda invocar desde el exterior de la estructura. Este método debe regresar un ob-jeto de tipo String y no necesita ningún parámetro.En el interior del método simplemente colocamos el código necesario para darle for-mato a la cadena y en nuestro caso hacemos uso de StringBuilder, aunque es válidousar cualquier otro método. Al finalizar ya tenemos la cadena con la informaciónde nuestros campos y la regresamos por medio de return.

9. ESTRUCTURAS Y ENUMERACIONES

284 www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 284

Page 287: C# aprenda a programar

Ahora que ya tenemos implementado ToString() mostrar la información conte-nida será tan sencillo como:

Console.WriteLine(amigo.ToString());

Veamos un ejemplo completo de estos conceptos:

public struct Agenda{

public String Nombre;public int Edad;public String Telefono;

public override String ToString(){

StringBuilder sb = new StringBuilder();sb.AppendFormat(“Nombre: {0}, Edad: {1},

Telefono: {2}”, Nombre, Edad, Telefono);

return (sb.ToString());}

}

static void Main(string[] args){

//// TODO: agregar aquí código para iniciar la aplicación//

Agenda []amigos=new Agenda[5];

amigos[1].Edad=25;amigos[1].Nombre=”Juan”;amigos[1].Telefono=”(555) 123-4567”;

Console.WriteLine(amigos[1].ToString());}

Las estructuras

285www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 285

Page 288: C# aprenda a programar

Como parte del ejemplo creamos un arreglo de la estructura Agenda que se llamaamigos y tiene 5 elementos, luego, para el elemento en el índice 1 colocamos losdatos. Para finalizar simplemente imprimimos el elemento 1 del arreglo amigos,pero usamos el método ToString() programado por nosotros. Si compilamos y eje-cutamos el programa obtendremos lo siguiente:

Figura 2. Podemos observar cómo por medio de ToString() obtenemos

la cadena con la información de la estructura y la mostramos en la consola.

Creación de un constructor para la estructuraEn el ejemplo anterior hemos visto la manera de cómo cada uno de los camposque componen la estructura ha tenido que inicializarse en forma individual. Estoes correcto y no presenta ningún problema, sin embargo, hay una forma de po-der inicializar los campos más fácilmente, sin tantas complicaciones.Para hacer esto podemos hacer uso de un constructor. El constructor no es otra co-sa que un método que nos permitirá llevar a cabo la inicialización de los campos. Sinembargo, este método tiene algunas características especiales. La primera característi-ca es que siempre se llamará igual que la estructura a la que pertenece. La segunda esmuy importante: el constructor se invoca automáticamente cuando llevamos a cabola instanciación de la variable de la estructura. La última característica del constructores que no tiene tipo. No sólo no regresa nada, no tiene tipo.

9. ESTRUCTURAS Y ENUMERACIONES

286 www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 286

Page 289: C# aprenda a programar

Adentro del constructor podemos colocar cualquier código válido de C#, pero esevidente que colocaremos código dedicado a la inicialización de los campos. Vea-mos un primer ejemplo de cómo podemos crear un constructor. El constructor siem-pre va adentro del bloque de código de la estructura.

public Agenda(String pNombre, int pEdad, String pTelefono)

{// Llevamos a cabo la asignaciónNombre=pNombre;Edad=pEdad;Telefono=pTelefono;

}

En el código del constructor vemos que el acceso es público. Esto es necesario ysiempre debemos dejarlo así. Si observamos luego se coloca directamente el nom-bre del constructor. El nombre es Agenda, ya que pertenece a la estructura Agenda.A continuación tenemos la lista de parámetros. Los valores pasados como paráme-tros serán asignados a los campos correspondientes. En la declaración de la variablelo tendremos que usar de la siguiente forma:

Agenda amigo=new Agenda(“Juan”,25,”(555) 123-4567”);

Aquí vemos que declaramos la variable amigo que es de tipo Agenda. Al hacer la ins-tanciación por medio de new vemos que pasamos los parámetros. Éstos serán losdatos que quedarán guardados en los campos de la variable amigo. La cadena “Juan”quedaría adentro del campo Nombre, el valor de 25 adentro del campo Edad y la ca-dena “(555) 123-4567” en el campo Telefono.

Veamos cómo quedaría un programa completo con el constructor:

Las estructuras

287www.redusers.com

El método ToString() se definió en la clase Object, de la cual desciende todo en C#, pero al estar

definiendo una versión nueva para nuestra estructura usamos override, que le indica al

compilador que creamos una nueva implementación que usará nuestra estructura. Así, al

invocar ToString() se usará la versión implementada por nosotros en lugar de la versión base.

EL USO DE OVERRIDE

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 287

Page 290: C# aprenda a programar

public struct Agenda{

public String Nombre;public int Edad;public String Telefono;

public Agenda(String pNombre, int pEdad, String pTelefono)

{// Llevamos a cabo la asignaciónNombre=pNombre;Edad=pEdad;Telefono=pTelefono;

}

public override String ToString(){

StringBuilder sb = new StringBuilder();sb.AppendFormat(“Nombre: {0}, Edad: {1},

Telefono: {2}”, Nombre, Edad, Telefono);

return (sb.ToString());}

}

static void Main(string[] args){

//// TODO: agregar aquí código para iniciar la aplicación//

9. ESTRUCTURAS Y ENUMERACIONES

288 www.redusers.com

En la dirección web que listaremos a continuación, encontraremos una pequeña tutoría sobre la

utilización de las estructuras en C#. Recordemos siempre buscar información, tutoriales y

cualquier otro material que nos sea de utilidad, para poder ampliar nuestros conocimientos:

www.devjoker.com/asp/ver_contenidos.aspx?co_contenido=161.

TUTORÍA DE ESTRUCTURAS

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 288

Page 291: C# aprenda a programar

Agenda amigo=new Agenda(“Juan”,25,”(555) 123-4567”);

Console.WriteLine(amigo.ToString());}

Ejecutemos el programa y veamos el resultado que obtenemos:

Figura 3. Vemos cómo efectivamente los datos han sido

colocados en los campos de la variable por medio del constructor.

Cómo usar el constructor para validar informaciónEl constructor no solamente puede ser utilizado para colocar la informaciónadentro de los campos, una de las grandes ventajas que éste nos da es la posibi-lidad de poder validar la información antes de que sea asignada a uno de sus cam-pos. Es posible que existan ciertas reglas sobre lo que se considera informaciónválida para nuestros campos, y por supuesto, podemos implementar estas mis-mas en el constructor. Supongamos que el teléfono sólo se considera válido si tiene más de 8 caracteres.En caso de que sea menor es inválido y no debe ser asignado para evitar proble-mas. Esta simple regla es fácil de programar en el constructor. En nuestro casopodría quedar de la siguiente forma:

Las estructuras

289www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 289

Page 292: C# aprenda a programar

public Agenda(String pNombre, int pEdad, String pTelefono)

{// Llevamos a cabo la asignaciónNombre=pNombre;Edad=pEdad;

if(pTelefono.Length>8)Telefono=pTelefono;

elseTelefono=”Teléfono no válido”;

}

Como vemos, hacemos uso de if y verificamos la longitud de la cadena pTelefono.Si es mayor a 8 entonces le asignamos pTelefono al campo Telefono. En caso con-trario, colocamos un mensaje que dice que el teléfono no es válido.

El programa completo es el siguiente:

public struct Agenda{

public String Nombre;public int Edad;public String Telefono;

public Agenda(String pNombre, int pEdad, String pTelefono)

{// Llevamos a cabo la asignaciónNombre=pNombre;

9. ESTRUCTURAS Y ENUMERACIONES

290 www.redusers.com

El mismo sitio web que nombramos anteriormente presenta una tutoría sobre el uso de la

enumeración en C# que complementa los conceptos que hemos aprendido en este capítulo:

www.devjoker.com/contenidos/Tutorial-C/164/Enumeraciones.aspx.

TUTORÍA DE ENUMERACIÓN

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 290

Page 293: C# aprenda a programar

Edad=pEdad;

if(pTelefono.Length>8)Telefono=pTelefono;

elseTelefono=”Telefono no valido”;

}

public override String ToString(){

StringBuilder sb = new StringBuilder();sb.AppendFormat(“Nombre: {0}, Edad: {1},

Telefono: {2}”, Nombre, Edad, Telefono);

return (sb.ToString());}

}

static void Main(string[] args){

//// TODO: agregar aquí código para iniciar la aplicación//

Agenda amigo=new Agenda(“Juan”,25,”(555) 123-4567”);Agenda amigo1=new Agenda(“Pedro”,32,”(555)”);Console.WriteLine(amigo.ToString());Console.WriteLine(amigo1.ToString());

Las estructuras

291www.redusers.com

Si deseamos ampliar los conceptos y conocimientos sobre el uso del constructor en las

estructuras, podemos visitar las tutorías del sitio web Devjoker: www.devjoker.com/

contenidos/Tutorial-C/163/Constructores-de-estructuras.aspx.

TUTORÍA SOBRE EL CONSTRUCTOR EN LAS ESTRUCTURAS

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 291

Page 294: C# aprenda a programar

}

Si compilamos y ejecutamos el programa tendremos el siguiente resultado:

Figura 4. Podemos ver cómo el constructor no sólo

ha asignado el valor sino que también ha validado la información.

La sobrecarga del constructorEl constructor puede ser sobrecargado y esta habilidad nos brinda mucha flexibi-lidad para poder utilizarlo. Supongamos que tenemos amigos que tienen teléfonoy otros que no. Si no tienen teléfono, no tiene sentido utilizar un constructor quelo solicite. Lo mejor sería tener una segunda versión del constructor que solamente

9. ESTRUCTURAS Y ENUMERACIONES

292 www.redusers.com

Sobrecarga es una técnica de programación que permite tener varias versiones de una función o un

método. El compilador selecciona la versión a utilizar basándose en la cantidad de parámetros y los

tipos. Esto nos permite agrupar métodos diferentes bajo un mismo nombre o concepto, facilitando

la programación, solamente recordando un nombre, y no los nombres para cada versión.

LA SOBRECARGA

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 292

Page 295: C# aprenda a programar

necesite el nombre y la edad, y podemos hacer que esta versión coloque un men-saje que indique que no tiene teléfono.Para hacer la sobrecarga colocamos la segunda versión debajo de la que ya tenemos.

Por ejemplo, nuestra segunda versión queda de la siguiente forma:

public Agenda(String pNombre, int pEdad){

// Llevamos a cabo la asignaciónNombre=pNombre;Edad=pEdad;

Telefono=”Sin teléfono”;}

Como podemos ver, solamente recibimos dos parámetros, pero aun así los tres cam-pos son asignados con un valor. Ningún campo se queda sin asignar. Para declararla variable le pasamos los 2 parámetros necesarios.

Agenda amigo2=new Agenda(“Luis”,28);

Veamos un ejemplo que utilice la sobrecarga del constructor de la estructura:

public struct Agenda{

public String Nombre;public int Edad;public String Telefono;

public Agenda(String pNombre, int pEdad, String pTelefono)

{// Llevamos a cabo la asignaciónNombre=pNombre;Edad=pEdad;if(pTelefono.Length>8)

Las estructuras

293www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 293

Page 296: C# aprenda a programar

9. ESTRUCTURAS Y ENUMERACIONES

294

Telefono=pTelefono;else

Telefono=”Teléfono no válido”;}

public Agenda(String pNombre, int pEdad){

// Llevamos a cabo la asignaciónNombre=pNombre;Edad=pEdad;

Telefono=”Sin teléefono”;}

public override String ToString(){

StringBuilder sb = new StringBuilder();sb.AppendFormat(“Nombre: {0}, Edad: {1},

Telefono: {2}”, Nombre, Edad, Telefono);

return (sb.ToString());}

}

static void Main(string[] args){

//// TODO: agregar aquí código para iniciar la aplicación//

Agenda amigo=new Agenda(“Juan”,25,”(555) 123-4567”);Agenda amigo1=new Agenda(“Pedro”,32,”(555)”);Agenda amigo2=new Agenda(“Luis”,28);

Console.WriteLine(amigo.ToString());Console.WriteLine(amigo1.ToString());Console.WriteLine(amigo2.ToString());

}

www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 294

Page 297: C# aprenda a programar

Si compilamos la aplicación, veremos el resultado en la siguiente figura:

Figura 5. En esta figura podemos observar cómo el constructor

sobrecargado también ha asignado la información necesaria en los campos.

Incluso podemos hacer que el constructor le solicite la información directamenteal usuario. Hay que recordar que podemos colocar cualquier código válido en suinterior. Esto lo logramos al crear una nueva sobrecarga.

Veamos cómo puede quedar esta nueva versión del constructor:

public Agenda(String pNombre){

// Asignamos el nombreNombre=pNombre;

// Pedimos la edadConsole.WriteLine(“Dame la edad:”);Edad=Convert.ToInt32(Console.ReadLine());

Las estructuras

295www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 295

Page 298: C# aprenda a programar

// Pedimos el teléfonoConsole.WriteLine(“Dame el teléfono:”);Telefono=Console.ReadLine();

if(Telefono.Length<8)Telefono=”Sin teléfono”;

}

Lo primero que hacemos es asignar el nombre que hemos recibido por parámetro.Luego de la forma usual pedimos la edad, notando cómo está colocada la senten-cia. Sabemos que ToInt32() necesita un parámetro que es la cadena a convertir yReadLine() regresa una cadena. De esta forma, aprovechamos y colocamos todo elcódigo adentro de una sola línea. Otra opción que podríamos haber utilizado esuna función que pida el dato, tal y como lo vimos en un capítulo anterior. Ense-guida solicitamos el teléfono y aprovechamos para validar la información.El programa completo queda de la siguiente manera:

public struct Agenda{

public String Nombre;public int Edad;public String Telefono;

public Agenda(String pNombre, int pEdad, String pTelefono)

{// Llevamos a cabo la asignaciónNombre=pNombre;Edad=pEdad;

9. ESTRUCTURAS Y ENUMERACIONES

296 www.redusers.com

Cuando utilizamos el constructor con nuestra estructura o cuando tenemos sobrecargas, tenemos

que tener cuidado con la cantidad de parámetros. Dentro de las estructuras el constructor

necesita tener al menos un parámetro ya que no es válido colocar un constructor sin parámetros.

Si olvidamos colocar los parámetros, tendremos un error durante la compilación del programa.

CONSTRUCTOR EN LA ESTRUCTURA

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 296

Page 299: C# aprenda a programar

if(pTelefono.Length>8)Telefono=pTelefono;

elseTelefono=”Teléfono no valido”;

}

public Agenda(String pNombre, int pEdad){

// Llevamos a cabo la asignaciónNombre=pNombre;Edad=pEdad;

Telefono=”Sin teléfono”;}

public Agenda(String pNombre){

// Asignamos el nombreNombre=pNombre;

// Pedimos la edadConsole.WriteLine(“Dame la edad:”);Edad=Convert.ToInt32(Console.ReadLine());

// Pedimos el teléfonoConsole.WriteLine(“Dame el teléfono:”);Telefono=Console.ReadLine();

if(Telefono.Length<8)Telefono=”Sin teléfono”;

Las estructuras

297www.redusers.com

Si deseamos conocer más sobre el modificador override en C#, podemos hacerlo

directamente en el sitio MSDN. Este sitio de Microsoft siempre es una muy buena referencia

y podemos encontrar toda la información que necesitemos. La dirección electrónica es:

http://msdn2.microsoft.com/es-es/library/ebca9ah3(VS.80).aspx.

EL MODIFICADOR OVERRIDE

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 297

Page 300: C# aprenda a programar

}

public override String ToString(){

StringBuilder sb = new StringBuilder();sb.AppendFormat(“Nombre: {0}, Edad: {1},

Telefono: {2}”, Nombre, Edad, Teléfono);

return (sb.ToString());}

}

static void Main(string[] args){

//// TODO: agregar aquí código para iniciar la aplicación//

Agenda amigo=new Agenda(“Juan”,25,”(555) 123-4567”);Agenda amigo1=new Agenda(“Pedro”,32,”(555)”);Agenda amigo2=new Agenda(“Luis”,28);Agenda amigo3=new Agenda(“Maria”);

Console.WriteLine(amigo.ToString());Console.WriteLine(amigo1.ToString());Console.WriteLine(amigo2.ToString());Console.WriteLine(amigo3.ToString());

}

Compilemos la aplicación y veamos cómo se comporta.

9. ESTRUCTURAS Y ENUMERACIONES

298 www.redusers.com

En MSDN también encontraremos información sobre las estructuras, sus constructores,

campos y demás elementos que las pueden constituir. También encontramos una referencia

a su guía de programación. La encontraremos en la siguiente dirección:

http://msdn2.microsoft.com/es-es/library/ah19swz4(VS.80).aspx.

INFORMACIÓN SOBRE ESTRUCTURAS EN MSDN

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 298

Page 301: C# aprenda a programar

Figura 6. Vemos que el constructor efectivamente

nos pide los datos por medio de la consola y luego son asignados.

Estructuras enlazadasLas estructuras nos dan la facilidad de poder agrupar información que está relacio-nada adentro de un mismo elemento. Ya vimos que se puede colocar como dato acualquier tipo que sea válido en C#. Estos tipos válidos también corresponden a ti-pos definidos por el programador, es decir otras estructuras.Tenemos una estructura que se llama Agenda, pero esta agenda está un poco in-completa, debido a que nos hace falta colocar la dirección o el domicilio de la per-sona. Esto lo podemos resolver de una manera práctica, colocando dos camposnuevos como la calle y el número de la casa, pero también podríamos pensar enotra estructura llamada Direccion que contenga esta información.

Por ejemplo, la estructura podría quedar de la siguiente forma:

public struct Direccion{

public String Calle;

Las estructuras

299www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 299

Page 302: C# aprenda a programar

public int Numero;

public Direccion(String pCalle, int pNumero){

Calle=pCalle;Numero=pNumero;

}}

Como vemos, los campos son Calle y Numero. Se ha creado un constructor para ayu-darnos a colocar la información fácilmente cuando se instancie una variable de es-te nuevo tipo. Ahora que ya tenemos definido el nuevo tipo Direccion, podemosusarlo en nuestra estructura Agenda, pero serán necesarios algunos cambios.

Primero veamos cómo agregar un campo de tipo Direccion a la estructura:

public struct Agenda{

public String Nombre;public int Edad;public String Telefono;public Direccion Domicilio;

Agregar un campo es muy sencillo, simplemente definimos la variable. Sin embar-go, si dejamos la estructura con ese cambio tendremos problemas, ya que el campoDomicilio no estará instanciado. Esta instanciación se puede llevar a cabo cuando seasignan los datos, por ejemplo, en el constructor.

Cambiemos el primer constructor para instanciar y asignarle datos al campo Domicilio:

public Agenda(String pNombre, int pEdad, String pTelefono, String pCalle, int pNumero)

{// Llevamos a cabo la asignaciónNombre=pNombre;Edad=pEdad;

if(pTelefono.Length>8)

9. ESTRUCTURAS Y ENUMERACIONES

300 www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 300

Page 303: C# aprenda a programar

Telefono=pTelefono;else

Telefono=”Teléfono no valido”;

Domicilio=new Direccion(pCalle, pNumero);

}

Vemos que hemos llevado a cabo algunos cambios. En primer lugar, el constructorde Agenda recibe todos los datos necesarios, incluidos los de la estructura Direccion.En el interior del constructor asignamos los datos que le corresponden a Agenda yen la parte final hacemos la instanciación de Domicilio por medio de new y le pasa-mos a su constructor los datos que le corresponden. También puede suceder que elconstructor de Agenda no reciba los datos de Domicilio. En ese caso, debemos ins-tanciar también al campo domicilio y pasar algunos datos de default al constructor.

public Agenda(String pNombre, int pEdad){

// Llevamos a cabo la asignaciónNombre=pNombre;Edad=pEdad;

Telefono=”Sin teléfono”;

Domicilio=new Direccion(“Sin dirección”,0);}

En este caso, vemos que la instanciación se lleva a cabo, pero simplemente pasamosalgunos parámetros de default. Si continuamos con estos cambios, el programa que-dará de la siguiente manera:

public struct Direccion{

public String Calle;public int Numero;

public Direccion(String pCalle, int pNumero){

Las estructuras

301www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 301

Page 304: C# aprenda a programar

Calle=pCalle;Numero=pNumero;

}}

public struct Agenda{

public String Nombre;public int Edad;public String Telefono;public Direccion Domicilio;

public Agenda(String pNombre, int pEdad, String pTelefono, String pCalle, int pNumero)

{// Llevamos a cabo la asignaciónNombre=pNombre;Edad=pEdad;

if(pTelefono.Length>8)Telefono=pTelefono;

elseTelefono=”Teléfono no valido”;

Domicilio=new Direccion(pCalle, pNumero);

}

public Agenda(String pNombre, int pEdad){

// Llevamos a cabo la asignaciónNombre=pNombre;Edad=pEdad;

Telefono=”Sin teléfono”;

Domicilio=new Direccion(“Sin dirección”,0);}

public Agenda(String pNombre)

9. ESTRUCTURAS Y ENUMERACIONES

302 www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 302

Page 305: C# aprenda a programar

{// Asignamos el nombreNombre=pNombre;

// Pedimos la edadConsole.WriteLine(“Dame la edad:”);Edad=Convert.ToInt32(Console.ReadLine());

// Pedimos el teléfonoConsole.WriteLine(“Dame el teléfono:”);Telefono=Console.ReadLine();

if(Telefono.Length<8)Telefono=”Sin teléfono”;

Domicilio=new Direccion(“Sin dirección”,0);

}

public override String ToString(){

StringBuilder sb = new StringBuilder();sb.AppendFormat(“Nombre: {0}, Edad: {1},

Telefono: {2}”, Nombre, Edad, Telefono);

return (sb.ToString());}

}

static void Main(string[] args){

//// TODO: agregar aquí código para iniciar la aplicación//

Agenda amigo=new Agenda(“Juan”,25,”(555) 123-4567”,”Av. Principal”,105);

Las estructuras

303www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 303

Page 306: C# aprenda a programar

Agenda amigo1=new Agenda(“Pedro”,32,”(555)”,”Calle

Bolivar”,350);Agenda amigo2=new Agenda(“Luis”,28);Agenda amigo3=new Agenda(“Maria”);

Console.WriteLine(amigo.ToString());Console.WriteLine(amigo1.ToString());Console.WriteLine(amigo2.ToString());Console.WriteLine(amigo3.ToString());

}

Podemos observar que en las variables amigo y amigo1 ya hemos colocado previa-mente los parámetros necesarios por el constructor modificado. Sólo queda quecompilemos y ejecutemos el programa.

Figura 7. Vemos que el resultado del programa es el mismo que el anterior.

Al parecer tenemos un problema ya que obtenemos el mismo resultado que el pro-grama anterior a pesar de los cambios. Esto sucede debido a que no hemos actuali-zado el método ToString() de Agenda ni creado el propio de Direccion.

9. ESTRUCTURAS Y ENUMERACIONES

304 www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 304

Page 307: C# aprenda a programar

Para Direccion:

public override String ToString(){

StringBuilder sb = new StringBuilder();sb.AppendFormat(“Direccion: {0} #{1}”, Calle,

Numero);return (sb.ToString());

}

Para Agenda:

public override String ToString(){

StringBuilder sb = new StringBuilder();sb.AppendFormat(“Nombre: {0}, Edad: {1},

Telefono: {2}”, Nombre, Edad, Telefono);

// Adicionamos la cadena que viene de Domicilio

sb.Append(Domicilio.ToString());return (sb.ToString());

}

Vemos que adentro del ToString() de Agenda agregamos la cadena que nos regre-sa el ToString() de Domicilio. De esta forma, cuando se impriman los contenidosde Agenda también se imprimirán los del campo Domicilio. El programa comple-to queda de la siguiente forma:

public struct Direccion{

public String Calle;public int Numero;

public Direccion(String pCalle, int pNumero){

Calle=pCalle;Numero=pNumero;

Las estructuras

305www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 305

Page 308: C# aprenda a programar

}

public override String ToString(){

StringBuilder sb = new StringBuilder();sb.AppendFormat(“Direccion: {0} #{1}”, Calle,

Numero);return (sb.ToString());

}}public struct Agenda{

public String Nombre;public int Edad;public String Telefono;public Direccion Domicilio;

public Agenda(String pNombre, int pEdad, String pTelefono, String pCalle, int pNumero)

{// Llevamos a cabo la asignaciónNombre=pNombre;Edad=pEdad;

if(pTelefono.Length>8)Telefono=pTelefono;

elseTelefono=”Teléfono no valido”;

Domicilio=new Direccion(pCalle, pNumero);

}

public Agenda(String pNombre, int pEdad){

// Llevamos a cabo la asignaciónNombre=pNombre;Edad=pEdad;

Telefono=”Sin teléfono”;

9. ESTRUCTURAS Y ENUMERACIONES

306 www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 306

Page 309: C# aprenda a programar

Domicilio=new Direccion(“Sin dirección”,0);}

public Agenda(String pNombre){

// Asignamos el nombreNombre=pNombre;

// Pedimos la edadConsole.WriteLine(“Dame la edad:”);Edad=Convert.ToInt32(Console.ReadLine());

// Pedimos el telefonoConsole.WriteLine(“Dame el teléfono:”);Telefono=Console.ReadLine();

if(Telefono.Length<8)Telefono=”Sin teléfono”;

Domicilio=new Direccion(“ Sin dirección”,0);

}

public override String ToString(){

StringBuilder sb = new StringBuilder();sb.AppendFormat(“Nombre: {0}, Edad: {1},

Telefono: {2}”, Nombre, Edad, Telefono);

// Adicionamos la cadena que viene de Domicilio

sb.Append(Domicilio.ToString());return (sb.ToString());

}

}

static void Main(string[] args)

Las estructuras

307www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 307

Page 310: C# aprenda a programar

{//// TODO: agregar aquí código para iniciar la aplicación//

Agenda amigo=new Agenda(“Juan”,25,”(555) 123-4567”,”Av. Principal”,105);

Agenda amigo1=new Agenda(“Pedro”,32,”(555)”,”Bolivar”,350);

Agenda amigo2=new Agenda(“Luis”,28);Agenda amigo3=new Agenda(“Maria”);

Console.WriteLine(amigo.ToString());Console.WriteLine(amigo1.ToString());Console.WriteLine(amigo2.ToString());Console.WriteLine(amigo3.ToString());

}

Ahora ejecutemos el programa y veamos el resultado.

Figura 8. Observemos que en este caso la información se presenta completa.

9. ESTRUCTURAS Y ENUMERACIONES

308 www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 308

Page 311: C# aprenda a programar

Las enumeracionesYa hemos aprendido las estructuras y ahora conoceremos otro nuevo tipo que pue-de ser definido por el programador. Este nuevo tipo se conoce como enumeracio-nes. Éstas son tipos que nosotros podemos definir, pero tendrán un número finitode valores posibles, es decir, que podemos definir el tipo y los valores a guardar.Las enumeraciones son útiles cuando tenemos información que sabemos que sola-mente puede tener uno de una serie de posibles valores. Por ejemplo, sabemos quela semana tiene siete días. Entonces, un día no puede tener un valor que no sea elde un día de la semana. La semana sería una enumeración. Esto lo podemos utilizar para cualquier otro ejemplo donde sepamos los valores po-sibles a utilizar. Otro ejemplo, supongamos que estamos haciendo un programa pa-ra una empresa que vende quesos. Tendremos un número finito de posibles tiposde queso. Entonces, podemos colocarlos adentro de una enumeración.Al parecer, las enumeraciones son muy sencillas, pero podemos correr el riesgo depensar que no son muy útiles. Sin embargo, nos dan grandes beneficios. Tambiénnos sirven para reducir la cantidad de errores que podemos tener en nuestra apli-cación al asignar y utilizar valores. Como beneficio, reducen la lógica que debe-mos utilizar e incluso mejoran el desempeño de nuestra aplicación. Por eso es útilaprender a usarlas correctamente.

Figura 9. Aquí vemos una representación

de la enumeración y sus posibles valores.

Veamos un ejemplo donde podemos utilizar la enumeración para mejorar nuestraaplicación. Si nuestro programa necesita guardar por algún motivo el día de la se-mana podemos pensar en diferentes opciones. La primera puede ser la utilizaciónde una variable de tipo entero, ya que cada día de la semana puede ser definidopor un número del 1 al 7. Sin embargo, esto nos presenta algunos problemas. Elprimer problema es que usamos un tipo que puede guardar miles de valores posi-bles, pero sólo usamos 7, entonces tenemos un desperdicio de memoria.El segundo problema es que el tipo, al poder guardar muchos valores, puede guar-dar datos que no correspondan a la realidad como el día 8 de la semana. Para evi-tar esto necesitamos agregar lógica de control con el uso de uno o varios if. De

Semana

Lunes Martes Miércoles Jueves Viernes Sábado Domingo

0 1 2 3 4 5 6

Las estructuras

309www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 309

Page 312: C# aprenda a programar

esta manera, se complica nuestra aplicación. Otro problema que esto nos presen-ta es el despliegue de la información. Cada vez que queremos mostrar el día te-nemos que poner lógica para transformar 1 a “Lunes”, 2 a “Martes”, y así sucesi-vamente para poder listar cada día de la semana.Quizás otra solución sería el uso de una cadena para guardar el día de la semana, pe-ro también presenta problemas. Un problema que podemos tener es que si nuestralógica funciona con “Lunes”, cuando el usuario introduzca un valor como “lunes” yano funcionará. Para corregir esto podemos usar el método ToUpper(), pero agregamás lógica y proceso extra a nuestra aplicación que no es necesario. También gas-tamos memoria de más ya que guardar una cadena requiere más memoria queguardar un simple número. Desde luego, la impresión sería más sencilla, pero laadministración de la información más complicada.Nuestra mejor opción es el uso de las enumeraciones. Ahora aprenderemos cómousarlas y cómo el problema anterior se resolvería fácilmente con ellas.

Declaración y asignación de valoresPara declarar una enumeración usamos el siguiente formato:

enum nombre {valor1, valor2, …, valorn};

En primer lugar, tenemos que colocar la palabra clave enum seguida del nombre conel que identificaremos al nuevo tipo de enumeración. Luego entre {} debemos colo-car los valores que puede tener este tipo. Hay que recordar que los valores son finitos.

Veamos cómo declarar una enumeración para nuestro ejemplo de la semana:

enum semana {Lunes, Martes, Miercoles, Jueves, Viernes, Sabado, Domingo};

En este caso, hemos declarado la enumeración con el nombre de semana. Cada unode los días que hemos listado entre {} serán los posibles valores que puede tener. Con

9. ESTRUCTURAS Y ENUMERACIONES

310 www.redusers.com

Cuando declaramos la enumeración llevamos a cabo el listado de todos los valores posibles.

Podemos pensar que internamente se guardan con un número de identificación. El primer

elemento tendrá el valor de cero, el segundo de uno y así en forma consecutiva. Sin embargo,

también es posible indicar cuál será el valor para el primer elemento de la enumeración.

LOS VALORES DE LAS ENUMERACIONES

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 310

Page 313: C# aprenda a programar

esto, el siguiente paso sería simplemente la creación de una variable de tipo semana.La declaración y asignación de la variable la hacemos de la forma tradicional.

semana miDia;

Aquí declaramos la variable miDia que es de tipo semana, por lo que solamente po-drá tener los valores listados en la enumeración. Si lo hubiéramos deseado, tambiénpodríamos haber declarado e inicializado la variable con algún valor.

semana miDia=semana.Martes;

La asignación del valor en esta variable se puede llevar a cabo en cualquier momento,dentro de nuestra aplicación, después de su declaración, como en cualquier otra va-riable, pero con uno de los valores contenidos en semana.

miDia=semana.Viernes;

Para imprimir el valor de una enumeraciónSi deseamos mostrar el valor de una variable de tipo enumeración, lo único que ne-cesitamos es utilizar el método ToString(). Éste nos dará una cadena con el valor co-rrespondiente y podemos utilizarla dentro de nuestra lógica para desplegar valores.El método ToString() regresa una cadena y esa cadena será el valor correspondien-te. Por ejemplo, si en la enumeración listamos un valor como Lunes, entonces lacadena regresada será “Lunes”.

String mensaje=”El día es ”;……mensaje=mensaje+miDia.ToString();

Otro mecanismo que podemos utilizar para desplegar la información de una varia-ble de tipo enumeración es la cadena de formato.

En este caso, simplemente colocamos la variable en nuestra lista de variables:

Console.WriteLine(“El dia es {0}”, miDia);

Las estructuras

311www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 311

Page 314: C# aprenda a programar

Para pasar de enumeración a valor numéricoSi necesitamos pasar el valor de la enumeración a una variable numérica, lo úni-co que necesitamos hacer es colocar un type cast. En nuestro ejemplo, Lunes alser el primer valor definido, se pasará como 0 a la variable numérica, Miercolesserá el valor 2 y así sucesivamente.

int valor=0;……valor=(int)miDia;

Para iniciar la enumeración con un valor definidoComo vimos antes, el primer valor recibe el índice 0, pero en algunos casos es posi-ble que necesitemos que nuestra enumeración tenga un rango de valores especiales.La forma como resolvemos esto es dándole al primer elemento de la enumeración elvalor que necesitamos y todos los demás elementos tendrán valores sucesivos a éste.

Por ejemplo, supongamos que para nuestros propósitos en la enumeración de la se-mana, el día Lunes debe tener el valor 3. Para esto colocamos lo siguiente:

enum semana {Lunes=3, Martes, Miercoles, Jueves, Viernes, Sabado, Domingo};

De esta forma, Lunes tendrá un valor de 3, Martes de 4 y así sucesivamente hastaDomingo con un valor de 9.

La enumeración en expresionesComo nosotros trabajamos con una variable de tipo enumeración, podemos utili-zarla en cualquier tipo de expresión. Sólo debemos ser cuidadosos con los tipos conlos que interactuamos en la expresión. Si fuera necesario, podemos hacer uso detype cast para que la expresión quede correctamente escrita.

9. ESTRUCTURAS Y ENUMERACIONES

312 www.redusers.com

Puede que en muchas oportunidades, a lo largo de los capítulos del libro, hayamos encontrado

algunas trabas, o ejercicios con cierta complejidad. el caso de este capítulo puede llegar a ser

uno. La recomendación es volver a repasar cada uno de los temas en los que hemos

encontrado estas trabas para lograr una mejor comprensión.

IMPORTANCIA EN EL APRENDIZAJE

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 312

Page 315: C# aprenda a programar

Por ejemplo, para una expresión aritmética podemos realizar lo siguiente:

int salario=0;int pagoDia=200;……salarion=pagoDia*((int)miDia);

En las expresiones aritméticas es muy común que usemos type cast. Si lo deseamos,podemos hacer uso de los paréntesis para ayudarnos a leer la expresión. En una ex-presión relacional también podemos hacer uso de la enumeración. Si comparamoshacia el mismo tipo no es necesario hacer uso de un type cast.

if(miDia == semana.Martes)

Pero en el caso que necesitemos realizar una comparación hacia otro tipo, en-tonces sí será conveniente hacer utilización de type cast.

if((int)miDia==3)

Dentro de una expresión lógica podemos hacer uso de algo similar:

if((miDia>semana.Lunes && (int)miDia<5)

Ejemplo de aplicaciónAhora que ya conocemos los conceptos más importantes de las enumeraciones, esmomento de hacer una aplicación. Nuestra aplicación será sencilla y simplementeprobará los conceptos que hemos aprendido.

Nuestra aplicación puede quedar de la siguiente manera:

// Declaramos la enumeraciónenum semana {Lunes, Martes, Miercoles, Jueves, Viernes,

Sabado, Domingo};enum colores { Rojo = 1, Verde, Azul, Amarillo };

static void Main(string[] args)

Las estructuras

313www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 313

Page 316: C# aprenda a programar

{int numerico = 0;// Creamos una variable de tipo semana

semana miDia;

// Asignamos un valormiDia = semana.Lunes;

// Pasamos de enumeración a enteronumerico = (int)miDia;

// Mostramos la informaciónConsole.WriteLine(“El dia es {0} con valor {1}”, miDia,

numerico);

// Creamos una variable de colorcolores miColor = colores.Rojo;

// Pasamos a número enteronumerico = (int)miColor;

// Mostramos la informaciónConsole.WriteLine(“El color es {0} con valor {1}”, miColor,

numerico);

}

En primer lugar, declaramos dos enumeraciones. La primera es semana y Lunestendrá como valor 0. La segunda enumeración se llama colores y la iniciaremoscon un valor inicial Rojo que será 1.Dentro de la función Main() declaramos una variable de tipo entero, que usaremospara nuestros experimentos de convertir las enumeraciones a valores numéricos.Posteriormente, declaramos una variable de tipo semana llamada miDia. En la lí-nea siguiente le damos el valor de Lunes contenido en la enumeración semana. Acontinuación convertimos miDia a entero y se lo asignamos a la variable numérico.Luego mostramos los valores de las variables. Creamos una variable de tipo colo-res e inmediatamente le asignamos el valor de Rojo de la enumeración colores. Laconvertimos a valor numérico y luego la mostramos. Si ejecutamos el programa,obtendremos la siguiente salida en la consola:

9. ESTRUCTURAS Y ENUMERACIONES

314 www.redusers.com

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 314

Page 317: C# aprenda a programar

Figura 10. Podemos ver cómo la variable tiene

el valor de la enumeración y su equivalente numérico.

Con esto ya hemos aprendido a lo largo de este capítulo, en complemento con otros,las bases del manejo de las estructuras y las enumeraciones. Su uso es recomenda-ble y debemos utilizarlas cuando tengamos programas grandes ya que nos ayudan aadministrar la información y reducir la cantidad de errores.

Las estructuras

315www.redusers.com

… RESUMEN

Las estructuras nos permiten crear un tipo nuevo y agrupar información que está

relacionada adentro de una unidad. Los datos adentro de la estructura se llaman campos.

También es posible crear variables del tipo estructura y poder asignarles información a

sus campos. El constructor nos ayuda a introducir la información original y a verificar que

sea válida. Las estructuras pueden estar enlazadas. En las enumeraciones nosotros

creamos un tipo que tendrá un número finito de valores posibles. Podemos darle un valor

inicial a la enumeración e incluso convertirla a valores numéricos.

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 315

Page 318: C# aprenda a programar

316 www.redusers.com

TEST DE AUTOEVALUACIÓN

1 ¿Qué es una estructura?

2 ¿Cómo accedemos a un campo de la

estructura?

3 ¿Cómo creamos un constructor para la

estructura?

4 ¿Para qué sirve un constructor?

5 ¿Cómo se usa la sobrecarga del

constructor?

6 ¿Qué son las estructuras enlazadas?

7 ¿Cómo se define una variable de la

estructura?

8 ¿Cómo podemos usar el método ToString()

en la estructura?

9 ¿Qué es una enumeración?

10¿Cómo se declara una enumeración?

11¿Cómo creamos una variable de

enumeración?

12¿De qué forma se le coloca un valor al

elemento de la enumeración?

ACTIVIDADES

EJERCICIOS PRÁCTICOS

1 Crear una estructura para guardar los

productos de una tienda.

2 Crear una estructura para guardar la

información de una cuenta bancaria.

3 Crear estructuras enlazadas para guardar

la información de una mascota y su

dueño.

4 Crear una enumeración para los

diferentes tipos de neumáticos.

5 Crear una enumeración para los

diferentes tipos de estrellas.

09_C#2010_AJUSTADO.qxd 8/9/10 11:20 AM Page 316

Page 319: C# aprenda a programar

Cómo crear

nuestras

propias clases

La programación orientada a objetos 318

Las clases 318Cómo declarar la clase y los datos 320Cómo crear la instancia de nuestra clase 324Cómo asignarles valores a datos publicos 324Cómo invocar métodos de un objeto 325Cómo imprimir un dato público 325Protección de datos y creación de propiedades 329Cómo acceder a las propiedades 333Métodos públicos y privados 333Convertir un objeto a cadena 334El constructor en las clases 336Sobrecarga del constructor 339

Resumen 347Actividades 348

Capítulo 10

En este capítulo empezaremos a ver

temas más avanzados. Hasta ahora

hemos utilizado C# para la programación

estructurada, pero ahora iremos hacia

otro paradigma de programación,

el de la orientación a objetos. C#

es un lenguaje orientado a objetos, por

lo que se puede obtener su mayor poder

y beneficio si programamos con ese

paradigma. Parte fundamental de la

programación orientada a objetos es la clase.

C#

SERVICIO DE ATENCIÓN AL LECTOR: [email protected]

10_C#2010_AJUSTADO.qxd 8/11/10 10:01 AM Page 317

Page 320: C# aprenda a programar

La programación orientada a objetos

La programación estructurada es muy sencilla e intuitiva. En ella simplementetenemos un problema y lo subdividimos en problemas cada vez más pequeños.Usamos funciones para colocar zonas especializadas de código o código que seusa constantemente en su interior.El paradigma estructurado es correcto, pero tiene algunas limitaciones y algunosproblemas cuando el programa a realizar es grande. Unos de estos problemas seconoce como la corrupción de información. Supongamos que tenemos una va-riable y ésta es utilizada en diversas partes del programa. Una forma sencilla parapoder tener acceso a la variable es declararla de forma global, así todo el progra-ma la conoce. Al hacer esto cualquier parte del programa no sólo puede leerla si-no también modificarla. Debido a este esquema, una parte del programa puedecambiarse sin que otra sepa de este cambio y así se producen errores en la infor-mación. Para evitar esto es posible pasarle la variable como parámetro a quien lanecesite, pero esto complica su administración. Los programas estructurados muy grandes también son difíciles de extender y man-tener, y llevar a cabo un cambio puede ser costoso. Generalmente, un cambio en unaparte del programa produce cambios en otras partes que quizá no estén relacionadasdirectamente. En general, los programas estructurados son poco flexibles.La programación estructurada es buena para los programas pequeños y paraaprender las bases de programación. Sin embargo, el mundo actual pide el desa-rrollo orientado a objetos. Como recomendación, después de este libro, pode-mos aprender análisis y diseño orientado a objetos y luego continuar aprendien-do más C# con todas las técnicas orientadas a objetos. Esto ya sería un nivel avan-zando - experto de programación.En la programación orientada a objetos tomamos una idea diferente en la resoluciónde los problemas. En lugar de subdividirlos, lo que hacemos es ver cuáles son los com-ponentes u objetos que componen el problema y la forma cómo interactúan. Noso-tros programaremos estos objetos y haremos que se comuniquen entre sí. Cuandolos objetos hagan su labor y se comuniquen, el problema estará resuelto.

Las clasesEl componente principal de la programación orientada a objetos es la clase. Nosotrospodemos pensar en la clase como si fuera un plano por medio del cual podemos cre-ar objetos, por ejemplo, pensemos en una casa. Para hacer una casa lo primero quehacemos es pensar en los cuartos que deseamos que tenga y luego diseñamos un pla-no. El plano no es la casa, ya que no podemos vivir ni actuar en él. Sin embargo, és-te nos proporciona las características de la casa. Por medio del plano podemos cons-truir la casa y en esta construcción sí podemos llevar a cabo nuestras actividades.

10. CÓMO CREAR NUESTRAS PROPIAS CLASES

318 www.redusers.com

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 318

Page 321: C# aprenda a programar

El plano sería equivalente a la clase y la casa construida al objeto. La clase es un pla-no, una descripción, y el objeto tiene esas características y puede llevar a cabo tra-bajo concreto. Si necesitásemos hacer otra casa igual, no sería necesario hacer unnuevo plano, simplemente tomaríamos el plano ya realizado y crearíamos otra ca-sa. Una clase nos puede servir para crear muchos objetos independientes pero quetienen las mismas características. El proceso de crear un objeto a partir de una cla-se es lo que conocemos como instanciación.Adentro de la clase, nosotros colocaremos información y más importante aún,los métodos que trabajan sobre esta información, es decir, que los datos y losmétodos que los procesan están contenidos dentro de una sola unidad. A esto lollamamos encapsulamiento. Al encapsular datos y métodos los protegemos con-tra la corrupción de información.Los objetos se comunicarán por medio del uso de mensajes. En estos mensajes es po-sible solicitarle un dato a otro objeto, pedirle que lleve a cabo un proceso, etcétera.

Los datosLos datos son la información con la que trabajará la clase. La clase solamente debetener los datos que necesita para poder llevar a cabo su trabajo. Declarar un dato esmuy similar a declarar una variable, pero al igual que en las estructuras, necesita-mos indicar el acceso ya que tenemos básicamente tres tipos de acceso: público, pri-vado y protegido. Cuando nosotros tenemos un dato con acceso público cualquierelemento del exterior, como la función Main() o algún otro objeto, puede accederal dato, leerlo y modificarlo. Cuando tenemos el acceso privado solamente los mé-todos definidos dentro de la clase podrán leerlo o modificarlo. El acceso protegidoes un poco más avanzado y está por afuera de los límites de este libro.Un punto muy importante con relación a los datos que no debemos olvidar es quelos datos definidos en la clase son conocidos por todos los métodos de la misma cla-se. Es decir, actúan como si fueran globales para la clase. Cualquier método puedeacceder a ellos directamente sin necesidad de que los pasemos como parámetro.En algunos casos podremos colocar el acceso a nuestros datos como público, aun-que preferentemente no lo haremos. Si nos excedemos o usamos el acceso públicoen un mal diseño, corremos el riesgo de corrupción de información. Por lo general,

La programación orientada a objetos

319www.redusers.com

Es una característica de la programación orientada a objetos. Ésta permite crear una nueva

clase que hereda las características (datos y métodos) de otra clase, de forma tal que solamente

tengamos que agregar los elementos necesarios para la nueva. Es una gran forma de

reutilización de código si se usa en forma adecuada.

LA HERENCIA

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 319

Page 322: C# aprenda a programar

nuestros datos serán privados, aunque esto puede parecer un problema ya que si elexterior necesita alguna información calculada por el objeto no podrá tener accesoa ella. Para resolver esto hacemos uso de las funciones de interfaz.Una función de interfaz es aquella que puede ser invocada desde el exterior y queregresa una copia del valor de algún dato dentro del objeto. También podemos usar-la para colocar un valor determinado en un dato. La ventaja que nos da la funciónde interfaz es que podemos administrar el acceso a nuestra información, y podemoscolocar dentro de ésta código de seguridad que verifique o valide la información queentra o sale. De esta forma evitamos la corrupción de información.

Los métodosLos métodos son las funciones que llevan a cabo el proceso o la lógica de la clase, ycrear un método dentro de la clase es muy parecido a la forma que hemos utilizadoanteriormente. Los métodos también tendrán un tipo de acceso, al igual que los da-tos. Trabajarán sobre los datos de la clase. No hay que olvidar que todos los méto-dos conocen todos los datos definidos dentro de la clase, y pueden recibir paráme-tros y regresar valores. A un dato definido dentro de la clase no necesitamos pasarlocomo parámetro ya que el método lo conoce. Solamente los métodos que necesitenser invocados desde el exterior deben tener acceso público. Si el método sólo se in-voca desde el mismo interior de la clase su acceso debe ser privado. Esto lo hacemoscon fines de seguridad y para mantener el encapsulamiento correctamente.

Cómo declarar la clase y los datosLa declaración de la clase es un proceso sencillo. Las clases se declaran dentro de unnamespace y cualquiera que tenga acceso a ese namespace puede crear objetos dela clase. No olvidemos que la clase es como el plano y los objetos son realmente losque usamos para llevar a cabo el trabajo.

Para declarar la clase tendremos un esquema como el siguiente:

class nombre{

// datos……

// métodos……

10. CÓMO CREAR NUESTRAS PROPIAS CLASES

320 www.redusers.com

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 320

Page 323: C# aprenda a programar

}

El nombre de la clase puede ser cualquier nombre válido dentro de C#. El nom-bre debe ser único para el namespace, es decir no podemos tener dos clases quese llamen igual adentro del mismo namespace. La clase necesita un bloque decódigo y en su interior llevamos a cabo las declaraciones de los elementos que lacomponen. Generalmente, declaramos primero los datos. Esto nos permite tenerun programa organizado y luego facilita la lectura. Además, es posible declararlos métodos implementados antes.La mejor forma de hacer esto es por medio de un ejemplo. Supongamos que creare-mos un programa que calcula el área y el volumen de cubos y prismas rectangulares.Como en esta ocasión lo hacemos vía programación orientada a objetos, lo primeroque hacemos es pensar en los objetos que componen el problema.Los objetos son: cubo y prisma rectangular. Ahora que ya conocemos los objetos,debemos pensar en los datos y las operaciones que se realizan sobre éstos.Para el cubo necesitaremos como datos primordiales la longitud de su lado, elárea y su volumen. En el caso del prisma requerimos aún más datos, que son elancho, el alto, el espesor, el área y el volumen.Enseguida debemos pensar en las operaciones que se realizan sobre estos datos.El cubo es más sencillo de resolver, ya que solamente necesitamos dos métodos, unollamado CalculaArea() y el otro llamado CalculaVolumen(). Para comprender mejorlas clases y por motivos ilustrativos el prisma necesitará tres métodos. El primero sellamará CalculaArea(), el segundo CalculaVolumen() y el tercero AreaRectangulo().Como el área del prisma es igual a la suma de los rectángulos de sus caras nos apo-yaremos en este método para calcularla.

Podemos diagramar las clases si hacemos uso de UML. La clase del cubo quedarácomo se muestra en la siguiente figura:

Figura 1. Éste es el diagrama de clases para el cubo.

Podemos ver todos los elementos que lo conforman.

Cubo

+ lado: int

+ área: int

+ volumen: int

+ CalculaArea() : void

+ CalculaVolumen() : void

La programación orientada a objetos

321www.redusers.com

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 321

Page 324: C# aprenda a programar

De igual forma es posible crear el diagrama de clases correspondiente al prisma:

Figura 2. Esta figura nos muestra

el diagrama de clases para el prisma.

Los diagramas anteriores se pueden leer fácilmente. Hay un rectángulo que re-presenta a la clase. El rectángulo está dividido en tres secciones. La sección supe-rior, que es utilizada para colocar el nombre de la clase, la sección intermedia, quese usa para indicar los datos que tendrá la clase y la sección inferior, que es paraindicar cuáles son los métodos a utilizar.El acceso se muestra por medio de los signos + o -. Cuando usamos el signo más es-tamos indicando que ese dato o método tiene un acceso del tipo público. En el ca-so de que coloquemos el signo menos, el acceso es del tipo privado.El formato de los datos lleva primero el acceso seguido del nombre del dato. Lue-go se coloca : y el tipo que tiene este dato. El tipo puede ser nativo o definido porel programador. En el caso de los métodos, primero indicamos el acceso seguido delnombre del método. Como ninguno de nuestros métodos necesita parámetros, en-tonces los dejamos vacíos. El tipo del método, es decir el tipo de valor que regresa,se indica por medio de : seguido del tipo. En nuestro ejemplo hasta el momentoningún método regresa algo, por lo que todos son de tipo void.Ahora podemos comenzar a declarar nuestras clases:

Prisma

+ alto: int

+ ancho: int

+ área: int

+ espesor: int

+ volumen: int

+ CalculaArea() : void

+ CalculaVolumen() : void

- AreaRectangulo(): void

10. CÓMO CREAR NUESTRAS PROPIAS CLASES

322 www.redusers.com

UML es un lenguaje unificado de modelado, un lenguaje visual que nos sirve para llevar a cabo

diagramas y modelado de sistemas. Resulta muy útil en la programación y el diseño orientado a

objetos, ya que facilita el diseño y la depuración de la aplicación aun antes de que se escriba una

línea de código. Es recomendable buscar información adicional sobre éste y aprenderlo.

EL USO DE UML

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 322

Page 325: C# aprenda a programar

class cubo{

// Declaramos los datospublic int lado;public int area;public int volumen;

}

class prisma{

// Declaramos los datospublic int ancho;public int alto;public int espesor;public int area;public int volumen;

}

Como podemos observar, declaramos dos clases. En cada una hemos declarado losdatos que le corresponden. La declaración de los datos es muy similar a la declara-ción de variables, y si prestamos atención, podemos notar que ambas clases tienennombres que se repiten en sus datos como area y volumen. Esto es posible porquecada clase es una entidad diferente, y estos nombres nunca se confundirán entre sí.Continuemos con nuestra clase cubo. Ahora lo que necesitamos hacer es colocar losmétodos de la clase. Las operaciones son muy sencillas. Nuestra clase cubo queda-rá como se muestra en el siguiente bloque de código:

class cubo{

// Declaramos los datospublic int lado;public int area;public int volumen;

// Método para calcular el áreapublic void CalculaArea(){

area = (lado * lado) * 6;}

La programación orientada a objetos

323www.redusers.com

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 323

Page 326: C# aprenda a programar

// Método para calcular el volumenpublic void CalculaVolumen(){

volumen = lado * lado * lado;}

}

La declaración de los métodos se hace adentro del bloque de código de la clase y cadauno de ellos tiene su propio bloque de código. Como podemos observar, usan los da-tos directamente. Esto se debe a que cualquier dato declarado en la clase es conocidopor todos los métodos de esa clase. Más adelante continuaremos con la clase prisma.

Cómo crear la instancia de nuestra claseYa tenemos la clase cubo que es el plano donde se indica qué datos tiene y qué in-formación utilizará con ellos. Ahora tenemos que construir el objeto, que es quienllevará a cabo el trabajo en realidad. Para instanciar un objeto de la clase cubo de-bemos utilizar el código que se muestra a continuación:

cubo miCubo = new cubo();

Quien realiza realmente la instanciación es new y esa instancia queda referenciadacomo miCubo. A partir de miCubo podremos empezar a trabajar con él.

Cómo asignarles valores a datos publicosComo ya tenemos la instancia, ya podemos comenzar a trabajar con ella. Lo pri-mero que haremos será asignarle un valor al dato lado. Haremos la asignaciónpor medio del operador de asignación = (igual), pero también deberemos indi-car a cuál de todos los datos de la clase vamos a acceder. Esto lo hacemos con el

10. CÓMO CREAR NUESTRAS PROPIAS CLASES

324 www.redusers.com

El acceso privado es utilizado cuando hacemos uso de la herencia. Si declaramos un dato como

protegido, la propia clase y las clases que hereden de ellas podrán acceder a él, leerlo y

modificarlo. Todas las demás clases lo verán como si su acceso fuera privado y no podrán

acceder a él directamente.

EL ACCESO PROTEGIDO

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 324

Page 327: C# aprenda a programar

operador punto. Por ejemplo, asignemos el valor de 5 al lado, realizando esto co-mo vemos en el código a continuación:

miCubo.lado = 5;

Cómo invocar métodos de un objetoCuando invocamos el método de un objeto, éste ejecuta el código que tiene ensu interior. Desde el exterior de la clase solamente podemos invocar métodos quesean públicos. La invocación del método es muy similar a lo que aprendimos enel Capítulo 3, con todos los casos que vimos. En este caso sólo tenemos que in-dicar con qué objetos trabajaremos, seguido el operador . y el nombre del méto-do con sus parámetros, si los necesita.Invoquemos los métodos para calcular el área y el volumen del cubo:

// Invocamos los métodosmiCubo.CalculaArea();miCubo.CalculaVolumen();

Cómo imprimir un dato públicoComo ya tenemos los valores calculados, ahora los podemos mostrar. Para esto losusaremos como cualquier variable normal, pero debemos indicar el objeto con elque trabajamos, seguido del operador . y en nombre del dato.

// Desplegamos los datosConsole.WriteLine(“Area={0}, Volumen={1}”, miCubo.area,

miCubo.volumen);

Nuestro programa queda de la siguiente manera:

class cubo{

// Declaramos los datospublic int lado;public int area;public int volumen;

La programación orientada a objetos

325www.redusers.com

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 325

Page 328: C# aprenda a programar

// Método para calcular el áreapublic void CalculaArea(){

area = (lado * lado) * 6;}

// Método para calcular el volumenpublic void CalculaVolumen(){

volumen = lado * lado * lado;}

}

class prisma{

// Declaramos los datospublic int ancho;public int alto;public int espesor;public int area;public int volumen;

}

class Program{

static void Main(string[] args){

// Instanciamos a la clase cubocubo miCubo = new cubo();

// Asignamos el valor del ladomiCubo.lado = 5;

// Invocamos los métodosmiCubo.CalculaArea();miCubo.CalculaVolumen();

// Desplegamos los datosConsole.WriteLine(“Area={0}, Volumen={1}”, miCubo.area,

miCubo.volumen);

10. CÓMO CREAR NUESTRAS PROPIAS CLASES

326 www.redusers.com

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 326

Page 329: C# aprenda a programar

}}

Si ejecutamos el programa obtendremos lo siguiente:

Figura 3. Vemos el resultado de la ejecución de nuestro programa.

Una de las ventajas que tiene la programación orientada a objetos es la reutilizaciónde código. Si necesitáramos dos cubos o más, simplemente creamos nuevas instan-cias. Cada una de ellas tendría en su interior sus propias variables y podría llevar acabo los cálculos que fueran necesarios. Por ejemplo, modifiquemos el programa para que se tengan dos cubos. El segundocubo estará en la instancia tuCubo y tendrá un valor de lado de 8.

static void Main(string[] args){

// Instanciamos a la clase cubocubo miCubo = new cubo();cubo tuCubo = new cubo();

La programación orientada a objetos

327www.redusers.com

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 327

Page 330: C# aprenda a programar

// Asignamos el valor del ladomiCubo.lado = 5;tuCubo.lado = 8;

// Invocamos los métodosmiCubo.CalculaArea();miCubo.CalculaVolumen();tuCubo.CalculaArea();tuCubo.CalculaVolumen();

// Desplegamos los datosConsole.WriteLine(“Mi cubo Area={0}, Volumen={1}”,

miCubo.area, miCubo.volumen);Console.WriteLine(“Tu cubo Area={0}, Volumen={1}”,

tuCubo.area, tuCubo.volumen);}

Este cambio solamente fue necesario en Main(), ya que todo el comportamiento quenecesitamos se encuentra en la clase. Ejecutemos el programa y veamos el resultado.

Figura 4. Aquí observamos los resultados calculados por ambas instancias.

10. CÓMO CREAR NUESTRAS PROPIAS CLASES

328 www.redusers.com

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 328

Page 331: C# aprenda a programar

Protección de datos y creación de propiedadesCon la clase cubo hemos visto cómo crear una clase sencilla que ya tiene funciona-lidad. Sin embargo, presenta un problema. El primero es que todos sus datos sonpúblicos, lo que nos puede llevar a corrupción de información. Para proteger los da-tos tenemos que hacerlos privados y proveer una función de interfaz a aquellos a losque se necesita acceder por el exterior.Para tener una comparación, trabajaremos sobre nuestra clase prisma. Lo primeroque hacemos es cambiar el acceso de los datos a privado.

class prisma{

// Declaramos los datosprivate int ancho;private int alto;private int espesor;private int area;private int volumen;

}

Las propiedades son funciones de interfaz. Nos permiten acceder a los datos priva-dos de una manera segura y controlada, pero van más allá de simples funciones yaque también nos brindan una forma de acceso intuitiva y sencilla.La propiedad puede ser de varios tipos: lectura, escritura y la combinación de am-bas(lectura-escritura). Una propiedad de lectura solamente nos permite leer el da-to, pero no podemos agregarle información. Una propiedad que es de tipo escritu-ra sólo nos permite colocar información en el dato, pero no podemos leerlo. La pro-piedad de lectura-escritura permite llevar a cabo ambas acciones.Para lograr esto, la propiedad tendrá dos métodos. El método relacionado con lalectura se conoce como get y el relacionado con la escritura es set. Dependien-do de cuál método coloquemos en la propiedad, será su tipo.La propiedad de éste tiene la siguiente forma de declaración:

public tipo nombre {

get{……return x;

La programación orientada a objetos

329www.redusers.com

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 329

Page 332: C# aprenda a programar

}

set{……x=value;}

}

Las propiedades son públicas para poder llamarlas desde el exterior de la clase. Eltipo está referenciado al tipo del valor que leerá o colocará, ya sea entero, flotante,doble, etcétera. En su interior tenemos get, donde colocamos el código para sacarun valor de la clase por medio de return, y a set, donde ponemos el código nece-sario para introducir un valor en la clase.Empecemos por crear propiedades para la clase prisma. Lo primero que tenemosque preguntarnos es a qué datos se necesita acceder por el exterior y qué tipo de ac-ceso requieren. Podemos ver que los datos ancho, alto y espesor necesitarán de es-critura, pero también de lectura. Esto es en caso de que necesitemos saber las di-mensiones. A sus propiedades las llamaremos: Ancho, Alto y Espesor.Los otros datos que necesitan tener una propiedad son area y volumen, pero en es-te caso solamente necesitamos leerlos. No tiene sentido escribir sobre esos datos, yaque la clase calculará sus propios valores.Ahora que ya sabemos cuáles son las propiedades necesarias podemos decidir si esnecesario algún tipo de validación. Sabemos que no podemos tener prismas concualquiera de sus lados con valor de 0 o negativos y ése es un buen punto para va-lidar. Si el usuario diera un valor incorrecto, entonces colocaremos por default elvalor 1. Hay que recordar que esto lo hacemos como ejemplo y cada aplicación pue-de tener sus propias reglas de validación para la información.Cuando usemos el método set tendremos una variable previamente definida por ellenguaje que se llama value. Esta variable representa el valor que el usuario asigna ypodemos usarlo en la lógica que necesitemos.

Nuestras propiedades de lectura y escritura quedan de la siguiente forma:

// Definimos las propiedadespublic int Ancho{

10. CÓMO CREAR NUESTRAS PROPIAS CLASES

330 www.redusers.com

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 330

Page 333: C# aprenda a programar

get {

return ancho;}

set{

if (value <= 0)ancho = 1;

elseancho = value;

}

}

public int Alto{

get{

return alto;}

set{

if (value <= 0)alto = 1;

elsealto = value;

}

La programación orientada a objetos

331www.redusers.com

En ocasiones, dentro de los métodos get y set de la propiedad, tendremos un return o una

asignación. Aunque esto es correcto, no debemos olvidar que en las propiedades podemos

colocar cualquier lógica válida de C# que nos permita validar la información que sale o entra. Esto

hará que nuestro código sea más seguro y evitaremos problemas con nuestra información.

EL USO DE LAS PROPIEDADES

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 331

Page 334: C# aprenda a programar

10. CÓMO CREAR NUESTRAS PROPIAS CLASES

332

}

public int Espesor{

get{

return espesor;}

set{

if (value <= 0)espesor = 1;

elseespesor = value;

}

}

Ahora crearemos las propiedades de sólo lectura para el área y el volumen:

public int Area{

get{

return area;}

}

public int Volumen{

get{

return volumen;}

}

Como estas propiedades son de sólo lectura únicamente llevan el método get.

www.redusers.com

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 332

Page 335: C# aprenda a programar

Cómo acceder a las propiedadesAcceder a las propiedades es muy sencillo ya que únicamente necesitamos colocarel objeto con el que queremos trabajar seguido del operador . y el nombre de la pro-piedad. La asignación se lleva a cabo por medio del operador =.Por ejemplo, si deseamos indicar que el ancho tiene 5 unidades, hacemos lo siguiente:

miPrisma.Ancho=5;

Y si deseamos imprimir el valor de la propiedad Volumen:

Console.WriteLine(“El volumen es {0}”,Volumen);

Métodos públicos y privadosComo mencionamos anteriormente, los métodos pueden ser públicos o privados.Los primeros pueden ser invocados desde el exterior del objeto y los privados sola-mente desde su interior. Al programar la única diferencia es el tipo de acceso quecolocamos. En nuestro ejemplo necesitamos dos métodos públicos para invocar alcálculo del área y el volumen, y un método privado que nos apoyará en el cálculodel área. Veamos cómo programarlos:

public void CalculaVolumen(){

volumen = ancho * alto * espesor;}

public void CalculaArea(){

int a1 = 0, a2 = 0, a3 = 0;

a1 = 2 * CalculaRectangulo(ancho, alto);a2 = 2 * CalculaRectangulo(ancho, espesor);a3 = 2 * CalculaRectangulo(alto, espesor);

area = a1 + a2 + a3;}

private int CalculaRectangulo(int a, int b)

La programación orientada a objetos

333www.redusers.com

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 333

Page 336: C# aprenda a programar

{return (a * b);

}

Los métodos son muy sencillos, lo importante es notar que el método CalculaRec-tangulo() tiene acceso privado, por lo que nadie del exterior puede invocarlo. Sinembargo, CalculaArea() lo invoca sin problemas ya que pertenece a la misma clase.

Convertir un objeto a cadenaTenemos varias opciones para imprimir la información que guarda un objeto enla consola. La primera consiste en leer la propiedad e imprimir de la forma tradi-cional. Otra opción puede ser crear un método dentro del objeto que se especiali-ce en la impresión de la información. Esto puede ser útil si deseamos imprimir tansolo uno o algunos datos.La última opción y la que aprenderemos a usar es la de programar el método ToString()para la clase. Esto ya lo hemos hecho en el capítulo anterior para las estructuras. El me-canismo es similar, simplemente tenemos que implementar una versión del métodoToString() para nuestra clase. Este método regresa una cadena que contiene la infor-mación en el formato que deseamos y tampoco necesita recibir ningún parámetro.Este método se implementa adentro de la clase y cada clase en la aplicación lo pue-de tener de ser necesario. Entonces, cuando necesitemos imprimir los contenidosdel objeto simplemente lo invocaremos e imprimiremos la cadena resultante. El mé-todo debe tener acceso público ya que es necesario que el exterior pueda invocarlo.

En nuestro caso, el método quedaría de la siguiente manera:

public override string ToString(){

String mensaje = “”;mensaje += “Ancho “ + ancho.ToString() + “ Alto “ +

alto.ToString() + “ Espesor “ + espesor.ToString();mensaje += “ Area “ + area.ToString() + “ Volumen “ +

volumen.ToString();return mensaje;

}

En este ejemplo hacemos uso de la concatenación para poder generar la cadena queel método regresará. Hacemos esto para comparar con el uso de StringBuilder, que se

10. CÓMO CREAR NUESTRAS PROPIAS CLASES

334 www.redusers.com

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 334

Page 337: C# aprenda a programar

ha utilizado en el capítulo donde hablamos de las estructuras. La concatenación sue-le utilizarse para agrupar registros obtenidos de una base de datos. Podemos hacer usode cualquiera de estos métodos según necesitemos de ellos. La impresión de los con-tenidos del objeto apoyándonos en este método puede ser de la siguiente forma:

Console.WriteLine(miPrisma.ToString());

Si lo deseamos, podemos probar a éste en nuestro programa, y ver que obten-dremos el resultado de la siguiente figura:

Figura 5. Podemos observar cómo hemos impreso

los contenidos del objeto apoyándonos en el método ToString().

Para imprimir solamente algunos datos

Si solamente necesitamos imprimir algunos datos, entonces es necesario crear unmétodo especializado para ello. Este método deberá tener acceso público paraque pueda ser invocado desde el exterior, y en el caso de llegar a necesitarlo, pue-de prepararse el método para recibir parámetros, aunque esto no es necesario.Supongamos que deseamos tener disponible un método que sólo imprima los re-sultados para el área y el volumen.

La programación orientada a objetos

335www.redusers.com

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 335

Page 338: C# aprenda a programar

El trozo de código para ello, es el que mostramos el el siguiente bloque:

public void ImprimeResultado(){

Console.WriteLine(“El área es {0}, el volumen es {1}”, area, volumen);

}

Como observamos, el código del método es muy sencillo. Igualmente podemos pro-barlo en nuestra aplicación y obtener el siguiente resultado en la consola.

Figura 6. Ahora podemos comparar la impresión

con la ayuda de ToString() y del método especializado.

El constructor en las clasesEl constructor es un método especial que podemos utilizar con las clases. Éste ge-neralmente es usado para inicializar los valores de los datos con los que trabajará elobjeto. La forma como lo utilizamos con las clases es equivalente a la forma comolo utilizamos con las estructuras en el capítulo anterior. El constructor es un méto-do especial y tiene ciertas características que lo distinguen de los demás métodos.

10. CÓMO CREAR NUESTRAS PROPIAS CLASES

336 www.redusers.com

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 336

Page 339: C# aprenda a programar

Su primera característica es que tiene el mismo nombre de la clase y su segunda ca-racterística más importante es que no tiene tipo, es decir, que no solamente no re-gresa nada, sino que no tiene tipo alguno. El constructor es invocado en forma automática cuando el objeto es instanciado, yaque esto nos da la oportunidad de llevar a cabo cosas en el instante que se instan-cia el objeto, como por ejemplo, hacer inicializaciones. El constructor puede teneren su interior cualquier código válido de C# y también puede tener parámetros ono. Si utilizamos los parámetros tendremos que pasar los valores necesarios en elmomento en el que instanciamos el objeto. Veamos un ejemplo de constructor para nuestra clase prisma. En este constructorno utilizaremos parámetros, veamos el siguiente ejemplo:

public prisma(){

// Datos necesariosString valor=””;

// Pedimos los datosConsole.WriteLine(“Dame el ancho”);valor=Console.ReadLine();ancho=Convert.ToInt32(valor);

Console.WriteLine(“Dame el alto”);valor=Console.ReadLine();alto=Convert.ToInt32(valor);

Console.WriteLine(“Dame el espesor”);valor=Console.ReadLine();espesor=Convert.ToInt32(valor);

}

La programación orientada a objetos

337www.redusers.com

Mucha gente confunde el constructor y cree erróneamente que es el encargado de construir el

objeto. Esto es falso. El constructor no se encarga de instanciar el objeto, sólo se invoca en forma

automática en el momento en que el objeto se instancia. No debemos tener esta confusión.

NO HAY QUE CONFUNDIR EL CONSTRUCTOR

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 337

Page 340: C# aprenda a programar

Como podemos observar dentro del ejemplo, el constructor tiene acceso de tipopúblico. Esto es importante, ya que como se invoca automáticamente, el exte-rior necesitará tener acceso a él.El constructor se encargará de solicitarle al usuario los datos necesarios. Cuando lle-vemos a cabo la instanciación, será de la siguiente forma:

prisma miPrisma = new prisma();

Si compilamos el programa, obtendremos el siguiente resultado:

Figura 7. Podemos observar cómo se ejecuta

el constructor y nos solicita los datos necesarios.

10. CÓMO CREAR NUESTRAS PROPIAS CLASES

338 www.redusers.com

En las técnicas avanzadas de programación, como por ejemplo la programación de patrones,

podemos encontrar constructores privados. Uno de los patrones que lo utilizan se conoce

como singleton. Generalmente, haremos uso de constructores públicos hasta que

aprendamos este tipo de técnicas avanzadas.

CONSTRUCTORES PRIVADOS

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 338

Page 341: C# aprenda a programar

Sobrecarga del constructorEl constructor puede ser sobrecargado, es decir, podemos tener más de una versióndel constructor. Esto resulta útil ya que podemos seleccionar cómo se inicializaránlos datos del objeto dependiendo del tipo de constructor que utilicemos.El compilador seleccionará automáticamente el tipo de constructor dependiendode los tipos y la cantidad de parámetros.Ya tenemos un constructor que nos pide directamente los datos, pero ahora pode-mos hacer un constructor que recibe los valores con los que se inicializará el prismaen el momento de la instanciación. Para esto tenemos que colocar parámetros en lasegunda versión del constructor.

public prisma(int pancho, int palto, int pespesor){

// Asignamos los valoresancho=pancho;alto=palto;espesor=pespesor;

}

Cuando instanciemos el objeto con este constructor, lo usaremos así:

prisma miPrisma3 = new prisma(5,3,7);

Observemos cómo los valores fueron pasados al momento de la instanciación. Elvalor 5 será colocado en el dato ancho, 3 en el dato alto y 7 en el dato espesor.Si tenemos el dato contenido en una variable, también es posible utilizarla cuandoinstanciamos el objeto. Solamente debemos asegurarnos de que el tipo de la varia-ble sea el mismo que el tipo del parámetro que colocamos. Si no fueran del mismotipo, lo recomendable es utilizar type cast. Supongamos que tenemos lo siguiente:

int miNumero=11;……prisma miPrisma4 = new prisma(5,3,miNumero);

Como vemos, pasamos una copia del valor de miNumero y ahora en el interior delobjeto miPrimsa4 en dato espesor tendrá el valor de 11.

La programación orientada a objetos

339www.redusers.com

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 339

Page 342: C# aprenda a programar

Podemos continuar llevando a cabo más sobrecargas del constructor, tantas comosean necesarias. La cantidad de sobrecargas dependerá del análisis y las necesidadesdel programa. No debemos exagerar en las sobrecargas, debemos colocar solamen-te aquellas que sean realmente necesarias.

El programa completo que tenemos luce de la siguiente manera:

class cubo{

// Declaramos los datospublic int lado;public int area;public int volumen;

// Método para calcular el áreapublic void CalculaArea(){

area = (lado * lado) * 6;}

// Método para calcular el volumenpublic void CalculaVolumen(){

volumen = lado * lado * lado;}

}

class prisma{

// Declaramos los datosprivate int ancho;private int alto;private int espesor;private int area;private int volumen;

// Definimos las propiedadespublic int Ancho{

get

10. CÓMO CREAR NUESTRAS PROPIAS CLASES

340 www.redusers.com

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 340

Page 343: C# aprenda a programar

{return ancho;

}

set{

if (value <= 0)ancho = 1;

elseancho = value;

}

}

public int Alto{

get{

return alto;}

set{

if (value <= 0)alto = 1;

elsealto = value;

}

}

public int Espesor{

get{

return espesor;}

La programación orientada a objetos

341www.redusers.com

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 341

Page 344: C# aprenda a programar

set{

if (value <= 0)espesor = 1;

elseespesor = value;

}

}

public int Area{

get{

return area;}

}

public int Volumen{

get{

return volumen;}

}

// Definimos los constructores

public prisma(){

10. CÓMO CREAR NUESTRAS PROPIAS CLASES

342 www.redusers.com

Las propiedades pueden tener cualquier nombre válido de C#. El nombre de las propiedades

debe reflejar de alguna forma el tipo de dato sobre el cual actúa. Si nuestro dato es costo,

entonces la propiedad se puede llamar Costo. El dato y la propiedad no pueden tener el mismo

nombre, pero recordemos que C# distingue entre mayúsculas y minúsculas.

LOS NOMBRES DE LAS PROPIEDADES

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 342

Page 345: C# aprenda a programar

// Datos necesariosString valor = “”;

// Pedimos los datosConsole.WriteLine(“Dame el ancho”);valor = Console.ReadLine();ancho = Convert.ToInt32(valor);

Console.WriteLine(“Dame el alto”);valor = Console.ReadLine();alto = Convert.ToInt32(valor);

Console.WriteLine(“Dame el espesor”);valor = Console.ReadLine();espesor = Convert.ToInt32(valor);

}

// Version sobrecargadapublic prisma(int pancho, int palto, int pespesor){

// Asignamos los valoresancho = pancho;alto = palto;espesor = pespesor;

}

// Definimos los métodos

La programación orientada a objetos

343www.redusers.com

Tenemos que decidir oportunamente el tipo de acceso que permitirá la propiedad. Si tratamos

de asignarle un valor a una propiedad de sólo lectura, el compilador nos indicará un error. Lo

mismo sucede si tratamos de leer una propiedad de sólo escritura. Por eso lo mejor es planificar

durante la etapa de análisis el acceso que les colocaremos a las propiedades de nuestra clase.

PROBLEMAS CON LAS PROPIEDADES

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 343

Page 346: C# aprenda a programar

public void CalculaVolumen(){

volumen = ancho * alto * espesor;}

public void CalculaArea(){

int a1 = 0, a2 = 0, a3 = 0;

a1 = 2 * CalculaRectangulo(ancho, alto);a2 = 2 * CalculaRectangulo(ancho, espesor);a3 = 2 * CalculaRectangulo(alto, espesor);

area = a1 + a2 + a3;}

private int CalculaRectangulo(int a, int b){

return (a * b);}

public override string ToString(){

String mensaje = “”;mensaje += “Ancho “ + ancho.ToString() + “ Alto “ +

alto.ToString() + “ Espesor “ + espesor.ToString();mensaje += “ Area “ + area.ToString() + “ Volumen “ +

volumen.ToString();return mensaje;

}

public void ImprimeResultado(){

Console.WriteLine(“El área es {0}, el volumen es {1}”, area, volumen);

}

}

class Program

10. CÓMO CREAR NUESTRAS PROPIAS CLASES

344 www.redusers.com

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 344

Page 347: C# aprenda a programar

{static void Main(string[] args){

// Instanciamos a la clase cubocubo miCubo = new cubo();cubo tuCubo = new cubo();

// Instanciamos el prismaprisma miPrisma = new prisma();

// Instanciamos con la versión sobrecargadaprisma miPrisma2 = new prisma(3, 5, 7);

// Asignamos el valor del ladomiCubo.lado = 5;tuCubo.lado = 8;

// Invocamos los métodosmiCubo.CalculaArea();miCubo.CalculaVolumen();tuCubo.CalculaArea();tuCubo.CalculaVolumen();

// Asignamos los valores al prisma// Quitar comentarios para versión sin constructor//miPrisma.Ancho = 10;//miPrisma.Alto = 3;//miPrisma.Espesor = 5;

// Invocamos los métodos del prismamiPrisma.CalculaArea();

La programación orientada a objetos

345www.redusers.com

Como siempre, podemos consultar MSDN para conocer más sobre los elementos que

aprendemos en este libro. Si deseamos conocer más sobre las clases en C# podemos consultar

el sitio web de Microsoft para interiorizarnos o profundizar conocimientos en el tema:

http://msdn2.microsoft.com/es-es/library/0b0thckt(VS.80).aspx.

APRENDER MÁS SOBRE LAS CLASES

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 345

Page 348: C# aprenda a programar

miPrisma.CalculaVolumen();

miPrisma2.CalculaArea();miPrisma2.CalculaVolumen();

// Desplegamos los datosConsole.WriteLine(“Mi cubo Area={0}, Volumen={1}”,

miCubo.area, miCubo.volumen);Console.WriteLine(“Tu cubo Area={0}, Volumen={1}”,

tuCubo.area, tuCubo.volumen);Console.WriteLine(miPrisma.ToString());miPrisma.ImprimeResultado();

Console.WriteLine(miPrisma2.ToString());}

}

Hemos escrito bastante código para el funcionamiento de esta aplicación. Ejecute-mos el programa y nuestro resultado es el siguiente:

Figura 8. Cada objeto usa el constructor que le corresponde.

10. CÓMO CREAR NUESTRAS PROPIAS CLASES

346 www.redusers.com

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 346

Page 349: C# aprenda a programar

Si revisamos el código que hemos presentado en el bloque anterior, podemos dar-nos cuenta del funcionamiento de las sobrecargas del constructor que hemos agre-gado, es importante reafirmar la idea que ya explicábamos en en párrafos anterio-res, tenemos la posibilidad de agregar cuantas sobrecargas sean necesarias pero siem-re debemos tener en cuenta la necesidad de no exagerar.

A través de este capítulo hemos analizado la importancia del uso de clases para la ge-neración de nuestros programas, utilizando C#. Con esto hemos visto el inicio de loselementos para programar clases. Aún queda mucho por aprender sobre la progra-mación orientada a objetos y su programación en C#, pero éstos serán temas de unlibro más avanzado y especializado en la programación del experto en el lenguaje C#.

La programación orientada a objetos

347www.redusers.com

… RESUMEN

La programación orientada a objetos es un paradigma de programación diferente a la

programación estructurada. Tenemos que reconocer los objetos que componen el sistema así

como la comunicación que tienen entre ellos. La clase es el elemento fundamental de este

tipo de programación y actúa como el plano sobre el que los objetos son construidos. Los

objetos o las instancias son los que realmente llevan a cabo el trabajo. Los datos y los

métodos pueden tener diferentes tipos de acceso: público, privado o protegido. Las

propiedades nos sirven como funciones de interfaz para poder acceder a los datos privados de

forma segura. Las clases pueden tener un constructor que nos ayuda a inicializar la

información. Es posible hacer uso de la sobrecarga en el constructor.

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 347

Page 350: C# aprenda a programar

348 www.redusers.com

TEST DE AUTOEVALUACIÓN

1 ¿Qué es la programación orientada a

objetos?

2 ¿Cómo definimos una clase?

3 ¿Cuál es la función de un objeto?

4 ¿Cómo se lleva acabo la instanciación de

un objeto?

5 ¿Qué es el acceso público?

6 ¿Cuál es el riesgo de corrupción de

información?

7 ¿Para qué sirve una propiedad?

8 ¿Cuáles son los diferentes tipos de

propiedades?

9 ¿Cómo se crean los métodos en una

clase?

10¿Cómo se invoca un método?

11¿Qué es el constructor?

12¿Cómo se sobrecarga el constructor?

ACTIVIDADES

EJERCICIOS PRÁCTICOS

1 Crear el diseño de una clase para llevar

el inventario de una tienda.

2 Crear una clase para llevar la

información de los estudiantes de una

escuela.

3 Crear una clase para polígonos con

sobrecarga del constructor.

4 Crear propiedades para la clase polígono

que solamente permitan colocar valores

válidos.

5 Programar el método ToString() para la

clase polígono.

10_C#2010_AJUSTADO.qxd 8/6/10 8:38 PM Page 348

Page 351: C# aprenda a programar

Flujos y

archivos

Los flujos 350Los stream en la memoria 351El uso de archivos 363

Resumen 371Actividades 372

Capítulo 11

A lo largo del libro hemos realizado

muchos programas, y cada vez que usamos

un programa, debemos introducirle

información. Esto no ha sido un gran

problema en los ejemplos realizados hasta

aquí, porque generalmente manipulamos

pocos datos. Sin embargo, en muchas

aplicaciones reales necesitaremos tener

alguna metodología para poder guardar

la información y recuperarla cuando

la aplicación se ejecute nuevamente.

Para resolver esto, tenemos acceso

a los archivos y los flujos.

C#

SERVICIO DE ATENCIÓN AL LECTOR: [email protected]

11_C#2010.qxd 8/11/10 10:03 AM Page 349

Page 352: C# aprenda a programar

LOS FLUJOS

Los flujos también son conocidos como streams por su nombre en inglés. Se losllama de esta forma porque nos recuerdan como fluye el agua, pero en este caso setratará de flujos de información. El stream es utilizado para poder mover informa-ción de un lugar a otro. A veces, moveremos la información de la memoria a otraparte de la memoria, pero generalmente lo que haremos será mover la informaciónde la memoria a un dispositivo de almacenamiento como el disco duro o del dis-positivo nuevamente a la memoria.Cuando hacemos uso de los flujos, la información no es enviada en un solo movi-miento, sino que se envía byte por byte de forma ordenada. Como el envío es de es-ta forma, tenemos que tener cuidado sobre qué byte procesamos en ese momento.

Figura 1. Los flujos nos permiten mover

la información de un lugar a otro de la memoria, byte por byte.

Para poder tener control sobre el byte a enviar, imaginaremos que tenemos un apun-tador o indicador en nuestro flujo. Este indicador siempre nos señala cuál es el si-guiente byte a enviar. Cada vez que enviamos un byte a su nuevo lugar por mediodel flujo, el indicador se actualiza y nos señala el siguiente byte. Esta forma de tra-bajo funciona muy bien si el envío de datos es secuencial, pero también debemostener un mecanismo que nos permita seleccionar a nosotros mismos el byte a en-viar. Para hacer esto tenemos que indicar de alguna manera el byte y esto solamen-te lo podemos llevar a cabo si tenemos un punto de referencia dentro del flujo.En el flujo encontramos tres puntos de referencia. El primero es el inicio del flujo.Si queremos colocarnos en un byte en particular para enviar, simplemente tenemosque decir a cuántos bytes de distancia desde el inicio se encuentra el byte que de-seamos procesar. El segundo punto de referencia será el final del flujo. De manerasimilar tenemos que decir a cuántos bytes de distancia se encuentra el byte a proce-sar desde el final del flujo. El tercer punto de referencia es la posición actual den-tro del flujo, de igual forma a los casos anteriores, debemos dar la distancia desdenuestra posición actual al byte que nos interesa procesar. En todos los casos, estebyte se volverá nuestro nuevo byte actual.

H

H

O

O

L

L

A

A

H O L A

11. FLUJOS Y ARCHIVOS

350 www.redusers.com

11_C#2010.qxd 8/6/10 8:39 PM Page 350

Page 353: C# aprenda a programar

Figura 2. Aquí vemos cómo un mismo byte

del stream puede estar referenciado de formas diferentes.

Los stream en la memoriaEmpecemos a trabajar con el stream. Éste simplemente llevará la información de unlugar a otro. La forma más sencilla de aprenderlo es haciendo streams en memoria.Aquí veremos las operaciones básicas que podemos realizar con ellos y después esteconocimiento puede ser llevado a streams que se comuniquen con dispositivos dealmacenamiento masivo como discos duros.Para trabajar con streams en la memoria nos apoyaremos de una clase conocida co-mo MemoryStream. Cuando necesitemos usar esta clase debemos agregar el names-pace al que pertenece. Para esto colocamos el siguiente código en la parte superiorde nuestro programa, antes de las declaraciones de las clases.

// Adicionamos para el uso de los streamusing System.IO;

Esta clase crea un stream, pero el lugar donde guarda la información es un sitio enmemoria. La información es guardada como un arreglo de bytes sin signo. La cla-se MemoryStream tiene sobrecargado su constructor y seguramente podemos en-contrar una versión de acuerdo con nuestras necesidades.El constructor puede cre-ar el arreglo en la memoria vacío o puede inicializarlo a un tamaño en particular.Hay que recordar que el tamaño está en bytes.

Desde inicio

Desde final

Desde posición actual

Los flujos

351www.redusers.com

Como hemos visto, para seleccionar un byte dentro del flujo debemos indicar su distancia desde

el punto de referencia. Si es el mismo punto de referencia el que deseamos enviar, la distancia

será cero. Las distancias se miden de izquierda a derecha, y negativas de derecha a izquierda.

Por ello cuando usamos como referencia el final del flujo las distancias llevan el signo menos.

DISTANCIAS EN LOS FLUJOS

11_C#2010.qxd 8/6/10 8:39 PM Page 351

Page 354: C# aprenda a programar

Nosotros usaremos la versión en la que podemos indicar el tamaño inicial del arre-glo y para instanciar MemoryStream podemos hacerlo de la siguiente manera:

// Creamos el stream en memory// La iniciamos con una capacidad de 50 bytesMemoryStream ms = new MemoryStream(50);

El objeto se llama ms, pero puede tener cualquier nombre válido de C#. El tamañoinicial que le asignamos es 50 bytes.

Cómo obtener información sobre el streamNosotros podemos obtener ciertos datos sobre el stream. Estos datos nos puedenservir en la lógica de nuestro programa y resulta útil poder conocerlos. Los datosque podemos obtener son: la capacidad, la longitud y la posición.

Figura 3. En este diagrama podemos observar las tres propiedades del stream.

La capacidad nos indica cuántos bytes puede almacenar el stream. En el ejemplo an-terior es de 50, ya que le hemos colocado ese tamaño en su instanciación. El valorde la capacidad se guarda en la propiedad Capacity y ésta es de tipo entero. Si dese-amos obtener la capacidad lo podemos hacer de la siguiente forma:

int capacidad = 0;

Tamaño

Capacidad

P. Actual

H O L A A T O D O S

11. FLUJOS Y ARCHIVOS

352 www.redusers.com

Los streams en memoria que se inicializan con un arreglo de bytes sin signo no pueden

modificar su tamaño. Esto hace importante que seleccionemos adecuadamente el tamaño a

utilizar. Podemos hacer una estimación del tamaño máximo y colocarla en el constructor.

CUIDADO CON EL TAMAÑO

11_C#2010.qxd 8/6/10 8:39 PM Page 352

Page 355: C# aprenda a programar

...

...capacidad = ms.Capacity;

El siguiente dato que podemos obtener es la longitud. Ésta nos indica el tamañode la información actual que tiene el stream. El tamaño está dado en bytes. La pro-piedad relacionada con esta información es Length. Esta propiedad es de tipo long.A continuación veamos un ejemplo de cómo podemos obtener este dato:

long longitud = 0;......longitud = ms.Length;

Por último tenemos la posición. Este dato es sumamente importante ya que nos in-dica el lugar donde se encuentra el byte actual, es decir el siguiente a ser procesado.Esta posición está referenciada con relación al inicio del stream. La propiedad paraeste dato se llama Position y al igual que la anterior también es de tipo long. La for-ma de obtener estos datos es similar a las anteriores.

long posicion = 0;......posicion = ms.Position;

Cómo colocar la posición en el streamUna de las actividades más importantes y frecuentes que realizaremos con los stre-ams es colocar la posición actual en un sitio determinado. Para esto hacemos uso deun método conocido como Seek(). Éste necesita dos parámetros. El primero es ladistancia desde el punto de referencia donde quedará la nueva posición actual en elstream. El segundo indica el punto de referencia que utilizaremos.El punto de referencia tiene que ser de tipo SeekOrigin. Este tipo tiene tres valo-res posibles: Begin, Current y End. El valor Begin es usado para indicar que es-tamos referenciados con relación al origen del stream. Cuando se utiliza el valorCurrent nuestra posición actual será usada como punto de referencia. Si usamosEnd, la parte final del stream será el punto de referencia para encontrar nuestranueva posición. Por ejemplo, si deseamos colocarnos en el inicio del stream, po-demos hacerlo de la siguiente manera:

Los flujos

353www.redusers.com

11_C#2010.qxd 8/6/10 8:39 PM Page 353

Page 356: C# aprenda a programar

ms.Seek(0, SeekOrigin.Begin); // nos colocamos a 0 distancia desde el inicio

En este caso, indicamos que nos encontramos a 0 distancia desde el inicio del stre-am. Si lo que deseamos es encontrarnos a 10 bytes de distancia desde el inicio, laforma de usar Seek() es la siguiente:

ms.Seek(10, SeekOrigin.Begin);

Pero también podemos colocarnos desde otro punto de referencia. Por ejemplo, pa-ra colocarnos a 10 bytes de distancia desde el final del stream usaremos:

ms.Seek(-10, SeekOrigin.End);

Hay que observar que el valor usado es -10, ya que, como vimos anteriormente,en la plaqueta de la página 251, las distancias que se miden hacia la izquierda delpunto de referencia son negativas.

Por último, si lo que deseamos es movernos con relación a nuestra posición actual,por ejemplo avanzar 5 bytes, lo que usaremos es:

ms.Seek(5, SeekOrigin.Current);

Y si lo que deseamos es retroceder 10 bytes desde nuestra posición actual, usaremosel código que veremos a continuación:

ms.Seek(-10, SeekOrigin.Current);

11. FLUJOS Y ARCHIVOS

354 www.redusers.com

Si no utilizamos correctamente el método Seek(), tendremos problemas con nuestro programa.

Un problema común es tratar de colocar una posición actual que está antes del punto de inicio o

después del final del stream. Debemos tener lógica para evitar estas acciones, y para lograrlo,

tenemos que hacer uso de las propiedades del stream como posición, longitud y capacidad.

PROBLEMAS CON EL USO DE SEEK()

11_C#2010.qxd 8/6/10 8:39 PM Page 354

Page 357: C# aprenda a programar

Cómo leer datos del streamAhora que ya nos hemos posicionado en algún lugar en particular del stream, po-demos proceder a leer información, que se lee byte por byte. Cuando hacemos unalectura, el byte que se lee es el que se encuentra en la posición actual. Inmediatamen-te después de leer, la posición actual se actualiza y nuestra nueva posición actual serála del byte consecutivo al que acabamos de leer. Esta lectura se lleva a cabo de formaautomática y nosotros no la controlamos.Para realizar la lectura podemos usar el método Read(). Este método necesita tresparámetros. El primero es un arreglo de bytes. Este arreglo es necesario porque se-rá el lugar donde se guarde la información leída por el stream. El segundo nos da lacapacidad de colocar un offset para el arreglo de bytes. Generalmente usaremos elvalor cero en este parámetro, ya que queremos que la información leída se coloquedesde el inicio en el arreglo. El tercero es la cantidad de bytes a leer.El arreglo de bytes para guardar la información es colocado de la siguiente manera:

byte [] buffer=new byte[50];

En este caso lo llamamos búfer y tendrá capacidad para 50 bytes.

Supongamos que deseamos leer cinco bytes a partir de la posición actual donde nosencontramos. Para ello hacemos uso de Read() de la siguiente manera:

ms.Read(buffer, 0, 5);

Después de ejecutarse esta línea, buffer contendrá los cinco bytes leídos y los pode-mos encontrar al inicio de buffer.

Cómo escribir información el streamNo solamente es posible leer información del stream, también podemos agregarla oescribirla. Para esto tendremos un método especializado que se llama Write(). Para

Los flujos

355www.redusers.com

Es posible tener problemas con la lectura de un stream, como el olvidar crear el búfer. Otro

problema es tratar de leer de un stream que ya se cerró o no ha sido abierto. Un error menos

frecuente es dar un valor negativo en el segundo o tercer parámetro. Si los valores se controlan por

variables debemos colocar una lógica que impida poner valores inválidos en los parámetros.

EVITAR ERRORES CON LA LECTURA

11_C#2010.qxd 8/6/10 8:39 PM Page 355

Page 358: C# aprenda a programar

el uso de este método utilizaremos tres parámetros. En el primer parámetro tene-mos que colocar el búfer o el arreglo de bytes desde el que tomaremos la informa-ción para colocarla en el stream. El segundo parámetro es la posición en el streamdesde donde empezaremos a escribir. Generalmente utilizaremos el valor de cero, yde esta forma empezará a escribirse desde el inicio del stream. El último parámetroes la cantidad máxima de bytes que se escribirán.

Un ejemplo práctico de esto es el siguiente:

// Escribimos los datos en la cadenams.Write(miBuffer, 0, 15);

Cómo cerrar el streamAlgo que no debemos olvidar hacer es cerrar el stream. Cuando éste está cerrado,los recursos que se hayan necesitado se liberan. Si el stream está cerrado no es posi-ble llevar a cabo ningún tipo de operación sobre él. El cierre del stream se lleva acabo por medio del método Close(), que no necesita ningún parámetro. La formade utilizar el método se muestra a continuación:

ms.Close();

Programa de ejemploAhora podemos crear un pequeño programa de ejemplo que utilice lo que hemosrealizado con los streams. El programa será sencillo, ya que únicamente nos intere-sa conocer y experimentar con el código. Nuestro programa le pedirá al usuario unacadena que será colocada en el stream y luego podremos leer diferentes partes delstream con los métodos que hemos aprendido.Como siempre, tenemos que empezar por definir las variables que son necesarias.

// Creamos el stream en memory// La iniciamos con una capacidad de 50 bytesMemoryStream ms = new MemoryStream(50);

// Cadena con informaciónString informacion = “”;

// Variables necesariasint capacidad = 0;

11. FLUJOS Y ARCHIVOS

356 www.redusers.com

11_C#2010.qxd 8/6/10 8:39 PM Page 356

Page 359: C# aprenda a programar

long longitud = 0;long posicion = 0;byte [] buffer=new byte[50];

En primer lugar tenemos un objeto llamado ms que es de tipo MemoryStream y quepuede guardar hasta 50 bytes en su interior. Luego creamos la cadena que utiliza-remos para guardar la frase escrita por el usuario. Como experimentaremos con elstream creamos tres variables. Cada una de ellas se usa para guardar la capacidad,la longitud y la posición, respectivamente. Al final creamos un arreglo de bytes lla-mado buffer y de tamaño 50.Pedir los datos será de la forma usual y no necesitamos explicarlo en este momento.

// El usuario da los datosConsole.WriteLine(“Dame la cadena para el flujo”);informacion = Console.ReadLine();

Ahora que ya tenemos una cadena, podemos escribirla adentro del stream.

ms.Write(ASCIIEncoding.ASCII.GetBytes(informacion), 0, informacion.Length);

Lo primero que hacemos es obtener los bytes de la cadena, pero éstos estarán co-dificados como ASCII. Luego indicamos que escribiremos en el stream desde suinicio. Por último, indicamos la cantidad de bytes a escribir, que lo obtenemospor medio de la longitud de la cadena. Ahora mostraremos la información quepodemos obtener sobre el stream.

// Obtenemos información de la cadenacapacidad = ms.Capacity;longitud = ms.Length;posicion = ms.Position;

// Mostramos la informaciónConsole.WriteLine(“Capacidad {0}, longitud {1}, posicion {2}”,

capacidad, longitud, posicion);

Después de obtener la información, simplemente la mostramos en la consola.

Los flujos

357www.redusers.com

11_C#2010.qxd 8/6/10 8:39 PM Page 357

Page 360: C# aprenda a programar

Figura 4. El programa ya tiene el stream y hemos obtenido su información.

Ahora podemos empezar a experimentar con stream. Nos colocaremos en diferen-tes posiciones y leeremos información desde ahí. Empecemos por lo más sencillo.Leeremos los primeros cinco bytes que se encuentran en el stream.

// Colocamos y leemos datos basándonos en el inicioms.Seek(0, SeekOrigin.Begin); // nos colocamos a 0 distancia

desde el inicioms.Read(buffer, 0, 5); // desde donde nos encontramos, 5

caracteres

// Mostramos la información Console.WriteLine(ASCIIEncoding.ASCII.GetString(buffer));

Lo primero que hacemos es usar el método Seek(). Con este método decimos quequeremos encontrarnos a distancia cero desde el inicio del stream. Evidentementeésta es la primera posición disponible. Como nuestra posición actual ya está defini-da, procedemos a hacer uso del método Read(). En este caso leemos cinco bytes des-de donde nos encontramos. Los bytes leídos desde el stream ahora se encuentranguardados en el arreglo de bytes que llamamos búfer.

11. FLUJOS Y ARCHIVOS

358 www.redusers.com

11_C#2010.qxd 8/6/10 8:39 PM Page 358

Page 361: C# aprenda a programar

Para mostrar lo que acabamos de obtener usamos el método WriteLine(), y comosolamente tenemos una colección de bytes, debemos codificarlas adecuadamente conGetString(). La codificación que deseamos es ASCII. En la consola aparecen los pri-meros cinco caracteres de la frase que escribimos.

Figura 5. Podemos observar que los primeros cinco caracteres son mostrados.

En el código que veremos a continuación, haremos una prueba, realizando otralectura en una posición diferente.

// Otra lectura desde el inicioms.Seek(10, SeekOrigin.Begin); // nos colocamos a 10 distancia

desde el inicioms.Read(buffer, 0, 5); // desde donde nos encontramos, 5

caracteres Console.WriteLine(ASCIIEncoding.ASCII.GetString(buffer));

En este caso, por medio del método Seek() nos posicionamos a 10 bytes de distan-cia desde que es iniciado el stream. Nuevamente procedemos a leer cinco bytes des-de esa posición que serán colocados en el buffer. Para poder comprobar que esto esóptimo y que funciona en forma adecuada lo mostramos en la consola.

Los flujos

359www.redusers.com

11_C#2010.qxd 8/6/10 8:39 PM Page 359

Page 362: C# aprenda a programar

Figura 6. En este caso podemos observar

los bytes leídos desde la posición donde nos encontramos.

Pero sabemos que no solamente podemos utilizar el inicio del stream como refe-rencia para indicar la posición actual. Ahora realizaremos otra prueba con el finaldel stream como punto de referencia.

// Lectura relativa al final del flujoms.Seek(-10, SeekOrigin.End); // nos colocamos a 10 distancia

desde el finalms.Read(buffer, 0, 5); // desde donde nos encontramos, 5

caracteres

Console.WriteLine(ASCIIEncoding.ASCII.GetString(buffer));

Para este ejemplo usamos nuevamente el método Seek(), pero con la diferencia queahora indicaremos que el punto de referencia es el final del stream. Nuestra nuevaposición actual se encontrará a una distancia de diez bytes desde el final del stream.Por esta razón, vamos a colocar el valor -10 en el primer parámetro. Ya colocadosen esta distancia simplemente procedemos a leer sólo cinco bytes. Al final de la lec-tura mostramos lo que hemos obtenido en la consola.

11. FLUJOS Y ARCHIVOS

360 www.redusers.com

11_C#2010.qxd 8/6/10 8:39 PM Page 360

Page 363: C# aprenda a programar

Figura 7. Ahora observamos los bytes

leídos con referencia al punto final del stream.

Debemos recordar que cuando se lleva a cabo una lectura o escritura en el stre-am, la posición actual se modifica. La última posición colocada explícitamentese encontraba a diez bytes del final del stream, pero después de la lectura se hamodificado en cinco bytes.Comprobemos esto de forma sencilla:

// Obtenemos nuestra posición actualposicion = ms.Position;Console.WriteLine(“La posicion es {0}”, posicion);

Los flujos

361www.redusers.com

Un problema con el que nos podemos encontrar cuando empezamos a utilizar los streams es

olvidar indicar el namespace necesario. Coloquemos la siguiente línea en la parte superior de

nuestro código: using System.IO;. Si no lo hacemos, el programa no podrá reconocer las clases

y los métodos relacionados con los stream y tendremos problemas de compilación.

PARA EVITAR PROBLEMAS CON LOS STREAM

11_C#2010.qxd 8/6/10 8:39 PM Page 361

Page 364: C# aprenda a programar

Simplemente obtenemos nuestra posición actual y la mostramos en la consola. Es-to lo podemos hacer en cada operación y verificar cómo se altera la posición actual.

Desde nuestra nueva posición actual podemos continuar leyendo.

// Lectura relativa desde la posición actualms.Read(buffer, 0, 5); // desde donde nos encontramos, 5

caracteresConsole.WriteLine(ASCIIEncoding.ASCII.GetString(buffer));

Ahora no hemos utilizado el método Seek() ya que deseamos continuar leyendo des-de donde nos encontramos.Por último, no debemos olvidar cerrar el stream.

// Cerramos el flujo, no olvidarms.Close();

A continuación, ejecutemos el programa para ver su funcionamiento:

Figura 8. Esta figura nos muestra la ejecución completa del programa.

11. FLUJOS Y ARCHIVOS

362 www.redusers.com

11_C#2010.qxd 8/6/10 8:39 PM Page 362

Page 365: C# aprenda a programar

El uso de archivosComo hemos aprendido, los streams no solamente funcionan en la memoria, sinoque también nos pueden servir para mover información de la memoria a un dispo-sitivo de almacenamiento masivo. Este dispositivo generalmente será el disco duro. Nosotros podemos crear, escribir y leer archivos en el disco duro apoyándonos enlos streams. En esta sección del libro haremos dos programas, uno que escriba da-tos en el disco, y otro que los lea y los presente en la consola.Todas las operaciones que hemos aprendido para los streams serán válidas y vere-mos que es sencillo llevar esto a cabo.

Cómo crear un stream a archivoLo primero que tenemos que hacer es crear un stream a archivo. En lugar de crearel stream en la memoria, éste utilizará un medio de almacenamiento masivo. Parapoder llevar a cabo esto, necesitamos utilizar la clase FileStream. Esta clase nos pro-vee de toda la funcionalidad que necesitamos.El constructor de esta clase necesita dos parámetros. El primero tiene que ser unacadena que contenga el nombre del archivo con el que trabajaremos. Es útil que elnombre del archivo también tenga su extensión.El segundo parámetro es más interesante. En este parámetro colocaremos el mododel archivo, que indica cómo funcionará y se manipulará el archivo. El valor colo-cado debe ser del tipo de la enumeración FileMode. Los valores posibles son: Append,Create, CreateNew, Open, OpenOrCreate, Truncate.Es importante conocer lo que significa cada uno de estos modos, por lo que lo co-mentaremos aquí. El modo Create nos permite crear un nuevo archivo. En caso deque el archivo ya existiera, simplemente se sobrescribe. El modo CreateNew tambiénnos permite crear un archivo, pero si el archivo ya existe, se produce una excepción.Las excepciones y su manejo lo veremos en un capítulo posterior.El modo Open nos permite abrir un archivo. Si el archivo que intentamos abrir noexiste, entonces se produce una excepción. En el modo OpenOrCreate si el archivoexiste, se abre, pero en el caso de que el archivo no exista, se crea. En el modo Append, si el archivo existe será abiero, y la posición actual será co-locada al final del archivo, de forma tal que cualquier información escrita, sea

Los flujos

363www.redusers.com

El nombre del archivo no necesariamente necesita ser colocado explícitamente. Podemos usar

una variable de tipo cadena para contenerlo. También es posible colocar toda la ruta al archivo

en este nombre. Si no colocamos la ruta del archivo, éste será creado en el mismo directorio que

el ejecutable de nuestra aplicación.

COLOCAR EL NOMBRE DEL ARCHIVO

11_C#2010.qxd 8/6/10 8:39 PM Page 363

Page 366: C# aprenda a programar

11. FLUJOS Y ARCHIVOS

364

agregada al archivo sin modificar lo anterior. En el caso de que el archivo no exis-ta, será creado un nuevo archivo.El modo Truncate es especial y debemos tener cuidado con él ya que abre el archi-vo. Entonces, los contenidos se eliminan hasta que el archivo tenga una longitud de0 bytes. Por ejemplo, podemos crear un stream a disco en modo de creación, comopodemos ver en el código a continuación:

FileStream fs = new FileStream(“miTexto.txt”, FileMode.Create);

El archivo a crear se llama miTexto.txt y será creado en el mismo directorio que elejecutable de nuestra aplicación. El nombre del stream es fs y ya podemos llevar acabo las operaciones necesarias sobre él.

Cómo escribir información en el archivoYa que tenemos el stream, es posible empezar a trabajar con él, y al igual que conlos streams de la memoria, podemos llevar a cabo diferentes operaciones, entreellas la de escritura. Para escribir el archivo usaremos el método Write(), que per-tenece al stream. Por ejemplo, si deseamos escribir una cadena al archivo, pode-mos hacerlo de la siguiente forma:

// Escribimos al stream la cadena capturada fs.Write(ASCIIEncoding.ASCII.GetBytes(cadena), 0, cadena.Length);

El método necesita tres parámetros, el primer parámetro es el arreglo de bytes queescribiremos, el segundo es la posición a partir de donde empezaremos a escribir conrespecto a nuestra posición actual, y el último parámetro nos sirve para indicar lacantidad de bytes que colocaremos. Es importante no olvidar que esta posición seactualiza después de hacer uso del método Write().En nuestro ejemplo a realizar vamos a suponer que una cadena será escrita al ar-chivo. A esta cadena la tenemos que colocar como un arreglo de bytes, pero éstosdeben estar codificados como ASCII, para lo cual usaremos la clase ASCIIEncoding.Para poder obtener los bytes de la cadena deberemos hacer uso del método GetBytes()por el que se pasa la cadena escrita como parámetro.La cantidad de bytes que deseamos colocar será la longitud de la cadena, que obte-nemos al hacer uso de la propiedad Length.

Cómo cerrar el archivoEl cierre del archivo es muy sencillo ya que únicamente debemos cerrar el stream.Sabemos que esto lo realizamos por medio del método Close().

www.redusers.com

11_C#2010.qxd 8/6/10 8:39 PM Page 364

Page 367: C# aprenda a programar

// Cerramos el streamfs.Close();

Ejemplo de un programa para escribir cadenas a discoAhora que ya conocemos los elementos necesarios para utilizar los streams a disco,podemos hacer un ejemplo sencillo. Haremos un programa que le preguntará alusuario cadenas, y cada una de éstas serán escritas a disco. Cuando el usuario déuna cadena vacía, es decir un return, el archivo se cerrará y se terminará la aplica-ción. Luego podremos utilizar un programa, como el Bloc de Notas, para poderleer el archivo que creamos.

Empecemos por definir las variables necesarias y crear el archivo:

// Variables necesariasString cadena = “”;

// Creamos el stream al archivo// Experimentar con append y createFileStream fs = new FileStream(“miTexto.txt”, FileMode.Create);

Luego, podemos hacer uso de un ciclo do while, que se repetirá constantemente has-ta que el usuario dé una cadena vacía. En el interior del ciclo llevaremos a cabo lapetición de la cadena y la escritura de ésta a disco.

// Capturamos cadenasdo{

// Leemos la cadena del usuariocadena = Console.ReadLine();

// Escribimos al stream la cadena capturadafs.Write(ASCIIEncoding.ASCII.GetBytes(cadena), 0,

cadena.Length);

} while (cadena != “”);

Para finalizar simplemente cerramos el archivo.

Los flujos

365www.redusers.com

11_C#2010.qxd 8/6/10 8:39 PM Page 365

Page 368: C# aprenda a programar

// Cerramos el streamfs.Close();

El programa completo queda de la siguiente manera:

using System;using System.Collections.Generic;using System.Text;using System.IO;

namespace Cap11_2{

class Program{

static void Main(string[] args){

// Variables necesariasString cadena = “”;

// Creamos el stream al archivo// Experimentar con append y createFileStream fs = new FileStream(“miTexto.txt”,

FileMode.Create);

// Capturamos cadenasdo{

// Leemos la cadena del usuariocadena = Console.ReadLine();

// Escribimos al stream la cadena capturadafs.Write(ASCIIEncoding.ASCII.GetBytes(cadena), 0,

cadena.Length);

} while (cadena != “”);

// Cerramos el streamfs.Close();

11. FLUJOS Y ARCHIVOS

366 www.redusers.com

11_C#2010.qxd 8/6/10 8:39 PM Page 366

Page 369: C# aprenda a programar

}}

}

Una vez escrito el programa, sólo nos queda compilar a ambos y ejecutarlos.Es posible escribir varias cadenas y luego simplemente presionar la tecla ENTERpara finalizar. Toda la información que se ha escrito en el programa será almacena-da en el archivo. Luego con el Bloc de Notas podemos abrir el archivo y ver queefectivamente se encuentra la información que escribimos.

Figura 9. En el programa hemos escrito

las frases y se han guardado en el archivo.

Los flujos

367www.redusers.com

Dentro de la carpeta que contiene nuestro proyecto o solución creado, debemos buscar otra

carpeta con el mismo nombre. En su interior ésta última debe haber otra carpeta con el nombre

bin. En ésta se encuentran dos carpetas, Debug y Release. En el interior de alguna de ellas estará

el archivo creado por nuestro programa.

CÓMO ENCONTRAR NUESTRO ARCHIVO

11_C#2010.qxd 8/6/10 8:39 PM Page 367

Page 370: C# aprenda a programar

Figura 10. Con el bloc de notas podemos

verificar que la información ha sido escrita.

Cómo hacer una aplicación que lee archivosComo ya tenemos el código para escribir información a un archivo, ahora sería bue-no poder tener una aplicación que lea esa información. El proceso es sencillo ya queconocemos los streams. Básicamente, lo que tenemos que llevar a cabo es la aperturade un stream a archivo y luego proceder a leer los contenidos. Debemos recordar queestamos leyendo bytes, por lo que es necesario procesarlos o convertirlos a un tipo ade-cuado para nuestro programa. En el programa anterior usamos cadenas ya que ahoralos bytes leídos serán colocados en una cadena. Desde luego, cuando hemos finaliza-do con la lectura debemos cerrar el stream del archivo. Para crear esta aplicación em-pecemos por definir un arreglo de bytes. La finalidad de este arreglo de bytes es reci-bir la información que proviene del archivo vía el stream. El tamaño del arreglo debeser lo suficientemente grande para contener la cantidad de información. Otra opciónes leer el stream en grupos de bytes del mismo tamaño que nuestro arreglo, pero estorequiere de lógica extra que controle el proceso. Con fines de experimentación, colo-caremos el tamaño del arreglo en 100 bytes ya que en nuestro programa anterior nohemos colocado cadenas muy grandes. El arreglo queda de la siguiente forma:

// Variables necesarias

11. FLUJOS Y ARCHIVOS

368 www.redusers.com

11_C#2010.qxd 8/6/10 8:39 PM Page 368

Page 371: C# aprenda a programar

byte[] infoArchivo = new byte[100];

Luego podemos proceder a abrir nuestro stream:

// Creamos el stream de lecturaFileStream fs = new FileStream(“miTexto.txt”, FileMode.Open);

Para esto creamos una instancia de la clase FileStream y la nombramos fs. En elconstructor indicamos que nuestro archivo es miTexto.txt. Debemos notar que elmodo del stream en este caso es Open ya que consideramos que el archivo existe ylo abriremos para trabajar con él. Como el archivo fue creado por el programa an-terior, deberemos copiarlo de la carpeta donde se encuentra a la carpeta corres-pondiente de este proyecto. La ruta es similar, solamente que está referenciada anuestro proyecto actual. Si no existe la carpeta Debug o Release, deberemos com-pilar nuestra aplicación para que sean creadas. Hay que copiar el archivo antes deejecutar el programa. Otra solución es colocar el nombre del archivo a abrir consu ruta completa. Si el archivo que queremos abrir no existe o no está donde indi-camos, el programa generará una excepción.

El siguiente paso consiste en leer los contenidos del archivo:

// Leemos el contenido del archivofs.Read(infoArchivo, 0, (int)fs.Length);

El método que utilizamos para la lectura es Read(). Este método pertenece al stre-am. El primer parámetro que colocamos es el arreglo de bytes donde se guarda-rán los bytes leídos. En el segundo parámetro indicamos que leeremos desde elinicio del stream y por último indicamos la cantidad de bytes a leer. En este casoleemos la totalidad de los bytes en el archivo, por eso indicamos como valor lalongitud del stream.

Con esto, ahora nuestro arreglo contiene una copia de los bytes del stream y des-plegaremos la información en la consola como cadena.

// Mostramos el contenido leido

Console.WriteLine(ASCIIEncoding.ASCII.GetString(infoArchivo));

Los flujos

369www.redusers.com

11_C#2010.qxd 8/6/10 8:39 PM Page 369

Page 372: C# aprenda a programar

Para mostrar la información tenemos que colocar los bytes como cadena y esta cade-na tendrá el formato ASCII. Para esto nos apoyamos nuevamente en ASCIIEncoding yel método GetString(), y pasamos nuestro arreglo de bytes como parámetro. La escri-tura en consola es como siempre, por medio de WriteLine(). Para finalizar, debemoscerrar el stream de la forma habitual con el uso del método Close().

// Cerramos el streamfs.Close();

Nuestro programa completo queda de la siguiente manera:

using System;using System.Collections.Generic;using System.Text;using System.IO;

namespace Cap11_3{

class Program{

static void Main(string[] args){

// Variables necesariasbyte[] infoArchivo = new byte[100];

// Creamos el stream de lecturaFileStream fs = new FileStream(“miTexto.txt”, FileMode.Open);

// Leemos el contenido del archivofs.Read(infoArchivo, 0, (int)fs.Length);

// Mostramos el contenido leidoConsole.WriteLine(ASCIIEncoding.ASCII.GetString(infoArchivo));

// Cerramos el streamfs.Close();

}}

}

11. FLUJOS Y ARCHIVOS

370 www.redusers.com

11_C#2010.qxd 8/6/10 8:39 PM Page 370

Page 373: C# aprenda a programar

Ahora ya podemos compilar y ejecutar la aplicación. En la consola podemos leer lascadenas que guardamos con el otro programa.

Figura 11. Podemos observar que nuestro

programa efectivamente ha leído la información del archivo.

Con esto hemos aprendido el trabajo básico de los flujos y los archivos en C#. Tam-bién hemos llevado a cabo una serie de manipulaciones sobre los archivos.

Los flujos

371www.redusers.com

… RESUMEN

Los flujos o streams permiten mover información de un lugar a otro. Puede moverse entre

diferentes partes de la memoria o entre la memoria y los dispositivos de almacenamiento. Para

ello necesitamos el namespace System.IO para poder utilizarlo. Para trabajar correctamente

con el stream podemos colocarnos en cualquier parte de éste referente al inicio, fin o posición

actual. Una vez en la posición adecuada podemos llevar a cabo la lectura de los bytes en el

stream. Una vez abierto el stream, y después de trabajar con él, es necesario cerrarlo para

liberar cualquier recurso utilizado. Los streams también se pueden utilizar para el acceso al

disco con los archivos, podemos abrir el archivo de diferentes formas y llevar a cabo

manipulaciones de los archivos como borrarlos, renombrarlos, copiarlos o moverlos.

11_C#2010.qxd 8/6/10 8:39 PM Page 371

Page 374: C# aprenda a programar

372 www.redusers.com

TEST DE AUTOEVALUACIÓN

1 ¿Qué es un flujo?

2 ¿Qué namespace es necesario para poder

trabajar con streams?

3 ¿Cómo abrimos un stream?

4 ¿Qué método se utiliza para colocar

nuestra posición en el stream?

5 ¿Qué puntos de referencia tenemos para

colocar nuestra posición en el stream?

6 ¿Por qué en algunos casos se colocan

valores negativos cuando indicamos

nuestra posición en el stream?

7 ¿Por qué debemos cerrar el stream?

8 ¿Cómo cerramos el stream?

9 ¿Cómo abrimos un archivo?

10¿Cuántos modos para abrir un archivo

tenemos?

11¿Cómo leemos información desde el

archivo?

12¿Cómo escribimos información hacia el

archivo?

ACTIVIDADES

EJERCICIOS PRÁCTICOS

1 Hacer un programa que genere un

stream en la memoria y coloque la

información de una cadena escrita por el

usuario. Luego leer esa cadena en orden

inverso y mostrarla. Es decir “hola” se

mostrará como “aloh”.

2 Hacer un programa que le pida al usuario

el nombre y la ruta de un archivo de texto

a leer y muestre sus contenidos en la

consola.

3 Hacer un programa que le permita al

usuario copiar un archivo, y le pregunte el

nombre y la ruta del archivo a copiar y la

ruta dónde quedará copiado.

4 Hacer un programa que le permita al

usuario borrar un archivo. Si el archivo

existe, deberá preguntarle al usuario si

realmente desea borrarlo y únicamente

en caso afirmativo proceder a eliminarlo.

5 Hacer un programa que le permita al

usuario cambiar el nombre de cualquier

archivo, pero el nuevo nombre siempre

debe tener más de cuatro letras.

11_C#2010.qxd 8/6/10 8:39 PM Page 372

Page 375: C# aprenda a programar

Depuración

Cómo empezar a depurar un programa 374

Para corregir los errores de compilación 374Cómo corregir los errores en tiempo de ejecución 379Cómo manejar los errores 383

Resumen 389Actividades 390

Capítulo 12

Hemos llegado al último capítulo del libro

y en este capítulo aprenderemos

las técnicas básicas de depuración.

La depuración es utilizada para corregir

problemas en el programa. Algunas veces

los programas tienen errores de sintaxis,

pero principalmente de lógica.

Al depurarlos podemos observar

su comportamiento de mejor forma

y detectar el comportamiento que está

dando problemas.

C#

SERVICIO DE ATENCIÓN AL LECTOR: [email protected]

12_C#2010_AJUSTADO.qxd 8/11/10 10:05 AM Page 373

Page 376: C# aprenda a programar

CÓMO EMPEZAR A DEPURAR UN PROGRAMA

Para depurar un programa nosotros tenemos varias herramientas, pero es impor-tante en primer lugar conocer los posibles errores que podemos tener. Básicamentepodemos tener dos clases de errores bien diferenciados: por un lado los errores decompilación y por otro los errores en tiempo de ejecución.Los errores de compilación son aquellos que impiden que el programa logre com-pilarse y generalmente son más fáciles de resolver. Muchos de estos errores se debena problemas de sintaxis, es decir, son responsabilidad del usuario.Los errores en tiempo de ejecución son aquellos que suceden cuando el programase está ejecutando. Estos errores pueden deberse a problemas de lógica, es decir, queel algoritmo no fue diseñado correctamente. Pero también pueden ocurrir debido aun mal control de la información, por ejemplo, podemos tratar de leer más allá delos límites correspondientes a un arreglo determinado.

Para corregir los errores de compilaciónLa mejor forma de poder aprender a depurar programas es con la práctica. Para es-to crearemos un pequeño programa de ejemplo. El siguiente programa tiene varioserrores para poder identificar y corregir. En el siguiente bloque de código, los erro-res han sido colocados en forma deliberada.

using System;using System.Collections.Generic;using System.Text;

namespace Cap12_1{

class Program{

static void Main(string[] args)

12. DEPURACIÓN

374 www.redusers.com

Los problemas de sintaxis son sencillos de corregir, se deben a que se ha escrito algo de for-

ma incorrecta. Algunas veces los nombres de variables se han escrito erróneamente, o hemos

olvidado colocar ; al final de la sentencia. Una revisión rápida de la línea donde está el error nos

permite encontrarlo, con la práctica también se reduce la incidencia de estos errores.

LOS PROBLEMAS DE SINTAXIS

12_C#2010_AJUSTADO.qxd 8/6/10 8:49 PM Page 374

Page 377: C# aprenda a programar

{// Variables necesariasint a = 5

int b = 10;int c = 0;int r = 0;

// Hacemos la divisionr = b / c;

// Mostramos el resultadoConsole.WrteLine(“El resultado es {},r);

// Mostramos el resultado 5 vecesfor (int n = 0; n < 5; n++){

Console.WriteLine(“El resultado es {0}”, r);}

// Invocamos la funcionMuestraValor();

}

static void MuestraValor(int n){

Console.WriteLine(“El resultado es {0}”, n);

}}

Cómo empezar a depurar un programa

375www.redusers.com

Cuando trabajamos con bloques de código un error común es olvidar cerrarlo. Para evitar esto,

es buena costumbre cerrar el bloque de código inmediatamente después de abrirlo y luego co-

locar el código que va a llevar en su interior. Si abrimos y colocamos el código, puede suceder

que olvidemos cerrarlo.

PARA EVITAR ERRORES CON LOS BLOQUES DE CÓDIGO

12_C#2010_AJUSTADO.qxd 8/6/10 8:49 PM Page 375

Page 378: C# aprenda a programar

El programa tiene varios errores, algunos de ellos muy comunes, por lo que es im-portante aprender a reconocerlos y resolverlos.Para comenzar, lo primero que hacemos es llevar a cabo una compilación. Si hayun error de compilación, inmediatamente aparece una ventana. Esta ventana se co-noce como lista de errores. Podemos observar esta ventana en la siguiente figura.

Figura 1. Después de compilar el programa,

podemos encontrar fácilmente la lista de errores.

La ventana de la lista de errores contiene información importante que nos permiteencontrar el error rápidamente. La lista tiene varias columnas. La primera columnanos indica si el elemento listado es un error o una advertencia. Esto depende delicono mostrado. Un icono con señal amarilla es una advertencia y el icono rojo unerror. En la segunda columna tenemos el número secuencial de error.La tercera línea es muy importante, ya que es una descripción del error. Esta des-cripción nos da pistas sobre la posible causa del error. La siguiente columna indicael documento en el cual ocurrió el error. Esto es útil cuando tenemos programasque se constituyen en varios documentos. Las dos siguientes líneas nos dicen el lu-gar donde está el posible error indicando la línea y la columna. Un punto impor-tante a tomar en cuenta es que la posición es solamente un indicador. Nuestra úl-tima columna indica el proyecto en el cual ocurrió el error, esto llega a ser útil cuan-do tenemos aplicaciones con múltiples proyectos.

12. DEPURACIÓN

376 www.redusers.com

12_C#2010_AJUSTADO.qxd 8/6/10 8:49 PM Page 376

Page 379: C# aprenda a programar

Si observamos el editor, veremos que hay texto que aparece con un subrayado rojo. Es-to indica el texto que está relacionado con la lista de errores y facilita su localización.Empecemos a corregir los errores. La depuración es un proceso iterativo, por loque tenemos que ir corrigiendo errores hasta que no quede ninguno. En algunasocasiones, cuando corrijamos un error aparecerán listados nuevos errores. No de-bemos preocuparnos por esto y tenemos que continuar corrigiendo los erroreslistados hasta que no quede ninguno.Cuando corregimos los problemas de nuestro programa, debemos referirnos a la lis-ta de errores. Siempre tenemos que empezar con el primer problema. Esto se debea que a veces un error en la parte superior del programa puede ocasionar que líne-as que sean correctas parezcan que tienen problemas.En la lista debemos dar doble clic al primer error. Esto nos lleva automáticamenteal código y señala la parte con el problema. Esto lo podemos observar en el ejem-plo que se muestra en la siguiente figura.

Figura 2. Podemos observar que la línea

donde se encuentra el problema ha sido señalada.

El problema señalado indica que se tiene una nueva línea en una constante. Estogeneralmente ocurre cuando usamos una cadena y olvidamos cerrarla. Si observa-mos la línea veremos que efectivamente la cadena de formato no se ha cerrado. Pro-cedamos a cerrar la cadena. De tal forma que la línea quede de la siguiente forma:

Cómo empezar a depurar un programa

377www.redusers.com

12_C#2010_AJUSTADO.qxd 8/6/10 8:49 PM Page 377

Page 380: C# aprenda a programar

// Mostramos el resultadoConsole.WrteLine(“El resultado es {}”,r);

Siempre que corregimos un problema, es bueno realizar una compilación. Esto ac-tualizará la lista de errores y podemos proceder con el siguiente. Después de la com-pilación nuestra lista de errores se ha reducido a únicamente dos. El siguiente error que corregiremos es muy común. Si vemos la descripción nos in-dica que se estaba esperando }. Este error ocurre cuando hemos olvidado cerrar unbloque de código. Puede ser a nivel de namespace, clase, método, ciclo, etc. La me-jor forma de resolverlo es verificar nuestros bloques de código y adicionar el cierredonde corresponde. En muchas ocasiones el cierre no necesariamente es donde loseñala el editor, por lo que se necesita revisar correctamente dónde colocar el cierre.En nuestro caso es muy sencillo y lo adicionamos al final.Ya cerrado el bloque de código, podemos compilar y ver la lista de errores. Ahoraúnicamente nos aparece un error en la lista. Inicialmente teníamos cinco, hemos co-rregido dos y solo queda uno. Estos cambios en la cantidad de errores son muy co-munes. Esto se debe a que los errores pueden suceder en cascada, como comentá-bamos, un error en la parte superior puede crear errores fantasma en otras partes. El error que tenemos que corregir en este momento es muy sencillo y ocurrecuando olvidamos terminar la sentencia con ;. Simplemente lo adicionamos enla línea que corresponde. Al parecer ya hemos terminado de corregir los proble-mas. Compilemos y veamos qué sucede.Después de corregir el último error, han aparecido dos errores más. Como men-cionábamos la depuración es iterativa y podemos pensar que el compilador hace va-rias pasadas. En este caso se nos presentan dos problemas en los métodos. El primer error que tenemos nos indica que no se tiene una definición para WrteLine.Este tipo de error ocurre generalmente en dos casos. El primero es cuando estamos in-tentando usar algo, ya sea método, variable, objeto, etc. que no hemos definido. Paracorregirlo simplemente definimos lo que necesitamos usar. El segundo caso es más co-mún y se relaciona a un error de escritura, es decir que hemos escrito mal el nombrede lo que queremos utilizar y al no reconocerlo el compilador nos marca este error.

12. DEPURACIÓN

378 www.redusers.com

Una forma de evitar errores de escritura para variables y métodos es apoyarnos en la función de

auto completar del editor. Esta función nos muestra el elemento que podemos colocar cuando

escribimos las primeras letras del nombre. Al dar la tecla de ENTER, lo escribe por nosotros. Ha-

cer una buena selección de nombres también ayuda a reducir los errores de escritura.

PARA EVITAR ERRORES DE ESCRITURA

12_C#2010_AJUSTADO.qxd 8/6/10 8:49 PM Page 378

Page 381: C# aprenda a programar

En nuestro ejemplo, el error está referenciado a un problema de escritura. Simple-mente debemos ir al código y escribir WriteLine de la forma correcta. Compilemosy continuamos con el siguiente errorNuevamente nos queda un error. Este error nos dice que no hay un método sobre-cargado. Este error suele pasar cuando tenemos una función o método y estamospasando una cantidad errónea de parámetros o los parámetros son de un tipo nocorrecto. En nuestro programa vemos que el método MuestraValor() necesita de unparámetro, pero en la invocación no se está pasando ningún valor y esto genera elproblema. Para resolverlo simplemente debemos colocar el valor a pasar. Por ejem-plo podemos colocar la línea de la siguiente forma:

// Invocamos la funcionMuestraValor(a);

Ahora podemos compilar nuevamente. La ventana de salida nos indica que se hacompilado exitosamente la aplicación. Esto significa que ya no tenemos errores decompilación, pero aún es posible tener errores en tiempo de ejecución.

Cómo corregir los errores en tiempo de ejecuciónLos errores en tiempo de ejecución se hacen notar cuando el programa está co-rriendo. El error puede provocar que el programa deje de funcionar o se termine re-pentinamente. En otros casos el programa no da resultados correctos.Cuando el programa no da resultados correctos, esto puede deberse a que nuestroalgoritmo no está adecuadamente implementado. En este caso, lo mejor es prime-ro revisar el análisis y tratar de encontrar el error a nivel de algoritmo. Si encontra-mos el error en el algoritmo, simplemente debemos corregirlo y luego modificar elprograma para que se ejecute de acuerdo con el algoritmo correcto.En el caso de que nuestro algoritmo esté correcto y el programa nos provee con re-sultados erróneos entonces es posible que la implementación, es decir la forma co-mo pasamos el algoritmo a programa, este equivocada. La mejor forma de corregiresto es ir depurando paso a paso el programa, viendo cómo cambian los valores yde esta forma encontrar dónde falló la implementación. Las técnicas para llevar acabo esto las veremos un poco más adelante.Ahora podemos ver los errores en tiempo de ejecución que provocan la finalizacióninesperada del programa. Muchos de estos errores se deben a que hemos realizadouna operación indebida con nuestro programa. A los errores de este tipo se les lla-ma excepciones y cuando ocurren se dice que se han levantado o aventado.Veamos cómo ocurren estos errores. Simplemente ejecutemos el programa anterior.El programa está listo para levantar una excepción.

Cómo empezar a depurar un programa

379www.redusers.com

12_C#2010_AJUSTADO.qxd 8/6/10 8:49 PM Page 379

Page 382: C# aprenda a programar

Figura 3. En cuanto el programa levanta una excepción, finaliza

su ejecución de forma inesperada y nos presenta un diálogo con información.

Como vemos el programa ha levantado una excepción. Para poder depurar el pro-grama debemos ejecutarlo en modo de depuración. Para esto seleccionamos el me-nú de Debug o Depurar y presionamos Start Debugging.

Figura 4. Aquí podemos seleccionar dónde llevar a cabo la depuración.

12. DEPURACIÓN

380 www.redusers.com

12_C#2010_AJUSTADO.qxd 8/6/10 8:49 PM Page 380

Page 383: C# aprenda a programar

Ya que nos encontramos en el depurador, el lugar donde se generó la excepción apa-rece marcado en forma muy clara, y junto a él tendremos un cuadro de diálogo quecontiene la información correspondiente.

Figura 5. El cuadro de dialogo nos indica el tipo de excepción que se levantó.

Si observamos el cuadro de diálogo veremos que la excepción, es decir el error,fue provocado por un intento de dividir entre cero. La división entre cero no es-tá definida y por eso es una operación inválida. Ahora que ya sabemos qué pro-voca el problema, simplemente podemos corregir el código. Podemos pensar que la corrección es sencilla y simplemente dividir entre la va-riable que tiene un valor de cero, puede ser algo como lo que se muestra en el si-guiente bloque de código, a modo de ejemplo:

Cómo empezar a depurar un programa

381www.redusers.com

Debemos acostumbrarnos a leer la descripción del error, es un punto muy importante. Con el

tiempo nos acostumbraremos a la descripción y sabremos inmediatamente qué hacer para re-

solver el problema. Muchos programadores con malos hábitos solamente van a la línea del error,

pero no leen la descripción del error. Esto los lleva a tiempos más largos para resolverlo.

LA DESCRIPCIÓN DEL ERROR

12_C#2010_AJUSTADO.qxd 8/6/10 8:49 PM Page 381

Page 384: C# aprenda a programar

// Hacemos la divisionr = b / a;

Si procedemos con la compilación, no aparece ningún problema, pero veamos quésucede cuando ejecutemos nuevamente el programa.

Figura 6. Una nueva excepción ha ocurrido en el programa.

El programa nuevamente tiene problemas de ejecución. Si observamos la infor-mación que nos provee el depurador inmediatamente nos damos cuenta de que laexcepción ha ocurrido porque no estamos colocando el formato correcto en la ca-dena. Al ver la línea de código podemos identificar que efectivamente el formatoes incorrecto, la línea con el formato adecuado debe ser como la siguiente:

// Mostramos el resultadoConsole.WriteLine(“El resultado es {0}”,r);

Después de corregir, nuevamente debemos compilar y ejecutar. Todo debe estarbien y el programa puede ejecutarse sin problema. El resultado lo vemos en el ejem-plo que se muestra en la siguiente figura:

12. DEPURACIÓN

382 www.redusers.com

12_C#2010_AJUSTADO.qxd 8/6/10 8:49 PM Page 382

Page 385: C# aprenda a programar

Figura 7. El programa por fin se ejecuta y podemos ver en la consola los resultados.

Ya vimos cómo localizar el código que nos genera excepciones. Pero lo mejor seríapoder evitarlas o controlarlas de alguna manera.

Cómo manejar los erroresNo es posible evitar las excepciones completamente. Esto se debe a que no siempretenemos control sobre la información o el manejo que va a tener el usuario en nues-tro programa. Por ejemplo, en el programa anterior, la excepción se eliminó al di-vidir entre la variable que no tiene el valor de cero. Pero imaginemos que el usua-rio es el que debe colocar el valor del divisor. En este caso no podemos forzar a unavariable con un valor diferente de cero. En algunas ocasiones el usuario colocará unvalor adecuado, pero también es posible que dé el valor de cero. En esos casos, elprograma terminará por el error.Como no podemos preveer todas las excepciones que pueden ocurrir, lo mejor quepodemos hacer es tener una forma de manejar o administrar los errores. Esto per-mitirá que el programa detecte la excepción y entonces puede hacer algo para sal-var la ejecución de programa. C# nos permite hacer esto ya que provee un sistema de manejo estructurado de ex-cepciones. Para ver cómo poder lograr esto, modificaremos el programa y le dare-mos el manejo de las excepciones. El programa modificado queda así:

Cómo empezar a depurar un programa

383www.redusers.com

12_C#2010_AJUSTADO.qxd 8/6/10 8:49 PM Page 383

Page 386: C# aprenda a programar

using System;using System.Collections.Generic;using System.Text;

namespace Cap12_2{

class Program{

static void Main(string[] args){

// Variables necesariasint a = 5;int b = 10;int c = 0;int r = 0;

// Pedimos el dato al usuarioConsole.WriteLine(“Dame el valor del divisior”);a = Convert.ToInt32(Console.ReadLine());

// Hacemos la divisionr = b / a;

// Mostramos el resultadoConsole.WriteLine(“El resultado es {0}”, r);

// Mostramos el resultado 5 vecesfor (int n = 0; n < 5; n++){

Console.WriteLine(“El resultado es {0}”, r);}

// Invocamos la funcionMuestraValor(a);

}

static void MuestraValor(int n){

12. DEPURACIÓN

384 www.redusers.com

12_C#2010_AJUSTADO.qxd 8/6/10 8:49 PM Page 384

Page 387: C# aprenda a programar

Console.WriteLine(“El resultado es {0}”, n);

}}

}

Veamos cómo este programa puede ejecutarse correctamente a veces y con proble-mas en otros casos. Si ejecutamos el programa y damos como valor 5, el programase ejecuta correctamente. Cuando ejecutemos el programa nuevamente, si el valorque damos es cero, entonces la excepción ocurrirá. Esto lo vemos claramente en lasdos figuras que se mostrarán a continuación.Es sencillo saber qué métodos pueden generar excepciones. Simplemente debemosir a MSDN y buscar la documentación del método a utilizar. Dentro de esta do-cumentación hay una sección que describe las posibles excepciones que pueden ocu-rrir. De esta forma hacemos que nuestro programa las evite.

Figura 8. En esta figura observamos el caso

en el cual la aplicación funciona correctamente.

Para llevar a cabo la administración de excepciones vamos a tener tres bloques decódigo conocidos como: try, catch y finally.

Cómo empezar a depurar un programa

385www.redusers.com

12_C#2010_AJUSTADO.qxd 8/6/10 8:49 PM Page 385

Page 388: C# aprenda a programar

Lo primero que tenemos que hacer es detectar dónde se encuentra el código peli-groso, es decir, dónde puede ocurrir la excepción. En nuestro caso es fácil de iden-tificar ya que sabemos que es la división.

Figura 9. Ahora podemos observar cómo la excepción

se ha levantado y el programa finaliza su ejecución.

El código que tiene el riesgo de levantar la excepción debe ser colocado en el blo-que de try. Por ejemplo, en nuestro caso colocaremos lo siguiente:

// Codigo peligroso, lo colocamos en try para administrar la excepcion

12. DEPURACIÓN

386 www.redusers.com

Existen muchos métodos y sentencias que pueden generar excepciones. Pero no es bueno exa-

gerar. Una gran cantidad de excepciones se evitan simplemente al usar correctamente los mé-

todos y hacer buen uso de nuestras variables y sus valores. Solamente debemos implementar la

administración de excepciones en las partes del programa que realmente lo necesiten.

NO EXAGERAR CON LAS EXCEPCIONES

12_C#2010_AJUSTADO.qxd 8/6/10 8:49 PM Page 386

Page 389: C# aprenda a programar

try{

// Hacemos la divisionr = b / a;

}

El código adentro de try tiene dos opciones: levantar o no la excepción. Si la ex-cepción se levanta entonces en el bloque de catch podemos colocar el código que seencargue de evitar que el programa termine inesperadamente. Aquí podemos ponercódigo que corrija lo ocurrido.En nuestro caso, no hay mucho que hacer, simplemente podemos enviar un men-saje al usuario y dar un valor adecuado a la variable de resultado.

catch (Exception e){

// Aqui colocamos el codigo que salva la aplicacion

Console.WriteLine(“No es posible dividir entre cero”);r = 0;

}

Vemos que este bloque tiene un parámetro llamado e. Adentro de este parámetropodemos encontrar información relacionada con la excepción. Lo que coloquemosen el interior del bloque depende de la lógica de nuestra aplicación. Si no hubieraexcepción el código adentro del bloque catch no se ejecuta.Tenemos otro bloque llamado finally. Este bloque es opcional. El código que se co-loque en el bloque finally se ejecuta siempre sin importar si la excepción se llevó acabo o no. Siempre se ejecuta una vez que try o catch han finalizado de ejecutarse.Finally puede ser utilizado para limpiar o liberar cualquier recurso que se haya uti-lizado en try o catch. En nuestro caso puede utilizarse simplemente para darle alusuario el valor del resultado.

finally{

// Mostramos el resultadoConsole.WriteLine(“El resultado es {0}”, r);

}

Cómo empezar a depurar un programa

387www.redusers.com

12_C#2010_AJUSTADO.qxd 8/6/10 8:49 PM Page 387

Page 390: C# aprenda a programar

12. DEPURACIÓN

388

Nuestro programa completo con la administración de la excepción es el siguiente:

using System;using System.Collections.Generic;using System.Text;

namespace Cap12_2{

class Program{

static void Main(string[] args){

// Variables necesariasint a = 5;int b = 10;int c = 0;int r = 0;

// Pedimos el dato al usuarioConsole.WriteLine(“Dame el valor del divisior”);a = Convert.ToInt32(Console.ReadLine());

// Codigo peligroso, lo colocamos en try para administrar la excepcion

try{

// Hacemos la divisionr = b / a;

}catch (Exception e){

// Aqui colocamos el codigo que salva la aplicacionConsole.WriteLine(“No es posible dividir entre cero”);r = 0;

}finally{

// Mostramos el resultadoConsole.WriteLine(“El resultado es {0}”, r);

www.redusers.com

12_C#2010_AJUSTADO.qxd 8/6/10 8:49 PM Page 388

Page 391: C# aprenda a programar

}

// Mostramos el resultado 5 vecesfor (int n = 0; n < 5; n++){

Console.WriteLine(“El resultado es {0}”, r);}

// Invocamos la funcionMuestraValor(a);

}

static void MuestraValor(int n){

Console.WriteLine(“El resultado es {0}”, n);

}}

}

Veamos si esto funciona adecuadamente. Compilemos el programa y al ejecutar-lo vamos a dar el valor de cero. El programa ahora no deberá generar problemas,pues hemos capturado la excepción y ejecutado código que evita que el programafinalice de forma no adecuada.

Cómo empezar a depurar un programa

389www.redusers.com

… RESUMEN

La depuración nos permite corregir los problemas que pueda tener nuestro programa. Los

errores de compilación impiden que el programa pueda ser compilado y muchas veces son

simples errores de sintaxis. Tenemos una ventana que nos muestra la lista de errores,

siempre debemos corregir el primer error de la lista, ya que muchos errores se generan

en cascada. La depuración es un proceso iterativo. Si tenemos código peligroso que puede

generar excepciones, es recomendable administrar ese código para evitar que la

excepción termine con nuestro programa, cuando administramos la excepción, podemos

colocar código que salve al programa.

12_C#2010_AJUSTADO.qxd 8/6/10 8:49 PM Page 389

Page 392: C# aprenda a programar

390 www.redusers.com

TEST DE AUTOEVALUACIÓN

1 ¿Qué es la depuración?

2 ¿Cuántos tipos de errores tenemos?

3 ¿Por qué algunos programas no pueden

compilar?

4 ¿Qué es un error de sintaxis?

5 ¿En dónde podemos ver los errores que

tenemos?

6 ¿Qué son los errores en tiempo de

ejecución?

7 ¿Qué es un error de lógica?

8 ¿Qué es una excepción?

9 ¿Qué es la administración de

excepciones?

10¿Cuáles son los bloques de código para

administrar la excepción?

11¿Qué es un punto de interrupción?

12¿Cómo podemos depurar paso a paso?

ACTIVIDADES

EJERCICIOS PRÁCTICOS

1 Usar la depuración paso a paso para

observar cómo cambia el valor de la

variable en el programa del factorial.

2 Utilizar el método WriteLine() de la clase

Debug para que las funciones nos

indiquen cuando entramos y salimos de

ellas.

3 Buscar en MSDN cuáles son las

excepciones que pueden ocurrir con los

arreglos.

4 Buscar en MSDN cuáles son las

excepciones que pueden ocurrir con los

streams.

5 Buscar en MSDN cuáles son las

excepciones que pueden ocurrir con el

método WriteLine().

12_C#2010_AJUSTADO.qxd 8/6/10 8:49 PM Page 390

Page 393: C# aprenda a programar

Servicios

al lectorEn este último apartado encontraremos

un índice temático con las palabras

más significativas de esta obra.

Una guía que nos servirá para encontrar

con mayor facilidad el contenido

que necesitamos.

C#

SERVICIO DE ATENCIÓN AL LECTOR: [email protected]

13_C#2010_REAJUSTADO.qxd 8/11/10 10:06 AM Page 391

Page 394: C# aprenda a programar

SERVICIOS AL LECTOR

392 www.redusers.com

#

.NET 15

16 bits 16

A

Acceso privado 319

Acceso protegido 319

Acceso público 319

Acumulador 123

Add() 219

Algoritmo 33

API 14

Append 363

Append() 262

AppendFormat() 262

ArrayList 218

Arreglos de dos dimensiones 196

Arreglos de una dimensión 189

Arreglos 188

ASCII 364

ASCIIEncoding 364

Assembly 16, 17

B

Basic 14

Begin 353

Bloque de código 34

Bloque de comentarios 46

Bool 44

Buffer 359

Build 24

Byte 44/350

Bytes 350

C

C++ 14

Cadenas 256

Case 105

Catch 387

Char 44

Chars 261

Ciclos 111

Ciclos enlazados 198

CIL 16, 17

Clase 23

Clases 318

Clear() 236, 245

CLR 15

CLS 16

Colecciones 218

COM 15

Comentarios 45, 46

Compare() 263

Compilador 15

Concatenar 260

Console 27, 35

Console Application 20

Constructor 238

Contador 123

Contains() 236, 244, 264

ContainsValue() 252

Convert 57

CopyTo() 267

Count 245

Cpp 21

Create 363

CreateNew 363

CultureInfo 274

Current 353

D

D.O.S. 25

DateTime 257

Datos públicos 324

Debug 25

Decimal 44

ÍNDICE TEMÁTICO

13_C#2010_REAJUSTADO.qxd 8/9/10 4:36 PM Page 392

Page 395: C# aprenda a programar

Decrementos 125

Depuración 373

Depurar 25

Dequeue 242, 244

Diagnostics 389

Diagrama de flujo 61

Disyunción 98

Do while 134

Double 44, 51

E

Else 84

Encapsulamiento 319

End 353

EndsWith() 266

Enqueue 242

Enumeraciones 309

Equals() 264

Errores de lógica 38

Errores de sintaxis 38

Estructuras enlazadas 299

Excepciones 380

Explorador de soluciones 21

Expresiones lógicas 96

F

FIFO 241

FileMode 363

FileStream 369

Finally 387

Float 45, 51

Flujos 350

For 112

Foreach 225

Format 257

Framework .NET 15

Funciones 147, 148, 156

G

Get 329

GetBytes() 364

H

Hashtable 218, 249

Herencia 319

I

If 76

If anidados 89

If-else 84

Incrementos 125

Indentación 92

IndexOf() 224

Insert() 222, 268

Instanciación 319

Int 43, 44

J

Jagged 205

Java 14

Jitter 17

L

LastIndexOf() 269

Length 262

LIFO 232

Línea de comandos 25

Long 45

M

Main() 23, 28

Math 22

Matriz 196

MemoryStream 351

Métodos 147

Mono 18

MSDN 57

Multiplataforma 16

N

Namespace 22

Not 96

Now 257

Índice temático

393www.redusers.com

13_C#2010_REAJUSTADO.qxd 8/9/10 4:36 PM Page 393

Page 396: C# aprenda a programar

O

Open 363

OpenOrCreate 363

Operador 49

Operador de asignación 45

Operadores 73

Orientado a objetos 34

Override 287, 297

OWL 14

P

PadLeft() 270

PadRight() 271

Paso por copia 178

Paso por referencia 178

Passport 18

Peek() 244

Pop 233, 235

Private 281

Proceso 62

Protección de datos 329

Proyecto 19

Public 281

Push 233

R

ReadLine() 56, 172

Recolector de basura 17

Recursión 183

RemoveAt() 223

Replace() 271

Runtime 14

S

Sbyte 44

Seek() 354

SeekOrigin 353

Set 329

SetValue() 239

Singleton 338

Solución 20

Split() 272

Stack 232

Static 149, 154

Streams 350

String 45, 256

StringBuilder 261

SubString() 265

Switch 105

System.IO 364

T

Tipo 43

Toint32() 57

ToLower() 273

ToSingle() 58

ToString() 256

ToUpper() 274

Trim() 275

TrimEnd() 276

TrimStart() 276

Truncate 363

Try 387

Type Cast 312

U

Uint 45

Uling 45

UML 321

Ushort 45

Using 22

V

Variable 42

Vista de clases 28

Visual Basic 14

Visual Studio 2008 18

W

While 141

Write() 41

WriteLine 35

SERVICIOS AL LECTOR

394 www.redusers.com

13_C#2010_REAJUSTADO.qxd 8/9/10 4:36 PM Page 394

Page 397: C# aprenda a programar

>> Vea información más detallada sobre cada libro de este catálogo.>> Obtenga un capítulo gratuito para evaluar la posible compra de un ejemplar.>> Conozca qué opinaron otros lectores.>> Compre los libros sin moverse de su casa y con importantes descuentos.>> Publique su comentario sobre el libro que leyó.>> Manténgase informado acerca de las últimas novedades y los próximos lanzamientos.

REDISEÑO BOMBOS LIBROS - APERTURA CATALOGO - Base Editable - Nov 09.indd 1REDISEÑO BOMBOS LIBROS - APERTURA CATALOGO - Base Editable - Nov 09.indd 1 23/11/2009 12:21:0823/11/2009 12:21:08

Page 398: C# aprenda a programar

usershop.redusers.com

PHP 6 200 Respuestas: Blogs Hardware paso a paso

200 Respuestas: Windows 7 Office paso a paso 101 Secretos de Hardware

Este libro es un completo curso de pro-gramación en PHP en su versión 6.0. Un lenguaje que se destaca tanto por su ver-satilidad como por el respaldo de una am-plia comunidad de desarrolladores lo cual lo convierte en un punto de partida ideal para quienes comienzan a programar.

Esta obra es una guía básica que respon-de, en forma visual y práctica, a todas las preguntas que necesitamos conocer para dominar la última versión del sistema operativo de Microsoft. Defi niciones, con-sejos, claves y secretos, explicados de manera clara, sencilla y didáctica.

Esta obra es una completa guía que responde a las preguntas más fre-cuentes de la gente sobre la forma de publicación más poderosa de la Web 2.0. Defi niciones, consejos, claves y secretos, explicados de manera clara, sencilla y didáctica.

Este libro presenta una increíble co-lección de proyectos basados en la suite de ofi cina más usada en el mun-do. Todas las actividades son desa-rrolladas con procedimientos paso a paso de una manera didáctica y fácil de comprender.

En este libro encontraremos una increíble selección de actividades que abarcan todos los aspectos del hardware. Desde la actuali-zación de la PC hasta el overclocking de sus componentes, todo en una presentación nunca antes vista, realizada íntegramente con procedimientos paso a paso.

Esta obra es la mejor guía visual y práctica sobre hardware del momento. En su in-terior encontraremos los consejos de los expertos sobre las nuevas tecnologías, las soluciones a los problemas más frecuen-tes, cómo hacer overclocking, modding, y muchos más trucos y secretos.

> COLECCIÓN: MANUALES USERS> 368 páginas / ISBN 978-987-663-039-9

> COLECCIÓN: 200 RESPUESTAS> 320 páginas / ISBN 978-987-663-035-1

> COLECCIÓN: 200 RESPUESTAS> 320 páginas / ISBN 978-987-663-037-5

> COLECCIÓN: PASO A PASO> 320 páginas / ISBN 978-987-663-030-6

> COLECCIÓN: PASO A PASO> 320 páginas / ISBN 978-987-663-034-4

> COLECCIÓN: MANUALES USERS> 352 páginas / ISBN 978-987-663-029-0

catalogo.indd 2catalogo.indd 2 02/08/2010 10:42:5402/08/2010 10:42:54

Page 399: C# aprenda a programar

¡Léalo antes Gratis!En nuestro sitio, obtenga GRATIS un capítulo del libro de su elección antes de comprarlo.

[email protected]

Access Redes Cisco Proyectos con Office

Dreamweaver y Fireworks Excel revelado Robótica avanzada

Este manual nos introduce de lleno en el mundo de Access para apren-der a crear y administrar bases de datos de forma profesional. Todos los secretos de una de las principales aplicaciones de Offi ce, explicados de forma didáctica y sencilla.

Esta obra nos presenta las dos herra-mientas más poderosas para la creación de sitios web profesionales de la actuali-dad. A través de procedimientos paso a paso, nos muestra cómo armar un sitio real con Dreamweaver y Fireworks sin necesidad de conocimientos previos.

Este libro permitirá al lector adquirir todos los conocimientos necesarios para planifi car, instalar y administrar redes de computadoras. Todas las tecnologías y servicios Cisco, desa-rrollados de manera visual y práctica en una obra única.

Este manual contiene una selección de más de 150 consultas de usuarios de Excel y todas las respuestas de Claudio Sánchez, un reconocido experto en la famosa planilla de cálculo. Todos los pro-blemas encuentran su solución en esta obra imperdible.

Esta obra nos enseña a usar las principales herramientas de Offi ce a través de proyectos didácticos y úti-les. En cada capítulo encontraremos la mejor manera de llevar adelante todas las actividades del hogar, la escuela y el trabajo.

Esta obra nos permitirá ingresar al fas-cinante mundo de la robótica. Desde el ensamblaje de las partes hasta su puesta en marcha, todo el proceso está expuesto de forma didáctica y sencilla para así crear nuestros propios robots avanzados.

> COLECCIÓN: MANUALES USERS> 320 páginas / ISBN 978-987-663-025-2

> COLECCIÓN: MANUALES USERS> 320 páginas / ISBN 978-987-663-022-1

> COLECCIÓN: MANUALES USERS> 320 páginas / ISBN 978-987-663-024-5

> COLECCIÓN: MANUALES USERS> 336 páginas / ISBN 978-987-663-021-4

> COLECCIÓN: MANUALES USERS> 352 páginas / ISBN 978-987-663-023-8

> COLECCIÓN: MANUALES USERS> 352 páginas / ISBN 978-987-663-020-7

catalogo.indd 3catalogo.indd 3 02/08/2010 10:43:4202/08/2010 10:43:42

Page 400: C# aprenda a programar

usershop.redusers.com

Windows 7 De Windows a Linux Producción y edición de video

Webmaster profesional Silverlight Flash extremo

En este libro, encontraremos las claves y los secretos destinados a optimizar el uso de nuestra PC tanto en el trabajo como en el hogar. Aprenderemos a llevar adelante una instalación exitosa y a uti-lizar todas las nuevas herramientas que incluye esta versión.

Esta obra explica cómo superar los pro-blemas más frecuentes y complejos que enfrenta todo administrador de sitios web. Ideal para quienes necesiten co-nocer las tendencias actuales y las tec-nologías en desarrollo que son materia obligada para dominar la Web 2.0.

Esta obra nos introduce en el apasio-nante mundo del software libre a través de una completa guía de migración, que parte desde el sistema operativo más co-nocido: Windows. Aprenderemos cómo realizar gratuitamente aquellas tareas que antes hacíamos con software pago.

Este manual nos introduce en un nuevo nivel en el desarrollo de aplicaciones interactivas a través de Silverlight, la op-ción multiplataforma de Microsoft. Quien consiga dominarlo creará aplicaciones visualmente impresionantes, acordes a los tiempos de la incipiente Web 3.0.

Un libro ideal para quienes deseen reali-zar producciones audiovisuales con bajo presupuesto. Tanto estudiantes como pro-fesionales encontrarán cómo adquirir las habilidades necesarias para obtener una salida laboral con una creciente demanda en el mercado.

Este libro nos permitirá aprender a fondo Flash CS4 y ActionScript 3.0 para crear aplicaciones web y de escritorio. Una obra imperdible sobre uno de los recursos más empleados en la indus-tria multimedia, que nos permitirá estar a la vanguardia del desarrollo.

> COLECCIÓN: MANUALES USERS> 320 páginas / ISBN 978-987-663-015-3

> COLECCIÓN: MANUALES USERS> 336 páginas / ISBN 978-987-663-011-5

> COLECCIÓN: MANUALES USERS> 336 páginas / ISBN 978-987-663-013-9

> COLECCIÓN: MANUALES USERS> 352 páginas / ISBN 978-987-663-010-8

> COLECCIÓN: MANUALES USERS> 336 páginas / ISBN 978-987-663-012-2

> COLECCIÓN: MANUALES USERS> 320 páginas / ISBN 978-987-663-009-2

catalogo.indd 4catalogo.indd 4 02/08/2010 10:43:5802/08/2010 10:43:58

Page 401: C# aprenda a programar

¡Léalo antes Gratis!En nuestro sitio, obtenga GRATIS un capítulo del libro de su elección antes de comprarlo.

[email protected]

Hackers al descubierto Vista avanzado 101 Secretos de Excel

Electrónica & microcontroladores PIC Seguridad PC Hardware desde cero

Esta obra presenta un panorama de las principales técnicas y herramien-tas utilizadas por los hackers, y de los conceptos necesarios para entender su manera de pensar, prevenir sus ataques y estar preparados ante las amenazas más frecuentes.

Una obra ideal para quienes desean aprovechar al máximo las aplicaciones prácticas de los microcontroladores PIC y entender su funcionamiento. Un material con procedimientos paso a paso y guías visuales, para crear pro-yectos sin límites.

Este manual es una pieza imprescindi-ble para convertirnos en administrado-res expertos de este popular sistema operativo. En sus páginas haremos un recorrido por las herramientas funda-mentales para tener máximo control so-bre todo lo que sucede en nuestra PC.

Este libro contiene un material im-prescindible para proteger nuestra información y privacidad. Aprendere-mos cómo reconocer los síntomas de infección, las medidas de prevención por tomar, y fi nalmente, la manera de solucionar los problemas.

Una obra absolutamente increíble, con los mejores 101 secretos para dominar el programa más importante de Offi ce. En sus páginas encontraremos un ma-terial sin desperdicios que nos permitirá realizar las tareas más complejas de manera sencilla.

Este libro brinda las herramientas nece-sarias para entender de manera amena, simple y ordenada cómo funcionan el hardware y el software de la PC. Está destinado a usuarios que quieran inde-pendizarse de los especialistas necesa-rios para armar y actualizar un equipo.

> COLECCIÓN: MANUALES USERS> 352 páginas / ISBN 978-987-663-008-5

> COLECCIÓN: MANUALES USERS> 368 páginas / ISBN 978-987-663-002-3

> COLECCIÓN: MANUALES USERS> 352 páginas / ISBN 978-987-663-007-8

> COLECCIÓN: MANUALES USERS> 336 páginas / ISBN 978-987-663-004-7

> COLECCIÓN: MANUALES USERS> 336 páginas / ISBN 978-987-663-005-4

> COLECCIÓN: MANUALES USERS> 320 páginas / ISBN 978-987-663-001-6

catalogo.indd 5catalogo.indd 5 02/08/2010 10:44:1202/08/2010 10:44:12

Page 402: C# aprenda a programar

usershop.redusers.com

200 Respuestas: Photoshop Creación de distribuciones Linux Métodos ágiles

SuperBlogger UML Ethical Hacking

Esta obra es una guía que responde, en forma visual y práctica, a todas las preguntas que necesitamos contestar para conocer y dominar Photoshop CS3. Defi niciones, consejos, claves y secretos, explicados de manera clara, sencilla y didáctica.

Esta obra es una guía para sumarse a la revolución de los contenidos digi-tales. En sus páginas, aprenderemos a crear un blog, y profundizaremos en su diseño, administración, pro-moción y en las diversas maneras de obtener dinero gracias a Internet.

En este libro recorreremos todas las alternativas para crear distribucio-nes personalizadas: desde las más sencillas y menos customizables, hasta las más avanzadas, que nos permitirán modifi car el corazón mis-mo del sistema, el kernel.

Este libro es la guía adecuada para iniciarse en el mundo del modelado. Conoceremos todos los constructores y elementos necesarios para com-prender la construcción de modelos y razonarlos de manera que refl ejen los comportamientos de los sistemas.

Este libro presenta una alternativa com-petitiva a las formas tradicionales de de-sarrollo y los últimos avances en cuanto a la producción de software. Ideal para quienes sientan que las técnicas ac-tuales les resultan insufi cientes para alcanzar metas de tiempo y calidad.

Esta obra expone una visión global de las técnicas que los hackers ma-liciosos utilizan en la actualidad para conseguir sus objetivos. Es una guía fundamental para obtener sistemas seguros y dominar las herramientas que permiten lograrlo.

> COLECCIÓN: 200 RESPUESTAS> 320 páginas / ISBN 978-987-1347-98-8

> COLECCIÓN: MANUALES USERS> 352 páginas / ISBN 978-987-1347-96-4

> COLECCIÓN: MANUALES USERS> 336 páginas / ISBN 978-987-1347-99-5

> COLECCIÓN: DESARROLLADORES> 320 páginas / ISBN 978-987-1347-95-7

> COLECCIÓN: DESARROLLADORES> 336 páginas / ISBN 978-987-1347-97-1

> COLECCIÓN: MANUALES USERS> 320 páginas / ISBN 978-987-1347-93-3

catalogo.indd 6catalogo.indd 6 02/08/2010 10:44:2502/08/2010 10:44:25

Page 403: C# aprenda a programar

Esta obra nos permitirá ingresar

al fascinante mundo de la robótica.

Desde el ensamblaje de las partes

hasta su puesta en marcha, todo

el proceso está expuesto de forma

didáctica y sencilla para así crear

nuestros propios robots avanzados.

>> HARDWARE / DESARROLLO>> 352 PÁGINAS>> ISBN 978-987-663-020-7

Bombo - RCT - LIBRO C# 2010 - Jul 10 - EDITABLE.indd 1Bombo - RCT - LIBRO C# 2010 - Jul 10 - EDITABLE.indd 1 28/07/2010 16:13:0728/07/2010 16:13:07

Page 404: C# aprenda a programar

This book is a full C# learning course. Aimedfor those who want to migrate to thislanguage, as well as for those who want tolearn programming, even if they do not haveprevious knowledge on the subject.

C# 2010

Este libro es un completo curso de programación en C#, actualizado a la ver-

sión 4.0, incluida en Visual Studio 2010. Es ideal tanto para quienes desean

migrar a este potente lenguaje, como para quienes quieran aprender a pro-

gramar, incluso, sin tener conocimientos previos.

C# es el lenguaje más utilizado en la actualidad, por ser poderoso, flexible y

robusto. En esta obra cubriremos desde las bases de la programación estruc-

turada hasta los fundamentos de la orientada a objetos, sin dejar de apren-

der el manejo de estructuras complejas, como los archivos y las clases.

Nicolás Cosio aporta su vasta experiencia y la didáctica comprobada de sus obras

previas, para facilitar al lector la tarea de comprender cómo se logra desarrollar

código optimizado destinado a obtener aplicaciones poderosas y eficientes.

Una obra imprescindible para fundar bases sólidas en el desarrollo y apren-

der a programar de la mejor manera.

Versión completamente mejorada, actualizada y ampliada de la obra "Curso de programación C#"

por Nicolás Arrioja Landa Cosio

CONTENIDO

N I V E L D E U S U A R I O

PRINCIPIANTE INTERMEDIO AVANZADO EXPERTO

1 | C# Y .NETProgramación para Windows / Comprender .NET /Compilador de C# / El ambiente de desarrollo

2 | LOS ELEMENTOS BÁSICOS DE UN PROGRAMALenguajes / Errores en los programas / Las variables /Comentarios / Precedencia de operadores / Pedido de datos

3 | EL PROGRAMA TOMA DECISIONESLa toma de decisiones / Expresiones y operadoresrelacionales / El uso de if y else / If anidados / Escalera de if-else / Expresiones lógicas / El uso de switch

4 | CREACIÓN DE CICLOSEl ciclo for / El valor de inicio / Límite de conteo / Control de incremento / El contador y el acumulador / Incrementos y decrementos / El ciclo while y do while

5 | FUNCIONES Y MÉTODOSLas funciones / Tipos de funciones / Optimizar con funciones/ Pasaje de parámetros por copia y paso por referencia

6 | LOS ARREGLOSDeclaración de arreglos / Asignación y uso de valores /Acceso a arreglos / Arreglos de tipo jagged

7 | LAS COLECCIONESArrayList / Declaración / Agregar información / El cicloforeach / Stack / Queue / Hashtable

8 | LAS CADENASEl método ToString() / StringBuilder / Justificación del texto /Intercambio entre mayúsculas y minúsculas

9 | ESTRUCTURAS Y ENUMERACIONESDefinición / Crear variables del nuevo tipo / Acceso a laestructura / Creación de un constructor

10 | CÓMO CREAR NUESTRAS PROPIAS CLASESProgramación orientada a objetos / Clases / Datos / Métodos/ Protección de datos / Métodos públicos y privados

CAPÍTULO 11: FLUJOS Y ARCHIVOSLos flujos / Streams en memoria / Uso de archivos

CAPÍTULO 12: DEPURACIÓNCómo depurar un programa / Errores de compilación /Errores en tiempo de ejecución / Manejo de errores / Erroresde lógica / Detener la ejecución

C#

En este sitio encontrará una gran variedad de recursos y software relacionado, quele servirán como complemento al contenido del libro. Además, tendrá la posibili-dad de estar en contacto con los editores, y de participar del foro de lectores, endonde podrá intercambiar opiniones y experiencias.

Si desea más información sobre el libro puede comunicarse connuestro Servicio de Atención al Lector: [email protected]

GUÍA TOTAL DEL PROGRAMADOR

Tapa C#.qxp 29/07/2010 16:15 PÆgina 1