Logo Studenta

FPR_U3_Contenido

¡Este material tiene más páginas!

Vista previa del material en texto

Ciencias Exactas Ingeniería y Tecnología 
Primer Semestre 
 
 
Programa de la asignatura: 
Fundamentos de programación 
 
 
 
Unidad 3. Funciones y estructuras de Datos 
 
 
 
Universidad Abierta y a Distancia de México 
 
 
 
 
 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 2 
Índice 
 
 
Presentación de la unidad ....................................................................................................................... 3 
Propósitos ............................................................................................................................................................ 4 
Competencia específica ............................................................................................................................. 5 
Logros………………………………………………………………………………………………………………………………………………. 5 
3.1. Diseño descendente (Top-Down) ................................................................................................ 6 
3.2. Definición, declaración e invocación de funciones en C .......................................... 12 
3.3. Alcance de las variables ................................................................................................................... 18 
3.4. Paso de parámetros .......................................................................................................................... 20 
3.4.1. Llamada a una función por valor ........................................................................................... 21 
3.4.2. Llamada a una función por referencia ............................................................................. 23 
3.5. Estructuras de datos ......................................................................................................................... 24 
3.5.1. Arreglos .................................................................................................................................................... 27 
3.5.2. Cadenas ............................................................................................................................................... 453 
3.5.3. Estructuras ........................................................................................................................................... 49 
Cierre de la unidad ...................................................................................................................................... 60 
Fuentes de consulta ................................................................................................................................... 61 
 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 3 
 
Presentación de la Unidad 
 
Hasta esta etapa del curso, has aprendido a utilizar las estructuras de control 
para diseñar soluciones de 
problemas simples. También has 
conocido diferentes formas de 
representar los datos involucrados en 
un problema, desde simples hasta 
estructurados (como arreglos, 
cadenas y estructuras). Sin embargo, 
todas las soluciones propuestas 
constan únicamente de un módulo 
(función), llamado principal (en C, 
main); lo cual no es conveniente 
cuando se trata de problemas complejos que requieran de una serie de tareas 
para lograr su solución, pues éste sería muy grande y, por lo tanto, difícil de 
corregir o modificar. 
 
Lo recomendable es crear módulos independientes que realicen cada una de 
las tareas específicas y que en conjunto implementen la solución del problema. 
Según Levine (2001), se podría definir un módulo como un conjunto de 
instrucciones que realizan una función específica, que están contenidos en un 
fragmento del código principal y que tiene la característica de no ser 
directamente ejecutable, sino que debe ser llamado para efectuar sus 
funciones. Los buenos hábitos de programación indican que el módulo 
principal debe ser pequeño y fácil de entender, y estar constituido casi por 
completo de llamadas a otros módulos de más bajo nivel que realicen 
efectivamente el trabajo. 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 4 
En esta unidad se explicarán las funciones, que son el medio por el cual se 
implementan los módulos en lenguaje C. Se presentará la sintaxis para crear 
una función y la forma en la que se utilizan. Además, se resolverá un problema 
utilizando el diseño modular para ejemplificar el tema. 
Así mismo y con el fin de poder dar solución a problemas cada vez más 
complejos, conoceremos las estructuras que nos permiten procesar datos 
relacionados entre sí y que están compuestas de conjuntos de datos básicos. 
 
 
Propósitos 
 
En esta unidad: 
 
• Identificarás la forma en la que puedes analizar un problema para 
resolver tareas simples que en su conjunto encuentren la solución total. 
• Diseñarás algoritmos modulares para solucionar un problema. 
• Construirás funciones en lenguaje C que realicen tareas específicas. 
• Determinarás las estructuras de datos involucradas en la solución de un 
problema. 
• Diseñarás soluciones empleando arreglos y estructuras (registros). 
• Utilizarás arreglos y estructuras (registros) en programas escritos en 
lenguaje C. 
 
 
 
 
 
 
 
 
 
 
 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 5 
 
 
Competencia específica 
 
 
 
 
 
Implementar funciones y utilizar estructuras de 
datos para almacenar y manipular información con 
el fin de resolver problemas cotidianos a través del 
desarrollo de programas modulares escritos en 
lenguaje C. 
 
Logros: 
 
• Analizar la funcionalidad del diseño descendente. 
• Diseñar programas modulares y declarar las funciones que se utilizarán 
en los módulos. 
• Representar los módulos en diagrama de flujo y pseudocódigo. 
• Codificar los algoritmos modulares. 
• Identificar las características de las estructuras de datos y formas en que 
pueden aplicarse. 
• Implementar un arreglo en un programa en C para dar respuesta a un 
caso planteado por el docente en línea. 
• Implementar una estructura en un programa en C para dar respuesta a 
un caso específico. 
 
 
 
 
 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 6 
 
3.1. Diseño descendente (top-down) 
 
La ventaja principal de los módulos o subrutinas es que organizan 
funcionalmente las acciones dentro de un sistema de programación por 
medio de su capacidad sintetizadora, que permite definir y asignar funciones 
de acuerdo con un plan maestro sin tener que resolver cada vez localmente 
problemas que pueden ser atendidos en un solo lugar (Levine, G. 2001 p.233). 
Esta característica de los módulos da lugar a una metodología de 
programación conocida como diseño estructurado. 
 
Dentro del diseño estructurado existen varias “escuelas”, una de las cuales 
parte de los módulos de más alto nivel, delegando responsabilidades a los de 
más abajo cuando así convenga, y sin tener que esperar a que éstos estén 
terminados (Levine, G. 2001 p.234). A esta metodología se le conoce como 
diseño descendente (top-down). 
 
La metodología del diseño descendente permite establecer una relación entre 
las etapas de estructuración de manera que se relacionen entre sí a través de 
entradas y salidas de datos. Es decir, se descompone el problema en etapas de 
estructuración, módulos o subrutinas jerárquicos, de forma que se pueda 
considerar cada estructura desde dos puntos de vista: ¿qué hace? y ¿cómo lo 
hace? 
Con lo anterior podemos decir que: un módulo se caracteriza por realizar una 
tarea específica, posee sus propios datos de entrada – llamados parámetros de 
entrada – y su resultado – llamado salida o valor de retorno –. El diseño de cada 
módulo debe ser independiente de los otros; si es necesario que exista 
comunicación entre ellos, ésta únicamente podrá realizarse a través de los 
parámetros de entrada y del valor de retorno. En este sentido, puede ser visto,por otros módulos, como una caja negra que hacia el exterior sólo muestra 
qué hace y qué necesita, pero no cómo lo hace. 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 7 
La creación de un módulo conlleva dos partes: la definición del módulo y la 
llamada o invocación (ejecución). La primera consta de tres partes: 
 
• Definir los parámetros de entrada; 
• Definir el valor de retorno; 
• Escribir todas las instrucciones que le permitirán llevar a cabo la tarea, 
es decir, un algoritmo. 
 
La llamada o invocación a un módulo es el proceso de ejecutar el conjunto de 
instrucciones definidas en el módulo dado un conjunto de entradas específico. 
La forma general de invocar un módulo es escribiendo su nombre y entre 
paréntesis los valores de cada uno de los parámetros de entrada, respetando 
el orden con el que se definió. 
 
No existe un método para saber en cuántos módulos se debe dividir un 
problema, sin embargo, es importante tener en cuenta los siguientes 
principios del diseño modular: 
 
• Las partes altamente relacionadas deben pertenecer a un mismo 
módulo. 
• Las partes no relacionadas deben residir en módulos diferentes. 
 
Para ejemplificar esta forma de resolver problemas y cómo implementarla, se 
presenta la siguiente situación: 
 
Problema 3.1. Análisis y diseño con el método descendente (Top Down): 
Realiza el análisis y diseño de un programa que lea las temperaturas promedio 
mensuales registradas en una ciudad a lo largo de un año y calcule el promedio 
anual. Además, debe convertir las temperaturas mensuales dadas en grados 
Celsius a grados Fahrenheit al igual que el promedio. 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 8 
Empecemos por hacer un bosquejo de los pasos que se tienen que realizar 
para llegar al resultado deseado. 
1. Leer las doce temperaturas promedio mensuales 
2. Calcular el promedio anual de las temperaturas 
3. Convertir las temperaturas promedio mensuales de Celsius a Fahrenheit 
4. Convertir el promedio anual de temperaturas a Fahrenheit 
5. Imprimir las temperaturas mensuales en grados Fahrenheit y el 
promedio anual de las temperaturas, en Celsius y Fahrenheit. 
 
Para registrar las temperaturas mensuales proponemos utilizar un arreglo de 
tamaño 12, y de acuerdo con lo anterior, proponemos tres módulos: El primero 
encargado de leer las temperaturas mensuales dadas en grados Celsius, este 
módulo necesita el nombre del arreglo donde va a almacenar los datos. Otro 
módulo encargado de calcular el promedio de las temperaturas, que recibe 
como parámetros de entrada el arreglo con las temperaturas mensuales y 
devuelve el promedio en grados Celsius. El último módulo sólo convierte 
grados Celsius a grados Fahrenheit. Esta información se resume en el 
diagrama modular que se muestra a continuación. 
 
 
Diagrama modular del problema 3.1 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 9 
Es mediante un diagrama modular como se representan de manera gráfica los 
módulos que integran la solución del problema. Y una vez que se han definido, 
el siguiente paso es diseñar el algoritmo de cada uno de ellos. 
 
En primer lugar, se muestra el pseudocódigo de los módulos secundarios: 
 
Algoritmo 3.1: Algoritmo del módulo leerTemps(temp[]) 
 
Módulo leerTemps(temp[ ]) 
 
Inicio 
Desde mes ← 1 mientras 
mes ≤ 12, mes ← mes + 1 
 Imprimir 
“Proporciona la 
temperatura del 
 mes”, mes 
 Leer temps[mes-
1] 
Fin_Desde 
Fin 
 
 
Observa que el ciclo del módulo leerTemps se inicia con mes igual a 1 y termina 
cuando mes es 13, se propone así porque se pide la temperatura de los meses 
1, 2, 3,.. 12, así que la variable mes guardará el número de mes correspondiente 
a cada lectura, sin embargo, para almacenar la temperatura en la posición del 
arreglo indicada se resta uno (temps[mes-1]), así se guarda desde la posición 0 
y hasta la posición 11. 
 
Algoritmo 3.2: Algoritmo del módulo promTemps(temp[]) 
En contraste con el ciclo del módulo leerTemp, en este módulo el contador del 
ciclo se inicia en 0 y termina en 11 (aunque el valor que tiene al finalizar el ciclo 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 10 
es 12) pues se utiliza para ir sumando cada uno de los elementos del arreglo, 
así que la variable mes indicará cada una de las posiciones del arreglo. 
 
Módulo promTemps(temp[]) 
Inicio 
suma ← 0 
Desde mes ← 0 mientras 
mes ≤ 11, mes ← mes + 1 
 suma ← suma + 
temps[mes] 
Fin_Desde 
Regresa (suma/12) 
Fin 
 
 
 
 
Algoritmo 3.3: Algoritmos de módulos secundarios del problema 3.1 
(pseudocódigo) 
Módulo aFahrenheit(tempC) 
Inicio 
tempF = 9 5⁄ tempC + 32 
Regresa tempF 
Fin 
 
 
 
A partir de los módulos secundarios presentados se puede plantear el 
módulo principal. 
 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 11 
Algoritmo 3.4: Algoritmo del módulo principal del problema 3.1 
(pseudocódigo) 
 
 
A manera de ejercicio, puedes realizar las representaciones en diagrama de 
flujo del módulo principal, considerando que el símbolo que se utiliza para 
llamar a módulos que no devuelven ningún valor, como es el caso se leerTemps 
se muestra a continuación: 
 
 
 
 
Módulo Principal 
Inicio 
/* Lectura de las temperaturas, invocando al módulo leerTemps */ 
Imprimir “Ingresa los promedios de temperaturas mensuales” 
leerTemps(temps[]) 
 
/* Cálculo del promedio utilizando el módulo promTemps */ 
promC ← promTemps(temps[]) 
 
/* Conversión del promedio a grados Fahrenheit, invocando al módulo 
aFahrenheit */ 
promF ← aFahrenheit(promC) 
 
/* Conversión de las temperaturas mensuales a grados Fahrenheit */ 
Desde mes ← 0 mientras mes ≤ 11, mes ← mes + 1 
 tempsF[mes] ← aFahrenheit(temps[mes]) 
Fin_Desde 
 
/* Impresión de temperaturas mensuales en Fahrenheit */ 
Desde mes ← 1 mientras mes ≤ 12, mes ← mes + 1 
 Imprimir “Temperatura en Fahrenheit del mes”, mes, “ es: ”, 
tempF[mes-1] 
Fin_Desde 
 
/* Impresión del promedio en grados Celsius y grados Fahrenheit */ 
Imprimir “ El promedio en grados Celsius es: “, promC 
Imprimir “El promedio en grados Fahrenheit es: “, promF 
Fin 
leerTemps(temp[]) 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 12 
Este no es el caso del resto de los módulos secundarios que sí devuelven un 
valor, así que se utiliza el símbolo de proceso (rectángulo). 
Con el ejemplo anterior resaltan indudablemente varias ventajas que 
proporciona un diseño modular: 
 
1. Es posible reutilizar código, ésta indudablemente es una de las más 
importantes ya que no es necesario escribir el mismo código cada vez 
que deseamos realizar una tarea semejante. Por ejemplo, el módulo 
aFahrenheit se utiliza 13 veces (12 en el ciclo y una para convertir el 
promedio) y sólo bastó definirlo una vez. 
 
2. Fácil detección y corrección de errores, dado que el problema fue divido 
en pequeños módulos cada uno responsable de una tarea, si en algún 
momento existiera un error en la solución global, basta identificar cuál 
de las tareas es la que no se está resolviendo adecuadamente y corregir 
únicamente aquellos módulos involucrados. 
 
3. Fácil modificación o extensión, si se requiere modificar una tarea del 
problema o agregar una nueva, no será necesario rediseñar todo el 
algoritmo, basta con hacer las modificaciones en los módulos 
pertinentes. 
 
Un problema se vuelva más sencillo de solucionar si pensamos de manera 
modular. 
 
Una vez que se ha ilustrado cómo realizar una solución modular, lo siguiente 
es explicar cómo se codifica cada uno de los módulos, tema que se abordará 
en las siguientes secciones. 
 
3.2. Definición, declaración e invocación de funciones en C 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 13 
En el caso particular de C,un módulo se implementa como una función, 
recuerda que anteriormente se explicó que un programa en C está integrado 
de varias funciones, donde una función se define como una porción de código 
(un conjunto de instrucciones agrupadas por separado) enfocado a realizar 
una tarea en específico, resaltando la función principal main. 
 
Al igual que la función principal, cada una de las funciones existe de manera 
independiente, tiene sus propias variables, instrucciones y un nombre que las 
distingue de las otras, además de los parámetros de entrada (también 
llamados argumentos) que recibe y el tipo de dato que regresa. 
 
 
 La forma general para definir una función es: 
 
 <tipo de dato retorno><identificador de la función>(<parámetros 
de entrada>) 
 { 
 <instrucciones de la función> 
 return<expresión>; 
} 
 
 
La expresión <tipo de dato retorno> indica el tipo de dato que devuelve la 
función (puede ser cualquiera de los tipos básicos), para lo cual se utiliza la 
palabra reservada return. Cuando la función no devuelve ningún dato, se 
especifica mediante el tipo void y no debe incluir la palabra reservada return. 
La expresión <identificador de la función> es el nombre que le vamos a 
dar a la función y con este nombre vamos a hacer referencia a ella. Se deben 
seguir las mismas reglas establecidas para los identificadores de variables y se 
recomienda que sean nemónicos. Después del nombre se coloca, entre 
paréntesis, la lista de parámetros o la declaración de las variables locales que 
van a contener los datos de entrada para la función, se debe especificar 
explícitamente el tipo y nombre de la variable, separados por comas aun 
cuando sean del mismo tipo. Ejemplo tipo1 param1, tipo2 param2, …, tipoN 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 14 
paramN. Finalmente, las instrucciones del cuerpo de la función van entre 
llaves. 
 
La primera línea de la definición de una función se conoce como encabezado 
de la función (en inglés header). 
 
Para ilustrar esto, a continuación se muestra la codificación del módulo 
aFahrenheit definido en la sección anterior. 
 
 
float aFahrenheit(float tempC) 
{ 
 return ((9.0/5.0)*tempC+32); 
} 
 
Programa 3.1: Codificación del módulo aFahrenheit 
 
La llamada o invocación de una función se realiza cuando se requiere que se 
ejecuten las instrucciones del cuerpo con valores de entrada determinados. 
Para invocar a una función se tiene que escribir el nombre seguido de los 
valores que deben coincidir con el orden, número y tipo de los parámetros de 
entrada dados en la definición de la función y deben estar encerrados entre 
paréntesis. 
 
La sintaxis general para invocar una función ya sea predefinida o definida por 
el programador, es la siguiente: 
 
<identificador de la función>( <lista de valores>); 
 
Los parámetros de entrada de una función son valores determinados y pueden 
ser constantes (8,’a’, 5.2, “cadena constante”), una variable (el valor almacenado 
pasa a la función) o una expresión. Por ejemplo, la llamada a la función que 
definimos se muestra en la siguiente instrucción: 
promF = aFahrenheit(promC); 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 15 
 
Al igual que las variables, una función debe ser declarada antes de utilizarse, es 
decir, antes de invocarla. La declaración de una función se realiza escribiendo 
el prototipo de la función. El prototipo de una función coincide con el 
encabezado de la misma terminando con punto y coma (;) El prototipo de una 
función sólo indica al compilador que existe y cómo es, más no lo que hace, por 
lo tanto, la función debe definirse después. Por ejemplo, el prototipo de la 
función anterior es: 
float aFahrenheit(float tempC); 
 
Cabe señalar que en el prototipo de las funciones se puede omitir los 
identificadores de los parámetros, más no los tipos. 
 
Para ilustrar todo lo anterior, a continuación, se muestra la codificación del 
algoritmo modular diseñado en la sección anterior. 
/* Programa: promedioTemp.c 
 * Descripción: Calcula el promedio de las temperaturas promedio 
 * mensuales registrada a lo largo de un año*/ 
 
/* Biblioteca */ 
#include<stdio.h> 
#include<stdlib.h> 
 
/* Variables globales */ 
int meses = 12; 
 
/* Prototipos de las funciones */ 
/* Función que lee las temperaturas promedio mensuales registradas 
en un año*/ 
void leerTemps( float temps[]); 
 
/* Función que calcula el promedio de las temperaturas promedio 
mensuales registradas en un año*/ 
float promTemps( float temps[]); 
 
/* Función que convierte de grados Celsius a grados Fahrenheit */ 
float aFahrenheit(float tempC); 
 
/* Función principal */ 
main() 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 16 
{ 
 /* Declaración de variables locales a main */ 
float temps[12], tempsF[12], promF, promC; 
int mes; 
 
 /* Lectura de las temperaturas, invocando a leerTemps*/ 
 printf(“Ingresa los promedios de temperaturas mensuales\n”); 
 leerTemps(temps); 
 
 /* Cálculo del promedio utilizando la función promTemps */ 
 promC = promTemps(temps); 
 
 /* Conversión del promedio a grados Fahrenheit, invocando 
al 
 módulo aFahrenheit */ 
 promF = aFahrenheit(promC); 
 
 /* Conversión de las temperaturas promedio mensuales a 
grados 
 Fahrenheit, invocando al módulo aFahrenheit */ 
for(mes = 0; mes<=11; mes++) 
 tempsF[mes] = aFahrenheit(temps[mes]); 
 
 /* Impresión de temperaturas promedio mensuales en grados 
 Fahrenheti*/ 
for(mes = 1; mes<=12; mes++) 
 printf(“\n La temperatura en grados Fahrenheit del mes 
%d es %.2f: ”, mes, tempsF[mes-1]); 
 
 /* Impresión del promedio */ 
 printf(“\n\n El promedio anual en grados Celsius es: %.2f ”, 
promC); 
 printf(“\n El promedio anual en grados Fahrenheit es: %.2f ”, 
promF); 
 
system(“pause”); 
 
} /* fin main */ 
 
 
 /* Definición de funciones */ 
 
void leerTemps (float temps[]) 
{ 
 /* Definición de variables locales a leerTemps */ 
 int mes; 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 17 
 
 for(mes = 1; mes<=12; mes++) 
 { 
 printf(“\n Ingresa la temperatura promedio del mes %d: ”, 
mes); 
 scanf(“%f”, &temps[mes-1]); 
 } 
} /* fin leerTemps */ 
 
float promTemps (float temps[]) 
{ 
 /* Definición de variables locales a promTemps */ 
 int mes; 
 float suma=0; 
 
 for(mes = 0; mes<=11; mes++) 
 suma = suma + temps[mes]; 
 
 return (suma/12); 
} /* fin leerTemps */ 
 
 
float aFahrenheit(float tempC) 
{ 
 return ((9.0/5.0)*tempC+32); 
} /* fin aFahrenheit */ 
 
 
Programa 3.2: promedioTemp.c 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 18 
 
Figura 3.1: Ejecución del programa promedioTemp.c 
 
Con este ejemplo se representa mediante un ejemplo, la estructura de un 
programa en C incorporando funciones. Se debe poner especial atención en la 
declaración de funciones para evitar errores de compilación. 
 
Considera que el compilador sí distingue las letras mayúsculas de las letras 
minúsculas; por lo tanto, debes tener especial cuidado al seleccionar los 
nombres de las funciones. 
 
 
3.3. Alcance de las variables 
 
Cuando nos referimos al alcance de las variables, hacemos referencia al ámbito 
en que se podrán utilizar dentro del código cuando son declaradas fuera del 
cuerpo de cualquier función se denominan variables globales y pueden ser 
utilizadas en cualquier punto del programa a partir del lugar donde fueron 
declaradas, en cambio cuando son declaradas dentro del cuerpo de alguna 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 19 
función se denominan variables locales a ésta, es decir sólo dentro de esa 
función pueden ser utilizadas. 
 
Las variables locales que tienen el mismonombre, pero fueron declaradas en 
diferentes funciones, no tienen relación, son espacios de memoria totalmente 
independientes uno de otro. Podemos decir que, son como dos personas 
diferentes que tienen el mismo nombre. Por otro lado, las variables que se 
ponen como argumentos en la declaración de una función se consideran 
locales a estas. Para ejemplificar lo anterior, se muestra el siguiente programa, 
en el cual se distinguen con diferentes colores el alcance de las variables. 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 20 
 
/asterisco porReferencia.casterisco/ 
#include<stdio.h> 
#include<stdlib.h> 
 
int TAM = 5; 
 
void inicializaA(int A[]) 
{ 
 int i; 
 for (i=0; i<TAM; i++) 
A [i] = 0; 
} 
 
main() 
{ 
 int i; 
int A[] = {1,1,1,1,1}; 
 printf(“Arreglo antes de la llamada a inicializaA: A = [”); 
for (i=0; i<TAM; i++) 
 { if(i< TAM -1) 
 printf(“%d ,”,A[i]); 
 else 
 printf(“%d ]\n\n\t”,A[i]); 
} 
 inicializaA(A); 
printf(“Arreglo después de la llamada a inicializaA: A = [”); 
for (i=0; i<TAM; i++) 
 { if(i< TAM -1) 
 printf(“%d ,”,A[i]); 
 else 
 printf(“%d ]\n\n\t”,A[i]); 
 } 
 system(“pause”); 
} 
Programa 3.3: porReferencia.c 
 
Al utilizar variables globales todas las funciones pueden manipularlas, sus 
valores permanecen mientras el programa está en ejecución. Sin embargo, 
su uso puede promover errores de tipo lógico, ya que al modificar el valor de 
una variable dentro de una función puede afectar el resultado de otra. 
 
Variable global 
Referencia a una 
variable global 
Variable local A 
inicializaA 
Variable local i 
Declaración de 
variables locales a main 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 21 
Por ejemplo, supongamos que la función inicializaA() modifica el valor de la 
variable TAM que almacena el número de elementos del arreglo A, este cambio 
repercutirá en los ciclos de la función main, los cuales imprimen el arreglo A. 
En este caso se producirá un error en la ejecución, pues si el valor es menor a 
cinco no se imprimirán todos los valores y si es mayor entonces habrá 
elementos indefinidos. Detectar y corregir este tipo de errores puede ser una 
tarea nada fácil, por lo que no se recomienda el uso de variables globales, lo 
cual no ocurre si son constantes. 
 
Las variables locales por otra parte favorecen mucho la reutilización de código 
y la modularidad, ya que cada función declara y manipula sus propias variables 
sin depender de lo que ocurra en otras funciones, esto no significa que al 
utilizar solamente variables locales no sea posible compartir datos entre las 
diferentes funciones, esto se hace mediante sus datos de entrada y retorno, 
una posible desventaja es que el valor de las variables locales se pierde cada 
vez que la función termina. 
 
 
3.4. Paso de parámetros 
 
El paso de parámetros se refiere a la forma en la que se transfiere como 
parámetro una variable a una función, esencialmente, si se le otorgan o no 
permisos para modificar los valores originales. Cuando no se le otorga 
permisos para que la modifique se dice que es paso de parámetros por valor, 
pues en este caso sólo se transfiere el valor de la variable, el cual se almacena 
en una variable local de la función que se está llamando. En cambio, cuando 
la función puede modificar el valor de la variable se dice que es un paso de 
parámetro por referencia, pues en este caso no se pasa sólo el valor sino la 
dirección de memoria que le corresponde a la variable. 
 
A continuación, se explica más a detalle los dos tipos de paso de parámetro. 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 22 
 
3.4.1. Llamada a una función por valor 
 
Cuando se realiza una llamada a una función por valor y en ésta aparece una 
variable como uno de los argumentos, en realidad no se está pasando la 
variable sino una copia del valor que ésta contiene, lo cual implica que si dentro 
de la función se modifica el argumento esto no se ve reflejado en el programa 
desde el cual se hizo la llamada, pues son localidades de memoria diferentes 
(recuerda que en cada llamada a una función se crean nuevas variables y se 
destruyen una vez finalizada la ejecución). 
 
/*porValor.c*/ 
#include<stdio.h> 
#include<stdlib.h> 
 
void inicializa(int a) 
{ 
 a = 0; 
 printf("\nEl valor de la variable local \"a\" es %d\n\n",a); 
} 
 
main() 
{ 
 int a=10; 
 
 /* Llamada a la función incializa */ 
 printf("\nEl valor de \"a\" antes de la llamada es %i\n\n", a); 
 inicializa(a); 
 printf("\nEl valor de \"a\" después de la llamada es %i\n\n", 
a); 
 
 system("pause"); 
} 
Programa 3.4: porValor.c 
 
 
 
 
 
 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 23 
 
 
La ejecución del programa es: 
 
 
Figura 3.2: Ejecución del programa pasoValor.c 
 
En la ejecución puedes ver que la variable local a main no se modifica, esto es 
porque se pasa una copia del valor que almacena cuando se realiza la llamada 
a la función inicializa(a). Este valor se guarda en un espacio de memoria, 
también llamado a, que es una variable local a la función y que existe mientras 
ésta se ejecuta. Observa que el cambio sí se realiza en la variable local de la 
función inicializa (). 
 
3.4.2. Llamada a una función por referencia 
 
La llamada a una función por referencia sí modifica el valor de la variable, 
pues lo que realmente se está pasando es la dirección de memoria asignada a 
la variable para que la función pueda modificar el valor. En C los arreglos 
siempre se pasan por referencia, ya que el nombre del arreglo en realidad 
almacena la dirección de memoria donde se encuentra almacenado el primer 
elemento del arreglo. De esta manera cuando se realiza una llamada a una 
función y se escribe el identificador de un arreglo como parámetro, se está 
pasando la dirección. Para ejemplificar lo anterior se muestra la ejecución del 
programa pasoReferencia.c que se presentó anteriormente. 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 24 
 
Figura 3.3: Ejecución del programa pasoRefencia.c 
 
En la ejecución del programa se observa que después de la llamada a la 
función cambia el estado del arreglo A. 
 
Finalmente, cabe mencionar que para realizar la llamada por referencia de una 
variable de tipo básico en lenguaje C es necesario pasar la dirección de la 
variable para lo cual se utiliza el operador & seguido del nombre de la variable 
(&nombre), como se hace en la función scanf, este operador regresa la dirección 
de memoria que le corresponde a la variable indicada. 
 
 
3.5. Estructuras de datos 
 
En muchas ocasiones nos vemos en la necesidad de procesar datos que están 
relacionados entre sí, a este tipo de datos se les conoce como estructurados, 
ya que están compuestos de un conjunto de datos básicos. A continuación se 
muestran los tipos de esctructuras de datos. 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 25 
 
Esquema de los tipos de estructuras de datos. 
 
Por ejemplo pensemos en el nombre completo de una persona, que está 
compuesto por: nombre, apellido paterno y apellido materno, o bien, en una 
dirección, formada por nombre de la calle, número y código postal, en este 
último caso no sólo está formada por varios datos simples sino que además 
podemos considerarlos de diferentes tipos (Figura 3.). 
 
 
Figura 3.3: Ejemplos de datos Estructurados 
 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 26 
Con este tipo de datos será útil poder hacer referencia a ellos bajo un mismo 
identificador, y así tratarlos como una unidad. Una estructura de datos es un 
mecanismo de agrupación de datos que facilitan el manejode datos 
estructurados y que se caracteriza por la forma en que se acede a sus 
elementos. 
Pensemos en otro ejemplo en el cual se tienen datos relacionados, 
supongamos que nos enfrentamos al siguiente problema: 
 
Problema 3.2: Se requiere un programa para llevar el registro de calificaciones 
de un grupo de diez estudiantes y generar los siguientes reportes: 
• promedio del grupo, 
• calificación máxima, 
• número de estudiantes con calificación superior al promedio del grupo. 
 
En este caso, es claro que las calificaciones de cada estudiante se pueden tratar 
como un dato simple e independiente de los otros, sin embargo, las 
operaciones que se desean realizar serán las mismas para todo el conjunto de 
calificaciones, de tal forma que habría que escribir una serie de instrucciones 
secuenciales para ingresar cada dato y procesarlo. 
 
Por ejemplo, para ingresar los datos se requiere leer una por una cada 
calificación, para obtener el promedio se tendría que hacer la suma de todas 
las calificaciones y después dividirlas entre 10, hasta aquí no se ha complicado 
mucho, pero imagina todas las comparaciones que debes hacer para 
identificar cuál es la calificación mayor. 
 
Es claro que este método resulta de lo más ineficiente, y por supuesto si 
consideramos la posibilidad de modificar el programa para que sea capaz de 
procesar 60 o más calificaciones, el programa además de extenderse, implica 
reestructurarlo en su totalidad y que éste sea más complejo que la versión 
anterior. En cambio, si consideramos a todas las calificaciones como un dato 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 27 
estructurado podemos hacer uso de una estructura de dato que nos facilite su 
manipulación. 
 
Existen diferentes tipos de estructuras de datos, cada una caracterizada por la 
forma de acceso a sus elementos, y el tipo que éstos pueden tener, así tenemos 
arreglos, listas, colas, tablas, pilas, entre otros. No obstante, para esta unidad 
nos centraremos sólo en las estructuras de datos que implementa el lenguaje 
C de forma directa: los arreglos y las estructuras. 
 
 
3.5.1. Arreglos 
 
El uso de arreglos facilita y hace más eficiente la declaración y manipulación 
de una colección de datos de un mismo tipo que están relacionados entre sí, 
como es el caso de las calificaciones en el Problema mencionado, ya que todas 
las calificaciones se pueden considerar como valores enteros. 
 
Definición y tipos de arreglos 
 
“Un arreglo se define como una colección finita, homogénea y ordenada 
de elementos. Finita ya que para todo arreglo debe especificarse el 
número máximo de elementos que podrá contener; la homogeneidad 
se refiere a que todos los elementos deben ser del mismo tipo, y 
ordenada porque es posible determinar cuál es el primer elemento, cual 
el segundo, y así hasta el enésimo elemento” (Cairo Osvaldo, Guardati 
Buemo Silvia, 1993). 
 
A la posición que ocupa un elemento dentro de un arreglo se le denomina 
formalmente índice y siempre es un número entero. 
El tamaño o longitud de un arreglo se define como el número de elementos 
que lo constituyen. 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 28 
La dimensión de un arreglo está relacionada con el número de índices 
necesarios para especificar a un elemento en particular. 
 
Podemos clasificar a los arreglos de acuerdo a su dimensión como 
unidimensionales o multidimensionales. 
 
Los arreglos unidimensionales (también llamados lineales) reciben su 
nombre debido a que cualquier elemento es referenciado por un único índice, 
por ejemplo retomando el caso de las calificaciones del problema 
mencionado, éstas pueden ser almacenadas en un arreglo unidimensional 
como el que se muestra en la ¡Error! No se encuentra el origen de la r
eferencia.siguiente: 
 
Representación gráfica de un arreglo unidimensional 
 
En donde el nombre del arreglo es lista y los nombres de las variables donde 
se almacenan las calificaciones son: lista[0], lista[1], lista[2], lista[3], lista[4], 
…, lista[9]. 
 En este caso el nombre en común es lista y lo único que cambia para cada 
elemento es el número que le corresponde a cada variable según la posición 
que ocupa en la lista. 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 29 
Observa que un solo índice es suficiente para diferenciar a un elemento de 
otro. 
 
Por otro lado, los arreglos multidimensionales son aquellos para los cuales un 
solo índice no es suficiente para poder referenciar a un elemento individual, los 
arreglos bidimensionales son el caso más comúnmente utilizado de arreglos 
multidimensionales y por tanto los únicos que presentaremos. 
“Un arreglo bidimensional es un conjunto de datos homogéneos, finito 
y ordenado, donde se hace referencia a cada elemento por medio de dos 
índices. El primero de los cuales generalmente se utiliza para indicar 
renglón y el segundo para indicar columna” (Cairo Osvaldo, Guardati 
Buemo Silvia, 1993) 
 
Un arreglo bidimensional también puede verse como una tabla de valores, 
de ahí la necesidad de dos índices, como se muestra en la figura siguiente: 
 
Representación gráfica de un arreglo bidimensional 
 
En ella se muestra un ejemplo gráfico de un arreglo bidimensional, en la cual 
del lado derecho podemos ver al arreglo como una tabla y del lado izquierdo 
representado como un arreglo de arreglos. Observa que cada renglón de la 
tabla es cada uno de los elementos del arreglo de arreglos. Es claro que con un 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 30 
solo índice no podríamos identificar a un único elemento ya que solo 
podríamos ubicar toda una columna o todo un renglón, en cambio la 
combinación de renglón-columna sí nos identifica a un elemento en particular. 
 
Declaración e inicialización 
En lenguaje C los índices de los arreglos siempre empiezan en cero, es decir, al 
primer elemento del arreglo le corresponde la posición 0, al segundo la 
posición 1, al tercero la posición 2 y así sucesivamente hasta llegar al elemento 
TAM-1, donde TAM corresponde al tamaño del arreglo, en el ejemplo antes 
mencionado. 
 
La declaración de un arreglo consiste en reservar espacio de memoria 
suficiente para el conjunto de datos homogéneos. La declaración de una 
variable de tipo arreglo sigue las mismas reglas que las variables simples; con 
la diferencia de que ahora será necesario especificar el tamaño del arreglo, esto 
se hace escribiendo el tamaño del arreglo encerrado entre corchetes [ TAM ], 
después del identificador. 
 
La sintaxis para la declaración de un arreglo unidimensional en lenguaje C es 
la siguiente: 
<tipo><nombre>[<tamaño>]; 
 
Y para un arreglo bidimensional es: 
<tipo><nombre>[<tamaño1>] [<tamaño2>]; 
 
El tipo de dato para los arreglos puede ser de cualquier tipo básico, es decir 
entero, flotante o caracter (en C int, float, double o char ). De todos ellos, los 
arreglos de tipo caracter (char) tienen un tratamiento especial, ya que un 
arreglo de este tipo se considera una cadena. 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 31 
Debido a la importancia que tienen las cadenas en la programación más 
adelante los abordaremos de manera particular. 
 
Al igual que las variables simples, un arreglo puede inicializarse al momento 
de ser declarado, para ello se utiliza el operador asignación “=”, pero como un 
arreglo almacena a un conjunto de datos, es necesario inicializarlo con un 
conjunto de valores, los cuales se indican mediante llaves {, separando por 
comas cada uno de los elementos del conjunto de valores iniciales, la sintaxis 
se muestra a continuación: 
<tipo><nombre>[<tamaño>]={<valor0>,<valor1>,…,<valorTAM-1>}; 
 
La asignación de cada valor inicial se hace consecutivamente desde el 
elemento 0, por lo tanto, no es posible asignar valores a elementos 
discontinuos.Veamos como ejemplo la declaración del arreglo unidimensional en la 
imagen: 
 
planteado para las calificaciones del problema mencionado. Inicializando sus 
elementos en la declaración queda como: 
int lista[10] = {9,10,8,5,9,6,7,9,4,8}; 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 32 
En el caso de los arreglos bidimensionales la sintaxis es la siguiente: 
<tipo><nombre>[<tamaño1>][<tamaño2>]={ 
{<valor00>,<valor01>,…,<valor0(TAM21)>}, 
{<valro10>,<valor11>,…,<valor1(TAM21-1)>},…, 
{<valor(TAM1-1)0>,<valor (TAM2-1)1>,…,<elem(TAM1-1)(TAM2-1)>} 
}; 
 
Veamos ahora cómo queda la declaración del arreglo bidimensional tabla 
mostrado en la imagen anterior, inicializando sus valores: 
 
int tabla[5][3]={{9,10,8},{5,9,6},{7,9,4},{8,9,6},{7,9,4}}; 
 
Aunque también es posible declararlo de la siguiente forma, para fines de 
comprensión de código se recomienda utilizar la estructura anterior: 
 
int tabla[5][3]={9,10,8,5,9,6,7,9,4,8,9,6,7,9,4}; 
 
 Esto se debe a que como ya se mencionó antes, un arreglo bidimensional se 
puede ver como un arreglo de arreglos. 
 
Por otro lado, en lenguaje C siempre es necesario especificar el tamaño del 
arreglo al momento de declararlo, sin embargo, esto se puede hacer de forma 
explícita o implícita. 
 
• Explícitamente es cuando se especifica el tamaño dentro de los 
corchetes que siguen al identificador. 
int lista[10] = {9,10,8,5,9,6,7,9,4,8}; 
 
• De forma implícita se hace cuando el arreglo es inicializado con un 
conjunto de valores, y se omite el tamaño dentro de los corchetes, 
entonces el compilador asume el tamaño del arreglo igual al tamaño del 
conjunto de valores iniciales, de tal forma que la declaración del arreglo 
lista puede quedar como: 
int lista[] = {9,10,8,5,9,6,7,9,4,8}; 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 33 
 
Observa que en este caso no se escribe el tamaño dentro de los corchetes, pero 
como hay 10 elementos en el conjunto de valores iniciales, el compilador de C 
asume un tamaño 10 para el arreglo. 
 
Para los arreglos bidimensionales, sólo es posible especificar una dimensión de 
forma implícita, el tamaño de renglones siempre debe hacerse de forma 
explícita. 
La asignación de un conjunto de valores al arreglo, en una sola operación de 
asignación, únicamente es posible en su declaración, si se intenta realizar en 
otro momento, el compilador marcará un error, ya que en cualquier otra parte 
del programa sólo se podrán asignar valores simples a cada uno de los 
elementos por separado. 
 
Es importante señalar que cuando se desea inicializar el arreglo al declararlo, 
es posible inicializar sólo algunos de sus elementos, pero en este caso se 
tendría que especificar explícitamente el tamaño, además se debe recordar 
que la asignación de valores iniciales es consecutiva desde el elemento 0. Los 
elementos para los cuales no se indique un valor inicial, automáticamente se 
inicializan en cero. Por ejemplo, la declaración 
int lista[10] = {5}; 
 
Reservará espacio en memoria para los 10 elementos del arreglo de los cuales 
al primer elemento se le asignará un 5 y al resto se les asignará un cero. 
 
En el caso de los arreglos bidimensionales es posible declarar sólo algunos 
elementos por renglón, siempre y cuando los elementos sean consecutivos, 
como en el caso de los unidimensionales. Por ejemplo, la siguiente declaración 
para el arreglo tabla: 
int tabla[5][3]={{9,10},{5},{7,9,4},{8,9,}}; 
 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 34 
Daría como resultado la siguiente asignación de valores iniciales 
 [0] [1] [2] 
[0] 9 10 0 
[1] 5 0 0 
[2] 7 9 4 
[3] 8 9 0 
[4] 0 0 0 
 
En el caso de que la declaración fuera: 
int tabla[5][3]={9,10,5,7,9,4,8,9,}; 
Entonces la asignación de valores iniciales se haría de la siguiente forma 
 [0] [1] [2] 
[0] 9 10 5 
[1] 7 9 4 
[2] 8 9 0 
[3] 0 0 0 
[4] 0 0 0 
 
Como puedes observar la correcta definición de arreglos te permitirá evitar 
errores en el manejo de los datos que se almacenen en él. 
 
Acceso a los elementos de un arreglo 
Para referirse a un elemento del arreglo es necesario indicar el nombre del 
arreglo seguido del índice o índices correspondientes al elemento que 
deseamos acceder. Para ello se debe seguir la siguiente sintaxis: 
 
Elementos de un arreglo unidimensional: 
<nombre del arreglo>[<índice>]; 
Elementos de un arreglo bidimensional: 
<nombre del arreglo>[<índice del renglón>][<índice de columna>]; 
 
Observa que para cada índice se utilizan corchetes separados. 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 35 
Cada elemento del arreglo se puede tratar igual que a cualquier otra variable, 
es decir, podemos asignarle un valor, incluir en una expresión algebraica o 
lógica, imprimir en pantalla su valor, asignarle desde el teclado un valor, etc. 
 
Veamos algunos ejemplos: 
Instrucción Descripción 
tabla[0][2] = 8; Asignar el valor de 8 al tercer 
elemento del primer renglón del 
arreglo tabla. 
printf(“%d”,lista[4]); 
Imprimir en pantalla el quinto 
elemento del arreglo lista. 
scanf(“%d”,&tabla[0][0]); 
Leer un número entero desde el 
teclado y lo asigna en la primera 
posición del arreglo tabla. 
lista[1]++; 
Incrementar en uno el valor del 
segundo elemento del arreglo lista. 
 
Ciclos y arreglos 
Los arreglos y los ciclos están estrechamente relacionados, podríamos afirmar 
que en cualquier programa que se emplee un arreglo, éste será manipulado 
por medio de una estructura repetitiva. Anteriormente mencionamos que un 
arreglo se utiliza cuando queremos almacenar y manipular datos relacionados 
entre sí y, generalmente, cuando tenemos un arreglo debemos ejecutar el 
mismo conjunto de operaciones sobre cada uno de sus elementos. 
 
En lenguaje C el índice del elemento se puede especificar mediante una 
expresión, es decir una variable, una constante o como el resultado de una 
operación, lo que hace posible ir cambiando el índice de un elemento dentro 
de un ciclo sin tener que escribir una serie de instrucciones secuenciales para 
realizar la misma operación sobre cada uno de los elementos del arreglo. 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 36 
La forma general de procesar un arreglo unidimensional por medio de un 
ciclo se muestra en la siguiente figura: 
 
Procesamiento de arreglos unidimensionales mediante ciclos 
Observa como la variable contador pos del ciclo, también se utiliza como índice 
para el elemento del arreglo, de tal forma que en cada iteración se haga 
referencia a un elemento diferente del arreglo. 
 
No es difícil intuir que para el caso de los arreglos bidimensionales será 
necesario no solo un ciclo sino un par de ciclos anidados, ya que tenemos dos 
dimensiones, cada uno de los ciclos se encargará de manipular a un índice, la 
estructura general para estos ciclos se muestra en la siguiente figura: 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 37 
 
Procesamiento de arreglos bidimensionales mediante ciclos anidados 
 
Como se puede apreciar dos ciclos están anidados cuando uno está dentro 
del otro, de tal forma que, por cada iteración del externo, el interno completa 
todo un ciclo. 
Considerando esto, observa que se toma como contador a la variable i para el 
ciclo externo, la cual también se utiliza como índice de renglón. Asimismo, se 
utiliza la variable j como contador para el ciclo interno, además de índice de 
columna, de esta manera se está recorriendo el arreglo por renglón. 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 38 
 
Si analizamos el diagrama de flujo podemos observar que para la primera 
iteración del ciclo externo, la variable i tiene el valor de 0 mientras que j toma 
los valores desde 0 hasta TAMC-1 (TAMC es el número total de columnas) de 
tal forma que el renglón se mantienefijo mientras nos movemos en todas las 
columnas, en la siguiente iteración cambia el renglón ya que i toma el valor de 
1 y recorremos nuevamente todas las columnas, este proceso se repite hasta el 
valor final de i que es TAMF-1 (TAMF es el número de renglones). 
 
Ejemplo Veamos cómo utilizar arreglos en la solución de un problema, 
resolviendo el ejemplo de las calificaciones, enfocándonos únicamente en la 
lectura de 10 valores y el cálculo del promedio. 
 
Para almacenar las calificaciones se puede utilizar un arreglo unidimensional 
de tipo entero, será necesario pedir al usuario que ingrese las 10 calificaciones 
para poder realizar las operaciones necesarias para el cálculo del promedio, es 
decir, la suma de las misma y la división entre el total de calificaciones, para 
finalmente imprimir en pantalla el promedio, adicionalmente se imprimirá 
también la lista de calificaciones ingresadas. No existe ninguna restricción que 
sea necesaria considerar. 
 
Cada uno de los procesos que se van a realizar sobre las calificaciones, es decir 
leerlas, sumarlas e imprimirlas en pantalla se pueden implementar mediante 
ciclos, en vez de tener que escribir 10 veces la misma expresión para cada una 
de las 10 calificaciones. La lectura y la suma de las calificaciones se pueden 
implementar dentro del mismo ciclo. De esta manera podemos resumir el 
análisis del problema de la siguiente forma: 
 
 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 39 
Datos de entada: Calificaciones de los 10 estudiantes (calif [ ]) 
Salida: Promedio de calificaciones (prom) 
Método: 
 
prom = 
∑ 𝑐𝑎𝑙𝑖𝑓[𝑖]9𝑖=0
10
 
 
La solución del problema se representa mediante el pseudocódigo que se 
muestra en el siguiente algoritmo. 
 
Inicio 
suma ← 0 
Desde i ← 0 mientras i<10, i ← i+1 
 Imprimir “Ingresa la calificación” i 
 Leer calif[i] 
 suma← suma+calif[i] 
 Fin Desde 
 prom ← prom/10 
Imprimir “Las calificaciones ingresadas fueron:” 
Desde i ← 0 mientras i<10, i ← i+1 
Imprimir “Calificación” i “:” calif[i] 
Fin Desde 
Imprimir “Calificación promedio = ” prom 
Fin 
Algoritmo Promedio de calificaciones 
 
 
La codificación del algoritmo anterior es la siguiente: 
/*Directivas de preprocesador*/ 
#include <stdio.h> 
#include <stdlib.h> 
/* Definimos como constante simbólica el tamaño del arreglo*/ 
#define TAM 10 
/* Definición de función principal */ 
main( ) 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 40 
{ 
 /*Declaración del arreglo calificaciones*/ 
int calif[TAM]; 
 double prom = 0; 
int i; 
 printf("*******************************************\n”); 
printf(“* El siguiente programa calcula el promedio de *\n"); 
printf(“* un grupo de diez estudiantes *\n”); 
 printf("********************************************\n”); 
 /*Lectura y suma de las calificaciones*/ 
for(i=0; i < TAM; i++) 
 { 
 printf("Proporciona la calificación %d: ",i+1); 
 scanf(“%d”, &calif[i]); 
 prom = prom + calif[i]; 
} 
/*Cálculo e impresión del promedio*/ 
 prom = prom/TAM; 
 /*Impresión de las calificaciones*/ 
 printf("\nLas calificaciones ingresadas fueron: \n"); 
for(i=0; i < TAM; i++) 
 printf("\nCalificacion %d: %d",i+1, calif[i]); 
 printf("\n\n\tPromedio = %.2f\n\n", prom); 
 system("pause"); 
} 
Codificación promCalificaciones.c 
 
 
 
 
 
 
 
 
 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 41 
En la siguiente figura se muestra una ejecución del programa. 
 
 
Ejecución del programa promCalificaciones.c 
 
Observa que el tamaño del arreglo se especifica por medio de una constante 
simbólica, utilizando la directiva #define, esto facilita el cambiar el tamaño del 
arreglo sin tener que hacer cambios en todo el código. 
A continuación, se presenta otro ejemplo para ilustrar el uso de arreglos 
bidimensionales. 
 
Ejemplo Se requiere un programa que calcule el determinante de una matriz 
de 2x2. Considerando la siguiente información. 
 
Dada la siguiente matriz: 
 
 
 
 
 
 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 42 
 
Su determinante se define como: 
∆=(a00a11)-(a01a10) 
 
Análisis del problema: Para este problema se puede utilizar un arreglo 
bidimensional de 2 renglones y 2 columnas para almacenar los valores de la 
matriz, los cuales se pueden solicitar al usuario utilizando la estructura de ciclos 
anidados presentada anteriormente, nuestro dato de salida será el valor del 
determinante y adicionalmente también se mostrará en pantalla la matriz 
ingresada. 
Datos de entada: Elementos de la matriz (A[ ][ ]) 
Salida: Valor del determinante (det) 
 
Método: 
𝒅𝒆𝒕 = 𝑨[𝟎][𝟎] ∗ 𝑨[𝟏][𝟏] − 𝑨[𝟎][𝟏] ∗ 𝑨[𝟏][𝟎] 
 
La solución del problema se da en el siguiente diagrama de flujo. 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 43 
 
Algoritmo Determinante de una matriz 2x2 
 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 44 
Puedes llevar a cabo la codificación del algoritmo como ejercicio, misma que 
se muestra a continuación: 
/* Directivas al preprocesador */ 
#include <stdlib.h> 
#include <stdio.h> 
/* Constantes con el tamaño de la matriz */ 
#define TAM 2 
/* Función principal */ 
main() 
{ 
 int i, j; 
 float det; 
float A[TAM][TAM]; /*declaración de la matriz*/ 
 
 /* Mensaje de bienvenida */ 
 printf("***************************************\n"); 
 printf("* Determinante de una matriz A de 2x2 *\n"); 
 printf("***************************************\n"); 
 
 /* Lectura de la matriz A */ 
for(i=0; i<TAM; i++) 
 for(j=0; j<TAM; j++){ 
printf("\nProporciona el elemento A[%d][%d]: ", i,j); 
scanf("%f", &A[i][j]); 
 } 
 det = A[0][0]*A[1][1] - A[0][1]*A[1][0]; 
 
printf("\nA: \n\t"); 
 
 /* Impresión de la matriz A */ 
for(i=0; i<TAM; i++){ 
 for(j=0; j<TAM; j++) 
 printf("%8.2f", A[i][j]); 
 printf("\n\t"); 
 } 
 
 printf("\n\n\t\tDeterminante = %.2f\n\n", det); 
 system("pause"); 
} 
Programa determinantes.c 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 45 
En la siguiente figura se muestra una ejecución del programa. 
 
Ejecución del programa determinante.c 
 
 
3.5.2. Cadenas 
 
Una cadena es una serie de caracteres tratados como una sola unidad. Una 
cadena puede incluir letras, dígitos y varios caracteres especiales (Deitel H. M., 
Deitel P. J., 1995). 
 
En algunos lenguajes de programación existe un tipo de dato específico para 
definir a las cadenas, sin embargo, en lenguaje C las cadenas se implementan 
por medio de arreglos de tipo caracter ya que no existe un tipo específico para 
ellas, pero existe todo un conjunto de funciones estándar definidas en la 
biblioteca string.h mediante las cuales es posible realizar las operaciones más 
comunes, por ejemplo: copiarlas, concatenarlas, compararlas, entre otras. 
Además, es posible imprimirlas y leerlas de forma similar que un dato simple. 
En lenguaje C toda constate de tipo cadena se indica entre comillas dobles, 
por ejemplo: 
“Calle 2 #135” 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 46 
Una cadena en lenguaje C termina siempre con el caracter nulo ‘\0’ (cuyo valor 
ascii es cero) que representa el fin de cadena. 
Al declarar arreglos de tipo char que sean una cadena se pueden inicializar 
directamente con una constante cadena de la siguiente forma: 
char cad[50]=”saludo”; 
 
Al inicializar una variable cadena de esta manera, se agrega automáticamente 
el símbolo de caracter nulo para indicar el fin de cadena, es decir, en la posición 
6 del arreglo cad se encuentra almacenado el fin de cadena ‘\0’. De forma 
general,es importante señalar que en un arreglo de tamaño N es posible 
almacenar correctamente una cadena de máximo N-1 caracteres. De tal forma 
que en el arreglo cad se puede almacenar una cadena de máximo 49 
caracteres. 
 
Las cadenas en C pueden ser asignadas a un arreglo de tipo char utilizando la 
función scanf mediante el especificador de formato %s, por ejemplo, la línea 
de código: 
scanf(“%s”, cad); 
De esta manera se lee desde el teclado una cadena y se guarda en el arreglo 
cad, sólo que en este caso no se incluye el operador & antes del nombre del 
arreglo, pues el identificador del arreglo almacena la dirección del primer 
elemento del mismo. 
 
La función gets() también nos permite leer del teclado una cadena y asignarla 
a un arreglo de tipo char, por ejemplo la instrucción: 
gets(cad); 
 
Lee una cadena desde el teclado y la almacena en el arreglo cad. 
 
Una diferencia importante entre usar scanf y gets es que con la primera 
función la lectura de la cadena se da por terminada cuando el usuario presiona 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 47 
la tecla [Enter] o Espacio, mientras que la segunda termina la lectura de la 
cadena únicamente cuando el usuario presiona la tecla [Enter], tal como se 
muestra en los siguientes ejemplos: 
Cadena 
ingresada 
Instrucción Contenido del arreglo cad[] 
“Calle 2 #135” scanf(“%s”,
cad); 
cad[]: 
C a l l e /
0 
/
0 
… /
0 
 
“Calle 2 #135” gets(cad); cad[]: 
C a l l e 2 # 1 3 5 /
0 
 /
0 
 
 
Similarmente, para imprimir en pantalla una cadena se puede utilizar la 
función printf con el especificador de formato %s, o bien, la función puts, 
nuevamente ambas funciones tienen un comportamiento similar con la única 
diferencia de que puts incluye siempre un salto de línea al final, esto se ilustra 
a continuación. 
Código c Ejecución 
Impresión de cadena con printf 
 
#include <stdio.h> 
#include <stdlib.h> 
main(){ 
char mensaje[30]=”Mar 
profundo ”; 
printf(“%s”,mensaje); 
system(“pause”); 
} 
 
 
Impresión de cadena con puts 
#include <stdio.h> 
#include <stdlib.h> 
main(){ 
char mensaje[30]=”Mar 
profundo ”; 
puts(mensaje); 
system(“pause”); 
} 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 48 
Las funciones que nos permiten el manejo de cadenas se encuentran en la 
biblioteca estándar string.h, para ilustrar algunas se muestra el siguiente 
programa en leguaje C. 
Ejemplo 3.3: El programa siguiente verifica si una clave (password) de 8 
caracteres alfanuméricos ingresado por el usuario es correcta. 
/*Directivas de preprocesador*/ 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> /* se incluye la biblioteca de cadenas */ 
main( ) 
{ 
 /* Declaración de variables */ 
 char pwscorrecto[9]=”jk278la0”; /* Clave correcta */ 
 char pwsingresado[9]; /* para leer la clave que 
 ingrese el usuario */ 
 char nombre[10]; /* Para leer el nombre del usuario */ 
 char mensaje[50]=”Bienvenido ”; 
 /* Lectura de datos */ 
 printf(“Nombre: "); 
 gets(nombre); /* Lectura de una cadena con espacios */ 
 printf(“pasword: "); 
 scanf(“%s”,pwsingresado); /* Lectura de una cadena sin 
 espacios*/ 
 if (!strcmp(pwscorrecto,pwsingresado)){ /* comparación 
 de claves, si la función strmp regresa 0 son iguales */ 
 printf(“pasword correcto \n”); 
 strcat(mensaje,nombre); /* pega al final de 
 mensaje el nombre del usuario*/ 
 puts(mensaje); /* impresión de la cadena con salto 
 de línea*/ 
 } 
 else { 
 strcpy(mensaje, “Acceso denegado”); /* copia la 
 cadena acceso denegado al mensaje */ 
 puts(mensaje); /* imprime la cadena*/ 
 } 
 system("pause"); 
} 
Programa password.c 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 49 
 
En la siguiente figura se muestran dos ejecuciones del programa 
 
 
 
 
 
 
a)Clave inválida b)Clave válida 
Ejecución del programa password.c 
 
Con esto concluye la sección de arreglos. Recuerda que un arreglo es un 
conjunto de datos del mismo tipo. En la siguiente sección verás cómo puedes 
agrupar datos de diferentes tipos. 
 
3.5.3. Estructuras 
 
Las estructuras en lenguaje C al igual que los arreglos, nos permiten tratar a 
un conjunto de datos bajo un mismo identificador, pero a diferencia de los 
arreglos, las estructuras son conjuntos de datos contiguos en memoria no 
homogéneos de tal forma que una estructura puede estar formada por datos 
de diferentes tipos. 
Una de las aplicaciones para las estructuras es para la manipulación de 
registros que se recuperan o se almacenan en una base de datos. 
 
Definición, declaración e inicialización de una estructura de datos 
“Una estructura es una colección de una o más variables, de tipos 
posiblemente diferentes, agrupadas bajo un nombre para manejo 
conveniente (en algunos lenguajes también se conocen como registros). 
Las estructuras permiten tratar a un grupo de variables relacionadas 
como una unidad, en vez de que se traten en forma separada (Kernighan 
& Ritchie, 1991, pág. 141)”. 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 50 
 
La definición de una estructura en el lenguaje C inicia con la palabra reservada 
struct seguida del identificador para el tipo de estructura y de un bloque de 
definiciones de variable que constituyen el conjunto de elementos que forman 
parte de ella, la sintaxis para definir la estructura es la siguiente: 
 
struct<identificadorEstructura> { 
<tipo1><identificadorE1>; 
<tipo2><identificadorE2>; 
 
<tipoN><identificadorEN>; 
} 
 
Observa que se utiliza la palabra reservada struct para iniciar la definición y que 
las declaraciones para los elementos de la estructura se encierran entre llaves. 
Una estructura puede contener a N elementos de diferentes tipos, de 
cualquiera de los tipos básicos, o incluso un arreglo. Veamos un ejemplo: 
 
struct paciente { 
int nss; /* número de seguro social */ 
char apellido[50]; 
char nombre[20]; 
int edad; 
float estatura; 
char sexo; 
} 
 
En este ejemplo se está definiendo la estructura paciente que tiene seis 
elementos: dos enteros (nss y edad), dos cadenas (apellido y nombre), un 
flotante (estatura) y un caracter (sexo). Sin embargo, la definición anterior no 
reserva espacio en memoria para la estructura, más bien define un tipo de 
dato, por lo tanto, para poder utilizar la estructura, es necesario declarar una 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 51 
variable de este tipo, es aquí cuando se reserva espacio en memoria. La sintaxis 
para hacer esta declaración es la siguiente: 
 
struct<identificadorEstructura><identificador_var>; 
 
Por ejemplo, la declaración: 
struct paciente paciente1, paciente2; 
 
Declara a las variables paciente1 y paciente2, las cuales son del tipo paciente y 
por tanto para cada una de ellas se reserva espacio en memoria suficiente para 
cada uno de sus seis elementos. 
 
Otra forma válida de llevar a cabo la declaración es haciéndola seguida a la 
definición de la estructura, para el ejemplo anterior puede escribirse como 
sigue: 
struct paciente { 
int nss; 
char apellido[50]; 
char nombre[20]; 
int edad; 
float estatura; 
char sexo; 
} paciente1, paciente2; 
 
En este caso el identificador para el tipo de estructura puede omitirse, pero 
entonces la única forma de declarar variables para ese tipo de estructura es en 
su definición, y no en una declaración por separado, de tal forma que nuestro 
ejemplo puede quedar como sigue: 
 
 
struct { 
int nss; 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 52 
char apellido[50]; 
char nombre[20]; 
intedad; 
float estatura; 
char sexo; 
} paciente1, paciente2; 
 
Por otro lado, al igual que los arreglos, también se pueden inicializar los 
elementos de una estructura en el momento de la declaración de una variable 
del tipo de la estructura en cuestión, éstos deben estar encerrados entre llaves 
y separados por comas. La sintaxis general es la siguiente: 
 
struct<identificadorEstructura><identificador_var> = 
{ <valorE1>,<valor2>, ,<valorN> }; 
 
Por ejemplo: 
 
struct paciente paciente1 = {1240, “PicaPiedra”, “Pedro”, 45, 1.80, ‘M’}; 
 
Sólo en el momento de la declaración es posible asignar todos los valores de 
una estructura (al igual que con los arreglos), así que si después se quiere 
modificar tendrán que hacerse las modificaciones de forma separada en cada 
uno de sus elementos, como se muestra en el siguiente subtema. 
Acceso a los elementos de una estructura 
Para referenciar un elemento de la estructura se utiliza el operador punto “.” 
con la siguiente sintaxis: 
<idenficador_var>.<idenficadorEi> 
 
Este operador seguido del identificador del elemento, hace referencia al 
elemento indicado, de tal forma que la sentencia para asignar al paciente1 un 
nss de 23442145 será: 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 53 
paciente1.nss = 23442145; 
 
Ahora, si se quiere asignar a la misma variable el nombre “Pablo”, la 
instrucción sería: 
 
paciente1.nombre = “Pablo”; 
 
Del mismo modo se realiza la impresión o lectura del elemento de la 
estructura, sin perder de vista su tipo. Para ilustrar esto se propone el siguiente 
ejemplo: 
 
En el siguiente programa se declara una estructura de tipo perro, que tiene los 
siguientes elementos: 
Elemento Tipo 
Raza char[] 
Edad int 
Peso float 
 
Posteriormente se declaran dos variables de este tipo, una se inicializa en la 
declaración y a la otra se le asignan valores desde el teclado, ambos se 
muestran al final en pantalla. 
 
#include <stdio.h> 
#include <stdlib.h> 
#include <conio.h> 
 
main(){ 
/* Declaración de la estructura perro*/ 
struct perro{ 
char raza[20]; 
 int edad; 
 float peso; 
} fido, pluto = {"labrador", 7, 20} ; /* inicialización de la 
 variable pluto*/ 
 
printf("***********************************"); 
printf("\n* Comparando perros *"); 
printf("\n***********************************"); 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 54 
printf("\n\nIngresa la raza de fido:"); 
scanf("%s",&fido.raza); /* lectura de un elemento */ 
 
printf("Ingresa la edad de fido en a%cos:", 164); 
scanf("%d",&fido.edad); /* lectura de un elemento */ 
 
printf("Ingresa el peso de fido en kilos de fido:"); 
scanf("%f",&fido.peso); /* lectura de un elemento */ 
 
/* impresión de los elementos de las estructuras */ 
printf("\nFido es de raza %s, tiene %d a%cos y pesa %.2f 
kilos\n",fido.raza,fido.edad,164,fido.peso); 
printf("\nPluto es de raza %s, tiene %d a%cos y pesa %.2f 
kilos\n",pluto.raza,pluto.edad,164,pluto.peso); 
 
/* comparación de los nombres que son cadenas */ 
if(!strcmp(pluto.raza,fido.raza)) 
printf("\nPluto Y Fido son de la misma raza \n"); 
else 
 printf("\nFido y Pluto son de razas distintas\n"); 
 
/* comparación de elementos de tipo numérico */ 
if(pluto.peso > fido.peso) 
 printf("Pluto es m%cs pesado que Fido\n",160); 
else if(pluto.peso < fido.peso) 
printf("Fido es m%cs pesado que Pluto\n",160); 
else 
 printf("Fido y Pluto pesan lo mismo\n"); 
 
if(pluto.edad > fido.edad) 
printf("Pluto es mas viejo que Fido\n"); 
else if(pluto.edad < fido.edad) 
printf("Fido es mas pesado que Pluto\n"); 
else 
 printf("Fido y Pluto tienen la misma edad \n"); 
 
getch(); 
} 
 
Codificación programa perros.c 
 
Nota: Observa que, en este caso, para poder imprimir la letra ñ se utilizó su 
código Ascii (164) para lo cual en la cadena de control del printf se escribió %c 
en donde se desea imprimir la ñ. Este mismo procedimiento se llevó a cabo 
para acentuar la letra a. 
 
En la siguiente figura se muestra una ejecución del programa anterior. 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 55 
 
Ejecución del programa perros.c 
 
Para concluir con esta sección veamos el siguiente ejemplo donde se utilizan 
estructuras y arreglos: 
Se requiere un programa que permita registrar los datos de los perros que 
ingresan a refugio canino, y poder desplegar los datos de alguno de los perros, 
a cada perro se le asigna una clave numérica consecutiva. Los datos que se 
registran del perro son: 
• la fecha de ingreso (cadena) 
• nombre (cadena) 
• raza (cadena) 
• color (cadena) 
• edad (entero) 
• peso (flotante) 
 
El refugio tiene capacidad máxima para 100 perros. 
 
Para la solución del problema se puede plantear un menú que permita 
registrar o desplegar los datos de un perro. En este caso tenemos como datos 
de entrada la opción del menú que elija el usuario. En el caso de que sea un 
registro se tiene como entrada los datos del perro. Para la opción de despliegue 
se tendrá que dar, como dato de entrada, la clave asignada al perro y la salida 
serán los datos correspondientes a la clave. 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 56 
 
Para desplegar y repetir el menú se requiere un ciclo y una estructura 
condicional que maneje las opciones del menú. Para almacenar los datos del 
perro, se puede utilizar una estructura similar al ejemplo anterior. Mediante un 
arreglo de estas estructuras estaremos en capacidad para manipular los datos 
de varios perros, el tamaño de este arreglo tendrá que ser igual a la capacidad 
del refugio (100 perros), de tal forma que el índice del arreglo que toca a cada 
perro corresponderá con su clave. 
 
Una restricción que hay que tomar en cuenta es que se debe verificar que no 
se sobrepase la capacidad de atención del albergue (100 perros), tanto al 
ingresar datos como al recuperarlos, para ello se llevará un contador (c) que 
actualice el número de perros ingresados. 
 
 Inicio 
 c ← 0 
 Hacer 
 Imprimir “Refugio para perros -Ladrido Feliz-” 
 Imprimir “1) Registrar un perro” 
 Imprimir “2) Buscar un perro” 
 Imprimir “3) Salir” 
 Imprimir “Elige una opción:” 
 Leer op 
 Casos para op 
 Caso 1: Si c≥100 entonces 
 Imprimir “El refugio está lleno” 
 Si no 
 Imprimir “Ingresa los datos del perro:” 
 Imprimir “Clave:” c 
 Imprimir “fecha de ingreso[dd/mm/aa]:” 
 Leer perros[c].fecha 
 Imprimir “color:” 
 Leer perros[c].color 
 Imprimir “nombre:” 
 Leer perros[c].nombre 
 Imprimir “raza:” 
 Leer perros[c].raza 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 57 
 Imprimir “edad:” 
 Leer perros[c].edad 
 Imprimir “peso:” 
 Leer perros[c].peso 
 c ← c+1 
 Fin si-si no 
 Caso2: Imprimir “Clave:” 
 Leer clave 
 Mientras clave≥100 v clave <0 hacer 
 Imprimir “La clave no es válida, ingresa 
nuevamente la clave:” 
 Leer clave 
 Fin mientras 
 Imprimir “nombre:”, perros[clave].nombre 
 Imprimir “fecha de ingreso:”, perros[clave].fecha 
 Imprimir “color: ”, perros[clave].color 
 Imprimir “raza: ”, perros[clave].raza 
 Imprimir “edad: ”, perros[clave].edad 
 Imprimir “peso: ”, perros[clave].peso 
 Caso 3: 
 Otro caso: Imprimir ”Opción no válida”Fin casos 
 Mientras op≠3 
 Fin Hacer-mientras 
 Fin 
Algoritmo Registro perros 
 
Puedes llevar a cabo la prueba de escritorio como ejercicio. La codificación 
del algoritmo se muestra a continuación. 
#include <stdio.h> 
#include <stdlib.h> 
#include <conio.h> 
main(){ 
/* Declaración del arreglo de tipo estructura perro */ 
struct perro{ 
char fecha[10]; 
 char raza[30]; 
 char color[50]; 
 char nombre[30]; 
 int edad; 
 float peso; 
} perros[100]; 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 58 
 
int c=0, op, clave; 
 
do{ /* Inicio del ciclo que imprime el menú*/ 
 printf( "\n----------------------------------------\n"); 
 printf( "\nRefugio para perros -Ladrido Feliz- \n" ); 
 printf( "\n----------------------------------------\n"); 
 printf( "1) Registrar un perro \n" ); 
 printf( "2) Buscar un perro \n" ); 
 printf( "3) Salir \n" ); 
 printf( "Elige una opci%cn:",162 ); 
 
scanf("%d",&op); 
 
 switch (op){ 
 case 1: /*Opción Registrar perro */ 
 printf( "\n------------------------------\n"); 
 if(c>=100) /* Verifica si hay espacio */ 
 printf("El refugio esta lleno\n"); 
 else{ 
 /*Si hay espacio pide los datos del perro y 
 Y los guarda en el registro c del arreglo */ 
 printf( "Ingresa los datos del perro:"); 
 printf( "Clave:%.3d\n", c); 
 printf( "fecha de ingreso[dd/mm/aa]: "); 
 scanf( "%s", perros[c].fecha); 
 printf( "nombre: "); 
 fflush(stdin); 
 gets( perros[c].nombre); 
 printf( "color: "); 
 gets( perros[c].color); 
 printf( "raza: "); 
 gets( perros[c].raza); 
 printf( "edad: "); 
 scanf("%d" ,&perros[c].edad); 
 printf( "peso: "); 
 scanf("%f" ,&perros[c].peso); 
 c++; 
 } 
 break; 
 case 2: /* Opción buscar perro */ 
 printf( "\n-------------------------------\n"); 
 printf( "Clave: "); 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 59 
 scanf("%d",&clave); 
 /* verifica que la clave sea válida */ 
 while(clave>=100 || clave <0){ 
 printf("La calve no es válida, ingresa 
 nuevamente la clave:"); 
 scanf("%d",&clave); 
 } 
/* Imprime los datos del perro correspondiente 
 a la clave */ 
 printf("nombre:%s\n",perros[clave].nombre); 
 printf( "fecha de ingreso: %s\n", 
 perros[clave].fecha); 
 printf( "color: %s\n", perros[clave].color); 
 printf( "raza: %s\n", perros[clave].raza); 
 printf( "edad: %d a%cos\n", 
 perros[clave]edad,164); 
 printf( "peso: %.2f kilos\n", 
 perros[clave].peso); 
break; 
 case 3: /* Caso salir, no hace nada */ 
 break; 
 default: /* Caso opción inválida */ 
printf( "Opcion no válida\n"); 
} 
 }while (op!=3); /* El ciclo do-while se repite mientras la 
 opción no sea salir (3) */ 
} 
 
 
Programa registroPerros.c 
 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 60 
 
Cierre de la unidad 
 
Como hemos podido observar la implementación de funciones facilita el 
desarrollo de módulos que pueden ser reutilizados y actualizado de forma más 
fácil y eficiente. Al utilizar estructuras de datos para resolver problemas, 
almacenar y manipular la información en el flujo de datos dentro del desarrollo 
de programas modulares es una característica que robustece la funcionalidad 
de los programas desarrollados en lenguaje C. Si requieres profundizar o 
resolver alguna duda sobre el tema no dudes en consultar a tu Docente en 
línea. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Unidad 3. Funciones y estructuras de datos 
UNADM | DCEIT | FPR 61 
 
 
 
Fuentes de consulta 
 
• Alonso Jordá, P., García Granada, F., Onaidía de la Rivadeherrera, E. (1998). 
Diseño e implementación de programas en lenguaje C. Valencia: Universidad 
Politécnica de Valencia, Colección Libro Docente. 
• Cairo Osvaldo, Guardati Buemo Silvia. (2006). Estructura de Datos. México: 
McGraw-Hill 
• Deitel H, M., & Deitel P, J. (1995). Cómo programar en C/C++. México: Prentice 
Hall. 
• Joyanes, L., & Zohanero, I. (2005). Programación en C. Metodología, algoritmos 
y estructuras de datos. aspaño: Mc Graw Hill. 
• Levine G. (2001). Introducción a la Computación y a la Programación 
Estructurada, México: Mc Graw Hill 
• Kernighan, B., & Ritchie, D. (1991). El lenguaje de programción C. México: 
Prentice-Hall Hispanoamericana. 
• López, L. (2005). Programación estructurada en lenguaje C. México: 
Alfaomega. 
• Pérez, H. (1992). Física General (Primera Edición ed.). México: Publicaciones 
Cultura.

Continuar navegando

Otros materiales