Apuntes de Programación Estructurada
Apuntes de Programación Estructurada
Apuntes de Programación Estructurada
Agosto - 2012
2
Índice general
1. Arquitectura de computadoras 1
1.1. Modelo actual de la Computadora . . . . . . . . . . . . . . . . . 1
1.1.1. Unidad central de procesamiento . . . . . . . . . . . . . . 2
1.1.2. Memoria . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.3. Dispositivos de entrada y salida de datos . . . . . . . . . . 5
1.2. Software de base . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2. Algoritmos 9
2.1. Algoritmo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2. Programación . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.3. Programación estructurada . . . . . . . . . . . . . . . . . . . . . 11
2.4. Diagramas de flujo . . . . . . . . . . . . . . . . . . . . . . . . . 12
3. Lenguaje C 13
3.1. Lenguaje C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.1.1. Tipos de datos . . . . . . . . . . . . . . . . . . . . . . . 13
3.1.2. Variables y constantes . . . . . . . . . . . . . . . . . . . 14
3.1.3. Operadores . . . . . . . . . . . . . . . . . . . . . . . . . 15
4. Estructuras de decisión 19
4.1. Decisión simple . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4.2. Decisión binaria . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.3. Decisión encadenada . . . . . . . . . . . . . . . . . . . . . . . . 23
4.4. Decisión anidada . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.5. Decisión múltiple . . . . . . . . . . . . . . . . . . . . . . . . . . 29
5. Funciones 33
5.1. Importancia de dividir un problema . . . . . . . . . . . . . . . . . 33
5.2. Reglas básicas para definir funciones . . . . . . . . . . . . . . . . 34
5.2.1. Declarar la función . . . . . . . . . . . . . . . . . . . . . 34
3
4 ÍNDICE GENERAL
6. Estructuras repetitivas 41
6.1. Estructura repetitiva “durante” (for) . . . . . . . . . . . . . . . . 41
6.2. Estructura repetitiva “mientras“ (while) . . . . . . . . . . . . . . 47
6.3. Estructura repetitiva “haz - mientras” (do-while) . . . . . . . . . . 49
8. Registros 75
8.1. Definición de variables de tipo registro. . . . . . . . . . . . . . . 75
8.2. Definición de un registro empleando alias. . . . . . . . . . . . . . 76
8.3. Representación de los registros en la memoria . . . . . . . . . . . 79
9. Archivos 83
9.1. Conceptos básicos . . . . . . . . . . . . . . . . . . . . . . . . . . 83
9.2. Funciones usuales para el manejo de archivos . . . . . . . . . . . 83
Arquitectura de computadoras
1
2 CAPÍTULO 1. ARQUITECTURA DE COMPUTADORAS
Unidad aritmético-lógica
Unidad de control
Código Operación
0000 Neutro (no hay operación por hacer)
0001 Suma
0010 Resta
0011 Multiplicación
Registros
Los registros son celdas de almacenamiento, propias de la CPU, que guardan
temporalmente tanto los datos de entrada que serán procesados por la ALU como el
resultado del procesamiento. Distinguimos tres tipos: registros de entrada, registros
de instrucción y el contador de programa.
1.1.2. Memoria
Es una colección de celdas de almacenamiento. Cada celda tiene un identifi-
cador único conocido como “dirección“. Los datos se transfieren hacia y desde la
memoria en grupos de bits llamados palabras.
Un bit es la unidad mı́nima de almacenamiento en una computadora; éste fı́si-
camente es un condensador (ver figura 1.2): si está cargado, entonces representa 1
(verdadero); si no está cargado, entonces representa 0 (falso).
4 CAPÍTULO 1. ARQUITECTURA DE COMPUTADORAS
Una palabra puede estar formada desde un patrón de 8 bits (ej. 10100100)
hasta 64 bits en computadoras recientes. La figura 1.3 representa una memoria con
8 celdas; donde cada celda está formada por un patrón de 8 bits. Cada una tiene
asignada una dirección expresada, de igual manera, en binario. Las direcciones
están designadas por un número consecutivo que inicia con la dirección 0.
Por ejemplo una computadora cuya memoria tiene 4MB y el tamaño de palabra
es igual a 16 bits tiene 4 ∗ 1, 048, 576 = 4, 192, 304 celdas, cada una con un tamaño
1.2. SOFTWARE DE BASE 5
de 2 byte. Todas con su dirección correspondiente: 0, 1, 2, ..,4, 192, 303 (pero ex-
presado en binario). Existen varios tipos de memoria, de los cuales distinguiremos:
1) la memoria de acceso aleatorio y 2) la memoria de solo lectura.
otros.
..
Capı́tulo 2
Algoritmos
2.1. Algoritmo
Un algoritmo es un conjunto de pasos precisos y ordenados, que nos permi-
ten alcanzar un resultado, o bien resolver un problema. Las caracterı́sticas de un
algoritmo son: Precisión, finitud y determinismo.
9
10 CAPÍTULO 2. ALGORITMOS
2.2. Programación
Programar es concebir un algoritmo que permita a una computadora resolver
un problema. El algoritmo debe escribirse en un lenguaje claro, estricto y universal,
a saber: pseudocódigo. Posteriormente, ese algoritmo expresado en pseudocódigo
podrá ser traducido a cualquier lenguaje de programación, en nuestro caso a len-
guaje C o lenguaje Basic.
La tabla 2.1 muestra gráficamente cada una de las estructuras básicas para cons-
truir un programa, a saber: estructura de secuencia, estructura de decisión y estruc-
tura de repetición. Estas estructuras tienen una sintaxis especı́fica en el lenguaje de
programación C; la definición y la sintáxis de cada una de ellas, las abordaremos
en las secciones ??.
Lenguaje C
3.1. Lenguaje C
C es un lenguaje de programación inventado por Dennis M. Ritchie entre 1969
y 1973 en los laboratorios Bell de New Jersey. C es un lenguaje estructurado, el
cual ofrece algunas ventajas: 1) control de flujo, 2) manejo de variables simples
y estructuradas, 3) simplificación en al expresar operaciones y 4) un conjunto de
operadores. Originalmente C fue diseñado para el sistema operativo UNIX; sin
embargo, el lenguaje C no esta ligado a ningún hardware o sistema operativo par-
ticular; podemos citar el ejemplo del sistema operativo Linux, desarrollado por
Linus Torvals utilizando únicamente lenguaje C.
El lenguaje C es especialmente poderoso, pero es un lenguaje fuertemente
orientado para ingenieros en Computación, porque es un lenguaje llamado nivel
intermedio (se pueden hacer cosas muy apegadas a la arquitectura con la que se
esté trabajando). Es un lenguaje con una curva de aprendizaje un poco más inclina-
da, pero como se mencionó anteriormente, esto permite hacer un uso más eficiente
del hardware, siempre y cuando se esté dispuesto a pagar el precio en tiempo y
esfuerzo que esto implica.
13
14 CAPÍTULO 3. LENGUAJE C
int valor1;
float valor2=5.4;
//se asigna un valor inicial a la variable
//El signo de igual (=) significa, en lenguaje C,
asignacion. El valor de la derecha del signo se asigna a
la variable o constante de la izquierda.
3.1. LENGUAJE C 15
3.1.3. Operadores
Distinguiremos tres tipos de operadores: 1) aritméticos, 2) relacionales y 3)
lógicos. También analizaremos los operadores simplificados, los operadores de
incremento-decremento y el operador coma (,).
Operadores aritméticos. Suponga que declaramos dos variables (v y x) una
de tipo real y otra de tipo entera: float v; int x; ver operaciones en la tabla 3.2
Prioridad Operadores
Mayor (), *, /, %
Menor +, -
Operación Operación
Operador
larga simplificada
+= x=x+5 x+=5
-= y=y-2 y-=2
*= x=x*y x*=y
/= x=x/y x/=y
%= x=x %y x %=y
Operación Resultado
y=x++ y=7
x=8
y=++x y=8
x=8
y=x– y=7
x=6
y=–x y=6
x=6
Operador
Descripción Ejemplo Resultado
relacional
== igual a ”h-=”p” 0 (F)
!= diferente de ”h¡=”p” 1 (V)
< menor que 7<5 0 (F)
> mayor que 22 > 11 1 (V)
<= Menor o igual que 15 <= 2 0 (F)
>= Mayor o igual que 35 >= 20 1 (V)
Operador Diagrama de
Significado
lógico Venn asociado
! NOT
&& AND
|| OR
P Q !P !Q P||Q P&&Q
1 1 0 0 1 1
1 0 0 1 1 0
0 1 1 0 1 0
0 0 1 1 0 0
Operador “,“ (coma). Sirve para encadenar expresiones. Dos ejemplos son:
int x, y, z, v;
x= (v=3, v*5);
v = 3
x= v*5 = 3*5
x=15
Otro ejemplo:
int x, y, z, v;
x=(y=(15>10), z=(2>=y), y&&z);
Prioridad Operadores
(+) ()
!, ++, –
*, /, %
+, -
==, !=, <, >, <=, >=
&&, ||
+ =, − =, ∗ =, / =, % =
(-) ,
Estructuras de decisión
19
20 CAPÍTULO 4. ESTRUCTURAS DE DECISIÓN
Entrada Salida
123.40 1 98.72
833.17 0 833.17
#include <stdio.h>
#define DESC 0.80
int main(void){
float venta=0.0;
int esMenor=0;
printf("Cual es la cantidad de la venta: ");
scanf(" %f",&venta);
printf("Es menor de edad (1-si 0-no): ");
scanf(" %d",&esMenor);
if(venta>=100 && esMenor==1){
venta=venta*DESC;
}
printf("A pagar: %8.2f",venta);
return 0;
}
NOTA:
1. En este programa es importante que el usuario introduzca los valores con el
formato correcto.
2. Recordemos que en el lenguaje C, el operador relacional “igual que“ es “==”;
en contraste con el operador asignación, que es “=”.
3. No olvidemos que los corchetes delimitan el inicio y fin de cualquier estruc-
tura de control, en este caso la estructura if.
4. El código de impresión esta limitado a 128 caracteres, en los programas en
C no se pueden imprimir acentos ni eñes.
√
−b + − b2 − 4ac
x= (4.1)
2a
Especificación: Las variables de entrada son tres valores reales, y como sa-
lida pueden ser dos números reales, ó dos números imaginarios. Cuando el de-
terminante es cero, la raı́z está degenerada y se imprime dos veces. La tabla 4.2
proporciona algunos datos de entrada y salida esperados.
4.3. DECISIÓN ENCADENADA 23
Entrada Salida
1 2.5 3 -1.25 + 1.198958 i
-1.25 - 1.198958 i
-1.5 2 3.5 -1
0.666667
#include <stdio.h>
#include <math.h>
int main(void){
float a, b, c, det, aux;
printf("Dame los 3 coeficientes de la ecuaci de segundo grado:");
printf("ax2+bx+c=0 :");
scanf(" %f %f %f",&a,&b,&c);
det=(b*b-4*a*c);
aux=-b/(2*a);
if(det < 0){
printf("x1 = %f + %f i \n",aux,pow(-det,.5)/(2*a));
printf("x2 = %f - %f i",aux,pow(-det,.5)/(2*a));
}
else {
printf("x1 = %f \nx2 = %f",aux+pow(det,.5)/(2*a),aux-pow(det,.5)/(2*
a));
}
return 0;
}
Cuando una condición que es falsa nos lleva a evaluar una nueva condición, de-
cimos que las estructuras de decisión están encadenadas. Cada condición se evalúa
siguiendo el orden, el bloque de instrucciones del otro caso else solo se ejecu-
tará cuando ninguna de las condiciones anteriores se ha cumplido. Observe que las
estructuras encadenadas mantienen independencia una de otra, por lo tanto es más
sencillo manipularlas durante la solución de un problema, ver figura 4.3.
24 CAPÍTULO 4. ESTRUCTURAS DE DECISIÓN
Especificación: En este problema no hay una entrada por parte del usuario;
el programa debe generar un valor aleatorio, correspondiente a los lados de la pi-
rinola, para luego indicar la acción que los jugadores deben realizar. La tabla 4.3
4.3. DECISIÓN ENCADENADA 25
Valor Acción
0 Pon uno
1 Pon dos
2 Toma uno
3 Toma dos
4 Toma todo
5 Todos ponen
6 Pierdes todo
Entrada Salida
Sin entrada toma todo
Sin entrada Pon uno
Sin entrada Todos ponen
int main(void){
double num=0.0;
srand(time(NULL));
printf("Pirinola/perinola/peonza digital \n");
num=rand() %7+1;
if(num == 1) printf("Pon uno \n");
else if(num == 2) printf("Pon dos \n");
else if(num == 3) printf("Toma uno \n");
else if(num == 4) printf("Toma dos \n");
else if(num == 5) printf("Toma todo \n");
else if(num == 6) printf("Todos ponen \n");
else printf("Pierdes todo");
return 0;
}
3y + 36 si 0 < y ≤ 11
y2 − 10 si 11 < y ≤ 33
y3 + y2 − 1 si 33 < y ≤ 64
0 en otro caso
Entrada Salida
3 45.0
44.4 89498.75
#include<stdio.h>
#include<math.h>
int main(void){
float x=0.0, y=0.0;
printf("Introduce el valor de y: ");
scanf(" %f", &y);
if(y>0.0 && y<=11.0) printf("x = %.2f", 3*y+36);
else if(y>11.0 && y<=33.0) printf("x = %.2f", pow(y,2)+10);
else if (y>33.0 && y<=64.0) printf("x= %.2f", pow(y,3)+pow(y,2)-1);
else printf ("x= %.2f", x);
return 0;
}
if(condicion1){
if(condicion2){
if(condicion3){ La condición puede estar compuesta por
bloque3_V; una o varias condiciones que al ser eva-
} luadas nos proporcionan un valor lógico
else{
(V-verdadero ó F-falso).
bloque3_F;
}
}
El bloque3 V solo se ejecutará cuando las
else{ condiciones 1,2 y 3 sean verdaderas
bloque2_F;
} Uno de los bloque F se ejecutará única-
} mente cuando la condición respectiva no
else{ se haya cumplido
bloque1_F;
}
Computadora
Usuario 1-piedra 2-Papel 3-Tijera
1-Piedra Empate Gané Ganaste
2-Papel Gané Empate Gané
3-Tijera Ganaste Ganaste Empate
Entrada Salida
1 Tu opción fue piedra, yo escogı́ piedra – Empatamos!
2 Tu opción fue papel, yo escogı́ tijera – Gané!
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(void){
int num=0, opc=0;
srand(time(NULL));
num=(rand() %3)+1;
printf("1-Piedra 2-Papel 3-Tijera \n");
printf("Escoge una de las opciones anteriores: ");
scanf(" %d",&opc);
if(opc==1){
if(num==1)
printf("Tu opcion fue Piedra, yo escogi Piedra - Empatamos!");
else if(num==2)
printf("Tu opcion fue Piedra, yo escogi Papel - Gane!");
else if(num==3)
printf("Tu opcion fue Piedra, yo escogi Tijera - Ganaste!");
}
else if(opc==2){
if(num==1)
printf("Tu opcion fue Papel, yo escogi Piedra - Ganaste!");
else if(num==2)
printf("Tu opcion fue Papel, yo escogi Papel - Empatamos!");
4.5. DECISIÓN MÚLTIPLE 29
else if(num==3)
printf("Tu opcion fue Papel, yo escogi Tijera - Gane!");
}
else if(opc==3){
if(num==1)
printf("Tu opcion fue Tijera, yo escogi Piedra - Gane!");
else if(num==2)
printf("Tu opcion fue Tijera, yo escogi Papel - Ganaste!");
else if(num==3)
printf("Tu opcion fue Tijera, yo escogi Tijera -Empatamos!");
}
return 0;
}
En problemas que involucran tomar una decisión entre múltiples opciones con-
viene emplear la estructura switch (ver figura 4.5), en lugar de emplear estruc-
turas condicionales encadenada. La estructura de decisión múltiple proporciona un
código más claro para quienes lo leen; su uso más común es la construcción de un
menú de opciones para el usuario del programa.
Programa 4.6: Cálculo de sueldo Dado el sueldo, la categorı́a y el costo por una
hora extra de trabajo, calcular el sueldo total de un empleado en base a la tabla 4.8.
El programa debe considerar que si el empleado trabaja más de 30 horas extras,
solo se le pagarán las primeras 30.
Entrada Salida
2 457.9 13 951.90
4 5219.9 45 7319.90
#include <stdio.h>
int main(void){
int categoria=0,hExtra=0;
float sueldo=0.0,PHE=0.0;
printf("CAT \t Precio HE \n");
printf(" 1 \t 30 \n 2 \t 38 \n 3 \t 50 \n 4 \t 70 \n");
printf("Categoria, sueldo, hrs extra: ");
scanf(" %d %f %d", &categoria,&sueldo,&hExtra);
if(hExtra > 30) hExtra=30;
switch(categoria){
case 1:
PHE = 30;
break;
case 2:
PHE = 38;
break;
case 3:
PHE = 50;
break;
case 4:
PHE=70;
break;
default:
PHE = 0;
break;
}
printf("El sueldo total es de : %.2f", sueldo+PHE*hExtra);
return 0;
}
Valor Acción
0 Pon uno
1 Pon dos
2 Toma uno
3 Toma dos
4 Toma todo
5 Todos ponen
6 Pierdes todo
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(void){
int num=0;
srand(time(NULL));
printf("Pirinola/perinola/peonza digital \n\n");
num=rand() %7;
switch(num){
case 0: printf("Pon uno \n"); break;
case 1: printf("Pon dos \n"); break;
case 2: printf("Toma uno \n"); break;
case 3: printf("Toma dos \n"); break;
case 4: printf("Toma todo \n"); break;
case 5: printf("Todos ponen \n"); break;
default: printf("Pierdes todo"); break;
}
return 0;
}
Funciones
33
34 CAPÍTULO 5. FUNCIONES
2. Definir de la función
Donde:
Las variables cuyos valores serán enviados a la otra función. Estas variables
se escriben dentro del paréntesis, siguiendo el orden y respetando el tipo de
dato declarado en el prototipo.
int main(void){
:
nombre_funcion(lista_de_valores);
:
return 0;
}
Programa 5.1: Encontrar el mayor de tres números. Dados tres números en-
teros a, b y c, encontrar al mayor de entre ellos.
Entrada Salida
82 1 7 82
342 867 950 867
#include <stdio.h>
int leeValor(void);
int encuentraMax (int, int, int);
void imprime(int);
int main(void){
int a,b,c,max;
a=leeValor();
b=leeValor();
c=leeValor();
max = encuentraMax(a,b,c);
imprime(max);
return 0;
}
int leeValor(void){
int val;
printf("Dame un valor entero: ");
scanf(" %d", &val);
return (val);
}
Entrada Salida
3 Tu opción fue Tijera, yo escogı́ Piedra – Ganaste!
2 Tu opción fue Papel, yo escogı́ Papel – Empatamos!
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(void){
int mine=0, yours=0;
printf("Juguemos a piedra papel o tijera \n");
printf(" 1. Piedra \n 2. Papel \n 3. Tijera \n");
printf("Cual es tu tirada: ");
scanf(" %d", &yours);
printf("Mi tirada es: ");
srand(time(NULL));
mine=rand() %3+1;
printf(" %d \n",mine);
referi(mine,yours);
return 0;
}
switch(yours){
case 1:
if(mine==2) printf("Gane !!!! \n");
else printf("Ganaste!!! \n");
break;
case 2:
if(mine==1) printf("Ganaste!!! \n");
else printf("Gane!!! \n");
break;
case 3:
if(mine==1) printf("Gane!!! \n");
else printf("Ganaste!!! \n");
break;
default:
printf("ERROR en tu tiro!!! \n");
break;
}
}
return;
}
int main(void){
int x=0,z=0;
int *y; //declaro a y como una variable de tipo apuntador
x=3;
5.4. PASO DE PARÁMETROS POR REFERENCIA 39
printf("z= %d ",z);
return 0;
}
Especificación: Este programa debe estar formado por una función que per-
mute los valores de dos variables a, b; esta función no devuelve ningún valor y
debe recibir las direcciones de las tres variables; la tabla 5.3 muestra dos ejemplos.
Entrada Salida
a=84 b=10 a=10 b=84
a=2 b=22 a=22 b=2
#include<stdio.h>
int main(){
int a=10, b=5;
printf("\n \n Los valores de las variables originales A y B son: %d y %
d",a,b);
intercambia(&a,&b);
printf("\n \n Los valores de A y B han sido intercambiados, ahora son:
%d y %d", a,b);
return 0;
}
Entrada Salida
123456a 34h 17m 36s
67758 18h 49m 18s
#include <stdio.h>
int main(void){
int segundos,hora,min,seg;
printf("Ingresa los segundos: ");
scanf(" %d",&segundos);
convertir(segundos,&hora,&min,&seg);
printf(" %d h %d min %d seg",hora,min,seg);
return 0;
}
Estructuras repetitivas
41
42 CAPÍTULO 6. ESTRUCTURAS REPETITIVAS
Salida
6 28 496 8128
#include <stdio.h>
#define MAX 1e4
6.1. ESTRUCTURA REPETITIVA “DURANTE” (FOR) 43
int main(void){
int num=0, sum=0, i=0;
printf("Numeros perfectos \n\n");
for(num=1; num<=MAX; num++){
sum=0;
for(i=1; i<=(num/2); i++)
if(num %i==0) sum = sum+i;
if(sum==num) printf (" %5d es numero perfecto \n", num);
}
return 0;
}
Entrada Salida
50 Es menor
25 Es menor
12 Es mayor
17 Es mayor
21 Acertaste!
20 Es mayor
40 Es mayor
60 Es mayor
80 Es mayor
90 Es menor
88 Es menor
86 Se acabaron tus intentos!
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(void){
int num=0, tuNum=0, i=0;
srand(time(NULL));
printf("Programa adivina un nmero en 7 oportunidades o menos\n");
printf("\n Estoy pensando un numero, entre 1 y 100");
num=(rand() %100)+1;
for(i=1; i<=7; i++){
printf("\n Intenta adivinar el numero: ");
scanf(" %d", &tuNum);
if(num < tuNum) printf("Mi numero es menor \n");
else if(num > tuNum) printf("Mi numero es mayor \n");
else{
printf("Acertaste!!! \n");
exit(1);
}
}
printf("\n Lo siento, agotaste tus oportunidades");
return 0;
}
Especificación: No hay entrada por parte del usuario; como salida se en lis-
tan los números primos con la siguiente leyenda: x es primo. La tabla 6.3 muestra
un ejemplo.
#include <stdio.h>
#define LIM 1e3
int main(){
int num=0, i=0, band=0, cont=0;
printf("Numeros primos comprendidios entre 2 y %.0f\n", LIM);
for(num=2; num<=LIM; num++){
band=0;
for(i=2; i<=num/2; i++){
if(num %i==0) band=1;
}
if(band==0){
printf(" %d es primo \n", num);
cont++;
6.1. ESTRUCTURA REPETITIVA “DURANTE” (FOR) 45
Salida
2 es primo
3 es primo
5 es primo
7 es primo
11 es primo
13 es primo
17 es primo
19 es primo
23 es primo
29 es primo
31 es primo
37 es primo
41 es primo
43 es primo
47 es primo
}
}
printf("\n %d numeros primos en el rango de 1 a %.0f\n", cont, LIM);
return 0;
}
Entrada Salida
0 1
10 3628800
#include <stdio.h>
int fact(int);
void serie(int);
void limite(int *n);
int main(void){
int n;
limite(&n);
serie(n);
return 0;
}
while(condicion){
bloque_v;
}
Salida
2 7 10 15 18 . . . 2500
#include <stdio.h>
int main(void){
int serie=2, cambio=1;
while(serie<=2500){
printf(" %d\t",serie);
if(cambio==1){
serie+=5;
cambio=0;
}
else {
serie+=3;
cambio=1;
}
}
return 0;
}
Entrada Salida
3 5 10 6.0
5.5 8.5 9.5 7.83333
#include <stdio.h>
int main(void){
float califica=0.0, total=0.0, contador=0.0;
printf("Calificacion: ");
6.3. ESTRUCTURA REPETITIVA “HAZ - MIENTRAS” (DO-WHILE) 49
scanf(" %f",&califica);
while(califica>=0 && califica<=10){
total+=califica;
contador++;
printf("Calificacion: ");
scanf(" %f",&califica);
}
if(total!=0){
printf("La suma es: %.2f \n",total);
printf("El promedio es: %.2f \n",total/contador);
}
return 0;
}
do{
bloque_V;
}while(condicion);
Entrada Salida
1234560 4.0 3.0
998876 7.3333 8.33333
#include <stdio.h>
int main(void){
int num=0;
float tpar=0.0,timp=0.0,npar=0.0,nimp=0.0;
do{
printf("Introduce un entero positivo: ");
scanf(" %d",&num);
if(num>0){
if(num %2==0){
tpar+=num;
npar+=1;
}
else{
timp+=num;
nimp+=1;
}
}
}while(num>0);
if(npar==0) printf("\nNo hay promedio par");
else printf("\nPromedio par = %f \n",tpar/npar);
if(nimp==0) printf("\nNo hay promedio impar");
else printf("\nPromedio impar = %f \n",timp/nimp);
return 0;
}
Problema 6.8: Cortina de números. Escriba un programa que genere una cor-
tina de números en la pantalla.
Entrada Salida
123321
3 12—21
1——1
1234554321
1234—4321
5 123——321
12———21
1————1
#include <stdio.h>
int pideDato(void);
void figura(int);
int main(void){
int num=0;
do{
num=pideDato();
}while(num<0);
if(num>0) figura(num);
else printf("\n Escogiste salir!!");
return 0;
}
int pideDato(void){
int num=0;
printf("\n\n Cortina de numeros. Para salir introduce un 0, o bien");
printf("\n introduce un numero entero positivo menor a 14");
printf("\n\n N = ");
scanf(" %d",&num);
return(num);
}
Entrada Salida
100 6 28
10000 6 28 496 8128
#include <stdio.h>
void numPerfecto(int);
int main(void){
int n=0;
do{
printf("Limite de la serie para encontrar numeros perfectos: ");
scanf(" %d",&n);
}while(n<0);
if (n!=0){
6.3. ESTRUCTURA REPETITIVA “HAZ - MIENTRAS” (DO-WHILE) 53
numPerfecto(n);
}
return 0;
}
Un arreglo es una colección de variables del mismo tipo, que se referencı́an por
un nombre común. En el lenguaje C, las celdas de memoria correspondientes a las
variables de un arreglo son contiguas; por lo tanto, la dirección de memoria más
baja corresponde al primer elemento del arreglo y la dirección de memoria más alta
corresponde al último elemento. Dado que un arreglo está formado por celdas de
memoria contigua, para acceder a un elemento es suficiente con emplear un ı́ndice,
el cual denota la posición de un elemento en el arreglo.
float num[40];
//corresponde a un arreglo llamado num de tamao 40 y cuyos
elementos deberan ser de tipo real
Cuando declaramos un arreglo, es posible darle valores iniciales, por ejemplo:
int vector[8]={2,4,6,7,5,1,9,3};
float num[3]={2.45,4.56,1.23};
float calificaciones[7]={0,0};
//todos elementos del arreglo son iguales a 0.0
int datos[]={36,21,23};
55
56 CAPÍTULO 7. TIPOS DE DATOS ESTRUCTURADOS
ı́ndice 0 1 2 3 4 5 6 7
vector 2.3 4.4 6.5 7.2 5.5 1.7 5.8 4.6
Todos los arreglos comienzan en con una posición 0 (cero); por lo tanto, el
tamaño de vector es 8, pero su última posición es 7. En general, para un arreglo de
tamaño n, su última posición será n − 1.
Para acceder a cualquier elemento, nos referimos a él a través de su posición,
por ejemplo:
En el ejemplo 7.1 para referirnos al elemento en la posición 2, escribimos
vector[2] es 6,5; para referirnos al elemento en la posición 6, escribimos vector[6]
es 5,8; el elemento del vector[2 + 3] es igual al vector[5], es decir 1,7.
Entrada Salida
34195 59143
6 28 49 68 12 12 68 49 28 6
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAX 5
int main(void){
int vector[MAX]={0}, i=0;
7.1. ARREGLOS UNIDIMENSIONALES 57
Salida
59143126849286735971
62849681259143126322
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAX 20
int main(void){
int enteros[MAX]={0}, i=0;
printf("\nGenerando valores aleatiorios, en un rango de [0..9]");
printf("\npara un vector de 20 elementos llamado enteros \n\n");
for (i=0;i<MAX;i++){
enteros[i]=rand() %10;
}
printf("\nLos 20 valores del vector enteros son: \n\n");
for (i=0;i<MAX;i++){
printf(" %d ", enteros[i]);
}
58 CAPÍTULO 7. TIPOS DE DATOS ESTRUCTURADOS
printf("\n");
return 0;
}
// Prototipo
void calcular(int datos[], int n);
void imprimir(int datos[], int n);
int main(void){
int datos[]={1,2,3,4,5};
imprimir(datos,5);
calcular(datos, 5); //Llamado a la funcion
imprimir(datos,5);
return 0;
}
#include<stdio.h>
// Prototipo
void calcular(int* datos, int n);
void imprimir(int* datos, int n);
int main(void){
int datos[]={5,6,7,8,9};
imprimir(datos,5);
calcular(datos, 5); //Llamado a la funcion
imprimir(datos,5);
return 0;
}
Problema 7.3: Suma de dos vectores enteros Construir un programa que cal-
cule la suma de 2 arreglos unidimensionales de tipo entero. El resultado debe al-
macenarse en un tercer arreglo.
Especificación: El programa debe tener tres funciones: una que lea los datos,
otra que haga la suma y finalmente otra que imprima los resultados. La tabla 7.3
muestra, como primer valor, el tamaño de los arreglos; luego, dos vectores dados
como entrada y el vector correspondiente con la suma de los valores de ambos.
60 CAPÍTULO 7. TIPOS DE DATOS ESTRUCTURADOS
Entrada Salida
3
123 5 8 11
468
4
3479 12 12 11 14
9845
#include <stdio.h>
#define MAX 100
int tamVEC(void);
void leeVEC(int X[],char nom,int n);
void sumVEC(int A[],int B[],int C[],int n);
void impVEC(int X[],char nom,int n);
int main(void){
int A[MAX]={0};
int B[MAX]={0};
int C[MAX]={0};
int tam=0;
tam=tamVEC();
leeVEC(A,’A’,tam);
leeVEC(B,’B’,tam);
sumVEC(A,B,C,tam);
impVEC(A,’A’,tam);
impVEC(B,’B’,tam);
impVEC(C,’C’,tam);
return 0;
}
int tamVEC(void){
int n=0;
do{
printf("Dame el tama de los arreglos (1-100)");
scanf(" %d",&n);
}while(n<=0 || n>=MAX);
return (n);
}
int i=0;
for (i=0; i<n; i++){
C[i]=A[i]+B[i];
}
return;
}
Entrada Salida
3 0.004597
4 0.013925 *
5 0.027767 **
6 0.046234 ****
7 0.069336 ******
8 0.097385 *********
9 0.115706 ***********
10 0.125015 ************
11 0.125067 ************
12 0.115598 ***********
13 0.097294 *********
14 0.069457 ******
15 0.046314 ****
16 0.027788 **
17 0.013925 *
18 0.004593
3 0.004658
4 0.013884 *
5 0.027817 **
6 0.046329 ****
7 0.069530 ******
8 0.097008 *********
9 0.115721 ***********
10 0.124956 ************
11 0.125053 ************
12 0.115827 ***********
13 0.097042 *********
14 0.069504 ******
15 0.046352 ****
16 0.027833 **
17 0.013837 *
18 0.004649
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NDADOS 3
7.2. ARREGLOS UNIDIMENSIONALES Y FUNCIONES 63
int main(void){
int cara[100]={0};
time_t tiempo1, tiempo2;
srand(time(NULL));
time(&tiempo1);
tiraDados(cara);
imprimeRes(cara);
time(&tiempo2);
printf("\nEl tiempo de ejecucion es: %f \n", (float)(tiempo2-tiempo1));
return(0);
}
Entrada Salida
1048596 100000000000000000000
123456 12422311
#include <stdio.h>
#define MAX 560
int main(void){
int decimal=0, base=0, i=0, conversion[MAX]={0};
float num[5][5];
//corresponde a un arreglo llamado valores de 5 renglones y
5 columnas; por lo tanto es una matriz cuadrada de 25
elementos de tipo real
Cuando declaramos un arreglo bidimensional, es posible darle valores iniciales,
por ejemplo:
int matriz[3][4]={12,24,46,17,25,31,49,63, 42,21,89,96};
// Se asignan los valores en el orden de aparicion,
cubriendo cada renglon
int matriz[3][4]={{12,24,4617},{25,31,49,63},{
42,21,89,96}};
// Esta forma proporciona claridad a quien lee el codigo
c0 c1 c2 c3
r0 12 24 46 17
r1 25 31 49 63
r2 42 21 89 96
Observe que también los arreglos bidimensionales comienzan en con una posi-
ción 0 (cero) tanto en los renglones como en las columnas; por lo tanto, el número
66 CAPÍTULO 7. TIPOS DE DATOS ESTRUCTURADOS
Problema 7.6: Traspuesta de una matriz. Construir un programa que dada una
matriz, obtenga la matriz transpuesta.
Entrada Salida
34 154
1234 277
5792 396
4767 427
23 1.2 7.8
1.2 3.4 5.6 3.4 8.9
7.8 8.9 0.1 5.6 0.1
#include <stdio.h>
#define MAX 50
int main(void){
float MAT1[MAX][MAX], MAT2[MAX][MAX];
7.3. ARREGLOS BIDIMENSIONALES 67
Entrada Salida
3
123
456 NO
789
4
3040
0124 SI
4259
0493
#include <stdio.h>
#define MAX 50
int leeMatriz(float[][MAX]);
int simetrica(float[][MAX],int);
int main(void){
float MAT[MAX][MAX];
int n=0,resp=0;
n=leeMatriz(MAT);
resp=simetrica(MAT,n);
if (resp==0) printf("\nLa matriz es simetrica\n");
else
printf("\nLa matriz no es simetrica\n");
return 0;
}
return n;
}
7.4. Cadenas
Una cadena es un arreglo unidimensional empleado para guardar elementos de
tipo caracter char. Una cadena se declara igual que los arreglos, por ejemplo:
char cad[10];
//corresponde a una cadena llamada cad de tamao 10 y cuyos
elementos deberan ser de tipo caracter
En el leguaje C, todas las cadenas terminan con un caracter nulo denotado por
una diagonal inversa y el número cero
0; por lo tanto, al momento de definir el tamaño de la cadena tenemos que contar
la celda que ocupará este caracter. El caracter nulo
0 sirve para marcar el fin de una cadena.
Cuando declaramos una cadena, es posible darle valores iniciales, por ejemplo:
char cadena[5]={h,o,l,a,\0};
//Los valores se asignan a cadena en el orden en que
aparecen
char cad[5]=hola;
// otra forma valida de inicializar a cad
char cad[5]= ;
//Todos elementos del arreglo tienen como valor inicial al
caracter espacio
ı́ndice 0 1 2 3 4
cadena h o l a X
getc(caracter);
putc(caracter);
gets(cadena);
puts(cadena);
Cuando se desea leer una nueva cadena, debemos emplear la función f f lush(stdin)
y f f lush(stdout), para limpiar el buffer de entrada y salida, donde se guarda una
cadena temporalmente. La tabla 7.10 muestra una serie de comandos básicos para
el manejo de cadenas en lenguaje C.
7.4. CADENAS 71
Comando Precauciones
strcpy(destino, origen). Copia el valor de No verifica que la cadena destino
cadena origen hacia la cadena destino. sea lo bastante grande como para al-
macenar el valor de la cadena ori-
gen.
strncpy(destino, origen, limite). Igual que Si limite se elige con cuidado, esta
la función strcpy de dos argumentos, solo función es más segura que la ver-
que se copian cuando mucho el lı́mite ca- sión strcpy.
racteres.
strcat(destino, origen). Concatena el valor No verifica que la cadena destino
de cadena origen con el final de la cadena sea lo bastante grande como para al-
destino. macenar el resultado de la concate-
nación.
strncat(destino, origen, limite). Igual que Si limite se elige con cuidado, esta
la función strcat de dos argumentos, solo función es más segura que la ver-
que se anexan cuando mucho lı́mite carac- sión srtcat.
teres.
strlen(origen). Devuelve un entero igual a
la longitud de la cadena origen; el caracter
nulo X no se cuenta en la longitud.
strcmp(cadena1 , cadena2 ). Devuelve 0 si Si cadena1 es igual a cadena2 esta
cadena1 y cadena2 son iguales. Devuelve función devuelve 0, lo que la con-
un valor menor a 0 si cadena1 es menor vierte en falsa cuando se evalúa. Es-
que cadena2 . Devuelve un valor mayor a 0 to es lo inverso de lo que podrı́amos
si cadena1 es mayor que cadena2 . Por lo esperar dado que las cadenas son
tanto, devuelve un valor distinto de cero si iguales. Tener cuidado con la lógi-
cadena1 y cadena2 son distintas. Cada ca- ca que sigue esta función.
racter tiene un valor entero, según la tabla
de ascii.
strncmp(cadena1 , cadena2 , limite). Igual Si limite se elige con cuidado, esta
que la función strcmp de dos argumentos, función es más segura que la fun-
solo que se comparan cuando mucho limite ción strcmp de dos argumentos
caracteres.
Entrada Salida
AnitaLavaLatinA Si
DammItImmaD Si
LaminaElizaBeT No
#include<stdio.h>
#include<string.h>
#define MAX 50
int main(void){
char cad[MAX]={’\0’};
int resp=0;
printf("Ingresa la cadena a ser evaluada como palindrome,");
printf("\npero SIN ESPACIOS ENTRE LAS LETRAS:\n");
scanf(" %s",cad);
printf("la cadena mide %i y contiene %s", strlen(cad), cad);
resp=palindrome(cad);
if (resp==0) printf("\nLa cadena no es palindrome\n");
else printf("\nLa cadena es palidrome\n");
return 0;
}
Especificación: El programa debe usar una función que reciba la cadena ori-
ginal y su tamaño; esta función deberá desordenar la cadena n veces; donde n es
el tamaño de la cadena que ingresó el usuario. Esta misma función se encargará de
imprimir la cadena resultante de cada iteración; la tabla 7.12 muestra dos ejemplos
de anagramas para sus respectivas cadenas.
Entrada Salida
William Shakespeare ep haileSreaiskmWla
ai pleeerSWsikaalmh
aihl lsmeaeWaSepirk
ikaiaWrseeplalheS m
i am a Weakish Speller ishpeWlSer
ilamkaearSemeaeahs apilklWi
mpilraS aaeikeelsWh
Sepimli ehakWeslara
salaieSWleepkhiarm
eis ieklhWalrSpmaae
eapWkaeiSishlalrem
epmiashkerWleilaaS
elmkhWe eSraasipali
eapmi lelshiSekaaWr
iSpmhe sklileearaWa
leeea ialWrikmhpaSs
imeh laelakareSWpis
lieeilaSsmapWharek
lofos sfool
soofl
lofso
fools
olfso
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include<string.h>
#define MAX 50
int main(void){
74 CAPÍTULO 7. TIPOS DE DATOS ESTRUCTURADOS
char nom[MAX]={’\0’};
srand(time(NULL));
printf("Escribe una cadena: ");
gets(nom);
desordena(nom);
return 0;
}
Registros
Un registro define un nuevo tipo de dato; es decir, podemos crear variables que
tienen la forma del registro recién definido. Todo registro debe ser definido antes de
la función principal main() y después de incluir las bibliotecas que emplearemos
en el programa.
75
76 CAPÍTULO 8. REGISTROS
tipo_dato campo_3;
tipo_dato campo_4;
};
int main(void){
struct registro reg_1, reg_2;
:
:
return 0;
}
Código 8.2: Declaración de variables locales de tipo registro
int main(void){
registro reg_1, reg_2;
:
8.2. DEFINICIÓN DE UN REGISTRO EMPLEANDO ALIAS. 77
:
return 0;
}
int main(void){
ejemplar reg_1, reg_2;
:
:
return 0;
}
de una persona deberá guardarse en un registro que incluya los campos de: año,
mes y dia.
Entrada Salida
Nombre: Susana Susana tiene un peso: 66.50 kg;
Peso:66.50 su fecha de nacimiento es
Dia de nacimiento: 13 13/6/1966
Mes de nacimiento: 6
Anio de nacimiento: 1966
Nombre: Daniel Daniel tiene un peso: 77.80 kg;
Peso:77.80 su fecha de nacimiento es
Dia de nacimiento: 19 19/10/1974
Mes de nacimiento: 10
Anio de nacimiento: 1974
#include<stdio.h>
typedef struct{
int anio;
int mes;
int dia;
}fecha;
typedef struct{
char nombre[30];
float peso;
fecha nace;
}persona;
int main(void){
persona p1, p2;
printf("Lectura de datos de dos personas \n");
leerPersona(&p1);
leerPersona(&p2);
imprPersona(p1);
imprPersona(p2);
return 0;
}
printf("----------------------------------");
printf("\nNombre: ");
scanf(" %s", una_persona->nombre);
fflush(stdin);
printf("\nPeso: ");
scanf(" %f", &una_persona->peso);
printf("\nDia de su nacimiento: ");
scanf(" %d", &una_persona->nace.dia);
printf("\nMes de su nacimiento: ");
scanf(" %d", &una_persona->nace.mes);
printf("\nAnio de su nacimiento: ");
scanf(" %d", &una_persona->nace.anio);
return;
}
nace); sin embargo, también es posible definir arreglos de registros, lo cual resulta
útil cuando se desea manipular numerosos registros de un mismo tipo.
Observe que el paso de parámetros por valor y por referencia también se aplica
en el manejo de registros. En el paso de parámetros por referencia, empleamos los
operadores: (∗) para declarar una variable de tipo apuntador a registro; (&) para
referirnos a la dirección de una variable tipo registro; y (∗) para referirnos al valor
al cual apunta la variable apuntador a registro. Ver el capı́tulo ?? para detalles del
manejo de apuntadores.
La figura 8.2 muestra las combinaciones que podemos realizar entre arreglos y
registros.
Registros con arreglos; es decir, al definir un registro uno más campos pue-
den ser de tipo arreglo unidimensional, arreglo bidimensional o cadena.
Entrada Salida
Nombre: Sergio Sergio tiene un peso de 56.50 kg;
Peso:56.50 la fecha de su nacimiento es
Dia de nacimiento: 23 23/9/1986
Mes de nacimiento: 9
Anio de nacimiento: 1986
Nombre: Arturo Arturo tiene un peso de 87.80 kg;
Peso:87.80 la fecha de su nacimiento es
Dia de nacimiento: 14 14/8/1976
Mes de nacimiento: 8
Anio de nacimiento: 1976
Nombre: Mario Mario tiene un peso de 98.30 Kg;
Peso:98.30 la fecha de su nacimiento es
Dia de nacimiento: 3 3/6/1973
Mes de nacimiento: 6
Anio de nacimiento: 1973
#include<stdio.h>
#define MAX 3
typedef struct{
int anio;
int mes;
int dia;
}fecha;
typedef struct{
char nombre[30];
float peso;
fecha nace;
}persona;
int main(void){
persona alumnos[MAX];
printf("\nLectura de datos de un grupo de alumnos \n");
leerPersona(alumnos);
printf("\n\nLos datos de los alumnos recien ingresados son: \n");
imprPersona(alumnos);
return 0;
}
Archivos
Las cosas se simplifican cuando separamos el programa de los datos con los que
opera, si los datos se mantienen en archivos aparte y los problemas vuelven a ser
cortos y simples de leer. Tenemos varios tipos de archivos, aquellos que usaremos
para consulta, otros que usaremos para poner la información de una ejecución en
el mismo, y también archivos ya existentes donde se agregarán los datos recién
procesados.
83
84 CAPÍTULO 9. ARCHIVOS
Función Descripción
fopen() Abrir archivo
fclose() Cerrar un archivo
fputc() Escribir un carácter en el archivo
fgetc() Lee un carácter de un archivo
fputs() Escribir una cadena en un archivo
fprintf() Imprimir a un archivo
fscanf() Leer sobre un archivo
feof() Devuelve cierto cuando llega al fin del archivo
ferror() Devuelve vierto si se ha producido un error
rewind() Colocar el indicador de posición de un archivo al principio
del mismo
remove() Eliminar un archivo
fflush() Vaciar el buffer que sirve para leer o escribir en el archivo
texto.txt; posteriormente, deberá cerrarse este archivo. La tabla 9.3 muestra dos
ejemplos.
#include <stdio.h>
int main(void){
char car;
FILE *ap;
printf("Escriba una cadena para ser guardada en un archivo");
printf("\n El fin de la cadena lo marca un <ENTER>\n");
ap=fopen("texto.txt","w");
if (ap!=NULL){
while ((car=getchar())!=’\n’){
fputc(car,ap);
}
fclose(ap);
}
else printf("No se puede abrir el archivo");
return 0;
}
#include <stdio.h>
int main(void){
char car;
FILE *ap;
if ((ap=fopen("prueba.txt","r"))!=NULL){
while (!feof(ap)){
car=fgetc(ap);
putchar(car);
}
fclose (ap);
}
else printf("No se puede abrir el archivo");
printf("\n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include<stdio.h>
#include<stdlib.h>
Entrada Salida
Pasaré el curso sin tener que estudiar? Lo dudo mucho
En verdad adivinas el futuro? Mejor no te digo ahora
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
int main(void){
char preg[100]={ }, resp[20][50];
srand(time(NULL));
printf("\n\n Este programa es magico, respondera a tus preguntas \n");
leeArchivo(resp);
do{
generaPreg(preg);
if(strcmp(preg,"fin") && strcmp(preg,"FIN"))
generaResp(resp);
}while(strcmp(preg,"fin") && strcmp(preg,"FIN"));
return 0;
}
fflush(stdin);
fgets(resp[i], 49, arch);
i++;
}
}
return;
}
como lo veo... si
Es seguro
Decididamente si
Es lo mas probable
Positivamente
Parece ser que si
Sin lugar a dudas
Si
Si - definitivo
Puedes confiar en eso
Respuesta ambigua... intente de nuevo
Preguntame despues
Mejor no te digo ahora
No puedo predecirlo ahora
Concentrate y vuelve a preguntar
No cuentes con ello
Mi respuesta es no
Mis fuentes dicen que no
No parece que pase
Lo dudo mucho
Programa 8.6: Precios con IVA Una papelerı́a necesita contar con un programa
que le permita obtener la lista de sus precios con el Impuesto al Valor Agregado
(IVA) correspondiente. El usuario deberá proporcionar el nombre del archivo don-
de se encuentran los precios originales en forma de lista; el programa debe calcular
los nuevos precios con IVA y colocarlos en el archivo que le indique el usuario.
9.2. FUNCIONES USUALES PARA EL MANEJO DE ARCHIVOS 91
#include<stdio.h>
#include<stdlib.h>
#define MAX 50
#define LON 15
int main(void){
float precios[MAX]={0.0}, total=0.0;
int tam=0;
tam = cargaDatos(precios);
total = calculaTotal(precios, tam-1);
guardaDatos(precios, total, tam-1);
return(0);
}
Especificación: El programa debe estar formado por: 1) una función que per-
mita consultar los registros que están guardados en un archivo; 2) una función que
permita modificar alguno de los registros; y 3) una función que permita agregar
un nuevo registro. El nombre del archivo lo proporciona el usuario. La tabla 9.9
muestra el archivo alumnos.txt y el menú que se espera proporcione el programa
al usuario; la tabla 9.10 muestra dos ejemplos para las operaciones de ”agregar
registro” y “consultar registro”.
2. Consultar registro
3. Modificar registro
Tabla 9.9 Archivo de entrada y menú de operaciones sobre la información del archivo
Opción Salida
1 (Agregar registro) Nombre: Luis Robles Pérez
Peso: 45.67
Dia nacimiento:4
Mes nacimiento:6
Anio nacimiento:1967
2 (Consultar registros) Ramiro Felix Reyes tiene un peso
de 56.76 kg; su fecha de nacimiento
es 7/12/1965
#include<stdio.h>
#include<stdlib.h>
#define MAX 50
#define LON 15
#define TRUE 1
94 CAPÍTULO 9. ARCHIVOS
#define FALSE 0
typedef struct{
int anio;
int mes;
int dia;
}fecha;
typedef struct{
char nombre[LON];
char paterno[LON];
char materno[LON];
float peso;
fecha nace;
}persona;
char menu(void);
void consultar(char* nom);
void agregar(char* nom);
void modificar(char* nom);
int cargaDatos(persona* alumnos, char* nom);
void imprPersona(persona* alumnos, int tam);
void leerPersona(persona* alumnos, int i);
void guardaDatos(persona* alumnos, int tam, char* nom, int agrega);
void nombreArchivo(char* nom);
int main(void){
char opcion=’ ’, nom[LON];
nombreArchivo(nom);
while((opcion= menu())!=’Z’ && opcion!=’z’){
switch(opcion){
case ’a’: case ’A’:
agregar(nom);
printf("-----Fin de la operacion agregar.....\n\n");
break;
case ’b’: case ’B’:
consultar(nom);
printf("-----Fin de la operacion consultar.....\n\n");
break;
case ’c’: case ’C’:
modificar(nom);
printf("-----Fin de la operacion modificar.....\n\n");
break;
default:
printf("Opcion no valida!!!!!!\n"); break;
}
}
return 0;
}
char menu(void){
char opcion=’ ’;
printf("\n\n Registro de alumnos\n");
printf("\nA) Agregar registros de alumnos a un archivo.\n");
printf("\nB) Consultar los registros de alumnos de un archivo.\n");
9.2. FUNCIONES USUALES PARA EL MANEJO DE ARCHIVOS 95
Petición Descripción
login: annie Primero me solicitará el usuario
con el cual fui registrado en el
servidor
password: A continuación me solicitará la
x32jh88a contraseña del mismo usuario
99
100 CAPÍTULO 10. INTRODUCCIÓN AL SISTEMA OPERATIVO UNIX
Distinguimos dos tipos de rutas para acceder a un directorio del árbol: ruta
absoluta y ruta relativa.
Ruta absoluta o completa: describe la ruta a seguir desde la raı́z del árbol
hasta el archivo o directorio al que deseamos referirnos en algún comando.
Ruta relativa: describe la ruta a seguir desde el directorio de trabajo donde
nos encontramos hasta el archivo o directorio al que deseamos referirnos en
10.2. COMANDOS BÁSICOS 101
algún comando.
La tabla 10.2 muestra las rutas absoluta y relativa cuando el directorio de trabajo
actual es /users/profesores. Con ruta ./ nos referimos al directorio actual. Con la
ruta ./long john nos referimos al hijo long john de pro f esores. Con la ruta longjoh-
n/programas nos referimos al directorio de programas que es nieto del directorio
de pro f esores.
La tabla 10.3 muestra las rutas absoluta y relativa cuando el directorio de tra-
bajo actual es /users/profesores/longjohn/clase. Con la ruta ../programas nos re-
ferimos al directorio programas que es hermano del directorio clase. Con la ruta
../../ nos referimos al directorio profesores que es abuelo del directorio clase. Con
la ruta ../../annie nos referimos al directorio annie que es tı́o del directorio clase.
(a) TIPO. Los tipos de archivo más comunes se muestran en la tabla 10.6:
Tipo Descripción
- Archivos ordinarios, tales como los
que creamos en lenguaje C
d Directorios
l Para indicar los enlaces simbólicos
(b) PERMISOS. Los derechos sobre un archivo se asignan a los roles: propietario,
grupo y otros (ver tabla 10.7). Los derechos posibles sobre un archivo son:
lectura (r − read), escritura (w − write) y ejecución (x − execute)
(i) NOMBRE DEL ARCHIVO. Indica el nombre del archivo o del directorio
Ejemplo 1
$ ls -l
total 906
-rw-r–r-x 1 longjohn profesor 666 Feb 12 2010 MCD.cpp
-rwxr-xr-x 1 longjohn profesor 10080 Feb 12 2010 MCD.exe
drwxr-xr-x 2 longjohn profesor 512 Feb 11 2009 programas
drwxr-xr-x 2 longjohn profesor 712 Feb 11 2009 tareas
Ejemplo 2
$ ls -Rl
total 906
-rw-r–r– 1 longjohn profesor 649 Feb 12 2010 MCD-B.cpp
-rwxr-xr-x 1 longjohn profesor 10084 Feb 12 2010 MCD-B.exe
-rw-r–r– 1 longjohn profesor 666 Feb 12 2010 MCD.cpp
-rwxr-xr-x 1 longjohn profesor 10080 Feb 12 2010 MCD.exe
./programas:
total 16
-rw-r–r– 1 longjohn profesor 503 Jan 28 2011 pirinola.c
-rwxr-xr-x 1 longjohn profesor 6536 Jan 28 2011 pirinola.exe
./tareas:
total 54
-rwxr-xr-x 1 longjohn profesor 8340 Jun 5 2007 distancia.exe
-rw-r–r– 1 longjohn profesor 3254 Jun 5 2007 distancia.c
-rwxr-xr-x 1 longjohn profesor 8520 Jun 5 2007 laminar.exe
-rw-r–r– 1 longjohn profesor 4298 Jun 5 2007 laminar.c
Modificador Descripción
-a Muestra todas los archivos, incluyendo aque-
llos que son ocultos
-C Muestra los nombres de archivos en columnas
-c Muestra todos los archivos ordenados por fe-
cha de creación
-u Muestra todos los archivos ordenados por la
fecha del último acceso
-R Muestra el contenido de los directorios
-p Distingue a los directorios de los archivos or-
dinarios a través de “/“, colocado al final del
nombre
Ejemplo 1
$ who
ip-18-03 pts/11 Feb 13 13:13 (172.16.2.61)
ip-16-18 pts/12 Feb 13 13:19 (172.16.20.58)
cbrrn pts/14 Feb 13 10:28 (172.17.12.82)
longjohn pts/15 Feb 13 10:40 (172.17.20.128)
ip-20-13 pts/17 Feb 13 13:28 (172.16.2.36)
ip-21-33 pts/18 Feb 13 13:36 (172.16.20.58)
ip-9-02 pts/19 Feb 13 12:13 (172.17.20.128)
Ejemplo 2
$ who am i
longjohn pts/15 Feb 13 10:40 (172.17.20.128)
Observe que clase es un subdirectorio del directorio de trabajo long john; es decir,
cuando estamos en un directorio especı́fico podemos acceder a sus subdirectorios
con solo escribir:
$cd [directorio]
$cd [ruta_absoluta]
$cd [..|../directorio]
Ejemplo 1
D. inicial <[email protected]>
</users/profesores/longjohn>
$ cd clase
D.actual <[email protected]>
</users/profesores/longjohn/clase>
Ejemplo 2
D. inicial <[email protected]>
</users/profesores/longjohn/clase>
$ cd /users/profesores/longjohn/programas
D. actual <[email protected]>
</users/profesores/longjohn/programas>
Ejemplo 3
D. inicial <[email protected]>
</users/profesores/longjohn/clase>
$ cd ../programas
D. actual <[email protected]>
</users/profesores/longjohn/programas>
Ejemplo 4
D. inicial <[email protected]>
</users/profesores/longjohn/clase>
$ cd /
D. actual <[email protected]>
</>
Ejemplo 1
<[email protected]>
</users/profesores/longjohn/clase> Directorio actual clase
$ mkdir archivos Crear directorio archivos en
clase
Ejemplo 2
<[email protected]>
</users/profesores/longjohn/clase/archivos> Directorio actual archivos
$ mkdir ../ciclos Crear directorio ciclos en el
directorio padre de archivos a
saber: clase
Ejemplo 3
<[email protected]>
</users/profesores/longjohn/> Directorio actual longjohn
$ mkdir /users/profesores/longjohn/clase/seleccion Crear directorio seleccion en
el directorio clase
Ejemplo 1
<[email protected]>
</users/profesores/longjohn/clase/seleccion> Directorio actual seleccion
$ rm calculadora.c Eliminar el archivo calcula-
dora del directorio actual
Ejemplo 2
<[email protected]>
</users/profesores/longjohn/clase/archivos> Directorio actual archivos
$ rm -i *.txt Eliminar archivos con exten-
sion txt del directorio actual
Ejemplo 3
<[email protected]>
</users/profesores/longjohn/> Directorio actual longjohn
$ rm ./clase/fuente.txt Eliminar archivo fuente.txt
del directorio clase
Ejemplo 1
<[email protected]>
</users/profesores/longjohn/clase/archivos> Directorio actual archivos
$ mv oficio.txt reporte.txt cambia de nombre oficio.txt a
reporte.txt
Ejemplo 2
<[email protected]>
</users/profesores/longjohn/clase/archivos> Directorio actual archivos
$ mv prueba.txt ../seleccion/datos.txt Mueve el archivo prueba.txt
al directorio seleccion con el
nombre datos.txt
Ejemplo 3
<[email protected]>
</users/profesores/longjohn/clase> Directorio actual clase
$ mv if ./seleccion Mover todos los archivos que
inician con if al directorio se-
leccion
Ejemplo 4
<[email protected]>
</users/profesores/longjohn/> Directorio actual longjohn
$ mv ./clase/multiple ./clase/seleccion Mover el directorio multiple
al directorio seleccion
Ejemplo 1
<[email protected]>
</users/profesores/longjohn/clase/archivos> Directorio actual archivos
$ cp reporte.txt reporte-ver01.txt copia el conteindo del ar-
chivo reporte.txt a reporte-
ver01.txt
Ejemplo 2
<[email protected]>
</users/profesores/longjohn/clase/seleccion> Directorio actual seleccion
$ cp prueba.txt ../archivos copia el archivo prueba.txt
al directorio archivos con el
mismo nombre
Ejemplo 3
<[email protected]>
</users/profesores/longjohn/clase> Directorio actual clase
$ mv *.c ./seleccion copia todos los archivos cu-
ya extensión es .c al directo-
rio seleccion
Ejemplo 4
<[email protected]>
</users/profesores/longjohn/clase/archivos> Directorio actual archivos
$ cp -R ./juegos ../ copia el contenido del direc-
torio juegos, incluyendo sus
subdirectorios, al directorio
clase
$man ps
10.2. COMANDOS BÁSICOS 113
$ man ps
NAME
ps - report process status
SYNOPSIS
ps [-aAcdefjlLPy] [-g grplist] [-n namelist] [-o format]...
[-p proclist] [-s sidlist] [-t term] [-u uidlist]
[U uidlist] [-G gidlist]
DESCRIPTION
The ps command prints information about active processes.
Without options, ps prints information about processes that
have the same effective user ID and the same controlling
terminal as the invoker. The output contains only the pro-
cess ID, terminal identifier, cumulative execution time, and
the command name. Otherwise, the information that is
displayed is controlled by the options.