programar en c - parte 1

36
El lenguaje C 1.12 Historia de C y sus autores El lenguaje C est´ a asociado al desarrollo del sistema Operativo UNIX. 1969 K. Thompson y D. Ritchie crean UNIX. —- lenguaje B de Ken Thomson (Bell labs.), BCPL. 1972 Dennis Ritchie crea el lenguajeC. Prop´ositoprogramarsobre UNIX m´as f´acil que en asembler y dar portabilidad a los programas. 1973 El primer UNIX basado en C, (90%) corre en la PDP11 1978 Se publica el libro de Brian Kernigan y Dennis Ritchie. El C de Ritchie se conoce desde entonces con el nombre de C de K y R. 1980 Barne Stroustrup crea C++, que agrega conceptos de programaci´on orientada a objetos. 1983 El American National Standard Institute define el ANSI C 1990 La International Standard Organization define su estandar para C, el ISO C. 1.13 Caracter´ ısticas del lenguaje C En la palabras de Kernighan y Ritchie, en el prefacio de la primera edici´on de su libro The C pro- gramming lenguage, [11], C es un lenguaje de programaci´ on de prop´osito general con econom´ ıa de expresi´ on, estructuras de datos y control de flujo modernos y un rico conjunto de operadores. C no es un lenguaje de “muy alto nivel”, asi como no es “grande”, ni tampoco es especializado a alguna ´ area especial de aplicaci´ on. Pero esta ausencia de restricciones y su generalidad lo hace, para muchas tareas, m´as conveniente y efectivo que otros lenguajes supuestamente m´as poderosos. No obstante lo dicho, originalmente C se cre´ o y us´o para suplantar al lenguaje ensamblador en el desarrollo de aplicaciones portables para el sistema operativo UNIX, y luego en la programaci´on de casi todo el sistema operativo Linux. Su uso como lenguaje de programaci´on en ciencias es m´as reciente y ha tomado importancia desde los a˜ nos 80 con el desarrollo de C++ y la metodolog´ ıa orientada a objetos. Se han desarroldo muchos programas de uso cient´ ofico y t´ ecnico con C. En el campo de la Mec´anica de Fluidos se destaca OpenFOAM. En el campo de la visualizaci´on se destacan la librer´ ıa VTK, Salom´ e, la plataforma integrada para simulaci´ on num´ erica de EDF (Electricite de France), etc. Es com´ un caracterizar al lenjuage C con los siguientes adjetivos: peque˜ no de bajo nivel peligroso

Upload: rociovelardez

Post on 15-Apr-2016

45 views

Category:

Documents


2 download

DESCRIPTION

Una pequeña guía para los que quieran iniciar en este lenguaje de programación.

TRANSCRIPT

Page 1: Programar en C - Parte 1

El lenguaje C

1.12 Historia de C y sus autores

El lenguaje C esta asociado al desarrollo del sistema Operativo UNIX.

1969 K. Thompson y D. Ritchie crean UNIX.

—- lenguaje B de Ken Thomson (Bell labs.), BCPL.

1972 Dennis Ritchie crea el lenguaje C. Proposito programar sobre UNIX mas facil que en asemblery dar portabilidad a los programas.

1973 El primer UNIX basado en C, (90%) corre en la PDP11

1978 Se publica el libro de Brian Kernigan y Dennis Ritchie. El C de Ritchie se conoce desdeentonces con el nombre de C de K y R.

1980 Barne Stroustrup crea C++, que agrega conceptos de programacion orientada a objetos.

1983 El American National Standard Institute define el ANSI C

1990 La International Standard Organization define su estandar para C, el ISO C.

1.13 Caracterısticas del lenguaje C

En la palabras de Kernighan y Ritchie, en el prefacio de la primera edicion de su libro The C pro-gramming lenguage, [11], C es un lenguaje de programacion de proposito general con economıa de

expresion, estructuras de datos y control de flujo modernos y un rico conjunto de operadores. C no

es un lenguaje de “muy alto nivel”, asi como no es “grande”, ni tampoco es especializado a alguna

area especial de aplicacion. Pero esta ausencia de restricciones y su generalidad lo hace, para muchas

tareas, mas conveniente y efectivo que otros lenguajes supuestamente mas poderosos.

No obstante lo dicho, originalmente C se creo y uso para suplantar al lenguaje ensamblador en eldesarrollo de aplicaciones portables para el sistema operativo UNIX, y luego en la programacion decasi todo el sistema operativo Linux.

Su uso como lenguaje de programacion en ciencias es mas reciente y ha tomado importancia desdelos anos 80 con el desarrollo de C++ y la metodologıa orientada a objetos. Se han desarroldo muchosprogramas de uso cientofico y tecnico con C. En el campo de la Mecanica de Fluidos se destacaOpenFOAM. En el campo de la visualizacion se destacan la librerıa VTK, Salome, la plataformaintegrada para simulacion numerica de EDF (Electricite de France), etc.

Es comun caracterizar al lenjuage C con los siguientes adjetivos:

• pequeno

• de bajo nivel

• peligroso

Page 2: Programar en C - Parte 1

xvi

Pequeno ¿Que significa que sea pequeno?. Significa que existen solo un numero relativamentepequeno de funciones predefinidas. El Estandard de C se limita a definir las sentencias, operadoresbasicos y sentencias de control de flujo. No define en cambio la interaccion con perifericos, mouse,ventanas, listados de directorio etc. etc.

Muchas de estas cosas dependen del entorno de trabajo particular, por ejemplo, del compilador, delprocesador, del SO. De manera que o se dejan libradas a la habilidad del programador, o son incluidasen librerıas de subrutinas.

Bajo nivel. Las estructuras que implementa son de un nivel bajo de abstraccion, (en este sentido nopodrıamos decir que tiene menos nivel de abstraccion que Fortran o Basic).

Peligroso. Con C puede hacerse lo que se quiera. No hay restricciones en lo que se puede programar.Pueden modificarse cualquier lugar de memoria, cualquier registro, cualquier posicion en el disco duro.

Para muchos lenguajes de programacion existen, en el tiempo de compilacion algunas salvaguardasque impiden que algunas sentencias se ejecuten si en ellas se direcciona lugares de memoria que nohan sido reservados para el programa. Este no es el caso de C. Cualquier sentencia sintacticamentecorrecta sera compilada, aun cuando sea peligrosa para el sistema.

1.14 El desarrollo de un programa en C

Existen varias etapas globales en el desarrollo de un program compilado, y en particular en C, estasson:

• Escritura del codigo fuente.

• Compilacion.

• Ejecucion.

• Depuracion de errores

Estas etapas se desarrollan en un ciclo. El estudio de estos ciclos con el proposito de desarrollarprogramas en forma eficiente se denomina ingenierıa de software. El ciclo de vida de un programagrande puede abarcar las siguientes etapas (modelo de cascada) con su costo relativo entre parentesis:

• Analisis del sistema. Que debe hacer el soft y que el hard.

• Analisis de requerimientos. Que debe hacer el soft.

• Diseno (60%). Como se lo llevara a cabo.

• Escritura del codigo fuente, (15%).

• Prueba y depuracion de errores, (25%).

• Mantenimiento. Cambios por errores o cambios de los requerimientos. Puede resultar tan costosocomo el 50-70 % del costo del proyecto.

1.14.1 Edicion del codigo fuente

El codigo fuente, o el programa fuente, o simplemente el programa es el texto con la secuenciade instrucciones que se archiva codificado como texto comun o codigo mASCII. Los archivos concodigo fuente en lenguaje C se distinguen por que se nombran agregando la extencion .c, por ejemplorungek.c.

La escritura del codigo fuente se realiza, en el ambiente de Linux, utilizando un editor de textocualquiera, o si se prefiere, utilizando algun entorno de desarrollo como Kdevelop o Eclipse. En estecurso escribiremos nuestros programas usando algun editor de textos mas o menos simple pero interfaz

Page 3: Programar en C - Parte 1

cursoC/curso/lenguajeC.tex -August 23, 2012 xvii

Figure 1.2: La ventana del editor gedit. OJO CAMBIAR FIGURA

grafica, tal como pueden ser Gedit, Kwrite o Kate (por supuesto, si se prefiere podra usarse los clasicosextremos vi o emacs, u otros como pico o nano).

Por ejemplo, con Kate podemos crear un archivo, que llamamos hola.c

1 #include <stdio.h>

2 /* este es el programa minimo*/

3 main()

4 {

5 printf("Hola todos.\n");

6 return 0;

7 }

Recuerde, los numeros a la izquierda son solo a los efectos de la presentacion impresa del programa.

Por ejemplo, a continuacion se presenta la ventana del editor Kate con el mismo codigo presentadoarriba;

Kate abre dos ventanas de trabajo, la ventana superior la edicion del texto y la ventana de abajopara la terminal. De manera que se puede trabajar conveniente en la edicion del texto y en la lıneade comandos para la etapa de compilacion. Kate tiene algunas ventajas avanzadas presentadas enun modo grafico agradable, por ejemplo, como el resaltado de sintaxis, mecanismo que marcainteligentemente los distintos tokens del programa, utilizando colores y tipografıas definidas:

• Con verde las directivas al compilador.

• Con gris claro y letra italica los comentarios

• Con negro las sentencias en general.

• Con rojo las cadenas de caracteres.

Page 4: Programar en C - Parte 1

xviii

Figure 1.3: La ventana del editor Kdevelop

Figure 1.4: La ventana del editor Eclipse

Page 5: Programar en C - Parte 1

cursoC/curso/lenguajeC.tex -August 23, 2012 xix

• Con violeta los caracteres de control de impresion

• Con azul los valores constante

Podra aprender mas sobre este editor en Manual del editor Kate, [1], que dispone en lınea.

1.14.2 Compilacion

Ahora, una vez que el programa ha sido escrito y guardado en un archivo, debe compilarse. Lacompilacion es la etapa en la cual convertimos nuestro codigo fuente en lenguaje de maquina. Tienenvarias subetapas que veremos luego. Recien, luego de la compilacion podremos ejecutar un programa.La compilacion se hace usando un programa (o series de programas) que por ahora llamaremos elcompilador. En UNIX el compilador de C se denomina CC y en Linux, el compilador es gcc.

Siguiendo con el ejemplo, podemos compilar el programa hola.c de la siguiente manera, la mascencilla, sin opciones

1 cardon@cardo:~/cursoC/curso > gcc hola.c

2 cardon@cardo:~/cursoC/curso > a.out

3 Hola todos.

4 cardon@cardo:~/cursoC/curso >

5

en la lınea 1 se compila el programa hola.c, en la lınea 2 se lo ejecuta, y en la lınea 3 se obtiene elresultado de la ejecucion, el mensaje ”Hola todos.” en la terminal.

El resultado del proceso de compilacion es un archivo ejecutable o binario, que por defecto se llamaa.out. Lo cual es bastante incomodo, ya que preferirıamos denominarlo de alguna manera especıfica.Para ello se usa la opcion -o (de output) seguida del nombre que querramos dar a nuestro programaejecutable. Por ejemplo, si saluda el nombre elegido para nuestro binario.

cardon@cardo:~/cursoC/curso > gcc -o saluda hola.c

cardon@cardo:~/cursoC/curso > saluda

Hola todos.

cardon@cardo:~/cursoC/curso >

1.14.3 Ejecucion

Una vez compilado un programa podemos ejecutarlo de la misma manera que se ejecuta cualquier otrocomando en Linux. De hecho, muchos de los comandos en Linux son programas en C. De manera quepara ejecutar un programa solo debemos invocar su nombre en la terminal y oprimir la tecla enter.En el caso de la compilacion sin opciones

cardon@cardo:~/cursoC/curso > a.out

Hola todos.

cardon@cardo:~/cursoC/curso >

o en el segundo caso

cardon@cardo:~/cursoC/curso > saluda

Hola todos.

cardon@cardo:~/cursoC/curso >

En ambos casos, la salida de este programa es un mensaje por la pantalla Hola todos..

Page 6: Programar en C - Parte 1

xx

Dependiendo de como este configurada nuestra variable PATH, puede ocurrir que en algunos casos elsistema no busque en nuestro directorio de trabajo el programa que se quiere ejecutar, como en elcaso siguiente

1 cardon@cardo:~/A-cursos/cursoC/curso> hola

2 bash: hola: command not found

3 cardon@cardo:~/A-cursos/cursoC/curso>

la shell bash envıa entonces el mensaje de la lınea 2, diciendo que no ha encontrado el comando. Sieste fuera el caso (configuracion por defecto de la shell bash), se puede instruir a la shell que buesqueel binario del comando a ejecutar en el directorio corriente, lo que se hace anteponiendo al comandoel sımbolo ./

cardon@cardo:~/cursoC/curso > ./saluda

Hola todos.

cardon@cardo:~/cursoC/curso >

1.14.4 Depuracion de errores

Una vez que podemos ejecutar el programa tendremos que ocuparnos de la depuracion de errores,que generalmente es un etapa mucho mas larga que la de desarrollo del programa. Luego veremosherramientas que nos pueden ayudar con la tarea.

Como recomendacion a los principiantes, y a los que no los son, no debe escribir un programa demuchas lıneas para luego compilar todo el conjunto. Usualmente quedara apabullado por la multitudde errores. Compile de pocas lıneas por vez, y ayudese con los mensajes de error para depurar sucodigo, luego continue con la edicion. Para esto es sumamente util trabajar con dos ventanas, unapara la edicion y otra para la complilacion y ejecuacion.

Le doy dos consejos. El primero

Avance sobre seguro!avance de a poco.

y compile y corrija sus errores sintacticos mientras esta trabajando en el mismo codigo que los produce.

El segundo, para cuando ya sea un mas avezado programador, es un viejo dicho, o principio, que datade los anos 60. Mantengalo Estupidamente Simple!. En su version original en ingles, el dichose conoce como el principio KISS, Keep it Stupid Simple o en su version mas agresiva, sin animode ofender, Keep it Simple, Stupid!. Volveremos mas sobre este principio cuando hablemos defunciones.

Page 7: Programar en C - Parte 1

cursoC/curso/lenguajeC.tex -August 23, 2012 xxi

1.15 Un programa basico

Un programa en C consiste en una o mas funciones. Por lo menos debe existir una funcion, lafuncion principal que se denomina main. La funcion main contiene las sentencias o instrucciones queejecutaran las tareas encomendadas a nuestro programa. Las sentencias son a su vez combinacionesde constantes numericas o alfanumericas, variables y operadores que expresan las instrucciones que senecesita ejecutar para llevar adelante la marcha de un algoritmo.

Si el proposito es llevar al estudiate a una rapida idea del lenguaje y como se puede escribir programascon el y realizar tareas dentro de su dominio de aplicacion, resultarıa tedioso y poco instructivodescribir en mucho detalle las partes constituyentes del lenguaje, terminos tales como funciones,variables, operadores, tipos de datos, etc. Por ello, al estilo de K&R supondre que el estudiante tieneun conocimiento general de todos estos terminos y su significado, para pasar a mostrar inmediatamentecomo es un programa en C. Luego podremos ir a los detalles.

La funcion principal, ademas de su encabezamiento y cuerpo, se escribe introduciendo sentencias oinstrucciones, que son las unidades basicas del mismo. Cuando el programa se ejecuta, estas sentenciasse ejecutan una por una en forma secuencial

Existen dos clases de sentencias

• Sentencias de expresion.

• Sentencias de control de flujo.

La sentencias correspondientes a la primera categorıa se utilizan para asignar valores a una variable,para declarar variables, evaluar expresiones, llamar a funciones, etc.. Se distinguen sintacticamentepor que terminan con un caracter especial, el terminador, que en C es el signo de punto y coma,;.Algunos ejemplos son los siguientes

i=0;

i=i*1;

j= i++;

x = sqrt(a*a + b*b);

printf("Hola\n");

Una sentencia de expresion puede usarse para calcular expresiones matematicas simples o complejas,pero siempre queda definida por la existencia del terminador.

Las sentencias de control de flujo no tienen como proposito llevar a cabo alguna operacion, comolas anteriores, sino controlar el flujo de programa, es decir el orden, y la cantidad de veces o lacondicionalidad con que otras sentencias del programa se ejecutaran.

Algunos autores distinguen una categorıa adicional, las sentencias combinadas. Estas son todasaquellas que constituyen un bloque encerrado por un par de llaves.

El siguiente es el codigo fuente de un programa sencillo en C, cuyo objetivo es asignar sucesivamenteun valor creciente a una variable i e imprimir ese valor en la terminal

1 #include <stdio.h>

2 /* imprime una lista de numeros */

3 main ()

4 {

5 int i;

6 for (i=0; i<10; i=i+1)

7 printf("i es %d\n",i);

8 return 0;

9 }

Las partes de este programa son, en la lınea 1 una directiva al preprocesador. En la lınea 2 un letrerocon el nombre del programa. En la lınea 3 la llamada a la funcion main, funcion de mayor jerarquıa

Page 8: Programar en C - Parte 1

xxii

de todo programa C. La definicion de la funcion main ocupa todo el resto del programa, desde lalınea 3 hasta la lınea 9. Las llaves que se abren en la lınea 3 y se cierran en 9 constituye un bloquede sentencias, que en este caso son el cuerpo de la funcion main. En la lınea 5 se declara la variablei. La declaracion de una variable origina que se reserve memoria para ella y se asocia el nombre dela variable al contenido de esa memoria. En la lınea 6 comienza un sentencia de control de flujo, lasentencia for que permite hacer una repeticion controlada de la sentencia que esta inmediatamentedebajo de ella. En la lınea 7 se llama a una funcion, la funcion printf de la librerıa de entrada ysalida stdio.a cuyos prototipos se encuentran en el archivo stdio.h, que sera incluido en el texto delprograma por el preprocesador a instancias de la directiva de la lınea 1. Finalmente, en la sentencia8 se devuelve el control a la shell.

Una vez escrito el programa debe ser compilado para que pueda ejecutarse.

cardon@cardo:~/cursoC/curso > gcc -o cuenta cuenta.c

y finalmente puede ejecutar el programa. En el listado siguiente se muestra la invocacion del programay su salida en la terminal

cardon@cardo:~/cursoC/curso > cuenta

i es 0

i es 1

i es 2

i es 3

i es 4

i es 5

i es 6

i es 7

i es 8

i es 9

cardon@cardo:~/cursoC/curso >

1.15.1 Mensajes del compilador

Es sumamente frecuente que al programar se cometan errores de sintaxis. Al contrario de lo que ocurrecon los lenguajes de programacion interpretados, como por ejemplo QBasic, en el que el entorno dedesarrollo y el editor detecta inmediatamente un error de sintaxis, y como en nuestro caso se trabajacon un editor de texto comun, este no puede detectar los errores de sintaxis cometidos. Estos errores, silos hubiera, son detectados en la etapa de compilacion y son listados por el compilador en la terminal.

Para mostrar un ejemplo, si se suprime el terminador en la sentencia de declaracion en la lınea 5 deprograma anterior, la compilacion dara el siguiente mensaje de error

ardon@cardo:~/A-cursos/cursoC/curso/programas> gcc -o cuenta cuenta.c

cuenta.c: En la funcion ‘main’:

cuenta.c:6: error: error sintactico before "for"

cuenta.c:6: error: ‘i’ undeclared (first use in this function)

cuenta.c:6: error: (Each undeclared identifier is reported only once

cuenta.c:6: error: for each function it appears in.)

cuenta.c:6: error: error de decodificacion before ’)’ token

cardon@cardo:~/A-cursos/cursoC/curso/programas>

El mensaje da cuenta de que en el codigo cuenta.c, en la lınea 6 de la funcion main, existe un errorsintactico. Que el error se ha cometido antes de for. Avisa tambien que la variable i no ha sidodeclarada. Observe que en este caso el error no esta en la lınea 6, sino en la lınea anterior, pero comono hay nada antes de for usted puede suponer que el error esta en la lınea previa. Corregido el error,si la compilacion es exitosa, no da ningun mensaje de ningun tipo.

Cometamos otro tipo de error frecuente. Omitamos la declaracion de la variable i.

Page 9: Programar en C - Parte 1

cursoC/curso/lenguajeC.tex -August 23, 2012 xxiii

cardon@cardo:~/A-cursos/cursoC/curso/programas> gcc -o cuenta cuenta.c

cuenta.c: En la funcion ‘main’:

cuenta.c:6: error: ‘i’ undeclared (first use in this function)

cuenta.c:6: error: (Each undeclared identifier is reported only once

cuenta.c:6: error: for each function it appears in.)

cardon@cardo:~/A-cursos/cursoC/curso/programas>

Nuevamente, el mensaje avisa que en el programa cuenta.c en la lınea 6 la variable i, usada porprimera vez aqui, no esta declarada (undeclared). Luego el mensaje le advierte que cada variable nodeclarada (undeclared identifier) sera reportada solo una vez, por cada funcion en la que aparezca.

Otro error comun, al menos para quienes programa en otros lenguajes, es cambiar los separadoresdentro de la sentencia de control del for. Por ejemplo, si en la lınea 6 escribimos

for (i=0; i<10,i=i+1) // error: note que se ha substitudi ; por ,

cardon@cardo:~/A-cursos/cursoC/curso/programas> gcc -o cuenta cuenta.c

cuenta.c: En la funcion ‘main’:

cuenta.c:6: error: error de decodificacion before ’)’ token

cardon@cardo:~/A-cursos/cursoC/curso/programas>

En esta caso, el mensaje avisa que el error se cometio antes del signo ).

1.16 Partes de un programa en C

Un programa fuente en C se divide en dos partes completamente distintas, no obstante ambas coexistenen el mismo archivo con el codigo fuente:

• La seccion de directivas al precompilador

• La seccion del codigo fuente propiamente dicho

Cada una de estas partes tiene propositos diferentes y seran procesadas por programas diferentes.Como ya habıamos anunciado, la compilacion se realiza en varias etapas. Todas ellas son lanzadasuna a continuacion de otra cuando se usa el comando gcc como en los ejemplos precedentes. Noobstante, en cada una de estas etapas se realizan tareas distintas y estas son realizadas por programasdistintos.

La primera de estas tareas es justamente la de preprocesamiento. La segunda es la tarea decompilacion. En realidad esta segunda etapa abarca varias fases que veremos en seguida. Tiene porobjeto construir un programa ejecutable.

1.16.1 Directivas al preprocesador

Los programas en C requieren por lo general la inclusion de codigo estandar, previamente escrito,relacionado a las funciones provistas en librerıas, y que serıa sumamente tedioso tener que incluirmanualmente en cada caso. Este es un ejemplo tıpico de trabajo que puede realizar el preprocesador.Un ejemplo de directiva al compilador se vio en la lınea 1 del programa anterior, en donde la directiva#include instruye al preprocesador la inclusion del archivo stdio.h.

El programa preprocesador, llamado cpp, distingue las directivas que van destinadas a el por el sımbolo# que las precede. El programa cpp es lanzado automaticamente por el programa compilador por loque, por lo general, no debemos preocuparnos por el.

Las directivas comienzan con el sımbolo # y tienen una sintaxis de lınea, lo que significa que ladirectiva termina al final de la lınea. Todo lo que no este precedido por el sımbolo # sera procesadopor el compilador.

Page 10: Programar en C - Parte 1

xxiv

Como en el ejemplo presentado como motivacion, una de las tareas principales del preprocesador eshacer substituciones textuales, es decir, cambiar en el codigo las directivas por texto, que el procesadorbuscara en lugares predeterminados. Existen otras tareas del preprocesador, como hacer compilacionescondicionales.

Inclusion de archivos

Una de las directivas mas comunes, como digimos, es la de substitucion de archivos, la directivainclude.

Para poder hacer uso de ciertas funciones de librerıa, muy comunes, C requiere que los llamadosprototipos (ya veremos luego que son) de esas funciones esten precentes al comenzar el codigo fuente.Como serıa muy tedioso tener que escribirlas cada vez, estos prototipos se hallan disponibles en losllamados archivos de encabezado. Los archivos de encabezados son archivos estandares que acompanana cada librerıa de subrutinas, y se los identifica con la extension h, (del ingles header, encabezados).Los archivos de encabezados estan escritos, por supuesto, en C.

Las dos directivas siguientes hacen que el contenido de los archivos de encabezados, encabezado.h,sean incluido en el archivo con el resto del programa

#include <encabezado.h>

#include "encabezado.h"

Notese la diferencia de sintaxis en una y otra directiva. En una el nombre del archivo esta encerradoentre los sımbolos de menor y mayor, < >, en la otra entre comillas, " ". Ambas causan que el con-tenido del archivo encabezado.h sea leido e incuido en el lugar del programa donde se encuentra ladirectiva include. En la primera version de la directiva, en la que se uso < encabezado.h>, el pre-procesador busca el archivo en el directorio estandar, que en el sistema SUSE LINUX es /usr/includeo alguno de sus subdirectorios

En la segunda, el archivo ”encabezado.h” se busca en el directorio de trabajo corriente. La primera seusa para las subrutinas estandares de C, mientras que la segunda se usa para subrutinas de nuestropropio desarrollo que no hayamos puesto todavıa en una ubicacion estandar.

El ejemplo tıpico es el de la directiva

#include <stdio.h>

que tenemos que poner en casi cualquier programa de C.

Bajo el control de esta directiva el preprocesador subtituye la directiva por el contenido del archivostdio.h, (standar input output), entradas y salidas estandares, un archivo de declaraciones que cor-responde a la librerıa de funciones de entrada y salida de C.

Terminado el preprocesamiento, el archivo resultante que contiene solo codigo C, es pasado al compi-lador.

Existen tres clases de substituciones textuales

• inclusion de archivos

• substitucion de macros

• compilacion condicional

Veremos las dos ultimas mas adelante.

Definicion de macros

La directiva define es otra muy usada. Con ella se pueden dar un nombres a constantes de usofrecuente. En el programa podemos usar ahora el nombre otorgado en vez de la cosntante. Antes de

Page 11: Programar en C - Parte 1

cursoC/curso/lenguajeC.tex -August 23, 2012 xxv

la compilacion, el preprocesador reemplazara la ocurrencia del nombre (substitucion textual) por elvalor de la constante.

Por ejemplo

1 #include <stdio.h>

2 #define PI 3.141592653589793

3 main ()

4 {

5 ...

6 theta_gardos=theta_rad* 180 / PI;

7 ...

8 }

Dejaremos para mas adelante el desarrollo de macros mediante esta directiva.

1.17 La funcion principal.

Un programa C consiste en una o mas funciones o modulos. La funcion es la unidad estructural masgrande de un programa C. La funcion principal, la funcion main siempre debe estar presente.

Por ejemplo, el siguiente codigo fuente representa el esqueleto de la funcion main

1 main ()

2 {

3 }

Las llaves delimitan el cuerpo o bloque definitorio de la funcion. Entre ellas se escriben las sentenciasque realizaran la tarea de la funcion. En este caso, el cuerpo de la funcion esta vacıo. Aunque elcodigo mostrado no hace nada, es una funcion principal valida, y sera correctamente compilada. Elbinario resultante podra ser ejecutado por el sistema operativo.

Apenas mas realista, el programa hola.c ya visto

1 #include <stdio.h>

2 main ()

3 {

4 printf(‘‘hola mundo \n’’);

5 }

Ahora el cuerpo de la funcion principal contiene una sentencia que imprimira nuestro saludo.

Decıamos que un programa C consiste en una o mas funciones. Para ejemplificar que significa estoconsidere el siguiente codigo

1 #include <stdio.h>

2 void mifuncion()

3 {

4 printf(‘‘hola mundo desde mi funcion\n’’);

5 }

6 main ()

7 {

8 printf(‘‘hola mundo desde la funcion main\n’’);

9 mifuncion();

10 }

las lıneas 2 a 5 definen la funcion mifuncion, mientras que las lıneas 6 a 10, definen la funcion main.

Page 12: Programar en C - Parte 1

xxvi

El orden en que se han dispuesto las dos funciones se debe a que el compilador requiere saber de lasfunciones que posiblemente seran llamadas a ejecutarse antes de que estas sean llamadas en el codigoque las llama.

Es posible avisar al compilador que usaremos la funcion mifuncion y como se usa, escribiendo elprototipo de la misma antes de la funcion main, luego podemosescribir la definicion de la funcion encualquier sitio. Personalmente prefiero esta ultima forma de trabajar.

1 #include <stdio.h>

2 void mifuncion(); // prototipo de la funcion mifuncion

3 main ()

4 {

5 printf(‘‘hola mundo desde la funcion main\n’’);

6 mifuncion();

7 }

8 void mifuncion()

9 {

10 printf(‘‘hola mundo desde mi funcion\n’’);

11 }

La lınea 2 es el prototipo de la funcion mifuncion. Indica el nombre y los parametros que usa. Indicatambien que tipo de valor devuelve la funcion, en este caso la devolucion es vacıa. El prototipo de unafuncion es una sentencia de declaracion y por lo tanto lleva el sımbolo de terminacion. Por el lugarde la declaracion de funcion, antes de la funcion main el ambito de la funcion declarada es gobal esdecir se puede usar en todo el programa y podra ser llamada por cualquier otra funcion del programa.Ampliaremos mucho mas este tema en el capıtulo 5.

La tarea que debe realizar la funcion debe definirse en el cuerpo de la funcion. En los ejemplosprecedentes la tarea fue imprimir un mensaje (en el caso de mifuncion) e imprimir un mensaje yllamar a otra funcion en el caso de main.

1.18 Sentencias o instrucciones

La sentencia o instruccion ([? ]) es la unidad mınima que hace que la computadora ejecute algunaaccion.

Las sentencias son combinaciones de variables, constantes y operadores (veremos ahora los de asig-nacion y aritmeticos) y expresiones en general. No hemos definido todavıa estos terminos, por lo queusaremos el concepto preexistente de ellos, hasta que podamos hacerlo correctamente. Mientras tantobaste el siguiente ejemplo

1 float a,b;

2 a=5.;

3 b= a + 4.5;

en a lınea 1 se declara el uso de dos variables, a y b. La declaracion obligara al compilador a reservarlugar en la memoria para alojar valores de tipo de punto flotante es decir, numeros reales. En estecaso, nos se asigna en esta sentencia ningun valor a las variables. En la lınea 2, en cabio, se asigna elvalor 5. a la variable a. El valor 5. es una constante. Esta constante tambien es de tipo de puntoflotante. En lo sucesivo, en el programa, se podra hacer referencia a al valor almacenado invocandoel nombre de las variables. En la lınea 3 se utiliza un operador, el operador adicion, para sumar alvalor de la variable a el valor de la constante 4.5. El resultado de la expresion a + 4.5 se asignara ala variable b.

Las sentencias de invocacion o llamada a otras funciones como las ya vistas son tambien sentencias:

1 printf(‘‘hola mundo desde la funcion main\n’’);

2 mifuncion();

Page 13: Programar en C - Parte 1

cursoC/curso/lenguajeC.tex -August 23, 2012 xxvii

Las sentencias pueden clasificarse8 en tres clases:

• simples

• compuestas

• de control de flujo.

Sentencias simples

Todas las sentencias simples se terminan con el sımbolo de terminacion, con un punto ycoma.

La gran mayorıa de sentencias simples son sentencias de asignacion o llamado a funciones. Lassentencias de asignacion son aquellas que se utilizan para asignar un valor a una variable. En cambio,los llamados a funciones son sentencias por los cuales se llama a un procedimiento para que realice laaccion programada en el mismo.

Las sentencias simples pueden ser de dos tipos:

• sentencias de declaracion

• sentencias de asignacion (instrucciones propiamente dichas).

Las sentencias de declaracion son aquellas en las que se declaran e inicializan variables o funciones.Vimos ya los ejemplos

1 void mifuncion();

2 float a,b;

en el primero se declara el uso de la funcion mifuncion y en el segundo el uso de las variables a y b.

En C, como en Pascal, todas las variables, antes de poder usarlas, deben ser declaradas, o presentadas.Con esta accion el compilador guarda un lugar en la memoria para ellas, acorde al tipo de variable deque se trate y reserva el nombre de la variable, que ya no puede usarse en otra declaracion dentro delmismo rango de visibilidad.

Las sentencias de asignacion o sentencias de instruccion son aquellas por las cuales se instruyeal compilador a efectuar alguna accion, por ejemplo, una asignacion, el calculo de una expresion, lallamada a una funcion, etc.

1 a=5.;

2 b= a + 4.5;

Las llamadas a una funcion son tambien sentencias simples, aunque no entran en la categorıa deasignacion.

1 printf(‘‘hola mundo desde la funcion main\n’’);

2 mifuncion();

Sentencias compuestas

Las sentencias compuestas son grupos de sentencias simples o de otro tipo que se encierran entrellaves. Al final de la llave no se requiere el sımbolo de terminacion. A tal grupo le denominanmostambien un bloque de sentencias. Tomemos por ejemplo la siguiente funcion matematica

A = (1− 0.1|Pe|)5 (1.6)

que puede programarse de la siguiente manera:

8La definicion de sentencia simple es mia.

Page 14: Programar en C - Parte 1

xxviii

1 float A,pe;

2 ...

3 { float pe; // pe es una variable auxiliar, solo tiene existencia dentro del bloque

4 p=fabs(Pe);

5 pe=(1.-0.1*pe);

6 A=pow(pe,5.);

7 }

cada una de las lıneas, de 3 a 7, son sentencias simples. La primera es una sentencia de declaracionde la variable auxiliar pe. Como la variable pe esta declarada dentro del las llaves, su existencia yvisibilidad de la misma esta restringida al entorno demarcado por ellas, es decir al bloque de sentencias.

Sentencias de control de flujo

Las caracterısticas de los lenguajes de programacion tales como C, Fortran, Basic, Pascal, etc, hacenque la mayorıa de las sentencias simples se vayan ejecutando una despues de otra de manera secuen-cial. No obstante, se puede requerir que algunas sentencias se realicen repetidas veces y que otras serealicen en forma condicional. Para ellos existen las sentencias de control de flujo.

Una sentencia de control de flujo tıpica es la sentencia for que vimos ya en nuestro ejemplo inicial

1 ...

2 for (i=0; i<10; i=i+1)

3 printf("i es %d\n",i);

4 ...

o la sentencia if. La sintaxis de las sentencias de control de flujo es mas complicada que la de lasentencias simples y la estudiaremos a fondo en el capıtulo 3.

1.18.1 Expresiones

Una expresion es una combinacion de variables constantes y operadores. Por ejemplo

45.0

a+b

R* pow(a,b)

i++

i+1

‘A‘

las expresiones se usan de diversas maneras en la construccion de sentencias simples, o de control deflujo.

1.18.2 Sentencias de asignacion

En C se utiliza el operador igual para asignar un valor a una variable, de la misma manera que sehizo en la inicializacion de variables.

Los siguientes son ejemplos de sentencias de asignacion

a=1.0;

b=1.0 + c;

area =pi * R*R;

char=‘A‘

en estos casos la sintaxis es

Page 15: Programar en C - Parte 1

cursoC/curso/lenguajeC.tex -August 23, 2012 xxix

variable = expresion ;

Aunque usamos el operador = para representar la asignacion, su sentido es distinto al que el mismosigno tiene en matematica. Una expresion matematica como la siguiente

a = b (1.7)

significa que la variables a y b son iguales. En cambio la asignacion

a=b;

es una orden que indica al SO que copie el contenido de la memoria asociada con la variable b a lamemoria asociada con la variable a. Antes de la sentencia los valores de a y b pueden diferir, luegode la sentencia ambos tienen el mismo valor.

Una expresion como la siguientea = a+ 1 (1.8)

no tiene sentido matematico, es siempre falsa. Cualquiera sean los valores de a, nunca puede ser quea sea igual a si misma mas uno. En cambio la sentencia

a=a+1;

si tiene sentido como asignacion. Esta ordena que se sume uno al valor de a y luego se asigne elresultado a la variable a.

1.19 Elementos lexicos

Todo lenguaje (incluidos los de programacion) tienen elementos lexicos, es decir, nombres o palabrascon un significado predefinido. Estas palabras solo pueden usarse para el proposito predeterminado,por ello se denominan tambien palabras reservadas. Las palabras reservadas de C son las siguientes:

auto extern sizeofbreak float staticcase for structcharconst goto switchcontinue if typedefdefault int uniondo long unsigneddouble register voidelse return volatile

shortenum signed while

Por ejemplo, auto o for son palabras reservadas. Solo se puede usar para el proposito que fue disenada.No la podremos usar entonces como nombre de una variable definida por el usuario ni de ninguna otramanera.

Si estuvieramos trabajando con una base de datos relacionada con automoviles, tendrıamos que tenercuidad con la palabra auto. Podrıamos usar variables que se denominen automovil, o vehiculo o laque se nos ocurra. Tampoco, no podrıamos usar la palabra for como variable. Estarıa bien usar Forque es una palabra distinta.

1.20 Tipo de datos basicos y operadores

Un programa se usa en general para manipular y procesar datos de diversos tipos. Por ejemplonombres de personas son datos de tipo alfaumericos mientras que la edad de las personas es un datode tipo numerico. Estas dos son las dos grandes categorıas de datos que puede manejar C.

Page 16: Programar en C - Parte 1

xxx

Se define como tipo a la carcaterıstica que define la clase de datos se puede representar con unadeterminada constante o variable. Las constantes y variables de C deben tener un tipo predeterminado.El tipo de una variable determina que clase de valores puede tomar y las operadores que puedenefecturase sobre ella.

Pongamos por ejemplo un dato numerico. Este podrıa ser un numero entero o real, podrıa ser unnumero grande o pequeno. La representacion de numeros enteros en una computadora es economicay las operaciones con ellos son rapidas y exactas. En cambio la representacion de numeros reales re-quiere mas memoria y tiene una organizacion mas complicada. En algunos lenguajes de programacion(Mathematica por ejemplo) se puede representar numeros de cualquier tamano con cualquier numerode cifras significativas. En cambio, para la mayorıa de los lenguajes de uso comun como C (Fortran,Basic, Pascal, Java) esto no es ası. Existen varios tipos de datos reales, pero cada uno de ellos tieneun tamano maximo predefinido y ademas tiene un numero predeterminado de cifras significativas quepuede almacenar. Las operaciones con estos numeros no son exactas y son mas costosas (en tiempode procesador) cuanta mas precision se requiere.

Usamos las constantes de C para representar valores inalterables en el desarrolo de nuestro pro-grama, en muchos casos representan datos fısicos (u de otro tipo) que tampoco cambian en la realidadrepresentada por el programa. Por ejemplo el numero π o el numero e, el numero 2 o cualquier otro,un valor de la conductividad termica de un material en particuar, etc.

Usamos la variables para representar datos que cambiaran en el desarrollo de nuestro programa. Elsiguinete jemplo muestra el uso de ambas

1 #include <stdio.h>

2 main ()

3 {

4 float theta_grados=0, theta_rad=0;

5 scanf(‘‘Entre theta_rad’’;&heta_rad);

6 ...

7 theta_grados=theta_rad* 180 / 3.141592653589793;

8 ...

9 }

podemos identificar dos constantes, 180, de tipo entera y la constante 3.141592653589793 de tiporeal. Diferenciamos un tipo del otro por la presencia o ausencia del punto. Por otro lado usamos lasvariables theta_grados y theta_rad para valores que eventualmente podran cambiar en el desarrollodel programa. De hecho la sentencia de la lınea 4 cambia el valor de la variable theta_rad y en lalınea 6 lo hace con el de theta_grados.

1.20.1 Tipos de datos

Los tipos de datos mas importantes y su identificador son

• entero, int.

• punto flotante, float

• caracter, char

Los datos de tipo entero y de punto flotantes sirven para representar valores numericos enteros y realesrespectivamente. Mientras que los datos de tipo caracter sirven para representar los caracteres delcodigo ASCII.

Cada uno de estos tipos principales tiene sus variantes, por ejemplo, los enteros, tienen las siguientesvariantes: cortos (short), enteros sin signo (unsigned int) y enteros largos (long int). Usamosdistintos tipos de variables para guardar distintos tipos de valores, por ejemplo, si uso una variablecomo un contador, sera suficiente que use un entero o un entero largo, siempre y cuando los objetosque se cuentan no excedan los valores lımites para la variable en cuestion. Usar la variable adecuadaa su funcion hara nuestro programa mas pequeno y eficiente.

Page 17: Programar en C - Parte 1

cursoC/curso/lenguajeC.tex -August 23, 2012 xxxi

Tipo Tamano en bytes Nombre lımites garantidoschar 1 caracter 0...255short 2 entero corto -128 ...127int 2 entero -32768...+32767

unsigned int 2 entero s/signo 0...65535long int 4 entero largo -2147.483.64...+2147.483.647float 4 punto flotante 3.4× 10−38...3.4× 1038

double 8 doble precision ±1.7× 10−308

long double 10 doble precision ±1.7× 10−308

enum

Table 1.1: Tipos de datos.

En general las operaciones con punto flotante son mucho mas costosas que las operaciones con enteros.Por lo que debemos preferir estas ultimas en ocasiones en donde esto sea posible y represente un ahorrode tiempo de computacion. Un caso muy comun ocurre en las expresiones de control en sentencias decontrol de flujo donde se usa con frecuencia operaciones sencillas como i=i+1 o i=i*5 pero que debenrepetirse muchas veces. En este tipo de operaciones se prefiere siempre que sea posible variables decontrol enteras.

La tabla 1.20.1 muestra los tipos de variables que dispone el Lenguaje C. La ultima columna da elrango de valores que puede aceptar una variable. Este rango es el mınimo que debe garantizar unaimplementacion de C para cumplir con el estandar. Cabe notar que C no tiene datos de tipos logicos.

El tipo de las constantes depende de como se las escriba. En general, para el caso de las constantesnumericas, la asusencia de punto indica una constante entera y su presencia una constante flotante.Veremos en seguida como forzar el tipo de constantes en los casos particulares.

El tipo de una variable se estable en la declaracion de las variables. Las variables en C deben serdeclaradas. la declaracion es una sentencias especial por la cual se ordena al compilador que reserveel nombre y la cantidad de memoria requerida por el tipo de variable delarada. Veremso los detallesmas adelante con el estudio particular de las variables.

Enteros (int)

Los enteros son el tipo de dato numerico mas pequeno. Su uso mas comun es como contadores enlazos y como ındices de arreglos o formaciones (vectores y matrices), y como punteros (si se quiere unavariacion de los ındices, caracterıstica propia de C) El ejemplo siguiente se muestra el uso de variosenteros.

1 #include <stdio.h>

2 /* imprime una lista de numeros */

3 main ()

4 {

5 int i;

6 for (i=0; i<10; i=i+1)

7 printf("i es %d\n",i);

8 return 0;

9 }

En la lınea 6, se usa en el lazo for las constantes enteras 0, 10 y 1. En al lınea 5 se declara la variableentera i, mientras que se la usa en las tres expresiones de control del for, en la lınea 6, y se imprimesu valor en a lınea 7. El sımbolo %d es un control de formato para la impresion de variables enteras.

Page 18: Programar en C - Parte 1

xxxii

charint no requiere

short intlong int L

unsingned int Ufloat no requieredouble por defecto

long double L

Table 1.2: Tipo de constantes.

1.20.2 Constantes

Una constante es un valor inmediato, absoluto que puede encontarse en una expresion. Las constantestambien responden a la tipificacion anterior, de manera que tendremos constantes de tipo entero,caracter, flotante, etc.

El tipo de una constante queda definido por un sımbolo agregado al final del numero, en el caso delas constantes numericas

pi=3.1416;

a= 7.0 * b;

Aquı las constantes son 3.1416 y 7.0. Las constantes pueden ser de cualquier tipo: escribiremos 7como constante en todos los tipos posibles:

a= 7; /* constante de tipo integer */

a= 7L; /* constante de tipo long integer */

a= 7.; /* constante de tipo float */

a= 1e4; /* constante de tipo float */

a= 7UL; /* constante de tipo unsigned long */

a= 07; /* octal */

a= 0X7; /* exadecimal */

Caracteres y cadenas constantes

Una constante de caracter es cualquier caracter del codigo ASCII entre comillas simples, ası en elejemplo siguiente se asignan distintos caracteres del codigo ASCII a la variable a

char a

a=’a’ /* la variable a contiene el caracter a, octal */

a=’A’

a=’9’

a=’/’

La tabla completa con el codigo ASCII se da en el apendice ??.

Pueden tambien asignarse valores del codigo ASCII extendido...

1.20.3 Cadenas de caracteres

Una cadena de caracteres es un conjunto de caracteres alfanumericos encerrado entre comillas dobles.

Una constante de cadena se define encerrando entre comillas (dobles) cero, uno o mas caracteres.

""

Page 19: Programar en C - Parte 1

cursoC/curso/lenguajeC.tex -August 23, 2012 xxxiii

\a alarma sonora\b retoceso de espacio\f avance de pagina\n retorno de carro y nueva lınea\r control de carro\t tabulacdor\v tabulador vertical\\ barra inclinada (backslash)\? signo de pregunta (cierre)* apostrofe\” comilla doble

Table 1.3: Caracteres de control

"A"

"Hola"

"Esto es Todo"

A los caracteres alfanumericos delimitados por las comillas, el compilador egrega al final el caracternulo del codigo ASCII. De esta manera, una cadena de caracteres siempre tiene al menos un elemento,como en le caso de la primera lınea del ejemplo anterior.

El caracter nulo es el terminador de la cadena de caracteres.

Cuando se habla de longitud de una cadena nos referimos al numero total de caracteres sin teneren cuenta al caracter terminador nulo.

Para introducir caracteres de difıcil tipeado (secuencias o caracteres de escape) se usa la barra \

Debe tenerse en claro la diferencia entre cadenas y caracteres:

caracter. Se refiere a un caracter, se delimita con comillas simples.

cadena. Se refiere a un agrupamiento, secuencia o arreglo de caracteres que puede tener cero o maselementos, se delimitan con comillas dobles.

1.21 Variables

Las variables nombres que asociamos a lugares en la memoria en donde guardaremos algun dato, seaeste numerico o alfanumerico. Requieren un nombre o identificador y deben declararse de algunode los tipos vistos previamente.

En C no se puede usar ninguna variable que no haya sido declarada anteriormente.

1.21.1 Declaraciones

En la etapa de compilacion la declaracion le anuncia al compilador que se usara una variable con tipoy nombre determinado y el compilador asigna un lugar de memoria para ella.

La sintaxis de una sentencia de declaracion de una variable es la siguiente

tipo identificador_v1,...identificador_vn;

donde identificador_v1 es el identificador o nombre de la priemra variable y asi.

Los siguientes son ejemplos de declaraciones

int i; /* se declara la variable i de tipo entero */

Page 20: Programar en C - Parte 1

xxxiv

int i,j; /* se declaran las variables enteras i y j

float x; /* se declara la variable x de tipo flotante */

char nombre; /* se declara la variable nombre de tipo caracter */

Tipos de variables

La variables se declaran de distinto tipo segun el tipo de valor que querramos almacenar en ella.

El lugar de la declaracion es significativo. El lugar donde se declara define la visibilidad y la vida utilde la variable (veremos esto con mas detalle en la seccion 5.7. Puede hacerse

• al comienzo de una funcion.

• al comienzo de un bloque (cualquier parte del codigo encerrada entre parentesis).

• fuera de cualquier funcion.

El lugar en donde se declara una variable controla la visibilidad y la vida util de una variable. Veremosestos conceptos en el capıtulo correspondiente a funciones.

Las variables deben declararse por que:

• Facilita las cosas la compilador

• Disciplina al programador

• El compilador protestara si no se declara, impidiendo la concrecion de un programa ejecutable.

El siguiente es un ejemplo en el que se muestra los mensajes del compilador al intentar compilar unprograma en el cual se ha omitido declarar la variable nota,

if.c: In function ‘main’:

if.c:8: ‘nota’ undeclared (first use in this function)

if.c:8: (Each undeclared identifier is reported only once

if.c:8: for each function it appears in.)

Todas las lıneas de error comienzan con if.c, el nombre del archivo donde reside el codigo fuentecompilado. La primera lınea indica que el error se produce en la funcion main. La segunda lınea nosdice que la variable nota no fue declarada, y que se usa por primera vez en esta funcion. Las otras doslıneas nos anuncia que cada identificador no declarado (como nota en este caso), solo sera reportadouna vez en esta funcion.

1.21.2 Nombre de las variables

Los nombres de las variables se denominan tecnicamente identificadores. Pueden ser

• Letras, numeros, raya de subrayado

• Deben comenzar con letras

• Pueden ser largos, pero el compilador no esta obligado a registar nombres largos en su totalidad

• La capitalizacion es significativa, como en Unix/Linux

• No se pueden usar las palabras reservadas del lenguaje

Page 21: Programar en C - Parte 1

cursoC/curso/lenguajeC.tex -August 23, 2012 xxxv

Como regla general, los nombres de las variables que se utilizan en un programa, deben estar rela-cionados con el nombre de la cantidad que representan. Consideremos las siguiente relacion

P = mg (1.9)

la variables que intervienen en la relacion son P , m, g. Esta formula, en el contexto de la mecanica dael peso P de una masa m en un campo gravitatorio cuya aceleracion es g. El calculo del peso podrıaescribirse en las siguientes sentencias de C

1 float P,m,g;

2

3 //P, Peso, Newton

4 //m, masa, kg

5 //g, aceleracion, m/seg^2

6 .

7 .

8 .

9 P=m*g;

esta sentencia deberıa ser facil de leer e interpretar por cualquier estudiante de fısica que sepa que elproblema que esta resolviendo y programando es un problema de mecanica. Si se quisieera ser masclaro, podrıa escribirse

1 float Peso,masa,gravedad;

2

3 //Peso, fuerza, Newton

4 //masa, masa, kg

5 //gravedad, aceleracion, m/seg^2

6 .

7 .

8 .

9 Peso=masa*gravedad;

Consideremos otro ejemplo. En la siguiente relacion

Nu =hD

k(1.10)

las variables de nuestro problema son Nu, h, D, k. En el contexto fısico de donde proviene, el estudiola transferencia de calor, Nu, es el numero de Nusselt, h es el coeficiente de transferencia de calor,D es una longitud caracterıstica, y a deducir de la notacion es probablemente el diametro, k es laconductividad termica.

Probablemente, la interpretacion en C mas adecuada, concisa, directa es

1 float Nu,D,h,k;

2 ...

3 Nu=h*D/k;

esta utiliza para las variables los mismos nombres que se utilizan comunmente para las cantidadesfısicas. La sentencia sera entendida inmediatamente por cualquier persona que conozca el problemafısico que se quiere resolver.

Se podrıa anadir, para ayuda del lector menos experto, algunos comentarios con las definiciones delas variables

1 float Nu,D,h,k;

2

3 // Nu numero de Nusselt, adimensional

4 // D diametro, m

Page 22: Programar en C - Parte 1

xxxvi

5 // h coeficiente convectivo, W/m^2 K

6 // k conductividad termica, W/m K

7 .

8 .

9 .

10 Nu=h*D/k;

Aun, a expensas de hacer nuestro programas mas verborragico, podemos elegir nombres para nuestrasvariables mas explıcitos o autoreferentes

1 float Nusselt,Diametro,coeficiente_convectivo,kconductividad;

2

3 Nusselt=coeficiente_convectivo*Diametro/conductividad;

Estos nombres daran origen a sentencias mas largas, lo que dificultara la lectura.

Por ultimo, debemos evitar utilizar nombres abstractos, sin relacion con el contexto del problema, porejemplo,

1 float u,v,w, x;

2

3 // u numero de Nusselt, adimensional

4 // v diametro, m

5 // w coeficiente convectivo, W/m^2 K

6 // x conductividad termica, W/m K

7 .

8 .

9 .

10 u=w*v/x;

este pequeno codigo, si bien realiza el mismo calculo que los anteriores, es una receta para el desastre.Salvo que usted tenga una memoria privilegida (a la que seguramente encontrara mejores usos),necesitara llevar tablas de significado de las variables todo a lo largo de su programa y no podra leery pensar sus sentencias en terminos fısicos, que es de la manera que se supone piensa o pensara ustedmuy pronto.

1.21.3 Inicializacion de variables

Al declarar una variable puede inicilizarse con algun valor determinado. La sintaxis de declaracioninicializacion es la siguiente.

tipo identificador_v1=constante1,...identificador_vN=conatanteN;

donde constante1 es el valor con que se inicilaiza la variable, y que debe ser del mismo tipo queaquella. Por ejemplo

int i=0;

int i=1,j=1;

float x=1.5;

char respuesta=‘S‘;

Es posible inicializar con una expresion en vez de una constante. La expresion evalua el valor con quese quiere inicializar. La sintaxis es entonces

tipo identificador_v1=expresion,...identificador_vn=expresion;

Un ejemplo

Page 23: Programar en C - Parte 1

cursoC/curso/lenguajeC.tex -August 23, 2012 xxxvii

float R=5.;

float pi=3.151416;

float area=pi*R*R;

aquı la variable area se calcula con la expresion pi*R*R .

1.21.4 Cuando y por que inicializar

• necesidad, logica del programa

• conveniencia, legibilidad

• de fondo, manejo de memoria

Cabe la pregunta de cuando y por que inicializar las variables.

Hay algunas situaciones en donde es evidente la necesidad de la inicializacion de variables

• Cuando la variable es un acumulador

1 float h,x;

2 float sum=0;

3 .

4 .

5 for (h=0;h<100;h=h+1).

6 sum=sum + 0.5* h*(fon(x) +fon(x+h))

En otras situaciones no es tan claro, y es una cuestion de preferencia. Considere el siguiente codigo

1 float T,a,b;

2 int n;

3 T=2000.;

4 a=0.1;

5 b=10.0;

6 n=50.;

mientras que podemos hacer lo mismo escribiendo

1 float T=2000.,a=0.1,b=10.0;

2 int n=50;

finalmente decida usted cual es mas legible.

1.21.5 Conversion entre tipos de datos.

Es usual que el dato contenido en una variable declarada de un determinado tipo deba asignarse aotra variable declarada de un tipo diferente.

El programador debe tener cuidado al hacer estas operaciones. Un caso comprobado en el que un errorde conversion causo perdidas cuantiosas fue la explosion de cohete Ariane 5 en su vuelo de 1996. En estecaso, la lectura de un valor que fue mayor del esperado, origino al ser ser asignado a una variable que nopodıa contenerlo, una condicion de error, que al no ser resuelta adecuadamente por el programa, originola caıda del cohete. Todo el sistema de referencia inercial se desactivo y la nave quedo fuera de controlhasta que se desintegro. (http://www.rvs.uni-bielefeld.de/publications/Incidents/DOCS/ComAndRep/Ariane/Esa/aria

Que ocurre cuando asignamos una constante de un tipo a una variable de otro tipo? En algunos casosC puede hacer una conversion de tipo automatica llamada casting. Considere el siguiente ejemplo

Page 24: Programar en C - Parte 1

xxxviii

float a;

int b=5;

a=b;

C convertira automaticamente el valor entero 5 para asignar el valor de punto flotante 5. a la variableb. Esto se puede hacer sin problemas por que la variable que recibe la conversion es mayor que el datoconvertido. Esta es una conversion implıcita, ya que no hace falta ningun operador para realizarla.

No ocurre lo mismo cuando asignamos un flotante a un entero.

1 #include <stdio.h>

2 main()

3 {

4 float a=5.79;

5 int b=a;

6 printf("b en main %d\n",b);

7 }

la salida de este programa es la siguiente

cardon@linux-pijg:~/A-cursos/cursoC/curso/programas> ./cas

b en main 5

cardon@linux-pijg:~/A-cursos/cursoC/curso/programas>

se observa que se perdieron los decimales en la conversion.

Otro caso que ocurre con frecuencia es el demostrado en el siguiente programa

1 #include <stdio.h>

2 main()

3 {

4 float a;

5 a= (1/2) *600.;

6 printf("a en main %f\n",a);

7 }

cuya salida es

cardon@linux-pijg:~/A-cursos/cursoC/curso/programas> ./cas2

a en main 0.000000

cardon@linux-pijg:~/A-cursos/cursoC/curso/programas>

evidentemente no se esperaba un cero como salida. El error es facil de explicar. La division deenteros entrega como resultado un entero, de manera que no puede alojar un numero fraccionario. Alintentarlo se pierden los decimales.

La solucion es muy simple. Utilice sus constantes numericas del tipo adecuado, en este casoutilice punto flotante en el menos una de las constantes, o mejor aun en las dos.

Otra forma de forzar un cambio de tipo es especificar el tipo de resultado que se espera anteponiendoentre parentesis el tipo de constante a converir.

1 #include <stdio.h>

2 main()

3 {

4 float a;

5 a= (float) 1/2;

6 printf("a en main %f\n",a);

7 }

Page 25: Programar en C - Parte 1

cursoC/curso/lenguajeC.tex -August 23, 2012 xxxix

esto dara el resultado esperado. Igualmente

1 #include <stdio.h>

2 main()

3 {

4 float a;

5 int b=9,c=5;

6 a= (float) b/ (float) c;

7

8 printf("a en main %f\n",a);

9 }

No obtante lo dicho, en los ejemplos precedentes no hay ninguna razon para no emplear las contantesy variables del tipo adecuado.

1.21.6 Operadores Aritmeticos

Utilizamos operadores aritmeticos en la construccion de expresiones matematicas. C tiene los oper-adores tıpicos que cabe esperar, para la suma, substraccion, multiplicacion y division. No tiene encambio el operador de potenciacion.9

Existen tambien los operadores modulo o resto. La tabla siguiente muestra los operadores y sussımbolos

+ suma- substraccion* multiplicacion/ division% modulo o resto

No hay exponenciacion

Table 1.4: Operadores aritmeticos

Precedencia y asociatividad

Supongase la expresion siguiente

a + b / c;

surge la pregunta de cual es el orden en que se realizan las operaciones, ¿se suma a y b primero yluego se divide por c? o ¿primero se devide b por c y se suma a a?. Es inmediato ver que los resutadosseran distintos. Todos los lenguajes de programacion tienen un conjunto de reglas de precedenciaque dirimen la cuestion. Para C la regla es las siguientes

• El producto y la division tiene prioridad frente a la suma o la resta

Que ocure cuando en cambio tenemos solo operadores de igual jerarquıa como en el siguiente caso

w=x - y + z;

Suponga que x = 10, y = 5 y z = 4. Si resta y de x, y luego se suma z, el resultado es 9, mientrasque si se suma y a z y se substrae de x, el resultado es 1. ¿Que operacion es la que se efectua? Laregla de asociatividad determina en que orden se agrupan los terminos y se ejecutan las operaciones.Estas reglas se dan en la tabla siguiente

9Debe llamarse a la funcion pow para eso.

Page 26: Programar en C - Parte 1

xl

Prioridad asociatividad+,-,unarios izquierda a deracha*, /, % izquierda a derecha+, . izquierda a derecha

Table 1.5: Prioridad y precedencia de los operadores aritmeticos.

operador ejemplo descripcion

= a=b asigna el valor de b a a*= a*=b a=a*b/= a/=b a=a/b%= a%=b a=a%b+= a+=b a=a+b-= a-=b a=a-b

Table 1.6:

En nuestro ejemplo, la precedencia, de izquierda a derecha, indica que el resutado sera 9.

El uso de parentesis, por otro lado, permite forzar la precedencia. Ası la sentencia

x=10;

y=5;

z=4;

w=x- (y +z);

tendra como resultado 1. El uso del parentesis es sumamente conveniente en expresiones largas ycomplicadas y si usted tiene cualquier tipo de dudas.

1.21.7 Operadores de asignacion

El operador de asignacion es el sımbolo = equivalente al sımbolo := de Pascal.

Las siguientes son expresiones de asignacion:

x=1;

a=b;

i=i+1;

El operador asignacion agrupa de derecha a izquierda:

c=a=b /* se interpreta como a=b y luego c=(a=b) */

1.21.8 Otros operadores de asignacion

C permite utilizar el operador de asignacion en conjunto con los operadores aritmeticos para abreviarexpresiones de uso frecuente, por ejemplo a = a + b se puede escribir a+ = b. Los cinco operadoresde este tipo son:

Operadores de incremento y decremento

La expresion i = i+ 1 se usa con tanta frecuencia como contador que en C existe una forma especialde escribirla. Se puede reeplazar por la expresion i++ tan tıpica de C. El operador ++ y el operador

Page 27: Programar en C - Parte 1

cursoC/curso/lenguajeC.tex -August 23, 2012 xli

- - se denominan operadores de incremento. Son operadores unarios es decir se aplican a unaunica variable y tiene por objeto incrementar (o decrementar) la variable en 1.

Nuestro programa basico inicial podrıa escribirse de la siguiente manera

1 #include <stdio.h>

2 /* imprime una lista de numeros */

3 main ()

4 {

5 int i;

6 for (i=0; i<10; i++)

7 printf("i es %d\n",i);

8 return 0;

9 }

Cuando un variable afectada del operador ++ o -- se encuentra como unica componente de la expresion,por ejemplo, como en la lınea 6 del ejemplo anterior, o en la lınea siguiente

6 for (i=0; i<10; ++i)

ambas formas del incremento o decremento son equivalentes. En los ejemplos citados, i++ o ++i apare-cen como unica expresion de control incremental en el lazo for y ambas sentencias son equivalentes.

Cuando i++ o ++i se encuentran en una sentencia de asignacion, la posicion del operador ++ define elorden en que se hara la asigancion y el incremento. Las sentencias

1 m=i++; // asigna i a m y luego incrementa i en 1

2 m=++i; // incrementa i en 1 luego signa el valor incrementado a m

tienen resultados diferentes. En la lınea 1 asigna i a m y luego incrementa i en 1, mientras que en lalınea 2 incrementa i en 1 luego signa el valor incrementado a m.

Usualmente se utiliza las expresiones i++ o i-- como expresion de incremento o decremento en lazosde control de flujo. En este caso el orden del signo es irrelevante.

Orden de precedencia inpredecible

Si bien estas abreviaciones que permite hacer C son interesantes, a mi parecer, obscurecen para ellector no entrenado la legibilidad del programa.

En algunos casos, no es posible predeterminar el orden de precedencia de la operaciones, como porejemplo en el ejemplo siguiente

a=++i * --i;

aqui no hay manera de determinar que operacion se realiza primero, si ++i o --i. El programadordebe evitar este tipo de problemas. De nuevo, vale aquı el principio KISS.

Page 28: Programar en C - Parte 1

xlii

1.21.9 Expresiones y operadores relacionales

Las expresiones relacionales son aquellas con las que dos enunciados se comparan entre si paradeterminar su valor o tamano relativo. Es decir, permiten determinar si una expresion es es igual,distinta, mayor o menor que otra. Veremos en el proximo capıtulo los distintos operadores relacionalesdisponibles y su uso en relacion a las sentencias de control de flujo. Aquı haremos solo una introduccional tema.

La sintaxis de una expresion relacional es la siguiente

expresion_1 operador_relacional expresion_2

Los operadores relacionales son los sımbolos que se utilizan para preguntar por una determinadarelacion. Por ejemplo, para preguntar si de dos expresiones, una es mayor que la otra, se utiliza, comoera de esperar, el operador >. La expresion relacional sera exp_1 > exp_2.

Como no existen variables de tipo logico (aquellas que toman como valores verdadero o falso), Cevalua las expresiones relacionales asignandoles un valor distinto de cero o cero segun la expresion seaverdadera o falsa respectivamente.

Ya hicimos, en nuestro programa basico, uso de expresiones relacionalas. En efecto, la segundaexpresion de control del lazo for es una expresion relacional

1 #include <stdio.h>

2 /* imprime una lista de numeros */

3 main ()

4 {

5 int i;

6 for (i=0; i<10; i=i+1)

7 printf("i es %d\n",i);

8 return 0;

9 }

El lazo se ejecutara mientras sea verdadero que i sea menor que 10.

Nos extenderemos mas sobre las expresiones relacionales y sus operadores en la seccion 3.2.1.

1.21.10 Expresiones y operadores logicos

Nuevamente, daremos aquı solo una rapida presentacion de las expresiones y operadores logicos. Dadasdos expresiones, una expresion logica es aquella que las relaciona de manera logica y da como resultadoun valor unico de verdad, verdadero o falso.

Por ejemplo sean las expresiones

b < a

y

c < a

Podemos construir una expresion logica para preguntar si ambas son ciertas de la siguiente manera

b < a && c < a

si ambas expresiones relacionales son ciertas, la expresion logica dara un valor verdadero, devolveraun numero distinto de cero.

Completaremos este tema mas adelante en la seccion 3.2.2.

Page 29: Programar en C - Parte 1

cursoC/curso/lenguajeC.tex -August 23, 2012 xliii

1.22 Funciones

Casi todos los lenguajes de programacion modernos permiten la definicion y uso de las llamadas fun-ciones (C, Basic, Fortran), subrutinas (Fortran), procedimientos (Pascal). Estas estructuras son lasque permiten programar en forma estructurada, paradigma de programacion dominante en los ultimos40 anos. La descripcion de las caracterısticas y posibilidades de las funciones merecen, para cualquierlenguaje de programacion, su propio capıtulo. Por lo que deremos aquı un breve pantallazo para queel estudiante pueda usarlas desde muy temprano en su formacion como programador cientıfico.

Una funcion en un pequeno programa dentro de otro, que hace alguna tarea muy especıfica, muy biendefinida. El proposito de escribir una tarea ası en una subrutina es compartamentalizar o modularizarel programa. El lema divide y venceras es aplicable aquı a la perfeccion.

Para introducir las funciones debemos tener en cuenta dos aspectos de ellas

• Por una lado, el uso o llamado a ejecucion de la funcion. Veremos dos formas de uso para ellas.

• La definicion de la funcion

Llamado a ejecucion de una funcion

Supondremos por ahora que las funciones de las que hablaremos estan disponibles listas para su uso.Veremos ahora como usarlas. Hacer uso de una funcion o ejecutar una funcion se denomina el llamadoa ejecucion de una funcion o se dice invocar a invocar funcion o referenciar a la funcion

Para ejemplificar podemos usar las funciones de librerıa provistas por C. Para que una funcion osubprograma pueda ejecutarse debera ser llamado por otra funcion. En el nivel maximo de jeraquıadebera ser llamada por el programa principal, la funcion main. Este llamado se hace con solo invocarel nombre de la funcion. En nuestro ejemplo basico

1 #include <stdio.h>

2 /* imprime una lista de numeros */

3 main ()

4 {

5 int i;

6 for (i=0; i<10; i=i+1)

7 printf("i es %d\n",i); // se invoca la funcion de impresion

8 return 0;

9 }

tal llamado se efectua en la lınea 7 al invocar o referenciar el nombre de la funcion printf quehace la tarea especıfica de imprimir algo en la pantalla.

La funcion podra (o no) recibir datos del programa que la invoca. Estos datos se pasan como unalista de parametros agrupados entre parentesis y separados por coma, a continuacion del nombrede la funcion.

Observe que las sentencia de llamada a la funcion, debe, como cualquier otra sentencia, finalizar conel sımbolo de terminacion.

En el caso de la funcion printf del ejemplo, los parametros pasados son dos, la cadena de caracteres"i es %d\n" y la variables i, cuyo valor se modifica en cada ciclo del lazo. Los dos parametrospasados son los datos suficientes que necesita la funcion para imprimir lıneas como las siguiente

...

i es 3

i es 4

i es 5

...

Page 30: Programar en C - Parte 1

xliv

En el ejemplo precedente, se llamo a la funcion printf a que ejecute la tarea de imprimir, una tareade entrada y salida de datos. Finalizada la tarea (aparentemente) no hubo10 ninguna otra devolucionde la funcion hacia el programa. Para otras funciones, el resultado de la tarea efectuada debe serusado por el programa que las llama. Por ejemplo, cuando estas relizan un calculo, se obtiene un datodel sistema, como la hora, o cuando se lee un dato de la terminal o de otro dipositivo de entrada osalida, etc.. En estos casos la funcion debe retornar un valor al programa principal. Puede ocurirtambien que se requiera saber si una tarea, como la de imprimir, fue realizada correctamente, en talcaso la funcion puede retornar un aviso del estado en que se completo la tarea.

El valor de retorno de la funcion substituye al texto de la llamada a la funcion. Las funcionesmatematicas representan un ejemplo tıpico de uso por retorno. Mas facil que explicarlo es mostrarloen un ejemplo

1 #include <stdio.h>

2 #include <math.h>

3 #define PI 3.141592653589793

4 main ()

5 {

6 float altura, hipotenusa, base, angulo;

7 hipotenusa=1.;

8 angulo 45.; //grados

9 angulo=angulo* 180 / PI; //radiantes

10 base =hipotenusa/cos(angulo);

11 altura=hipotenusa/sin(angulo);

12 printf("base %f y altura %f \n",base,altura);

13 return 0;

14 }

En las lıneas 9 y 10 se llama a las funciones matematicas cos y sin, cuyos argumentos son, re-spectivamente, un angulo expresado en radianes. El resultado del calculo de la funcion matematicaseno y coseno efectuado por estas funciones sera retornado en lugar de las expresiones de llamadacos(angulo) y sin(angulo). De esta manera el uso de las funciones es intuitivo y condice connuestra forma matematica de expresarnos.

El lugar de donde se llama a la funcion puede ser cualquiera. Podrıa haberse programado de lasiguiente manera

6 hipotenusa=1.;

7 angulo=45.; //grados

8 angulo=angulo* 180 / PI; //radiantes

9 printf("base %f y altura %f \n",hipotenusa/cos(angulo),altura,hipotenusa/cos(angulo))

En este caso, se llama al calculo del seno y coseno al evaluar el parametro pasado a la funcion printf.

Los parametros pasados a las funciones deben coincidir en el tipo de datos requeridos por ellas,tanto en un sentido logico como en su tipologıa. En el ejemplo anterior es evidente que las funcionestrigonometricas requieren (requisito impuesto por la logica del calculo interno de la funcion) un anguloen radiantes, mientras que el tipo de datos requerido es un float o double.

1.22.1 Definicion de una funcion

En general, las funciones deben ser definidas, es decir el codigo de definicion debe ser escrito por unprogramador y estar accesible al programa que llamara las subrutinas en la etapa de compilacion.

Las funciones usadas en los ejemplos precedentes estan definidas en las librerıas correspondientesstdio y math. Usualmente no necesitamos acceder al codigo de definicion, aunque podrıamos hacerlo.

10Aparentemente, por simplicidad de la explicacion. En realidad si hubo pero no se uso el retorno de printf.

Page 31: Programar en C - Parte 1

cursoC/curso/lenguajeC.tex -August 23, 2012 xlv

La funcion main es por supuesto una funcion. En general, las funciones tienen un nombre, una listade argumentos y un cuerpo de definicion. En el caso de main, la lista de argumentos esta vacıa. Sucuerpo es el bloque de sentencias por debajo de la primera lınea de definicion.

Las funciones como las variabes deben declararse. En el caso de main la declaracion y la definicion dela funcion es la misma. Para cualquier otra funcion, si se la define antes que el main, la declaracion yla definicion de la funcion tambien coinciden.

El siguiente es un prototipo o esquema de una funcion de la definicion de una funcion

tipo nombre(tipo arg1, tipo arg2,...)

{

sentencia 1

.

.

.

ultima sentencia

return nombre=algun valor;

}

Como vemos, esta funcion difiere en dos aspectos de la funcion main. Por un lado existe una lista deargumentos. Por otro, se ha antepuesto un tipo al nombre de la funcion.

El nombre de la funcion sigue las mismas reglas que los nombres para variables.

1.22.2 La lista de argumentos

Volveremos al tema de funciones en el capıtulo 5.

1.23 Funciones de la librerıa math.h

Varias de las funciones matematicas que en otros lenguajes (por ejemplo Fortran) se denominanfunciones matematicas intrınsecas estan programadas como funciones de librerıa.

La tabla 1.7 lista las funciones matematicas disponibles en la librerıa math.

La funciones aceptan argumentos de tipo double y float o int.

Par usar las funciones de la librerıa matematica debe incluir la directiva

#include <math.h>

y debe compilar de la siguiente manera

gcc -o prog prog.c -lm

observe que se ha incluido la opcion -lm.

1.23.1 Funciones trigonometricas

La lista siguiente muestra los prototipos de las funciones trigonometricas de la librerıa matematica:

double tan(double x);

double cos(double x);

double sin(double x);

Page 32: Programar en C - Parte 1

xlvi

retorno nombre y argumentosint abs (int x);double acos(double x);double asin(double x);double atan(double x);double atan2(double x);double ceil(double);double cos(double x);double cosh(double x);double exp(double x);double fabs(double x);long double fabsl(long double x);double floor(double x);double fmod(double x, double y);double frexp(double x, int *exp);double frexpl(long double x, int *exp);double hypot(double x, double y);long int labs(long int n);double ldesp(double x, int exp);long double ldexpl(long double x, int exp);double log(double x);double log10(double x);int matherr(struc exception *e);double modf(double x, double *partent);double poly(double x, int n, double c[] );double sin(double x);double sinh(double x);double sqrt(double x);double tan(double x);double tanh(double x);int rand(void);int random(int x);void randomize(void);

Table 1.7: Funciones matematicas de la librerıa math

double acos(double x);

double asin(double x);

double atan(double x);

double hypot(double x, double y);

La funciones aceptan argumentos de tipo double y float o int.

Las funciones trigonometricas requieren el argumento angular en radianes. Angulos θ en grados debenconvertirse a radianes Φ

Φ =θ × π

180(1.11)

Se usan de las siguiente manera

float a, angulo_grados=45., pi=3.1415;

angulo_radianes = 45.* pi/180.;

a= sin(angulo_radianes);

Las funciones trigonometricas inversas de la librerıa math son

double acos(double x);

Page 33: Programar en C - Parte 1

cursoC/curso/lenguajeC.tex -August 23, 2012 xlvii

double asin(double x);

double atan(double x);

1.23.2 Funciones raiz cuadrada, potenciacion y exponenciacion.

Las funciones relacionadas con la potenciacion y exponenciacion son las siguientes

double exp(double x);double frexp(double x, int *exp);double frexpl(long double x, int *exp);double ldesp(double x, int exp);long double ldexpl(long double x, int exp);double sqrt(double x);double pow(double x,double y)

Table 1.8: Funciones potenciacion y exponenciacion de la librerıa math

Las mas comunes no requieren mayor explicacion y son

double exp(double x);

double sqrt(double x);

double pow(double x,double y);

Considere al expresion de la Ley de Planck para la potencia emisiva monocromatica

Eb,λ =c1λ5

1

(e(c2/λT ) − 1)(1.12)

Esta funcion requiere el calculo de la quinta potencia de λ y el calculo de la exponencial de (c2/λT ).que se pueden calcular de la siguiente manera

float lambda,float c2, float T;

float, aux1,aux2,aux3;

.

.

.

aux1=pow(lambda,5.);

aux2=c2/(lambda*T);

aux3=exp(au2x);

La raiz cuadrada se obtiene con la funcion sqrt, se usa como en el ejemplo siguiente

x0=1./sqrt(f);

1.23.3 Funciones logarıtmicas

La librerıa math.h dispone de funciones para calcular los logaritmos naturales o neperianos y loslogaritmos en base diez. Considere la siguiente funcion matematica, la ecuacion de Colebrook (es

double log(double x);double log10(double x);

Table 1.9: Funciones logarıtmicas de la librerıa math

una relacion experimental que relaciona el factor de friccion f con los parametros de la tuberıa (eldiametro y la rugosidad) y el numero de Reynolds):.

Page 34: Programar en C - Parte 1

xlviii

1√f= −2.0log10

(

ε/D

3.7+

2.51

Re√f

)

(1.13)

El calculo de la raiz inversa de f , 1/√

(f), se puede expresar

float raiz_i_f;

float esD, Re; // Datos

...

raiz_i_f= -2.0 *log10( esD/3.7 + 2.51*raiz-i_f/Re); // requiere un caculo iterativo

...

1.23.4 Valor absoluto y funciones de redondeo.

C dispone de numerosas funciones relacionadas al redondeo y valor absoluto de numeros enteros yreales. La tabla muestra algunas de ellas

int abs (int x);double ceil(double);double fabs(double x);long double fabsl(long double x);double floor(double x);double fmod(double x, double y);long int labs(long int n);double ldesp(double x, int exp);double modf(double x, double *partent);double poly(double x, int n, double c[] );

Table 1.10: Funciones de redondeo y valor absoluto de la librerıa math

1.23.5 Valores aleatorios

En fısica computacional es frecuente el uso de numero aleatorios. Para ello la librerıa stdlib poseevarias funciones relacionadas.

int random(int x);void randomize(void);void srand(unsigned x);

Table 1.11: Funciones aleatorias de la librerıa stdlib

El proposito de estas funciones es generar secuencias de numeros aleatorios.

Las secuencia se inicia con una semilla, es decir un valor inicial. Este puede ser a su vez aleatoria opredefinida. Esta ultima opcion se requiere para generar secuencias repetibles de numeros aleatorios,de manera que los calculos efectuados con ella tienen repetibilidad, lo que facilita la programacion yla correccion de errores.

Se disponen dos funciones para iniciar una secuencia de numeros aleatorios srand y randomize.

La funcion srand(unsigned x) inicializa el generador de numeros aleatorios con una semilla prede-terminada x. Si x = 1 el generador se reinicializa. Cualquier otro valor fija el generador de numerosaleatorios en un punto inicial aleatorio.

La sentencia randomize inicializa o genera la semilla para el generador de numeros aleatorios. Estasemilla es funcion de la hora actual del sistema. Esta funcion impide que las secuencias aleatorias serepitan.

Existen dos funciones para generar numeros aleatorios, random(n) y rand(). La primera generanumeros aleatorios entre 0 y (n−1). La segunda genera numeros aleatorio en el rango 0−RANDMAX ,

Page 35: Programar en C - Parte 1

cursoC/curso/lenguajeC.tex -August 23, 2012 xlix

donde RAND_MAX es una variable predefinida en el archivo de encabezados stdlib.h. Su valor es215− 1..

Page 36: Programar en C - Parte 1

Bibliography

[1] rothberg.

[2] The american heritage science dictionary. Aug 2010.

[3] Dictionary of algorithms and data structures. Aug 2010.

[4] Dictionary.com unabridged. Aug 2010.

[5] Merriam-webster dictionary. Aug 2010.

[6] P. Chaudhuri. Parallel Algorithms. Design and Analisis. Prentice Hall, 1992.

[7] Dijtstra.

[8] R. W. Hamming. Numerical Methods for Scientists and Engineers. Dover, second edition, 1973.

[9] K. Hirose. Earth’s missing ingredient. Scientific American, june 2010.

[10] S.L.S Jacoby and J.S. Kowalik. Mathematical modeling with computers. Prentice-hall, Inc., 1980.

[11] Kernighan and Ritchie.

[12] H. L. Langhaar. Dimensional Analysis amd Theory of Models. John Wiley and Sons, 1951.

[13] C. Pursell. The machine in America. A social history of Technology. Johns Hopkins UniversityPress, 1995.

[14] B. Winston. Media Technology and Society. A History: From the Telegraph to the Internet.

Routledge, London, 1998.