Está en la página 1de 1

Nociones Básicas de C

Antecedentes
C es un lenguaje de alto nivel creado a principios de la década de 1970 en los laboratorios Bell por Dennis
Ritchie. En sus inicios, el lenguaje C fue utilizado para reescribir el núcleo del sistema operativo Unix en
sistemas PDP-11. En 1978, Brian Kernighan y Dennis Ritchie publicaron el libro The C Programming Language
que sería una referencia obligada para los programadores C durante muchos años.

En menos de una década, el uso de C se expandió fuera de los laboratorios Bell hacia organizaciones
industriales, gubernamentales y de investigación convirtiéndose en uno de los lenguajes de programación
más utilizados. Existen compiladores C para la mayoría de las arquitecturas de cómputo modernas. El
lenguaje C ha extendido tal aceptación que fue estandarizado en 1989 por el comité ANSI (American
National Standards Institute) y por la O cina Internacional para la Estandarización (ISO) en 1990.

Los compiladores C ponen a disposición del programador un conjunto de rutinas llamado biblioteca
estándar. Esta funcionalidad facilita el manejo de los dispositivos de entrada/salida, el manejo de la
memoria, trabajo con cadenas de caracteres y el cálculo de funciones matemáticas trascendentes. El
contenido de la biblioteca estándar está regulada por los organismos de estandarización; esto signi ca que
el código fuente de C escrito bajo el estándar ISO puede ser construido con cualquier compilador
compatible.

Las secciones siguientes describen en detalle la sintaxis del programa presentado en el capítulo anterior,
introduciendo algunos conceptos fundamentales de programación a lo largo del camino. A pesar de su
simplicidad, este programa contiene el soporte básico cualquier aplicación que despliegue información en
la consola de comandos, proporcionando una base para la construcción de programas otros programas
más complejos. Antes de ahondar en la sintaxis de C, es necesario conocer el alfabeto aceptado por el
estándar del lenguaje C.

El Alfabeto en C
El estándar ISO de ne un conjunto de mínimo de símbolos que debe aceptar todo compilador C. El
alfabeto C está compuesto por las letras del alfabeto latino en mayúsculas y minúsculas, los números
decimales y un conjunto de caracteres especiales. Las letras con signos diacríticos, como acentos y diéresis,
no forman parte del estándar ISO.

0 1 2 3 4 5 6 7 8 9

a b c d e f g h i j k l m
n o p q r s t u v w x y z
A B C D E F G H I J K L M
N O P Q R S T U V W X Y Z

! " # % & ' ( ) * + , - . / :


; < = > ? [ \ ] ^ _ { | } ~

Identi cadores
Un identi cador es una secuencia de caracteres que sirve para identi car de forma única las entidades de
un programa. El término identi cador es utilizado dentro del estándar C y puede ser considerado como
sinónimo de "nombre". Existen algunas reglas para construir los identi cadores:

Un identi cador no puede iniciar con un dígito.


El único carácter especial que acepta un identi cador es el guion bajo _ .
Únicamente los primeros 31 caracteres de un identi cador son signi cativos.

El lenguaje C distingue entre letras mayúsculas y minúsculas, a esta propiedad se le denomina case
sensitive en inglés. Por lo tanto, los identi cadores Divisor , divisor y diviSor son tratados por el
compilador como entidades distintas.

Aún cuando se puede elegir casi cualquier combinación de caracteres para formar un identi cador, es muy
útil seguir una convención de nombres para crear identi cadores. Una convención de nombres es la elección
de un conjunto de reglas para escribir un identi cador. En este trabajo, los identi cadores de las variables
locales y los parámetros una función se escriben en letras minúsculas. Por otra parte, la primera letra de
un identi cador de una función inicia en mayúscula. Esto sirve para distinguir claramente las entidades que
representan código, de las entidades que representan datos. Las convenciones para nombrar estructuras
se tratarán en el capitulo correspondiente.

Algunos identi cadores son reservados para uso exclusivo del compilador, comúnmente se les llama
palabras reservadas. Las palabras reservadas no deben usarse para identi car entidades dentro del
programa, ya que esto genera errores de compilación.

typedef enum sizeof


extern auto register volatile static
char int double float
const short long signed unsigned void
if else switch case default break goto return
do while for continue
struct union

Comentarios
A continuación se reproduce el programa de la sección~\ref{} con el n de hacer más ágil la discusión de su
sintaxis.

/* Ejemplo de la estructura básica de un programa */


#include <stdio.h>

int main( void ) {


 printf( "Primer Programa en C" );
 return 0;
}

La primera línea del programa de ejemplo es un comentario. Los comentarios sirven para hacer notas de
referencia para las fases de depuración y mantenimiento. Se recomienda incluir información acerca del
programador y el propósito general del programa como mínimo. Los comentarios son una parte
fundamental durante el diseño mediante pseudocódigo.

Un comentario puede incluir cualquier secuencia de caracteres válidos con excepción de las secuencias /*
y */ , que sirven para marcar el inicio y el n de un comentario respectivamente. Esto implica que no
puede haber comentarios anidados, es decir, un comentario dentro de otro. Los comentarios pueden
abarcar varias líneas de texto, y pueden aparecer en cualquier lugar en donde sea válido un espacio. Todo
comentario es tratado como un único espacio por el compilador.

Directivas del Preprocesador


Cualquier línea del código que inicie con el carácter # es una directiva del preprocesador. El preprocesador
se encarga de hacer sustituciones de texto antes de pasar el código al compilador. En el ejemplo que nos
ocupa, la directiva #include provoca que dicha línea sea reemplazada por todo el contenido del archivo
cuyo nombre se encuentra encerrado entre los símbolos < > . El archivo stdio.h contiene las
declaraciones requeridas para trabajar con la biblioteca estándar encargada de la interacción del programa
con los dispositivos de entrada y salida.

Otra directiva común es #define IDENTIFICADOR OBJETIVO , mediante la cual el preprocesador


reemplazará IDENTIFICADOR con OBJETIVO . Uno de los principales usos de #define es la de nición
constantes simbólicas; es decir, constantes que son identi cadas por su nombre. Si bien no es un requisito
del lenguaje, por convención se utilizan identi cadores en mayúsculas para escribir las constantes
simbólicas.

Además de mejorar la legibilidad del código, las constantes simbólicas son un valioso aliado para las
actividades de mantenimiento. Para ilustrar este hecho suponga que desarrolló un código que de ne la
constante PI de la siguiente manera:

#define PI 3.1416

También suponga que el programa usa el valor de PI 50 veces. Si durante la fase de prueba se detecta la
necesidad de emplear un dígito signi cativo adicional, simplemente se modi ca la de nición de PI y se
recompila el programa. Esto no solo disminuye el tiempo invertido en la modi cación, también reduce la
posibilidad de errores humanos al teclear las correcciones individuales.

Hasta este punto, el programa del ejemplo únicamente contiene declaraciones. Una forma de ver una
declaración es como un manual de instrucciones que utiliza el compilador para tratar correctamente las
entidades de nidas. Hay dos tipos de entidades principales, las que representan instrucciones para el
procesador y las que representan los datos sobre los que operan las instrucciones. Las secciones
siguientes se ocupan de la descripción de las primeras, mientras que las entidades que representan datos
son tratadas en el siguiente capítulo.

Punto de Entrada
Todo programa codi cado en el lenguaje C debe tener una función llamada main . Al ejecutar un programa,
el sistema operativo lee el archivo que contiene el código ejecutable desde la unidad de almacenamiento
primario, y lo carga en la memoria RAM. Acto seguido, el sistema operativo transferirá el control del
procesador al programa invocando la función main . Debido a este hecho la función main es llamada
punto de entrada al programa. Cuando main termina, el control del procesador regresa al sistema
operativo.

Por ahora solo conoce el propósito de main y aún desconoce que es una función. La respuesta a esta
interrogante es tan importante que amerita una sección aparte.

Funciones
De acuerdo con McConnell, las funciones o rutinas son la invención más importante en las ciencias de la
computación (Code Complete 2, capítulo 7). En el ámbito de la programación una función es un conjunto de
instrucciones que resuelven una tarea especí ca y puede ser invocada mediante un enunciado simple. Las
funciones se utilizan con varios propósitos, entre ellos:

Reducen la complejidad; es decir, hacen que los programas sean más fáciles de comprender y de
escribir.
Evitan la duplicidad del código.
Mejoran la portabilidad.
Mejoran el desempeño.
Aíslan partes complejas.
Esconden detalles de implementación.
Limitan el efecto de los cambios.

La de nición de una función consta de cuatro partes principales:

1. Nombre de la función. Es un identi cador válido en C y se usa para invocarla. Por convención los
identi cadores de las funciones que se escriben en esta obra inician en mayúsculas. En contraste, las
funciones de la biblioteca estándar tienen nombres en letras minúsculas. Un principio útil para
nombrar una función es utilizar un verbo seguido de un sustantivo por ejemplo HacerPromedio .

2. Parámetros de entrada. Es una lista con las variables requeridas por la función para realizar su tarea. La
lista se encierra entre paréntesis y cada elemento se separa mediante comas. Los nombres de las
variables son precedidos por el tipo de dato requerido. No todas las funciones necesitan valores de
entrada. Cuando este es el caso, se puede dejar la lista vacía () , o bien, se puede escribir la palabra
reservada void .

3. Cuerpo de la función. Son las instrucciones que se ejecutan al invocar la función. El cuerpo de la función
debe estar encerrado entre llaves {...} . La llave de apertura se escribe inmediatamente después del
identi cador. Puede añadir un espacio o un salto de línea entre el paréntesis y la llave para mejorar la
legibilidad.

4. Valor de retorno. Es un valor que regresa la función al terminar su ejecución. Las funciones que no
devuelven valores se declaran con la palabra reservada void .

Valor de Retorno
Nombre de la función
Parámetros de entrada

int Add ( int a, int b ) {


return a + b
} Cuerpo de la función
Cuando se invoca una función el control del programa se trans ere al cuerpo de dicha función. Al terminar
la tarea, la función devuelve el control a la línea que precede a la invocación. La declaración de la función
main es

int main( void )

La palabra reservada int sirve para indicar que la función devuelve un valor entero. Este valor puede ser
utilizado por un programa para indicarle al sistema operativo si la ejecución se realizó con éxito. Por
convención, cuando main regresa cero signi ca que el programa se ejecutó sin errores. La declaración de
main también le indica al compilador que no requiere parámetros de entrada.

El cuerpo de la función main se compone de dos instrucciones. La primera instrucción invoca la función de
la biblioteca estándar printf , y sirve para desplegar un mensaje en la consola de comandos. A diferencia
de main , existen muchas funciones que necesitan valores externos para hacer su trabajo; por ejemplo, la
función prinft necesita una cadena de texto con el mensaje que presentará en pantalla. Una cadena de
texto es una secuencia de caracteres encerrados entre comillas "" . Si desea que el programa del ejemplo
presente un mensaje diferente simplemente reemplace el texto "Primer Programa en C" .

La identación; es decir, el espacio en blanco que antecede a cada una de las líneas del cuerpo de la función,
simpli ca la tarea de ubicar el inicio y el nal de una función. A diferencia de lenguajes como Python su uso
no es obligatorio en C, pero es altamente recomendable porque mejora la legibilidad del código.

La segunda instrucción de la función main establece el valor de retorno de la función mediante la palabra
reservada return . Cuando se ejecuta una instrucción return la función termina sin importar si hay otras
líneas de código subsecuentes.

Es importante resaltar que los enunciados que contienen instrucciones como la invocación de una función
o el regreso del valor de retorno deben terminar en punto y coma. Es posible escribir dos o más
enunciados con instrucciones en una sola línea; sin embargo, con el n de mejorar la legibilidad del
programa es muy recomendable escribir cada instrucción en una línea separada.

Llegó el momento de poner en práctica los conceptos aprendidos hasta ahora. El diseño de programas
para el cálculo de fórmulas matemáticas básicas nos proporciona un medio conveniente para alcanzar este
n. Ya que los números serán nuestra unidad básica de trabajo, debemos conocer como declarar un
número en el lenguaje C.

Declaración de Números
Una declaración es una secuencia de identi cadores que le indican al compilador el nombre y la naturaleza
de una entidad. El compilador usa la declaración para determinar el conjunto de operaciones que pueden
aplicarse sobre la entidad. La declaración de un número tiene la siguiente estructura:

MODIFICADOR PRIMITIVA IDENTIFICADOR

Una primitiva es un tipo de datos básico que soporta el compilador. Existen cuatro tipos básicos: char ,
int , float y double . Las primitivas int y char declaran variables que solo pueden representar
números enteros. Las otras dos primitivas son necesarias para aplicaciones que necesitan cantidades con
partes fraccionarias, o bien, aplicaciones que requieren notación cientí ca.

Un modi cador puede cambiar la cantidad de memoria que ocupa una primitiva; también se emplean para
alterar el manejo de enteros sin signo. En el lenguaje C, las variables enteras pueden contener números
negativos y positivos. El modi cador unsigned sirve para declarar valores enteros que no toman valores
negativos; es decir, números naturales. Hay otros modi cadores disponibles; el efecto que tienen sobre las
primitivas se estudiará con detalle en el capítulo~\ref{}.

Las variables numéricas más comunes en el lenguaje C son:

Número Modi cador Primitiva

Natural unsigned int

Entero de 8 bits   char

Entero   int

Real   float

Real   double

La instrucción unsigned int sumando declara una variable entera llamada sumando que solo puede tomar
valores positivos.

Diseño de una Función


El objetivo de la primera práctica será el diseño de una función que realice el cálculo de la suma de una
secuencia de números naturales consecutivos que inicia en 1. Las partes de una función se determinan al
estudiar detalladamente las cantidades que tienen un papel relevante en el problema que se desea
resolver.

Sabemos que una sucesión aritmética solamente contiene números enteros positivos; es decir, números
naturales. También se sabe que la suma de uno o más números naturales es otro número natural, por lo
tanto, el valor de retorno de la función debe ser de este tipo.

La discusión anterior nos orienta acerca de la naturaleza de los posibles parámetro entrada, pero no aún
no sabemos cuantos parámetros son necesarios. Para determinar esta cantidad se debe estudiar la
fórmula para calcular la suma de una sucesión aritmética:

Esta ecuación utiliza dos constantes y una variable , que representa al último término de la secuencia.
Dentro del programa llamaremos a esta variable cota , y es el único parámetro de entrada que requiere la
función. De acuerdo con la Real Academia Española una cota es "el elemento superior o inferior a todos los
de un determinado conjunto ordenado".

Falta elegir un nombre para la función. Se deben crear nombres que describan el propósito de la función.
Esto ayuda a comprender el funcionamiento y simpli ca el mantenimiento del código en caso de ser
necesario. Siguiendo la recomendación de la sección~\ref{funciones}, usaremos el nombre
SumarSecuencia como identi cador. La declaración de la función es:

unsigned int SumarSecuencia( unsigned int cota )

Cuando la declaración de una función incluye el cuerpo de la función se convierte en una de nición.

Operadores Aritméticos
Al programar una función matemática el cuerpo de la función debe contener instrucciones que realicen
operaciones aritméticas. Las instrucciones que efectúan cálculos se llaman expresiones y contienen al
menos un operador. El lenguaje C de ne varias categorías de operadores en C. Para nes de esta discusión
basta con conocer los operadores aritméticos:

Operador Aritmético Signi cado

* Multiplicación

/ División

% Módulo

+ Suma

- Resta

Estos operadores son operadores binarios; es decir, operadores que requieren dos operandos y regresan
un valor. Los operandos se escriben a la derecha y a la izquierda del operador. Por el momento no
ahondaremos en el operador módulo; su uso se discutirá más adelante.

Los operadores aritméticos tienen la precedencia matemática habitual; por ejemplo, en la expresión
se calcula primero la multiplicación y después la suma. Al igual que en las expresiones aritméticas
convencionales el orden de los cálculos puede ser modi cado mediante paréntesis. Para hacer que la suma
sea evaluada antes que la multiplicación debe escribir . Los corchetes [] y llaves {} no se
pueden usar dentro de una expresión.

El código completo de la función SumarSecuencia es:

unsigned int SumarSecuencia( unsigned int cota ) {


   return cota * ( cota + 1 ) / 2;
}

Durante la compilación, las constantes 1 y 2 son convertidas a un formato binario y quedan jas dentro de
los comandos de lenguaje ensamblador que realizan las operaciones.

El uso de paréntesis es obligatorio para este caso. ¿Qué sucede si no se usan? Debido a la precedencia de
operadores la multiplicación y la división se calculan antes que la suma. La expresión sin paréntesis
regresaría el cuadrado de cota . El valor 1/2 se ignora porque el cociente de esta operación es cero.

Invocando una Función


La etapa nal del diseño es invocar SumarSecuencia desde la función main . El procedimiento para invocar
una función es simple: se escribe el nombre de la función, y entre paréntesis se escriben los parámetros de
entrada. Es indispensable contar con una declaración de la función antes de invocarla; por lo tanto, la
de nición de SumarSecuencia debe colocarse antes de main . La siguiente versión hace el cálculo de la
secuencia de números del 1 a 10.

/* Suma de la secuencia de números del 1 al 10 mediante fórmula */


unsigned int SumarSecuencia( unsigned int cota ) {
 return cota * ( cota + 1 ) / 2;
}

int main( void ) {


 SumarSecuencia( 10 );
 return 0;
}

Al ejecutar este programa aparentemente no sucede nada. En su forma actual el programa realiza el
cálculo, pero como no se agregaron instrucciones para enviar el resultado a la consola de comandos no
podemos verlo. La siguiente sección demuestra como resolver este inconveniente.

Salida de Datos
La consola de comandos es una interfase de usuario basada en texto. Un programa debe convertir la
representación binaria de un número en secuencias de caracteres antes de enviar el mensaje a la consola.
Precisamente esta es la nalidad de la función printf , que es parte de la biblioteca estándar. Su
declaración se encuentra en el archivo stdio.h y se accede a ella mediante la directiva #define . Como
mínimo printf requiere un parámetro de entrada, tal y como se mostró en el programa de la
sección~\ref{}; sin embargo, se pueden agregar tantos parámetros de salida como sea necesario.

Especi cador de Formato


Para alcanzar toda la funcionalidad que ofrece printf se deben utilizar especi cadores de formato. Los
especi cadores de formato son caracteres antecedidos por el signo de porcentaje que se ubican dentro de
la cadena del mensaje. Los especi cadores de formato son reemplazados por la conversión en caracteres
de una variable dada. Por cada especi cador de formato se debe incluir una variable del tipo
correspondiente en la lista de parámetros, siguiendo el mismo orden en el que aparecen dentro de la
cadena del mensaje. Los especi cadores de formato más comunes son:

Especi cador de Formato Tipo de Dato Ejemplo

%u unsigned int 231

%d o %i int -100

%f float 2.345

%lf double 2.345

%c char z

%s char[] Mensaje

Por ejemplo, para desplegar el número natural 50 en la consola se utiliza la siguiente instrucción:

printf( "%u", 50 );

Usando este conocimiento, el código para hacer el despliegue del resultado de la función SumaSecuencia
es:

#include <stdio.h>

/* Suma de la secuencia de números del 1 al 10 mediante fórmula */


unsigned int SumarSecuencia( unsigned int cota ) {
 return cota * ( cota + 1 ) / 2;
}

int main( void ) {


 printf( "%u", SumarSecuencia( 10 ) );
 return 0;
}

La instrucción que invoca printf usa dos parámetros. El primero es un mensaje compuesto por un
especi cador de formato. El segundo parámetro proviene de invocar la función SumarSecuencia . El
compilador genera código que llama a las funciones en el orden correcto; en este caso, primero se llama
SumarSecuencia y su valor de retorno es empleado como parámetro para la función printf .

Podemos hacer más claro el resultado del programa anterior añadiendo una breve descripción. Por
simplicidad, solo se incluyen las correcciones pertinentes en la llamada a la función printf .

printf(
   "La suma de los numeros del 1 al 10 es : %u",
   SumarSecuencia( 10 ) );

Secuencias de Escape
El formato del mensaje se puede controlar mediante secuencias de escape, las cuales representan
caracteres o acciones para los cuales no hay símbolos de nidos; tal es el caso de los saltos de línea y los
tabuladores. Las secuencias de escape siempre inician con una barra invertida. La siguiente tabla contiene
las secuencias de escape soportadas por el lenguaje C.

Secuencia de Escape Carácter

\a Sonido de Alerta

\b Retroceso

\e Escape

\f Salto de Página

\n Nueva Linea

\r Retorno de Carro

\t Tabulador Horizontal

\v Tabulador Vertical

\\ Diagonal Invertida

\' Apostrofe

\" Comillas

\? Signo de interrogación

\nnn Código ASCII en octal

\xhh Código ASCII en hexadecimal

\uhhhh Código Unicode en hexadecimal menor a 10000

El salto de línea es una de las secuencias de escape más empleadas para dar formato a un mensaje.
Agregar saltos de línea en una cadena de formato permite escribir múltiples líneas con una sola invocación
a printf . Una aplicación muy es la creación de tablas con un número jo de columnas y renglones. El
siguiente fragmento muestra como desplegar una tabla con la suma de una tres series aritméticas:

printf(
 "Cota   Suma\n%u %u\n%u %u\n%u %u",
   10, SumarSecuencia( 10 ),
  100, SumarSecuencia( 100 ),
 1000, SumarSecuencia( 1000 ) );

En este programa la función SumarSecuencia se invoca tres veces con diferentes valores. La secuencia de
escape \n se usa para iniciar una nueva línea de texto. El mensaje que aparece en la consola al ejecutar el
programa es:

Cota   Suma
10 55
100 5050
1000 500500

Especi cador de Ancho


Para alinear las celdas de la tabla se usan los especi cadores de ancho, los cuales indican la cantidad
mínima de caracteres que debe abarcar una conversión. Si los datos convertidos ocupan menos espacio
que el solicitado, se agregan espacios en blanco a la izquierda. El especi cador de ancho es un número que
se coloca entre el signo de porcentaje y el carácter que identi ca el formato.

Para mostrar una tabla con números alineados a la derecha se utiliza el siguiente código:

printf(
 "Cota   Suma\n%4u %6u\n%4u %6u\n%4u %6u",
   10, SumarSecuencia( 10 ),
  100, SumarSecuencia( 100 ),
 1000, SumarSecuencia( 1000 ) );

Los especi cadores de formato para la columna Cota tienen un ancho de cuatro caracteres, mientras que
los que corresponden a la columna Suma tienen 6 caracteres. La salida del programa es

Cota   Suma
10     55
100   5050
1000 500500

La documentación de la función printf incluye otros especi cadores de ancho y de formato, su uso será
descrito en capítulos posteriores.

El Operador Módulo
Probablemente esta sea la primera vez que ha escuchado acerca del operador módulo. El operador
módulo se requiere para trabajar con cantidades cuyo valor no puede exceder un valor límite. Los días de
la semana, un ángulo en grados, o la hora del día son cantidades que cumplen con esta condición. Cuando
estas cantidades crecen se repiten de forma cíclica cuando alcanzan el valor límite; es decir, el valor límite
regresará a cero.

El operador módulo calcula el residuo de una división entera y tiene la misma precedencia que una
multiplicación o una división. Por las propiedades de la división es claro que el residuo de una división se
puede obtener mediante la fórmula:

dónde es el dividendo, es el divisor y el cociente. Este enfoque requiere almacenar el cociente de la


división en una variable para poder funcionar. Adicionalmente, se requieren tres operaciones para obtener
el resultado: una división, una resta y una multiplicación. En contraste, el operador módulo simplemente
calcula la división, descarta el cociente, y regresa el residuo.

Para poner en práctica el operador modulo, considere la siguiente situación. Un médico que atiende
consultas a domicilio sabe que el día 40 de cada año es día festivo. Con el n de plani car sus actividades,
el médico le encarga a usted un programa para determinar que día de la semana corresponde esa fecha.

La solución de los ejercicios que se ha presentado hasta ahora hacen uso de las leyes de las matemáticas o
de la física. Este tipo de leyes han pasado a través del rigor del método cientí co, por lo cual, las variables
que in uyen en el modelo son bien conocidas. Sabemos que no existen modelos ampliamente aceptados
para el problema que nos ocupa, así que debemos crear uno mediante la abstracción.

Abstracción es un proceso mediante el cual se identi can las propiedades relevantes de un objeto para
resolver un problema. Las propiedades que no tienen un efecto signi cativo sobre el resultado son
ignoradas. En este contexto, la abstracción sirve para remplazar una situación compleja de mundo real por
un modelo que puede ser expresado en instrucciones de computadora.

Son siete los días de la semana, cada uno tiene un nombre diferente y un orden preestablecido. Por otra
parte, si dividimos un número entre siete, el rango de posibles resultados va de cero a seis. Esto sugiere
que podemos remplazar los nombres de los días de la semana por un número que se encuentre dentro de
este rango. Ya que los nombres de los días ocurren en un orden bien establecido, el mapeo entre nombres
y números debe respetar este hecho; es decir, sí el viernes es el día cinco, el sábado debe equivaler al día
seis.

Es extremadamente importante el hacer notar que los días del año inician en 1, mientras que en nuestra
abstracción los días inician en cero. Este desfase debe ser corregido restando una unidad al día del año
que se desea analizar.

El inicio de la semana puede ser elegido por varias razones siendo la semana laboral, y el calendario
religioso dos de las razones más comunes. Basados en las necesidades del médico utilizaremos el lunes
como el primer día de la semana. El código con la solución del problema es:

#include <stdio.h>
#define UINT unsigned int
#define FESTIVO       40
#define DIAS_EN_SEMANA 7
#define LUNES           0
#define MARTES         1
#define MIERCOLES       2
#define JUEVES         3
#define VIERNES         4
#define SABADO         5
#define DOMINGO         6

/* Determina el dia de la semana de cualquier dia del año.


* Se debe especificar el dia de la semana del primer día del año */
int DiaDeSemana( UINT eneroUno, UINT dia ) {
 return ( eneroUno + dia - 1 ) % DIAS_EN_SEMANA;
}

int main( void ) {


 printf(
   "\nEl día %u del año cae en %u\n",
   FESTIVO, DiaDeSemana( SABADO, FESTIVO ) );
 return 0;
}

El listado~\ref{} usa la directiva #define con un nuevo propósito: simpli car la escritura del programa.
Recuerde que el preprocesador hace reemplazos en el texto del código; cuando encuentra el identi cador
UINT reemplaza el texto por unsigned int antes de enviarlo al compilador.

Enumeradores
La solución del problema del programa anterior ha expuesto las bondades de las constantes simbólicas.
Evitan tener que memorizar los valores de cada constante y facilitan la comprensión de los enunciados que
las emplean. Un efecto colateral que resulta desagradable es la cantidad de texto que se debe incluir en el
código. Por fortuna, los creadores de C incluyeron una sintaxis alternativa que simpli ca las declaración de
este tipo de constantes.

La palabra reservada enum asigna valores enteros consecutivos a una lista de identi cadores. Las
declaraciones de los días de la semana se pueden simpli car escribiendo:

enum DIA_EN_SEMANA {
 LUNES, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO
};

La llave de cierre debe ser precedida por un punto y coma. Al primer identi cador de la lista se le asigna el
valor cero por defecto. Puede incluir una asignación después del nombre del identi cador para hacer que
la sucesión inicie en 1, o cualquier otro valor que sea conveniente

enum DIA_EN_SEMANA {
 LUNES=1, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO
};

La asignación del valor de cada constante puede ocurrir en cada identi cador y en cualquier orden. La
siguiente declaración implementa la abstracción usada en la solución del problema anterior de niendo
cada constante individualmente:

enum DIA_EN_SEMANA {
 DOMINGO = 6, JUEVES    = 3, LUNES  = 0,
 MARTES  = 1, MIERCOLES = 2, SABADO = 5, VIERNES = 4
};

Ejercicios
Los siguientes ejercicios requieren el diseño de un programa. Incluya en los comentarios de cada listado las
razones que lo llevaron a elegir un tipo de dato dado, tanto en los parámetros de entrada como en el valor
de retorno. Los valores de los parámetros de entrada y el resultado deben mostrarse en la consola de
comandos.

1. Calcule los segundos transcurridos dentro de un lapso de tiempo especi cado en días, horas, minutos
y segundos.
2. Escriba un programa para convertir grados centígrados a grados Fahrenheit.
3. Escriba un programa para calcular la resistencia equivalente de dos resistencias conectadas en
paralelo.
4. En el ejercicio anterior, ¿que sucede con el programa si el valor de ambas resistencias es cero?
5. A partir de los valores de desplazamiento inicial , velocidad inicial , aceleración y el tiempo ,
escriba un programa para calcular su desplazamiento nal.

8. ¿Puede aplicar función obtenida en el problema anterior para resolver un problema similar de
movimiento angular uniforme? ¿Se puede usar para evaluar los puntos de una parábola?

9. Diseñe un programa para convertir de segundos a horas, minutos y segundos. El resultado debe tener
formato de tabla.

10. Escriba un programa que calcule la suma de ángulos interiores de un polígono y aplíquelo para el
triángulo, el cuadrilátero, el hexágono y el icoságono (20 lados). Utilice constantes simbólicas para el
número de lados de cada gura. Los resultados deben aparecer en una tabla cuya primera columna
contiene el número de lados del polígono. La ecuación es:

Donde es el número de lados del polígono.

También podría gustarte