programación en c-texto completo

19
Programación en C/Texto completo 1 Prólogo El avance de la tecnología y la concurrente entrega de información, nos permite generar una edición, variable y alternativa en la enseñanza del lenguaje de programa- ción que más impacto social ha tenido en la historia de la informática. Este libro ha sido forjado con la incansa- ble ayuda de informáticos de habla hispana, quienes byte a byte han colaborado por hacer de la información una fuente de conocimiento global. De la misma forma, con- tinúa hoy siendo modificado en una constante búsqueda de superación de la calidad. Esta obra está llamada a ser la piedra angular en la en- señanza de la programación, logrando abarcar todos los aspectos del lenguaje en diversos niveles y de esta forma ser tanto una referencia técnica para quienes ya dominan el lenguaje como una introducción sencilla para quienes están empezando a conocerlo. Viajaremos por la historia del lenguaje, veremos su pro- pósito e indagaremos en la ciencia de la programación. El fin es otorgar al lector una doctrina clara de la progra- mación y el lenguaje C; lo induciremos a conseguir un manejo importante del lenguaje. 1.1 ¿Para quién es este libro? Este libro está dirigido a todos los que deseen obtener co- nocimientos de programación, pues el objetivo explícito que nos ha motivado a crearlo es difundir la importancia del lenguaje C en el mundo de la informática. Si nos en- focamos a un grupo social específico, podremos indicar que este libro contribuirá con los estudiantes de carreras del área informática, debido a que los temas convenidos, son parte de su plan de estudios. 1.2 ¿Por qué otro manual de C? Porque el lenguaje C es la base fundamental de la pro- gramación. Para quienes están en el ambiente de la in- formática es crucial tener por lo menos nociones de este lenguaje. Varios sistemas operativos, cientos de bibliote- cas, y miles de programas están construidos utilizando C, al conocerlo es posible entender, colaborar y desarrollar en este lenguaje. Los sistemas, programas, juegos y herramientas que no- sotros disfrutamos hoy fueron construidos por personas como nosotros, que empezaron con nuestro mismo po- tencial y fueron aprendiendo a hacer cosas fantásticas con las herramientas que tenían a mano. Una razón importante para otro libro de lenguaje C es también que los libros existentes muestran muy poca do- cumentación de calidad. En Internet existe una cantidad inmensa de información publicada pero está dispersa, y mal manejada en algunos sitios. Es la intención de este libro crear un buen compendio de información, que per- mita a los interesados aprender a programar en C. 2 Enlaces Nociones básicas de programación (generales, indepen- dientes del lenguaje): Fundamentos de programación Wikilibro similar a éste en inglés C Programming esquema de operadores y expresiones 3 Licencia y autores Copyright © 2004 Envite Copyright © 2005 Alejandro Moreno Calvo Copyright © 2006 Andreu Correa Casablanca Copyright © 2009 zerohours Ver el historial de cada página para el resto de autores. 4 ¿Cómo contribuir a este WikiLi- bro? Contribuir con este libro es muy simple primero deberías registrarte un usuario y/o entrar (esto no es necesario pe- ro si muy conveniente) a Wikilibros, para que podamos identificar tus ediciones. Luego, si nunca has contribuido 1

Upload: amra26721

Post on 17-Jan-2016

16 views

Category:

Documents


0 download

DESCRIPTION

Programación en C

TRANSCRIPT

Page 1: Programación en C-Texto Completo

Programación en C/Texto completo

1 Prólogo

El avance de la tecnología y la concurrente entrega deinformación, nos permite generar una edición, variabley alternativa en la enseñanza del lenguaje de programa-ción que más impacto social ha tenido en la historia dela informática. Este libro ha sido forjado con la incansa-ble ayuda de informáticos de habla hispana, quienes bytea byte han colaborado por hacer de la información unafuente de conocimiento global. De la misma forma, con-tinúa hoy siendo modificado en una constante búsquedade superación de la calidad.Esta obra está llamada a ser la piedra angular en la en-señanza de la programación, logrando abarcar todos losaspectos del lenguaje en diversos niveles y de esta formaser tanto una referencia técnica para quienes ya dominanel lenguaje como una introducción sencilla para quienesestán empezando a conocerlo.Viajaremos por la historia del lenguaje, veremos su pro-pósito e indagaremos en la ciencia de la programación.El fin es otorgar al lector una doctrina clara de la progra-mación y el lenguaje C; lo induciremos a conseguir unmanejo importante del lenguaje.

1.1 ¿Para quién es este libro?

Este libro está dirigido a todos los que deseen obtener co-nocimientos de programación, pues el objetivo explícitoque nos ha motivado a crearlo es difundir la importanciadel lenguaje C en el mundo de la informática. Si nos en-focamos a un grupo social específico, podremos indicarque este libro contribuirá con los estudiantes de carrerasdel área informática, debido a que los temas convenidos,son parte de su plan de estudios.

1.2 ¿Por qué otro manual de C?

Porque el lenguaje C es la base fundamental de la pro-gramación. Para quienes están en el ambiente de la in-formática es crucial tener por lo menos nociones de estelenguaje. Varios sistemas operativos, cientos de bibliote-cas, y miles de programas están construidos utilizando C,al conocerlo es posible entender, colaborar y desarrollaren este lenguaje.Los sistemas, programas, juegos y herramientas que no-sotros disfrutamos hoy fueron construidos por personascomo nosotros, que empezaron con nuestro mismo po-

tencial y fueron aprendiendo a hacer cosas fantásticas conlas herramientas que tenían a mano.Una razón importante para otro libro de lenguaje C estambién que los libros existentes muestran muy poca do-cumentación de calidad. En Internet existe una cantidadinmensa de información publicada pero está dispersa, ymal manejada en algunos sitios. Es la intención de estelibro crear un buen compendio de información, que per-mita a los interesados aprender a programar en C.

2 Enlaces

Nociones básicas de programación (generales, indepen-dientes del lenguaje):

• Fundamentos de programación

Wikilibro similar a éste en inglés

• C Programming

esquema de operadores y expresiones

3 Licencia y autores

• Copyright © 2004 Envite

• Copyright © 2005 Alejandro Moreno Calvo

• Copyright © 2006 Andreu Correa Casablanca

• Copyright © 2009 zerohours

Ver el historial de cada página para el resto de autores.

4 ¿Cómo contribuir a este WikiLi-bro?

Contribuir con este libro es muy simple primero deberíasregistrarte un usuario y/o entrar (esto no es necesario pe-ro si muy conveniente) a Wikilibros, para que podamosidentificar tus ediciones. Luego, si nunca has contribuido

1

Page 2: Programación en C-Texto Completo

2 9 PARA LOS MÁS AVANZADOS

en un proyecto de wikipedia o en otro wiki deberías leerel manual de uso de wikilibros.Una vez hecho esto todo lo que tienes que hacer es agre-gar el contenido que consideres necesario para el libro.Para editar cualquier sección basta con hacer click al linkque dice editar en la pestaña en la parte superior de la pa-gina, seria bueno revisar (antes de editar cualquier cosa)la pestaña de discusión que está ahí para ser usada. Tenen cuenta que el material que ya está fue escrito por per-sonas que deseaban contribuir igual que tú, así que tratade respetarlo. Aunque con esto no me refiero a que si senecesita alguna corrección, reorganización, quitar partesque sean ambiguas, no dejes de hacerlo. Lo mejor seríaque todos contribuyéramos de cualquier manera al libro.Además, es recomendable consultar la página de discu-sión del libro y la del articulo en particular que quierasmodificar, ya que de esta manera se pueden coordinar es-fuerzos.Recuerda que todo el contenido que añadas al libro espublicado bajo la licencia GFDL, por lo que no uses ma-terial que no haya sido escrito por ti o que no esté ya pu-blicado bajo GFDL. Recientemente wikimedia decidióadoptar la Licencia Creative Commons Compartir-Igual3.0 para todos los aportes, por lo que actualmente el librotiene una licencia dual.

5 Objetivos

El objetivo principal de este Wikilibro es que cualquierpersona sin conocimientos previos de programación pue-da ser capaz de programar en el lenguaje C.Una vez logrado el dominio del lenguaje, es probableque los lectores se interesen por otros temas más com-plejos que superen a los temas básicos. También les serámás o menos sencillo aprender cualquier otro lenguaje deprogramación estructurada.Sin embargo, este no es un libro que apunte únicamentea programadores principiantes. También puede resultarde interés para quienes ya tengan experiencia en el áreade programación. En esta introducción hay dos seccionesen las que se explica para los dos grupos principales delectores qué camino seguir para comenzar a programaren el lenguaje C o bien perfeccionar conocimientos.El lenguaje C es tan usado porque es un lenguaje de pro-gramación que emplea pocas instrucciones en lenguajemáquina para traducir elementos del código. Esto reducelos tiempos de ejecución de los programas.

6 Nota sobre la exactitud

Muchas de las cosas expresadas en este wikilibro, espe-cialmente en los primeros capítulos, no son completa-mente exactas, aunque son buenas aproximaciones. Los

detalles más exactos irán apareciendo posteriormente,una vez que los materiales anteriores hayan sido correcta-mente asimilados por el lector. En general, dadas dos de-finiciones o datos contradictorios en este wikilibro, debeconsiderarse siempre como más exacto al segundo, ha-biendo aparecido el primero como una introducción másgeneral al tema.

7 Estándar utilizado

El lenguaje C fue creado en los años setenta, y a lo largode su historia ha pasado pormuchasmodificaciones, tantocon respecto a la sintaxis como con respecto al códigoincluido dentro de la biblioteca estándar. Es por ello quese fueron desarrollando estándares, para que todos sepancon qué versión del lenguaje se está trabajando.Los distintos estándares del lenguaje C han sido: el Cde Kernighan y Ritchie, un estándar no-oficial que sur-gió luego de la publicación de su libro en 1978; el C89 oC90, el primer estándar oficial, posterior a la publicaciónde los estándares ANSI en 1989 e ISO en 1990; y el C99,publicado en 1999.En este libro se utilizará el estándar C99, si bien por cues-tiones de estilo y compatibilidad muchas veces se utiliza-rá código compatible con el estándar C89.

8 Para los principiantes

Para quien no haya programado antes, es recomendableseguir el orden del libro. Los temas están especialmen-te organizados de manera incremental o acumulativa. Talvez, lo que se te va a hacermás útil en el camino del apren-dizaje es la constancia; sé terco, no trastabilles, no te rin-das, tal vez tu pregunta sea ¿cuántas veces tengo que in-tentar?, las veces necesarias para lograr tu objetivo, seríala respuesta.Claro que el principal enemigo de nosotros los humanoses el tiempo y por eso en caso de que de verdad estéstrancado en algo busca ayuda de alguien que sepa “másque tú". ¿Que no tienes a nadie a tu alrededor con esacaracterística? Tal vez no buscaste bien y tal vez quierasusar la red de redes. Utiliza los buscadores, pregunta enIRC, en foros de programación, en listas de correo.

9 Para los más avanzados

El lanzamiento queda libre por supuesto, solo tú sabeslo que necesitas. Las reglas del juego son las mismas desiempre: primero saber lo que se quiere o necesita y atacarpor ahí.En este caso, te será útil acceder a los contenidos a partirdel índice, eligiendo sólo aquellos que te sean necesarios.

Page 3: Programación en C-Texto Completo

3

10 Requisitos

Se presupone que los lectores tienen conocimientos ele-mentales de informática a nivel de usuario, y son capacesde instalar un compilador del lenguaje C en sus sistema.Los detalles sobre la instalación se verán en la secciónHerramientas.Con respecto al Hardware, sólo será necesario contar conuna PC con sistema operativo, donde sea posible instalarun compilador, y en lo posible un entorno de desarro-llo. Cuanto mejor sea la computadora, más rápido seráel proceso de compilación y ejecución de los programas.Sin embargo, cualquier PC sirve para aprender con losejemplos de este libro.Para quienes no tengan conocimientos básicos de progra-mación, puede ser una buena idea comenzar leyendo losprimeros capítulos del Wikilibro Fundamentos de pro-gramación, ya que algunos temas explicados en ese librose asumen ya conocidos.Finalmente, un requisito imprescindible en todo progra-mador es tener sentido común. Muchas veces se puedenadoptar mejores o peores soluciones ante los diversosproblemas, y la decisión de cuál elegir pasa por la apli-cación del sentido común.

11 Herramientas

Para programar tanto en C, como en C++, Java o cual-quier otro lenguaje de programación, necesitamos contarcon aplicaciones o herramientas que nos permitan poneren funcionamiento nuestro programa.El lenguaje de programación C es compilado, así que eneste caso necesitaremos un compilador, que será el en-cargado de transformar nuestro código fuente en códigoque la computadora pueda ejecutar.Además, para facilitar la tarea de los programadores exis-ten los denominados Entorno de desarrollo integrados(IDE). Enmuchos casos, estos entornos incluyen un com-pilador, un depurador, y otras herramientas.Las herramientas a instalar dependerán del sistema ope-rativo utilizado. A continuación se listan algunas posibili-dades para el sistema operativo Windows o GNU/Linux,no es imprescindible utilizar estas herramientas en parti-cular, cualquier compilador puede servir.

12 Windows

Uno de los entornos de desarrollo más conocidos en-tre los programadores de C sobre Windows, tanto no-vatos como expertos, es el Bloodshed Dev-C++, que esun entorno libre multiplataforma. Tal entorno de desa-rrollo fue abandonado y retomado mejorándolo pasando

a llamarse WxDev-C++. Otro entorno libre y gratuito esel Code::Blocks. Ambos entornos pueden utilizarse tantopara C como para C++.También hay otras alternativas privativas como los com-piladores de Borland o de Microsoft (Microsoft VisualC++).

13 GNU/Linux

En los sistemas GNU/Linux, será necesario tener insta-ladas las herramientas gcc y make y la versión 6 de laglibc con su documentación, que son las que permitiráncompilar los programas.Para escribir y modificar el código, es posible utilizarcualquier editor de texto plano (en lo posible que cuen-te con resaltado de sintaxis), como son emacs, vim, kate,gedit o geany.Sin embargo, para quienes son novatos en la programa-ción, es recomendable utilizar un entorno de desarrollocomo son el Anjuta DevStudio (para el entorno GNO-ME) o KDevelop (para el entorno KDE), ya que inclu-yen facilidades adicionales para la ejecución y soluciónde problemas.Los programas mencionados se incluyen dentro de la ins-talación estándar de la mayoría de las distribuciones ac-tuales de GNU/Linux, de modo que para instalarlos sóloserá necesario seguir el procedimiento usual de instala-ción de aplicaciones para la distribución deseada.El lenguaje de programación C fue creado por DennisRitchie entre 1969 y 1973 cuando trabajaba en Bell La-boratories de AT&T junto con Ken Thompson en el dise-ño del sistema operativo UNIX. C fue creado para poderescribir dicho sistema operativo en un lenguaje de altonivel, independiente del hardware donde se ejecutara.Contar con un lenguaje de alto nivel permitió el avancede los sistemas operativos, ya que el mismo código po-día ser utilizado en las distintas plataformas, propician-do la reutilización de código y reduciendo los tiempos dedesarrollo. Así es que los sistemas operativos basados enUNIX, el sistema BSD, el sistema GNU/Linux y muchosotros fueron desarrollados en C.Además, con el paso del tiempo se han desarrollado cien-tos de bibliotecas que permiten a los programadores deC utilizar el código desarrollado por otros para la realiza-ción de tareas comunes. Esto, a su vez, ha propiciado eldesarrollo de aplicaciones en lenguaje C.Actualmente es imposible contar la cantidad de aplica-ciones y herramientas desarrolladas en C.

Page 4: Programación en C-Texto Completo

4 16 DEFINICIONES

14 Evolución

A mediados de los años 60s, Martin Richards diseñó ellenguaje BCPL con la finalidad de usarlo para escribirsoftware de sistemas operativos y compiladores.En 1969, Ken Thompson escribió el Lenguaje B, en BellLaboratories, con el objetivo de recodificarUNIX (escritohasta ese momento en lenguaje ensamblador) usando unlenguaje de alto nivel más portable y flexible.Durante los siguientes años, Dennis Ritchie modificó ellenguaje B, llegando a crear el lenguaje C y reescribiendoel sistema UNIX en dicho lenguaje; añadió característicasnuevas, como son el diseño de tipos y las estructuras dedatos.En 1978, Dennis Ritchie y Brian Kernighan publicaronla primera edición del libro El lenguaje de programaciónC. Este libro fue durante años la especificación informaldel lenguaje. El lenguaje descrito en la primera ediciónde este libro, fue conocido como “el C de Kernighan yRitchie” o simplemente “K&R C”. En este libro se in-trodujeron nuevas características al lenguaje: los tipo dedatos struct, long int y unsigned int; los operadores =+ y=- fueron sustituidos por += y -=.Amediados de los años 80, Bjarne Stroustrup (también delos laboratorios Bell), crea el lenguaje C++, un lenguajebasado en C, con numerosas características adicionales,siendo la principal que está orientado a objetos. Si biense han creado muchos lenguajes basados en C, C++ es elque ha permanecido más asociado a C.En los años siguientes a la publicación del C de Kernighany Ritchie, se añadieron al lenguaje muchas característi-cas no oficiales, que estaban presentes en algunos com-piladores y no en otros. Fue por ello que en 1989 ANSI(American National Standards Institute) publicó el pri-mer estándar oficial de C, que es conocido como ANSIC.En este estándar se tomaron muchas de las funcionali-dades no oficiales y se agregaron funcionalidades nuevascomo los prototipos de función, y un preprocesador me-jorado. También se cambió la sintaxis de la declaraciónde parámetros de funciones, para que incluyeran el tipojunto con el nombre.Al año siguiente, en 1990 se publicó la estandarizaciónISO del lenguaje. Este estándar es básicamente el estándarANSI, con unas pocas modificaciones de formato. A esteestándar se lo conoce, entonces, como C89, o C90, y setrata del mismo lenguaje.Basándose en el estándar ANSI que estaba en prepara-ción, en 1988 Kernighan y Ritchie publicaron la segundaedición de su libro, que es aún hoy utilizada como una delas referencias principales del lenguaje.Durante los siguientes años, el lenguaje C permaneció sindemasiados cambios. Sin embargo, como había sucedi-do antes, los distintos compiladores fueron incorporando

características adicionales, que otros compiladores no te-nían, siendo C++ la principal influencia.Fue por ello que a finales de los noventa se decidió revisarel estándar de C, lo que llevó a la publicación del estándarC99. Este estándar incluye varias nuevas característicascomo son: las funciones inline; la posibilidad de declararvariables en cualquier parte del código; los comentariosde una sola línea utilizando //; los tipos de datos long longint, bool y complex, entre otras.Aún hoy el proceso de evolución del lenguaje sigue avan-zando, y desde 2007 se está trabajando en el armado deun nuevo estándar.

15 Más información

• Lenguaje de programación BCPL

• Historia del lenguaje del programación C

• The Development of the C Language

En este capítulo veremos un resumido listado de concep-tos básicos, esta información puede encontrarse en formamás elaborada en el WikiLibro Fundamentos de progra-mación.

16 Definiciones

• Se denomina algoritmo a una secuencia de instruc-ciones que permiten obtener un resultado en parti-cular. No necesariamente son programas de compu-tadora, una receta de cocina, o las instrucciones paracambiar un neumático son ejemplos de algoritmosde la vida real.

• Las computadoras, son maquinas sin inteligenciapropia, cuya única finalidad es interpretar el códigoque se les provee.

• El lenguaje de máquina es el único lenguaje que lacomputadora “entiende” y es capaz de ejecutar.

• Los lenguajes de programación son el medio decomunicación entre el programador y una compu-tadora. El programador escribe en algún lenguajede programación y utiliza las herramientas provis-tas por ese lenguaje para transformarlo en lenguajede máquina.

• Finalmente, denominamos programa a una secuen-cia de órdenes a ser ejecutadas por una computado-ra. Un programa debe estar escrito en algún lenguajede programación, y puede incluir uno o más algorit-mos.

Page 5: Programación en C-Texto Completo

5

17 Tipos de lenguajes

Existe una gran cantidad de lenguajes de programación,que están pensados para distintas finalidades, siguen dis-tintos paradigmas, y de una u otra forma se diferenciande los demás.

17.1 Esquemas de programación

El esquema de programación llamado ProgramaciónImperativa, consiste en escribir una secuencia de ins-trucciones una detrás de la otra, que se ejecutarán en or-den. Algunas de esas instrucciones pueden hacer que lamáquina pase a una instrucción que no sea la siguiente,tal vez porque se cumpla una condición que hayamos es-tablecido.En los últimos años ha tomado fuerza otro paradigma decomputación, llamado Programación Orientada a Ob-jetos , en el cual se intentan modelar los sistemas creadoscomo extensiones de la realidad mediante la definiciónde “objetos” que modelan entidades de la vida real y queinteractúan entre sí mediante “mensajes” llamadas méto-dos.El lenguaje C es un lenguaje imperativo, no orientado aobjetos.

17.2 Alto o bajo nivel

Por otro lado, los lenguajes de programación se clasificanen niveles. Un lenguaje es de más bajo nivel cuanto máscercano esté al código de máquina, y un lenguaje que esde más alto nivel cuanto más lejano esté de la máquina ymás cercano al lenguaje humano.C es un lenguaje de alto nivel aunque tiene muchas ca-racterísticas de lenguaje de bajo nivel (como el uso quepermite hacer de la memoria). Estas características ha-cen que C sea un lenguaje muy potente, ya que permiteoptimizar al máximo los recursos de la máquina. Por en-de, esto también hace que la dificultad y que los erroresque se puedan cometer programando aumenten. Así quea C se le considera de nivel medio.Lenguajes de más alto nivel que C son aquellos en losque el programador no necesita encargarse de manipularla memoria, como Java, C#, Python, Ruby, entre otros.

17.3 Compilados o interpretados

Otra forma de clasificar a los lenguajes de programaciónque es según la forma en que se ejecutan sus órdenes.Existen los lenguajes que son interpretados, cuyas ór-denes pasan a través de un intérprete que se encarga deejecutarlas (a partir del código fuente) en el mismo mo-mento en que están siendo leídas. Algunos de los lengua-jes interpretados son Python, Perl o Tcl, entre muchos

otros.La contraparte de los lenguajes interpretados son los len-guajes compilados (como el mismo C) que se diferen-cian en que las órdenes son transformadas a lenguaje demáquina que se almacena en un archivo ejecutable. Esearchivo puede ejecutarse luego, sin recurrir al compila-dor.Los lenguajes compilados tienen la ventaja de la velocidady la eficiencia, pero los interpretados tienen la ventaja deque, generalmente, son muy portables y de más alto nivel.

18 Estructura de la memoria

Parte de esta potencia de C viene de que permite accedercon mucha libertad a la memoria de la máquina. Para en-tender un poco cómo es posible, debemos entender cómose guardan los datos en la memoria.Imaginemos que la memoria tiene un montón de casillas,una enorme fila de casillas, cada una de las cuales contieneun dígito binario (bit):0101001010100001010101001010000100111010110010010101001011010110001101010110101010110111...Es exactamente así, pero es más cómodo recordar queesos bits se encuentran agrupados de ocho en ocho, for-mando octetos (bytes):Cada octeto puede contener 28 = 256 combinacionesdistintas de ceros y unos, es decir, cualquier número entre0 y 255:También podemos representar estos números en base he-xadecimal:O considerarlos caracteres, mediante alguna codificación:Este es el tipo de datomás elemental que nos podemos en-contrar en C: el caracter. Un caracter ocupa exactamenteun byte (8 bits) de memoria, y puede contener un númeroentre 0 y 255, o entre −128 y 127, dependiendo si que-remos considerarlo como sin signo o con él.En el libro “El Lenguaje de Programación C”, Kernighany Ritchie introdujeron al lenguaje C utilizando un sencilloprograma que mostraba un saludo por la pantalla. Desdeentonces se hizo tradición empezar con cualquier lenguajede programación con el ejemplo del Hola mundo.En particular en C se involucran muchas partes y sintaxisdel lenguaje, por lo cual es especialmente útil verlo comoel primer ejemplo de programación en C.Ejemplo: Hola mundo/* Inclusión de archivos */ #include <stdio.h> /* Funciónprincipal */ int main (int argc,char **argv) { /* Impre-sión por pantalla y salida del programa*/ printf(“Holamundo\n”); return 0; }

Para poder editar y ejecutar este programa será necesa-rio utilizar algún editor y luego un compilador, como se

Page 6: Programación en C-Texto Completo

6 20 COMPILACIÓN DE PROGRAMAS SEGÚN LA PLATAFORMA

explicó en la sección Herramientas necesarias.Si se tiene el compilador gcc en un entorno UNIX oGNU/Linux, la forma sencilla de compilar y ejecutar se-rá:$ gcc holamundo.c $ ./a.out Hola Mundo $Es decir que el compilador genera un archivo, en este ca-so llamado a.out, y la salida generada por ese archivo es“Hola mundo”. A continuación una explicación detalladasobre el proceso de compilación del programa, y luego unanálisis línea por línea del contenido de este ejemplo.

19 Pre-requisitos para la compila-ción de programas

Como ya se mencionó, será necesario tener instalado elcompilador y un editor o entorno de desarrollo que permi-tan escribir el código a compilar. Para más informaciónver la sección Herramientas necesarias.El código a compilar debe guardarse con un nombre querepresente al programa en cuestión y la extensión .c. Enel caso del ejemplo del Hola mundo, el archivo puede lla-marse hola.c.En las explicaciones a continuación, se asume que secuenta con un compilador instalado y se ha editado unarchivo hola.c que se quiere compilar. Si tu sistema ope-rativo no aparece en esta lista busca en internet, ya queseguro que existe algún compilador para ese sistema.

20 Compilación de programas se-gún la plataforma

20.1 Windows

Para compilar un programa C en entornos Windows, de-bemos seguir una serie de pasos que varían según el com-pilador de C que queramos utilizar. Antes que nada, se-ría bueno que se revises la documentación del compiladorelegido para conocer los comandos exactos.

20.1.1 Compilación del código fuente

Si se utiliza un entorno de desarrollo, será posible com-pilar directamente desde el entorno, mediante un botón ouna combinación de teclas.Si se ejecuta el compilador desde la línea de comandos, lalínea será distinta según el compilador utilizado. A con-tinuación algunos ejemplos de ciertos comandos según elcompilador:

• En Turbo C de Borland es: tcc hola.c

• En C++ de Borland: bcc hola.c• En Visual C de Microsoft: cl hola.c• En GNU gcc: gcc hola.c o cc hola.c• El C de Zortech: ztc hola.c

Una vez compilado el código fuente se genera un archivollamado archivo objeto o programa objeto que es luegoenlazado mediante el enlazador, para generar el archivoejecutable.Los compiladores actuales suelen hacer dos funciones deuna vez, compilando y enlazando todo en una sola fun-ción, aunque es posible pedirles que no lo hagan medianteparámetros adicionales.Según el compilador y la configuración utilizada, se ob-tendrán dos o tres archivos:El archivo fuentehola.cEl archivo objetohola.objEl archivo ejecutablehola.exeEste último es el que nos interesa, puesto a que es el có-digo ejecutable, el programa en sí. Al ejecutarlo se pro-ducirá la salida deseada en una ventana de consola.

20.1.2 Salida por pantalla

Si ejecutamos en entorno Windows el programa directa-mente desde el navegador de archivos, o también desdealgunos entornos de desarrollo, lo que sucederá será queapenas abierta la ventana de la consola, se mostrará la ca-dena esperada y luego de terminada la función, la conso-la se cerrará sin tener el tiempo suficiente de ver nuestromensaje en pantalla.Para poder ver la salida por pantalla será necesario ejecu-tar el programa desde la línea de comandos, o modificarla configuración del entorno de desarrollo para que mues-tre la salida por pantalla al ejecutar el programa.Una posible solución es agregar una función adicional anuestro “hola.c":/* Inclusión de archivos */ #include <stdio.h> #include<stdlib.h> /* Función principal */ int main (int argc,char**argv) { /* Impresión por pantalla y salida del progra-ma*/ printf(“Hola mundo\n”); system (“pause”); return0; }

Las dos líneas agregadas permiten que utilicemos la bi-blioteca stdlib, que incluye la función system y que me-diante esta función se ejecute el comando pause del siste-ma, que evita que el programa siga hasta que se presioneuna tecla.

Page 7: Programación en C-Texto Completo

7

Así es posible visualizar que la salida de hola.c se com-pletó perfectamente.

20.2 GNU

Si bien existen otros compiladores, lo más usual y mássencillo para compilar un programa en GNU/Linux es elcompilador gcc, ya que es el que se incluye en todas lasdistribuciones.De cualquier forma, es posible realizar la compilacióndesde línea de comandos o desde el entorno gráfico.Para realizarla desde línea de comandos, será necesa-rio contar con una terminal (xterm, konsole, gnome-terminal, etc). No es necesario contar con permisos deroot para crear o compilar programas. En esa terminalserá necesario escribirgcc hola.cSi no existen errores en el código, este comando noscreará un archivo ejecutable, que por omisión se llama“a.out”, y que podemos ejecutar desde la línea de coman-dos de la siguiente forma:./a.out Hola mundoEs una buena idea especificar el nombre que el archivoejecutable tendrá, pasando como parámetro al compila-dor la opción -o, de la siguiente forma:gcc hola.c -o holaCon lo cual, el nombre del archivo creado será hola. Estearchivo no tiene extensión ya que es la forma usual dellamar a los archivos ejecutables en los entornos UNIX yGNU/Linux, sin embargo funcionaría de la misma formasi se llamara hola.exe.Para ejecutarlo, haremos los mismo que en el caso ante-rior:./hola Hola mundoExisten otros parámetros que podemos especificar alcompilador en la línea de comandos, dependiendo del ti-po de programa, y en función de la complejidad del mis-mo. Por ejemplo, podemos agregar las siguientes opcio-nes:gcc hola.c -o hola -Wall -pedanticLa opción -Wall nos mostrará todos los avisos que pro-duzca el compilador, no solamente los errores. Los avisosnos indican dónde y/o porqué podría surgir algún error ennuestro programa.La opción -pedantic nos aporta más información sobrelos errores y los avisos mostrados por GCC.

21 Diseccionando el “Hola Mun-do”

A continuación veremos cuál es la estructura básica de unprograma en C, para poder entender qué hace cada unade las líneas de nuestro sencillo programa.Es probable que lo primero que salte a la vista sea la línea:printf(“Hola mundo\n”);

Esta es la línea que hace aparecer la cadena Hola Mundoen nuestra pantalla. Notamos que en C la sentencia paraimprimir algo por pantalla es printf() y, además, hay quecolocar paréntesis alrededor de lo que queremos imprimirpara utilizarla.Esto se debe a que en C, printf es una función, que impri-me su argumento (la cadena Hola Mundo\n) en la pan-talla. Se denomina invocar una función a la acción deutilizarla para que realice una acción.Podemos observar también que la cadena a imprimir ter-mina con una extraña combinación: \n. La combinación\n no representa a dos caracteres independientes, sino querepresenta un único carácter no imprimible: el salto delínea. Sin el salto de línea, el resultado al ejecutar el pro-grama sería:$ ./a.out Hola Mundo$Es decir que no hay salto de línea entre la cadena impresa,y la siguiente entrada de la línea de órdenes, que no es loque esperábamos.Lo último a notar en la línea es que termina con un puntoy coma. En C, todas las sentencias terminan con un puntoy coma. Al principio puede parecer obvio dónde terminauna sentencia, pero ya veremos más adelante que no lo estanto.Observemos ahora la siguiente sentencia del programa:return 0;

Luego de esta sentencia, termina el programa. En el casode la instrucción return dentro de la función main, el re-sultado es que se finaliza el programa, comunicándoleal sistema operativo que el valor de retorno (un códigonumérico que el sistema utiliza para saber si el progra-ma ha funcionado bien o ha dado fallos) es 0, es decir,correcto.Las dos últimas sentencias se encuentran encerradas entrellaves. De esta manera, forman un bloque, es decir, ungrupo de sentencias que se ejecutarán siempre de formacorrelativa.¿Y qué es esa línea que precede (en realidad, que da nom-bre) al bloque?int main (int argc, char **argv)

Page 8: Programación en C-Texto Completo

8 24 ENTEROS

Pues es la definición de una función, en este caso llama-da main. En C (y en general en todos los lenguajes deprogramación estructurada) todo se hace a base de fun-ciones, como main y printf.La función main es especial, porque es el la que se invocacuando se ejecuta el programa. Todos los programas en Ccomienzan su ejecución al principio de la función main,y cuando ésta acaba, el programa también.Veamos con más detalle la definición de la función:int main (int argc, char **argv) { ... }

• El nombre de la función que viene a continuación,entre llaves, es main.

• Recibe dos argumentos: int argc y char **argv (querepresentan a la cantidad de argumentos ingresadosal ejecutar el programa y a los valores de estos argu-mentos respectivamente).[1]

• La función devuelve como resultado un número en-tero, int (que es el 0 de la instrucción return).[2]

Finalmente, y un tanto aparte (está separada del resto poruna línea en blanco), tenemos la línea:#include <stdio.h>

Que parece bastante distinta al resto del programa, y que,además, parece no tener sentido, puesto que ya hemosdefinido la función main que hace todo el trabajo.Efectivamente, esa línea no es parte del programa, aun-que sea imprescindible. La línea es una instrucción delpreprocesador de C, como nos lo indica el símbolo #, ylo que hace es incluir en ese punto el contenido de otrofichero, antes (de ahí el nombre de preprocesador) de quecomience la compilación. El fichero stdio.h es el que con-tiene la definición de la función printf(), que antes utili-zamos pero que no escribimos, ya que forma parte de labiblioteca estándar de C.

22 Comentarios

Una vez escrito un código, tratar de entenderlo un añomás tarde solo con leerlo puede ser frustrante: no hay ma-nera de saber (si el programa es medianamente compli-cado) qué es cada variable, o qué hace cada bloque decódigo. Por esto, en cualquier lenguaje de programaciónson importantes los comentarios.Un comentario en C es todo lo que se encuentre entre lossímbolos /* y */. Hay que tener en cuenta que los comen-tarios no se pueden anidar: si dentro de un comentariohay un /*, seguirá siendo el primer */ el que finalice elcomentario, no se esperará al segundo.Hay otro tipo de comentarios en C, procedentes del len-guaje C++, e incorporadas al estándar de C a partir de

C99: //. Todo lo que esté después de estos signos, has-ta el final de la línea, se considerará un comentario y elcompilador no lo tomará en cuenta.En el ejemplo presentado pueden verse tres líneas concomentarios, que documentan someramente las distin-tas funcionalidades del código. En los próximos capítulospodrán verse mejores usos de los comentarios dentro delcódigo.También podría decirse que es una herramienta básicabasada en compilador

[1] En un capítulo posterior podrá ver un ejemplo del uso delos parámetros que recibe main.

[2] Es importante señalar que el estándar dice que main de-berá definirse como función que retorna un entero, o delo contrario el resultado queda indefinido.

23 Historia

En el lenguaje C estandarizado como C89, existían cuatrotipos de datos básicos que son: los números enteros, losnúmeros reales, los caracteres, y los punteros. A partir delestándar C99 se agregan: los valores lógicos (verdaderoo falso) y los números complejos.Estos tipos de datos son parte del lenguaje, y por ello selos considera primitivos. Más adelante veremos que conel uso de estructuras y uniones es posible crear tipos com-puestos de datos a partir de estos tipos primitivos.En este capítulo veremos los enteros, los reales y los ca-racteres. Más adelante se verán otros tipos de datos máscomplejos, como son los vectores, las cadenas de carac-teres, y los punteros en general.

24 Enteros

Los enteros son el tipo de dato más primitivo en C. Seusan para representar números enteros. Pero siempre sepueden encontrar otras aplicaciones para los números en-teros. En general se pueden usar para representar cual-quier variable discreta.Los tipos de datos enteros son: short, int, long y long long,cada uno representando un número entero de un tamañoo capacidad determinado. Según el compilador y la plata-forma de hardware, cada uno de estos tipos de dato puedeocupar desde 1 byte hasta 8 bytes en memoria (para másdetalles busca en la referencia).Además, el lenguaje C hace la distinción de si el enteroes con signo (signed) o sin signo (unsigned). En caso deque no se declare si es con signo o sin signo, se toma consigno.Algunos ejemplos de declaraciones de enteros:

Page 9: Programación en C-Texto Completo

9

int a; unsigned int a; signed long a; signed long long a =10000000;

Todos los números son representados en memoria me-diante una cadena de bits. En el caso de los números consigno, el bit más significativo es el que se usa para re-presentar el signo. La representación de los números ne-gativos se realiza mediante el complemento a dos, quees una técnica que permite operar con los números nega-tivos de forma lógica.A modo de ejemplo, la representación en memoria delnúmero −8 en una variable de 2 bytes, entera, con signo,sería la siguiente:1111111111111000

25 Flotantes

Se denomina flotantes a los tipos de datos que represen-tan a los números reales, ya que utilizan un sistema de re-presentación basado en la técnica de coma flotante, quepermite operar con números reales de diversas magnitu-des, mediante un número decimal llamadomantisa y unexponente que indica el orden de magnitud.El tipo de dato flotante en lenguaje C sólo tiene dos ta-maños: el float y el double, que son 4 bytes y 8 bytes res-pectivamente. Se los puede utilizar tanto para representarnúmeros decimales, como para representar números en-teros con un orden de magnitud muy grande.La forma de declarar una variable flotante es escribiendoen una línea uno de los tipos de datos flotantes y a conti-nuación el nombre de la variable y tal vez algún valor quese les quiera dar.Algunos ejemplos:float a; double a = 1e23; double a = 3.1416; float a =4e-9; double a = −78;

Hay que tener en cuenta que aunque los valores flotantesson más convenientes para algunas aplicaciones, hay ca-sos en los que se prefieren los enteros. Esto se debe a quelos números flotantes no necesariamente tienen soportede hardware, en particular en las plataformas integradas.Una alternativa que se utiliza en estas situaciones es in-terpretar los enteros como decimales de forma que 150se interprete como 1.5 y 2345 como 23.45.Para el caso de los flotantes de 4 bytes, se utiliza 1 bit parael signo, 8 bits para el exponente y 23 bits para el valordel número. El procedimiento para almacenar un númeroen una variable flotante es el siguiente:

1. Se convierte a binario la parte entera.2. Se coloca el signo en el bit más significativo de la

misma manera que en los enteros (1 para el - y 0para el +).

3. Se mueve la coma (en la representación binaria dela parte entera) hasta que esté a la derecha del pri-mer uno y éste se descarta (el uno más significativo).El valor del exponente será el número de posicionesque se movió la coma. El exponente usa la represen-tación de un entero con complemento a dos.

4. Se convierte en binario la parte decimal del número.Esto usando el peso de los bits. el bit decimal mássignificativo vale 1/2, el siguiente vale 1/4, el otro1/8, el otro 1/16 y así hasta completar lo que faltapara los 23bits del valor.

5. Se concatena todo y ese es el valor flotante represen-tado en memoria.

26 Caracteres

Los caracteres se representan utilizando el tipo char, quetiene sólo 1 byte de tamaño. Este tipo se utiliza para re-presentar los 256 caracteres de la tabla de caracteres delsistema. El tipo char es también un tipo entero, ya quepuede tomar valores de 0 a 255. Por lo tanto también pue-de ser signed o unsigned.En cuanto a la forma de declarar variables de tipo char esla misma forma que con los otros tipos.char a; char a = 's’; unsigned char a = 48;

Como puedes ver, se le puede asignar un número a unavariable char, ya que se trata de un tipo entero. Enmuchassituaciones se utiliza el tipo char para almacenar númerospequeños, ya que ocupa en memoria sólamente un byte.Es importante notar que con la llegada de la codifica-ción UTF-8, los caracteres de los diversos idiomas pue-den ocupar 1, 2, 3 o 4 bytes, de modo que el tipo char yano alcanza para la representación de todos los caracteresposibles. Por ello, el estándar C99 introduce el tipo wcharque puede ocupar más de 1 byte, según sea necesario parala codificación utilizada por el sistema.En este capítulo veremos un poco más sobre como inter-actuar con el usuario de nuestros programas desde la con-sola, utilizando printf() como vimos en el primer ejem-plo “Hola mundo”, así como scanf() para la lectura delteclado.

27 Imprimir por pantalla

Como hemos visto hasta ahora en los ejemplos, hay unafunción que utilizamos para sacar por pantalla textos ar-bitrarios o el resultado de alguna operación: la funciónprintf().Si miramos (en la documentación) su definición, no nosaclarará demasiado:

Page 10: Programación en C-Texto Completo

10 28 LECTURA DE DATOS DEL TECLADO

int printf (const char *TEMPLATE, ...)...claro que por algo tiene una sección completa de la do-cumentación para ella sola.Veámosla poco a poco. Se trata de una función de la bi-blioteca estándar, lo que quiere decir que para utilizarlatenemos que incluir previamente su definición. La encon-traremos en <stdio.h>.Lo primero que vemos en la definición es que es una fun-ción de tipo int, lo que quiere decir que devuelve un en-tero. Ese entero es el número de caracteres impresos enla pantalla, o un número negativo en caso de que se pro-duzca algún error.Lo siguiente a notar es su primer argumento: const char*TEMPLATE. Se trata de una cadena de caracteres (char*) que no será modificada por la función (const), con loque puede ser una constante de cadena o una variable quecontenga una cadena, pero siempre debe acabar con elcarácter nulo \0.Y luego vienen esos extraños puntos suspensivos. Esaelipsis nos indica que como argumentos adicionales deprintf() podemos poner una serie ilimitada de otros ar-gumentos, que se supone que la función sabrá qué hacercon ellos. Y eso es justamente lo que hace tan fabulosa yútil a printf().Como hemos visto, el uso más simple de printf() es im-primir una cadena de texto simple y corriente. Como yavimos:printf(“Hola Mundo\n”); /*imprime la cadena*/Y también hemos visto printf() también puede, con unargumento extra y una sintaxis especial, imprimir un nú-mero entero que hayamos almacenado en una variable:char resultado;resultado=5+2;printf(“Resultado de la suma: %i\n”,resultado);

Aquí el punto de inserción es la secuencia %i. printf()siempre trata las secuencias que comiencen por % comosecuencias de control que le dicen que debe imprimir al-go que le proporcionamos en los otros argumentos. Así,podemos imprimir varios enteros distintos en los sitiosque queramos de la cadena, insertando varias de estas se-cuencias %i:int numero;numero=3;printf(“El doble de %i es %i y su cuadrado es%i\n”,numero,numero*2,numero*numero);

28 Lectura de datos del teclado

La entrada de datos se puede hacer de muchas manerasy entre ellas están desde el uso de dispositivos especialeshasta nuestro simple teclado. La entrada de datos se re-

fiere a cualquier forma de influencia del usuario sobre losdatos que posee el sistema.Con el fin de mostrar una forma de entrada simple para elaprendizaje vamos a hablar de la función scanf() que seencuentra definida en <stdio.h> y que se usa para capturardiferentes tipos de datos.

28.1 La función scanf()

scanf() es una de las funciones más usadas por los princi-piantes para hacer entrada de datos en el lenguaje C. Tie-ne una sintaxis muy parecida a printf: recibe una cadenacon el formato de los datos y luego se ponen las variablesen orden que correspondan a ese tipo de datos. Es decir,así como en printf se pueden mostrar por pantalla los da-tos de varias variables en una misma sentencia, en scanfse pueden capturar varios datos en una sola sentencia.#include <stdio.h> int main() { int a; printf (“diga unvalor para a:"); scanf("%i”,&a); printf (“el valor es:%i\n”,a); return 0; }

Por ahora no nos interesan las demás sentencias, sólo laque contiene scanf. En el código se ve lo siguiente:scanf("%i”,&a);

Se observa que la funcion printf dejó en pantalla una pe-tición para que el usuario introdujera un valor. Entonces,scanf recibe como argumento una cadena del formato enque se van a capturar los datos y la lista de variables quevan a recibir valores y que deben coincidir con los delformato.En este caso la cadena de formato, "%i”, especifica queel usuario ingresará un número entero. Luego se designaa la variable a para contener a ese número. El símbolo(&) que precede a a es para especificar que lo que se es-tá enviando como argumento no es el valor que posee lavariable a sino la dirección de memoria en que se encuen-tra. En este momento eso no tiene mucha relevancia, sólohay que recordar que se debe usar el símbolo & dentrodel scanf. En el momento en que hablemos de punterosveremos más detalles de esto.Otro ejemplo del uso de scanf:#include <stdio.h> int main() { int a,b; printf (“in-troduzca dos valores con el formato \"a,b\" :");scanf("%i,%i”,&a,&b); printf (“el primer valor :%i\n”,a); printf (“el segundo valor : %i\n”,b); return 0; }

Aquí hemos introducido una nueva variable en el código.La cadena de formato, "%i,%i” especifica que el usuarioingresará un número, seguido de una coma, y luego otronúmero. El primer %i será capturado por la variable a yel segundo por b.Vamos a tratar ahora de que el ordenador haga un poco

Page 11: Programación en C-Texto Completo

11

de matemáticas para nosotros. Por ejemplo, que realiceunas pocas sumas, restas multiplicaciones y divisiones.#include <stdio.h> int main(void) { int resulta-do; resultado=5+2; printf(“Resultado de la suma:%i\n”,resultado); resultado=5-2; printf(“Resultado de laresta: %i\n”,resultado); resultado=5*2; printf(“Resultadode la multiplicación: %i\n”,resultado); resultado=5/2;printf(“Resultado de la división: %i\n”,resultado); re-turn(0); }

Después de grabarlo (por ejemplo, con el nombre ejem-plo.c), lo compilamos y ejecutamos, con (respectivamen-te):$ gcc ejemplo.c $ ./a.out Resultado de la suma: 7 Re-sultado de la resta: 3 Resultado de la multiplicación: 10Resultado de la división: 2 $Fijémonos en la línea del principio de la función main:int resultado;

Esta línea lo que hace es reservar un trozo de memoria,del tamaño de un int (normalmente 4 bytes), y asignarleel nombre resultado, para poder después referirnos a él.A partir de este momento, podemos considerar que ennuestro programa existe una variable, que no tiene valordefinido, pero a la que le podremos dar valor posterior-mente.Las líneas con printf() ya las conocemos, pero hay algoen ellas que no habíamos visto antes. Esos %i y la partede resultado son nuevas para nosotros.La función printf() no sólo sabe imprimir cadenas sim-ples, como “Hola Mundo\n”, sino también imprimir va-riables. Para ello, en el lugar de la cadena donde queremosque aparezca el valor de la variable, introducimos lo quese llama una cadena de conversión de printf(). Estas ca-denas siempre empiezan por %, siendo %i la cadena paraimprimir un entero, como es en nuestro caso int resul-tado. Finalmente, printf() debe saber qué valor escribir,por eso le damos otro argumento (u otros), usando , co-mo separador, que contienen las variables cuyos valoresqueremos mostrar.En el resto del programa hemos visto cómo decirle al or-denador que ejecute una suma, una resta, una multiplica-ción y una división entera, con los operadores +, -, * y /.Es de notar que el resultado de una operación como estasentre números enteros será siempre otro entero, como sepuede observar en la división, en la que no obtenemos unbonito decimal, sino un resultado entero. Además, hemosvisto que el resultado de esas operaciones, que llamamosexpresiones, puede ser asignado a una variable:resultado = 7;

Esa asignación se hace mediante el operador de asigna-ción: =. Con él, ya conocemos cinco operadores.

Pero, como = también es un operador, ¿cómo sabe el or-denador qué operador debe ejecutar primero? Y si es unoperador, ¿por qué no da un resultado? ¿No crea una ex-presión?Empezando por las últimas preguntas, el operador deasignación sí crea una expresión, como los operadoresde suma, resta, multiplicación y división, y esa expresióntiene un resultado, que es el valor que obtiene el lado iz-quierdo al realizar la operación. En cuanto a saber quése debe ejecutar primero, el ordenador tiene una lista deprecedencia, según la cual siempre ejecuta primero lasmultiplicaciones y divisiones, de izquierda a derecha, acontinuación las sumas y restas, de izquierda a derecha,y a continuación las asignaciones, de derecha a izquierda.Para más detalles acerca de la precedencia de los opera-dores ver el anexo de los operadores.En cuanto a los caracteres de punto y coma, notamos aquíque una expresión también puede ser una sentencia por símisma, sin necesidad de que haya ninguna función. Dehecho, una sentencia puede no tener siquiera una expre-sión. La línea: ; es una sentencia perfectamente válida, lasentencia vacía, que sera útil en puntos donde el lenguajerequiera una sentencia pero no sea necesaria para nuestroprograma.Como ya se ha mencionado, C es un ejemplo deprogramación estructurada. En este tipo de programa-ción, es necesario contar con ciertas estructuras que per-mitan controlar el flujo del programa, es decir, tomar de-cisiones y repetir acciones.

29 La estructura condicional if ...else

En la gran mayoría de los programas será necesario to-mar decisiones sobre qué acciones realizar. Esas decisio-nes pueden depender de los datos que introduzca el usua-rio, de si se ha producido algún error o de cualquier otracosa.La estructura condicional if ... else es la que nos permitetomar ese tipo de decisiones. Traducida literalmente delinglés, se la podría llamar la estructura “si...si no”, es de-cir, “si se cumple la condición, haz esto, y si no, haz estootro”.Un ejemplo sencillo sería el siguiente (no se trata de unprograma completo, sino tan sólo una porción de código):if (edad < 18) printf(“No puedes acceder.\n”); elseprintf(“Bienvenido.\n”);

Este código de ejemplo dice que si el valor de la varia-ble edad es menor que 18 se imprimirá “No puedes ac-ceder.\n”, mientras que en caso contrario se imprimirá“Bienvenido.\n”.Como se ve en el ejemplo, la estructura de un condicional

Page 12: Programación en C-Texto Completo

12 29 LA ESTRUCTURA CONDICIONAL IF ... ELSE

es bastante simple:if (condición) { sentencias_si_verdadero; } else {sentencias_si_falso; }

La condición, encerrada entre paréntesis, es una expre-sión que puede dar como resultado 0 (interpretado comofalso) o cualquier valor distinto de 0 (interpretado comoverdadero). Cuando la condición sea verdadera, se eje-cutarán las sentencias dentro del primer bloque de código,cuando la condición sea falsa, se ejecutarán las sentenciasdel segundo bloque de código. Las expresiones y valoresde tipo verdadero/falso son también llamados valores ló-gicos o booleanos.La indentación o sangría (los espacios al comienzo de laslíneas) no es necesaria, pero ayuda a la claridad del códi-go. La utilización de las llaves {...} es obligatoria cuandose quiere utilizar más de una instrucción por bloque, yoptativa cuando sólo se quiere escribir una instrucción.Por claridad, sin embargo, es recomendable utilizarlasaún cuando sólo vaya a haber una instrucción.El bloque del else es opcional. Si no se lo encuentra, sólose realizará la acción correspondiente al bloque if.A continuación, un ejemplo con una función, que devuel-ve el mayor de dos números:int mayor(int a, int b) { if (b > a) { return b; }// No poseeespecificación de la parte “else”, ya que no es necesaria.return a; // Finaliza la función retornando el valor de “a”. }

29.1 Operadores de comparación

El símbolo > visto en el último ejemplo es un operador,que en este caso compara dos números enteros y devuelveverdadero si el primero es mayor, falso en caso contrario.A continuación un listado de los posibles operadores decomparación en C y su significado.Teniendo en cuenta que en C se toma como falso el va-lor 0, y como verdadero cualquier otro valor, una prácticacomún es expresar condiciones sin utilizar ningún opera-dor:float division(int dividendo, int divisor) { if (divisor) {return dividendo / divisor; } else { printf (“No se puededividir por cero\n”); return 0; } }

En este caso, la expresión (divisor) es equivalente a (di-visor != 0).

29.2 Operadores lógicos

Los operadores && (“y”), || (“o”) y ! (“no”) son opera-dores lógicos. Permiten operar con expresiones lógicaspara generar expresiones más complejas.

Por ejemplo: determinar si un año es bisiesto o no. Losaños son bisiestos si son divisibles por 4, pero no si sondivisibles por 100, a menos que también sean divisiblespor 400.if ( (!(a % 4) && (a % 100)) || !(a % 400) ) { printf(“esun año bisiesto.\n”); } else { printf(“no es un añobisiesto.\n”); }

En realidad, teniendo en cuenta la prioridad de los ope-radores utilizados, podemos simplificar la expresión an-terior del siguiente modo:if ( !(a % 4) && (a % 100) || !(a % 400) ) { printf(“esun año bisiesto.\n”); } else { printf(“no es un añobisiesto.\n”); }

Además, como a cada rama del if le sigue una única ins-trucción, podemos expresar la expresión anterior del si-guiente modo:if ( !(a % 4) && (a % 100) || !(a % 400) ) printf(“es unaño bisiesto.\n”); else printf(“no es un año bisiesto.\n”);

En este caso, se utiliza el operador módulo (%), que ob-tiene el resto de la división entera de un número por otro.Cuando un número es divisible por otro, el resto de sudivisión entera será cero. Siendo que cero es equivalentea falso, y cualquier valor distinto de cero es equivalente averdadero, podemos usar el operador % para verificar siel número es múltiplo de 4, de 100 o de 400.

29.3 Evaluación de cortocircuito

La evaluación en corto circuito es una característica dellenguaje C que se utiliza para optimizar la ejecución deprogramas. Consiste en que el programa puede verificar siuna expresión es verdadera o falsa antes de haber evaluadotoda condición.Por ejemplo, si se tiene una condición como la siguiente:if ((a > 2) || (b < 4)) { ... }

Al ejecutarse el programa, se evaluará primero si a > 2.En el caso en que sea verdadero, no continuará con lasiguiente condición, ya que el resultado será de cualquiermodo verdadero.De la misma forma, si la condición fuera:if ((a > 2) && (b < 4)) { ... }

En este caso, si no se cumple que a > 2, no se evaluarála siguiente condición, ya que el resultado será falso detodos modos.Esta característica no tiene demasiada importancia al co-menzar a programar, pero facilitará ciertas operaciones yoptimizaciones en programas avanzados.

Page 13: Programación en C-Texto Completo

13

30 La estructura condicionalabierta y cerrada switch ...case

La estructura condicional switch ... case se utiliza cuandoqueremos evitarnos las llamadas escaleras de decisiones.La estructura if nos puede proporcionar, únicamente, dosresultados, uno para verdadero y otro para falso. Una es-tructura switch ... case, por su parte, nos permite elegirentre muchas opciones. Ejemplo:#include <stdio.h> #include <stdlib.h> int main(void) {int dia; printf(“que número de día de la semana es?");scanf("%d”,&dia); switch(dia) { case 1 : printf(“Lun,Lunes”); break; case 2 : printf(“Mar, Martes”); break;case 3 : printf(“Mier, Miercoles”); break; case 4 :printf(“Jue, Jueves”); break; case 5 : printf(“Vie, Vier-nes”); break; case 6 : printf(“Sab, Sabado”); break; case7 : printf(“Dom, Domingo”); break; default : printf(“Noexiste”); } return 0; }

La estructura anterior, de realizarse con sentencias if, ne-cesitaría cuatro de ellas, resultando un enorme bloquemuy difícil de leer. En la mayoría de los casos, además, lasentencia switch proporciona una ganancia en velocidaddel código, pues permite al compilador trabajar en basea que se trata de una decisión múltiple para una única va-riable, cosa que con sentencias if el compilador no tienepor qué detectar.Como vemos, para cada valor de la variable se ejecutaun bloque de sentencias distinto, en el que no necesita-mos llaves. Hay un caso especial, default, que se ejecutasi ningún otro corresponde, y que no es necesario poner.Es, en todo, equivalente al bloque else de una sentenciaif.Las sentencias break sonmuy importantes, ya que el com-portamiento normal de un bloque switch es ejecutarlo to-do desde la etiqueta case que corresponda hasta el final.Por ello, si no queremos que se nos ejecute más de un blo-que, pondremos sentencias break al final de cada bloqueexcepto el último.Es decir, las etiquetas case son puntos de entrada de laejecución, y no implican que al acabarse el bloque casela ejecución salte al final del bloque switch. Las etiquetascase siguientes a la que hemos utilizado para entrar son,sencillamente, ignoradas.A la ausencia de sentencias break se le llama, en ocasio-nes, “dejar caer la cascada switch”.

31 El bucle while

El bucle while sirve para ejecutar código reiteradas veces.while (/*condicion*/) { /* Código */ }

La condición debe de ser una expresión lógica, similar ala de la sentencia if. Primero se evalúa la condición. Siel resultado es verdadero, se ejecuta el bloque de código.Luego se vuelve a evaluar la condición, y en caso de darverdadero se vuelve a ejecutar el bloque. El bucle se cortacuando la condición da falso.Ejemplo: imprimir los números de 0 a 99:int i = 0; while (i < 100) { printf("%d\n”, i); i = i + 1; }

32 El bucle for

El bucle for es un bucle muy flexible y a la vez muy poten-te ya que tiene varias formas interesantes de implemen-tarlo, su forma más tradicional es la siguiente:for (/* inicialización */; /* condición */; /* incremento*/) { /* código a ejecutar */ }

Inicialización: en esta parte se inicia la variable que con-trola el bucle y es la primera sentencia que ejecuta el bu-cle. Sólo se ejecuta una vez ya que solo se necesita al prin-cipio del bucle.Expresión condicional: al igual que en el bucle while, estaexpresión determina si el bucle continuará ejecutándoseo no.Incremento: es una sentencia que ejecuta al final de ca-da iteración del bucle. Por lo general, se utiliza para in-crementar la variable con que se inicio el ciclo. Luegode ejecutar el incremento, el bucle revisa nuevamente lacondición, si es verdadera tiene lugar una ejecución másdel cuerpo del ciclo, si es falsa se termina el ciclo y así.Aquí se muestra el mismo ejemplo visto para el buclewhile, pero implementado con un bucle for:int i; for (i=0; i < 100; i = i + 1) { printf("%d\n”, i); }

Nota: En C, la sentencia i = i + 1 puede escribirse enforma más reducida como i++. Esta forma se utiliza máscomúnmente en el bucle for:int i; for (i=0; i < 100; i++) { printf("%d\n”, i); }

33 El bucle do...while

El bucle do...while es un bucle que, por lo menos, se eje-cuta una vez. Do significa literalmente “hacer”, y whilesignifica “mientras”Su forma es esta:do { /* CODIGO */ } while (/* Condición de ejecucióndel bucle */)

Page 14: Programación en C-Texto Completo

14 35 FUNCIONES

Os muestro un ejemplo sencillo de uso:int aleatorio; do { aleatorio = rand(); } while (aleatorio!= 25);

La verdad es que este ejemplo puede resultar un poco ab-surdo, pero es bastante intuitivo. El código del bucle asig-na un valor aleatorio a la variable definida anteriormente,y mientras esa variable no tenga el valor 25, el bucle sigueejecutándose.

34 La sentencia goto

La sentencia goto sirve para indicar al programa que con-tinue ejecutándose desde la línea de código indicada. Susintaxis es más o menos así:/* Código */ ETIQUETA: /* Código */ goto ETIQUE-TA; /* Código */

Así, cuando se ejecute la sentencia goto, el programa “sal-tará" y continuará su ejecución a partir de la etiqueta mar-cada.Como se puede observar se puede usar para crear un bu-cle, o para ir a una parte del código u otra si se combi-na con una sentencia if...else. Pero por lo general puedeobtenerse el mismo efecto utilizando los bucles anterior-mente vistos.Por eso, la sentencia goto es poco aceptada por la comuni-dad de programadores, pues puede provocar que se haganprogramas un poco “sucios” y confusos. Sólo en ocasio-nes muy excepcionales será recomendado el uso del gotoal crear iteraciones muy complejas. Sin embargo, con elpasar de los años este comando ya ha quedado práctica-mente descartado del lenguaje de los programadores.

35 Funciones

Como vimos anteriormente C tiene como bloque bási-co la función main() , también hemos visto la sentenciaprintf() que es otra función, y de igual forma hay mu-chas más funciones predefinidas, pero nosotros mismostambién podemos definir nuestras propias funciones. Dehecho, es fundamental hacerlo.Podemos definir una función cualquiera de la misma ma-nera en que definimos la función main(). Basta con ponersu tipo, su nombre, sus argumentos entre paréntesis y lue-go, entre llaves, su código:/* Inclusión de archivos */ #include <stdio.h> voidholamundo(void) /* Función donde se ejecuta la ló-gica del programa */ { printf(“Hola Mundo\n”); /*imprime la cadena */ return; /* sale de la función */

} int main(void) /* Función principal del programa */{ holamundo(); /* llamada a la función holamundo */return 0; /* sale del programa con código 0 (correcto) */ }

Este código es en todo equivalente al “Hola Mundo” ori-ginal, sólo que nos muestra cómo escribir y cómo utilizaruna función. Y además nos muestra un principio de buenaprogramación: meter las sentencias que “hacen el traba-jo” en otras funciones específicas para sacarlas de main(),dejando en ésta tan sólo un guión general de lo que haceel programa, no las órdenes específicas. De esta mane-ra se facilita la comprensión del programa, y por tanto elfuturo trabajo de modificarlo.

35.1 La sentencia return

La sentencia return puede utilizarse dentro de una funciónpara terminar su ejecución.En el ejemplo anterior, la función holamundo fue decla-rada con valor de retorno de tipo void (es decir, valor deretorno nulo). En ese caso, la sentencia return no llevaningún parámetro adicional, ya que la función no debedevolver ningún valor a la función que la llama.En cambio, la función main tiene un valor de retorno detipo int, por lo que return debe ir seguido de un valor en-tero (0 en el ejemplo). El valor 0 se utiliza para indicarque el programa ha llegado a un punto en el que todo seha desarrollado correctamente y se utiliza cualquier otrovalor para indicar que ha habido algún tipo de error.La instrucción return no es una función, se trata de unasentencia que lo que hace es retornar como valor de lafunción el valor que se le proporciona como argumento.

35.2 Argumentos

Las funciones también pueden recibir argumentos o pará-metros, para modificar su comportamiento. Por ejemplo,la definición de una función para sumar dos números seríade la siguiente manera:

35.3 Declaración y definición

En el ejemplo anterior podemos notar que la función su-mar figura en el código antes que main. ¿Qué pasaría silas escribiéramos en distinto orden?#include <stdio.h> int main(void) { int suma = su-mar(5, 3); /* ERROR, sumar no ha sido declarada aún*/ printf(“La suma es: %d ", suma); return 0; } intsumar(int numero1, int numero2) { return numero1 +numero2; }

En este caso el programa es erróneo y no compila, ya queen la línea donde se llama a la función sumar, el compi-

Page 15: Programación en C-Texto Completo

35.5 Variables Locales y Globales 15

lador aún no conoce ninguna función con ese nombre, ycuáles son sus argumentos y valor de retorno.Una posible solución es declarar el prototipo de la fun-ción al principio, para informar al compilador que existe,y luego definir el cuerpo de la misma en cualquier lugardel programa:#include <stdio.h> /* Declaración */ int sumar(intnumero1, int numero2); int main(void) { int suma =sumar(5, 3); printf(“La suma es: %d ", suma); return 0;} /* Definición */ int sumar(int numero1, int numero2){ return numero1 + numero2; }

35.4 Paso de Parámetros

Las funciones pueden recibir datos como lo hemos obser-vado, pero existen dos formas de enviar los datos haciauna función por valor y por referencia, las cuales mo-difican en diferente forma el comportamiento de el pro-grama.

35.4.1 Por Valor

El paso por valor envía una copia de los parámetros ala función por lo tanto los cambios que se hagan en ellano son tomados en cuenta dentro de la función main().Ejemplo:/* * por_valor.c * * Julio César Brizuela <[email protected]> 2009 * * para el wikilibro“Programación en C” * bajo licencia FDL, adaptadodel Dominio Público */ #include <stdio.h> void su-mar_valor(int numero); /* prototipo de la función */int main(void) { int numero = 57; /* definimos numerocon valor de 57*/ sumar_valor(numero); /* enviamosnumero a la función */ printf(“Valor de numero dentrode main() es: %d\n”, numero); /* podemos notar queel valor de numero se modifica * sólo dentro de lafunción sumar_valor pero en la principal * número siguevaliendo 57 */ return 0; } void sumar_valor(int numero){ numero++; /* le sumamos 1 al numero */ /* el valor denúmero recibido se aumenta en 1 * y se modifica dentrode la función sumar_valor() */ printf(“Valor de numerodentro sumar_valor() es: %d\n”, numero); return; }

35.4.2 Por Referencia

El paso por referencia se hace utilizando apuntadores. Seenvía la dirección de memoria de la variable, por lo tantolos cambios que haga la función si afectan el valor de lavariable. Ejemplo:/* * por_referencia.c * * Julio César Brizuela <[email protected]> 2009 * * para el wikilibro“Programación en C” * bajo licencia FDL, adaptado

del Dominio Público */ #include <stdio.h> void su-mar_referencia(int *numero); /* prototipo de la función*/ int main(void) { int numero = 57; /* definimosnumero con valor de 57*/ sumar_referencia(&numero);/* enviamos numero a la función */ printf("\nValor denumero dentro de main() es: %d ", numero); /* podemosnotar que el valor de numero se modifica * y que ahoradentro de main() también se ha modificado * aunque lafunción no haya retornado ningún valor. */ return 0; }void sumar_referencia(int *numero) { *numero += 1; /*le sumamos 1 al numero */ /* el valor de numero recibidose aumenta en 1 * y se modifica dentro de la función */printf("\nValor de numero dentro sumar_referencia() es:%d”, *numero); return; }

35.5 Variables Locales y Globales

Además de pasar valores a una función, también se pue-den declarar tipos de datos dentro de las funciones, estostipos de datos declarados dentro de una función solo sonaccesibles dentro de esta misma función y se les conocencomo variables locales, así pues podemos definir los mis-mos nombres de variables en diferentes funciones, ya queestas variables solo son accesibles dentro de esas funcio-nes. Ejemplo:/* * locales.c * * Julio César Brizuela <[email protected]> 2009 * * para el wikilibro“Programación en C” * bajo licencia FDL, adaptado delDominio Público */ #include <stdio.h> void funcion1(){ int dato = 53; /* definimos dato en 53*/ char num1 ='a'; /* num1 vale a */ /* imprimimos */ printf(“Funcion1,dato=%d, num1=%c\n”, dato, num1); return; } voidfuncion2() { int dato = 25; /* definimos dato en 25*/char num2 = 'z'; /* num2 vale z*/ /* imprimimos */printf(“Funcion2, dato=%d, num2=%c\n”, dato, num2);return; } int main(void) { funcion1(); /* llamamos afuncion1() */ funcion2(); /* llamamos a funcion2() */return 0; }

En este caso la variable dato, esta definida dentro de ca-da una de las funciones y son totalmente distinta una deotra y no se puede utilizar fuera de esta, así pues num2no puede ser utilizada por la funcion1() y num1 tampocopuede ser utilizada por funcion2().Existen pues variables que se definen fuera de la funciónprincipal main() y fuera de cualquier otra función creadapor nosotros, estas variables se les conoce con el nombrede Variables Globales ya que se pueden utilizar dentro demain() y dentro de cualquier función creada por nosotros.Ejemplo:/* * global.c * * Julio César Brizuela <[email protected]> 2009 * * para el wikilibro “Programa-ción en C” * bajo licencia FDL, adaptado del DominioPúblico */ #include <stdio.h> int variable_global = 99;/* inicializamos la variable global */ void funcion(); int

Page 16: Programación en C-Texto Completo

16 36 FUNCIONES RECURSIVAS

main(void) { /* imprimimos el valor*/ printf(“main(),acceso a variable_global %d\n”, variable_global); /*llamamos a la función */ funcion(); return 0; } voidfuncion() { /* imprimimos el valor*/ printf(“funcion(),acceso a variable_global %d\n”, variable_global); return;}

36 Funciones Recursivas

La recursividad (recursión) es la propiedad por la cual unafunción se llama a sí misma directa o indirectamente.La recursión indirecta implica utilizar más de una fun-ción.Se puede considerar la recursividad como una alternativaa la iteración. La recursión permite especificar solucionesnaturales, sencillas, que serían, en caso contrario, difíci-les de resolver. Toda función recursiva debe contemplarun caso base o condición de salida, para terminar, o larecursividad no podrá terminar nunca.Una función recursiva podría definirse así:funcion_recursiva( /* parámetros recibidos por la fun-ción */ ) { /* Código */ funcion_recursiva( ); /* llamadaa la función misma */ /* Código */ }

Uno de los ejemplos más representativos en la recursivi-dad es el factorial de un numero ( n! ):

n! =n∏

k=1

k ∀n ∈ N

la definición de recursividad del factorial es:

n! =

{1 Si n = 0

n(n− 1)! Si n > 0∀n ∈ N.

En esta definición, n = 0, es nuestro caso base, que le dafin a la recursividad.Entonces nuestro programa que calcula el factorial es:/* *factorial.c * * Julio César Brizuela <[email protected]> 2009 * * para el wikilibro“Programación en C” * bajo licencia FDL, adaptado delDominio Público */ #include <stdio.h> long factorial(intn) { if (n == 0) /* caso base */ return 1; /* como 0! = 1,se retorna 1*/ else return n * factorial (n - 1); /* llamadaa esta misma función */ } int main(void) { /* en estecaso se llama a la función y se imprime directamente*/printf("%ld ", factorial(5)); return 0; }

También existen otros tipos de funciones recursivas comolo es el producto de dos números. El producto de a × b,donde a y b son números enteros positivos seria:

Solución iterativa:

a× b =a+ a+ · · ·+ a︸ ︷︷ ︸

b veces=

∑bi=1 a

Solución recursiva:

a× b =

{0 Si b = 0

a+ a× (b− 1) Si b > 0

Así pues 7× 3 es:

7×3 = 7+7×2 = 7+7+7×1 = 7+7+7+0 = 21

Podemos ver que la multiplicación de dos números a, b sepuede transformar en otro problema más pequeño multi-plicar a por (b-1), el caso base se produce cuando b = 0y el producto es 0. Ejemplo:/* * producto.c * * Julio César Brizuela <[email protected]> 2009 * * para el wikilibro“Programación en C” * bajo licencia FDL, adaptado delDominio Público */ #include <stdio.h> int producto(inta, int b) { if (b == 0) /* caso base */ return 0; /* comob = 0, se retorna 0*/ else return a + producto (a, b -1); /* llamada a esta misma función */ } int main(void){ /* en este caso se llama a la función y se imprimedirectamente*/ printf("%i ", producto( 7, 3)); return 0; }

36.1 Recursividad indirecta o recursiónmutua

Esta se produce cuando una función llama a otra, que estaa su vez terminará llamando de nuevo a la primera fun-ción. El siguiente programa visualiza el alfabeto utilizan-do recursión indirecta o mutua:/* * elalfabeto.c * * Julio César Brizuela <[email protected]> 2009 * * para el wikilibro“Programación en C” * bajo licencia FDL, adaptadodel Dominio Público */ #include <stdio.h> void fun-cionA(char c); /* se declara el prototipo de la funciónpara que el llamado */ void funcionB(char c); /* a lamisma en la función no sea implícita */ int main(void){ funcionA('z'); /* llamado a funcionA */ return 0; }void funcionA(char c) { if (c > 'a') /* caso base mientrasc no sea menor que A */ funcionB(c); /* llamado a lafuncionB */ printf("%c ", c); /* imprimimos el valorde c */ *la variable es un parametro no utilizado paraeste proceso } void funcionB(char c) { funcionA(--c); /*llamado a la funcionA decrementando el valor de 'z' */ }

36.2 Recursión versus Iteración

Tanto la iteración como la recursión se basan en estructu-ra de control: la iteración utiliza una estructura repetitivay la recursión una estructura de selección. La iteración

Page 17: Programación en C-Texto Completo

36.2 Recursión versus Iteración 17

utiliza explícitamente una estructura repetitiva mientrasque la recursión consigue la repetición mediante llamadasrepetitivas a funciones.La iteración termina si la condición del bucle no se cum-ple, mientras que la recursión termina cuando se reconoceun caso base.La recursión puede presentar desventajas ante la iteraciónya que se invoca repetidas veces al mecanismo de llamadade funciones y se necesita un tiempo mayor para realizarcada llamada.La razón por la cual se puede elegir u optar por usar re-cursividad es que existen muchos problemas complejosque poseen naturaleza recursiva y, en consecuencia, sonmas fáciles de implementar.

36.2.1 Ejemplo Iterativo

/* * iterativo.c * * Julio César Brizuela <[email protected]> 2009 * * para el wikilibro“Programación en C” * bajo licencia FDL, adaptado delDominio Público */ #include <stdio.h> long factorial(intnumero); int main(int argc, char** argv) { int contador= 0; /* calcula el factorial de 0 a 10 */ for ( contador =0; contador <= 10; contador++ ) printf("%d! = %ld\n”,contador, factorial( contador )); return 0; } /* funcionfactorial iterativa */ long factorial( int numero ) { longresultado = 1; int i = 0; /* declaracion de la funciónfactorial iterativa */ for ( i = numero; i >= 1; i-- )resultado *= i; return resultado; }

36.2.2 Ejemplo Recursivo

/* * recursivo.c * * Julio César Brizuela <[email protected]> 2009 * * para el wikilibro“Programación en C” * bajo licencia FDL, adaptado delDominio Público */ #include <stdio.h> long factorial(intnumero); int main(int argc, char** argv) { int contador= 0; /* calcula el factorial de 0 a 10 */ for ( contador =0; contador <= 10; contador++ ) printf("%d! = %ld\n”,contador, factorial( contador )); return 0; } /* funciónfactorial recursiva */ long factorial( int numero ) { if (numero <= 0 ) /* caso base */ return 1; /* casos bases:0! = 1 y 1! = 1 */ else /* llamada recursiva */ returnnumero * factorial( numero - 1 ); /* llamada a la funciónfactorial */ }

Los vectores son una forma de almacenar datos que per-miten contener una serie de valores del mismo tipo, cadauno de los valores contenidos tiene una posición asociadaque se usará para accederlos. Está posición o índice serásiempre un número entero positivo.En C la cantidad de elementos que podrá contener un vec-tor es fijo, y en principio se define cuando se declara elvector. Los vectores se pueden declarar de la siguiente

forma:tipo_elemento nombre[largo];

Esto declara la variable nombre como un vector de ti-po_elementos que podrá contener largo cantidad de ele-mentos, y cada uno de estos elemento podrá contener unvalor de tipo tipo_elemento.Por ejemplo:double valores[128];

En este ejemplo declaramos un vector de 128 elementosdel tipo double, los índices de los elementos irían entre 0(para el primer elemento y 127 para el último).De la misma forma que con las otras declaraciones devariables que hemos visto se le puede asignar un valoriniciar a los elementos.O también se pueden declarar:tipo_elemento nombre[largo]={valor_0, valor_1, va-lor_2};

En caso estamos asignadole valores a los primeros 3 ele-mentos del vector nombre. Notar que largo debe ser ma-yor o igual a la cantidad de valores que le estamos asig-nando al vector, en el caso de ser la misma cantidad noaporta información, por lo que el lenguaje nos permiteescribir:tipo_elemento nombre[]={valor_0, valor_1, valor_2};

Que declarará nombre como el vector de largo 3.Para acceder a un elemento accederemos a través de suposición. Es decir:tipo_elemento elemento; ... elemento = nombre[2];

Asumiendo que tenemos el vector anterior definido esta-ríamos guardando valor_2 en elemento.Veamos algunos ejemplos:/* * Ejemplo : El producto escalar de dos vectores */#include <stdio.h> double producto_escalar(double v1[],double v2[], int d); int main() { const int largo = 3; doublevector_1[] = {5,1,0}; double vector_2[] = {−1,5,3};double resultado = producto_escalar(vector_1, vector_2,largo); // imprime el resultado printf("(%f, %f, %f). (%f, %f, %f) = %f\n”, vector_1[0], vector_1[1],vector_1[2], vector_2[0], vector_2[1], vector_2[2],resultado); return 0; } /* producto escalar entre dosvectores */ double producto_escalar(double v1[], dou-ble v2[], int d) { double resultado = 0; int i; for (i=0; i< d; i++) { resultado += v1[i] * v2[i]; } return resultado; }

En el ejemplo anterior usamos los vectores de C para re-presentar vectores matemáticos y calcular el producto es-

Page 18: Programación en C-Texto Completo

18 36 FUNCIONES RECURSIVAS

calar entre ellos. Una peculiaridad que se puede notar esque al recibir un arreglo en una función no se especificael largo, volveremos a esto en un capítulo posterior.Otra función clásica es la búsqueda de un máximo o mí-nimo, que podemos escribirla de la siguiente manera:int buscar_maximo(double valores[], int num_valores) {int maximo_pos = 0; for (int i = 1; i < num_valores; i++){ if (valores[i] > valores[maximo_pos]) { maximo_pos= i; } } return maximo_pos; }

Otro ejemplo sencillo, calcular el promedio de los valores.double promedio(double valores[], int largo) { doublesuma=0; for (int i=0;i<largo;i++) { suma+=valores[i]; }return suma/largo; }

Cuando una función recibe un vector por parámetro ycambia su contenido y el cambio es permanente (se ve aúnfuera de la función). Esto puede parecer extraño despuésdel énfasis que pusimos en resaltar que todos los paráme-tros de una función se reciben por valor, pero se aclararáen el siguiente capitulo.Mientras tanto usemos esto para definir una función quele aplique otra función que recibe por parámetro a cadaelemento del vector, guardando el resultado en el mismovector y una llamada de ejemplo a esta.void cuadrados(double vector[], int largo) { for (inti=0;i<largo;i++) { vector[i]=cuadrado(vector[i]); } } ...double cuadrado(double valor) { return valor*valor; } ...cuadrados(elementos,num_elem); ...

De la misma forma que venimos usando vectores de ti-pos básicos, podemos tener vectores de vectores, estos sedeclaran de la siguiente forma:int matriz[3][7]; int tabla[3][4]={ { 1, 2, 3, 4}, { 5, 6,7, 8}, /* los espacios y saltos de líneas no son tomadosen cuenta */ { 9,10,11,12} }; double v[2][2][2]; ...printf(“tabla[0][1]: %i\n”, tabla[0][3]); // Imprime 4printf(“tabla[2][0]: %i\n”, tabla[2][0]); // Imprime 9 ...

En este ejemplo tabla es un vector de longitud 3, cuyoselementos son vectores de longitud 4 de elementos de tipoint.En resumen, suponiendo que v[n] es un vector de cual-quier tipo de dato con n cantidad de posiciones, al vectorv se le aplican las siguientes reglas:

1. La primera posición siempre será v[0]

2. La última posición es v[n-1]

3. En versiones previas a C99 n es una constante defi-nida antes de la declaración de v[n]

Page 19: Programación en C-Texto Completo

19

37 Text and image sources, contributors, and licenses

37.1 Text• Programación en C/Texto completo Fuente: http://es.wikibooks.org/wiki/Programaci%C3%B3n%20en%20C/Texto%20completo?

oldid=171299 Colaboradores:Maxy y Drinibot

37.2 Images

37.3 Content license• Creative Commons Attribution-Share Alike 3.0