Professional Documents
Culture Documents
FUNDAMENTOS DE PROGRAMACIÓN
Tema 5
Estructuras Estáticas
__________________________________________________________________________________________________________
Estructuras Estáticas 1
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
1. INTRODUCCIÓN.
Hasta ahora, los datos manejados en los programas han sido los denominados
datos simples (numéricos, carácter, ...). En numerosas ocasiones es necesario utilizar un
conjunto de datos relacionados entre sí. Por ejemplo, si se quiere manipular una lista de
100 edades de personas, es conveniente tratar este conjunto de datos de forma unitaria
en lugar de utilizar 100 variables, una para cada edad.
Un conjunto de datos homogéneos (del mismo tipo) que se tratan como una sola
unidad se denomina estructura de datos.
Si una estructura de datos reside en la memoria central del ordenador se
denomina estructura de datos interna. Recíprocamente, si reside en un soporte
externo, se denomina estructura de datos externa.
Las estructuras de datos internas pueden ser de dos tipos:
Una tabla consiste en un número fijo y finito de elementos, todos del mismo
tipo y bajo un nombre común para todos ellos.
Nombre
0 1 2 3 4 5 6 7 ... N-1 (índice)
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│Val.1│Val.2│Val.3│Val.4│Val.5│Val.6│Val.7│Val.8│ ... │Val.N│
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
↑ ↑
1.er elemento enésimo elemento
__________________________________________________________________________________________________________
Estructuras Estáticas 2
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
- Unidimensionales
- Bidimensionales
- Multidimensionales
Cuando en un programa el número de datos del mismo tipo, que mantengan una
relación “ordenada” entre ellos, aumenta un poco, no interesa definir una variable para
cada uno de ellos ya que la proliferación de las mismas llevaría a la confusión y
resultaría dificultoso su manejo. Por ejemplo, para hallar la media de diez notas no sería
eficiente definir diez variables de la forma n1, n2, n3 ...n10. Por tanto, para manejar en
memoria interna un número mediano o grande de datos es conveniente recurrir a
estructuras complejas de datos como son las tablas.
1. Cada uno de los elementos de una tabla se referencia por un nombre común a
todos ellos y por uno o varios índices particulares, que determinan su posición
relativa en la memoria, dentro del conjunto de elementos de la tabla. Hay que
tener en cuenta que en C el primer índice que se puede utilizar es el que tiene el
valor 0 y que el nombre de una tabla es un puntero a la dirección de
memoria de comienzo de la tabla .
3. El nombre de una tabla (idéntico al de cada uno de sus elementos) sigue las
mismas reglas de formación que conocemos para identificadores de variables.
5. Los índices deben ser números enteros; señalan el orden relativo en que están
almacenados los elementos de la tabla. El número de índices determina la
dimensión de la tabla:
__________________________________________________________________________________________________________
Estructuras Estáticas 4
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
11. Las operaciones que se suelen realizar habitualmente sobre una tabla son:
__________________________________________________________________________________________________________
Estructuras Estáticas 5
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
También se pueden insertar y/o borrar elementos de la tabla, pero sólo de una
forma lógica, nunca física.
Puesto que las tablas son habitualmente fáciles de recorrer y de buscar en ellas y
de ordenar, suelen utilizarse para almacenar conjuntos de datos relativamente fijos.
3. TABLAS UNIDIMENSIONALES:VECTORES.
• Concepto
Los vectores son tablas de una sola dimensión, es decir, cada elemento del
vector se referencia mediante el nombre de la tabla y un solo índice.
Los índices son números enteros y consecutivos que indican la posición relativa
de cada uno de los elementos dentro del vector. El valor del primer índice (en el
lenguaje C) es el 0 y no se puede variar.
El identificador de cada elemento (nombre e índice) determina la posición de
memoria donde se encuentra almacenado su contenido o valor.
El vector se denomina tabla unidimensional porque tiene un sólo índice de
referencia, es decir, una sola dimensión.
• Definición
- Clase de almacenamiento
- Tipo de cada uno de los elementos
- Identificador del vector
- Número de elementos (entre corchetes, en C).
El formato es:
Ejemplo:
int meses[12];
Ejemplo:
short int meses[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
Cuando el número de valores es menor que el tamaño del vector, el resto de los
elementos no inicializados lo hacen a 0. En cambio, si el número de valores es mayor
que el tamaño declarado se produce un error.
Si se emplean corchetes vacíos cuando se inicializa un vector, el compilador
cuenta el número de valores de la lista, y ese será su tamaño.
Por otra parte, el operador sizeof proporciona el tamaño en bytes del vector.
Por ejemplo:
#include <stdio.h>
#include <conio.h>
short int meses[]={31,28,31,30,31,30,31,31,30,31,30,31};
void main(void)
{
int indice;
extern short int meses[]; //declaracion opcional
for(indice=0; indice < sizeof meses/(sizeof(short int));indice++)
printf ("Mes %2d = %d dias.\n", indice+1, meses[indice]);
getch();
}
Cuando se quiere pasar una tabla unidimensional a una función hay que pasarle
la dirección del primer elemento pues en C no se puede pasar el vector completo como
argumento a una función. El parámetro actual puede ser el nombre del vector o la
dirección de memoria del primer elemento. El parámetro formal se puede declarar como
un vector no delimitado (aunque también puede ser el puntero constante
__________________________________________________________________________________________________________
Estructuras Estáticas 7
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
#include <stdio.h>
#include <conio.h>
#define NUM_ALUMNOS 10
float fmedia2 (float vector[] , int);
float fmedia (float vector[] , int);
void main(void)
{
float notas[NUM_ALUMNOS], nota_media;
int i;
for (i=0; i < NUM_ALUMNOS; i++ )
{
printf("NOTA %d : ",i+1);
scanf("%f", ¬as[i]); // scanf necesita la dirección
}
nota_media = fmedia (¬as[0], NUM_ALUMNOS);
//Tb. nota_media=fmedia(notas,NUM_ALUMNOS);
printf("Nota media = %5.2f ", nota_media );
getch();
}
/* fmedia es una función general que halla la media de los elementos
de cualquier vector de tipo entero. También es válido:
float fmedia (float vector[10], int num_elem )*/
__________________________________________________________________________________________________________
Estructuras Estáticas 9
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
Todos los métodos relacionados aquí se utilizan con estructuras de datos internas
unidimensionales (tablas), es decir, no se utilizan para el caso de ficheros en disco.
Además, por claridad se utilizan datos numéricos en las tablas, lo cual no quiere decir
que no pueda hacerse con cualquier otro tipo de datos donde pueda establecerse una ley
de ordenación (caracteres, cadenas, etc).
Se considera que en los vectores no hay valores repetidos (considérense las
diferencias que puedan haber en cada caso si no se cumple esta premisa).
#define N 10
int v[N];
else
return -1;
}
Para su realización utilizamos tres variables que nos indican en qué zona del
vector nos encontramos. Son estas variables:
1.- Se saca del vector el elemento I-ésimo (aux es una variable que lo recibe).
__________________________________________________________________________________________________________
Estructuras Estáticas 12
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
- aux es una variable auxiliar del mismo tipo que los elementos del vector que
contendrá el valor del elemento i-ésimo que vamos a tratar.
- i apunta al elemento que vamos a tratar.
- j apunta a los elementos anteriores.
Este método tiene dos versiones basadas en la misma idea, que consiste en
“recorrer sucesivamente el vector comparando los elementos consecutivos e
intercambiándolos cuando estén descolocados”. El recorrido del vector se puede
hacer de izquierda a derecha (desplazando los valores mayores hacia su derecha) o de
derecha a izquierda (desplazando los valores menores hacia su izquierda), ambos para la
clasificación en orden ascendente. A continuación veremos el método con recorrido
izquierda-derecha.
Consiste en realizar pasadas sucesivas direccionando desde el primer elemento
hasta el penúltimo, comparando cada uno de ellos con el siguiente.
Esta versión del método va colocando en cada pasada el menor elemento de los
tratados en la primera posición, quedando colocado y por tanto excluido de los
elementos a tratar en la siguiente pasada:
__________________________________________________________________________________________________________
Estructuras Estáticas 13
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
for (j=elem-1;j>i;j--)
if (v[j]<v[j-1])
{
aux=v[j];
v[j]=v[j-1];
v[j-1]=aux;
}
}
EJERCICIO.-
Como ejercicio de tratamiento de vectores, el alumno debe implementar un
algoritmo de ordenación que no se ha visto anteriormente: la ordenación por Selección
Directa. A continuación se expresa con palabras su funcionamiento:
El método consiste en “repetir el siguiente proceso desde el primer elemento
hasta el penúltimo: se selecciona el componente de menor valor de todos los
situados a la derecha del tratado y se intercambia con éste”.
En realidad se trata de sucesivas búsquedas del menor de los elementos que
quedan por ordenar.
Para la realización del intercambio se utiliza una variable auxiliar aux.
5. CADENAS.
El lenguaje C no dispone de un tipo especial para cadenas, sino que las cadenas
son vectores de caracteres (de tipo char) que terminan con el carácter nulo, o sea,
‘\0‘ .
De todos modos, el lenguaje C soporta la mayoría de las funciones más potentes
de manipulación de cadenas que aparecen en cualquier lenguaje.
Existen muchas formas diferentes de definir en C una cadena o tira. Veámoslas.
__________________________________________________________________________________________________________
Estructuras Estáticas 15
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
• Cadenas constantes
Ejemplo:
#define VOCALES "aeiou"
.........
puts(VOCALES);
puts("Esta es una tira");
printf(“%s\n%s\n”, VOCALES, "Esta es otra tira");
Ejemplo:
• Vectores de caracteres.
char nombre[81];
donde nombre es un vector para ser leído en tiempo ejecución. Aquí se tiene que
declarar obligatoriamente el tamaño, y se deberá controlar la entrada de caracteres para
que su número no sobrepase el espacio reservado (el tamaño menos 1). En el ejemplo
anterior, nombre puede almacenar hasta 80 caracteres como máximo más el carácter
nulo; en total, 81 caracteres.
• Función gets()
Su prototipo es:
• Función puts()
La función puts() da salida sólo a cadenas y por ello es más simple que
printf() por lo que deberemos emplearla siempre que sea posible pues así se añade
menos código a nuestro programa y se ejecuta más rápidamente que si se emplea esta
última.
Hay que tener en cuenta que puts() añade automáticamente un retorno de
carro, lo que no hace printf()
Su prototipo es:
#include <stdio.h>
#include <conio.h>
void main (void)
{
char nom_mes[16], nom_dia[21], nom_ape[51];
puts("Introduzca cada dato seguido de INTRO");
puts("(si se permiten espacios)");
puts("");
puts("Nombre y apellidos (max. 50 car.): ");
gets(nom_ape);
puts("Nombre de un mes (max. 15 car.): ");
gets(nom_mes);
puts("Nombre de un día de la semana (max. 20 car.): ");
gets(nom_dia);
printf("\n\n");
puts(nom_ape);
puts("encuentre los días de este año que caen en ...");
puts (nom_dia);
puts ("y pertenecen al mes...");
puts (nom_mes);
getch();
}
• Función strcat()
Esta función concatena una copia de cad2 al final de cad1 y añade al final de
cad1 un carácter nulo. El carácter nulo que inicialmente finalizaba la cadena cad1 es
sobrescrito por el primer carácter de cad2. La cadena cad2 no se modifica con esta
operación. Esta función devuelve cad1. Resumiendo, al final en cad1 queda: cad1 +
cad2.
__________________________________________________________________________________________________________
Estructuras Estáticas 18
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
• Función strcmp()
• Función strcpy()
Esta función se utiliza para copiar el contenido de cad2 en cad1; cad2 debe ser
un puntero a una cadena que termine en un carácter nulo. Además, devuelve un puntero
a cad1.
Si cad1 y cad2 se solapan, el comportamiento de la función es indefinido.
• Función strncat()
El tipo size_t está definido, mediante typedef, como un entero sin signo.
• Función strncpy()
__________________________________________________________________________________________________________
Estructuras Estáticas 19
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
• Función strnset()
Esta función define los primeros cuenta caracteres de la cadena apuntada por cad
con el valor de c. Esta función devuelve cad.
• Función strstr()
• Macro isalnum ( )
• Macro isalpha ( )
• Macro isdigit ( )
__________________________________________________________________________________________________________
Estructuras Estáticas 20
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
• Macro islower ( )
• Macro ispunct ( )
• Macro isspace ( )
• Macro isupper ( )
• Función tolower ( )
• Función toupper ( )
__________________________________________________________________________________________________________
Estructuras Estáticas 21
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
tipo nombre_array[tamaño_primera_dimension][tamaño_segunda_dimension];
Ejemplo: Para almacenar datos de la lluvia caída cada mes durante 5 años definimos:
Para inicializar una matriz se colocan los valores de cada fila entre llaves y
separados por comas. Los valores de diferentes filas se separan por comas. Todo el
conjunto se encierra entre un par de llaves externo.
Ejemplo: La definición...
int puntos[3][4]={{1,9,3,8},{2,6,4,6},{9,0,1,2}};
Ocurre que si entre un par de llaves hay más elementos de los declarados se
producirá un error; pero si hay menos, los elementos restantes se incializarán a 0 por
defecto.
Ejemplo: La definición...
Hay que tener en cuenta que cuando no se colocan llaves internas la tabla
bidimensional se va llenando en orden por filas.
Ejemplo: La definición...
0 1 2 3
0 1 2 5 6
1 7 2 0 0
2 0 0 0 0
#include <stdio.h>
#include <conio.h>
#define MAX_ALUMNOS 15
#define MAX_ASIGNATURAS 6
void main(void)
{
int i, j, notas[MAX_ALUMNOS][MAX_ASIGNATURAS]={{6,7,6},{5,3,2},{7,5,4,2,3}};
printf("ALUMNO RAL FP SMM FOL REL
IEA\n\n");
for (i = 0 ; i < MAX_ALUMNOS ; i++)
{
printf("\n%4d) ", i+1); //numero del alumno
for (j = 0 ; j < MAX_ASIGNATURAS ; j++)
printf("%8d", notas[i][j]);
}
getch();
}
__________________________________________________________________________________________________________
Estructuras Estáticas 23
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#define ASIGNAT 3
#define ALUMNOS 5
void ver_notas(int n[][ALUMNOS]);
void leer_notas(int n[][ALUMNOS]);
void main(void)
{
char ch;
int notas[ASIGNAT][ALUMNOS]={0};
do
{
do
{
clrscr();
printf("(E)ntrar notas\n");
printf("(M)ostrar notas\n");
printf("(S)alir\n");
ch = toupper(getch());
}
while(ch!='E' && ch!='M' && ch!='S');
clrscr();
switch(ch)
{
case 'E': leer_notas(notas);
break;
case 'M': ver_notas(notas);
break;
}
}
while (ch != 'S');
}
//*****************************************************
void leer_notas(int n[][ALUMNOS])
{
int asig, i, nota;
for(asig=0; asig < ASIGNAT; asig++)
{
printf("\n\nAsignatura %d: \n", asig + 1);
for(i=0; i< ALUMNOS; ++i)
{
do
{
printf("\nAlumno %d : ", i+1);
nota = getche();
}
while (nota <'0' || nota >'9');
n[asig][i] = nota -'0'; //Equivale scanf("%d", n[asig]+i);
}
}
}
//*****************************************************
void ver_notas (int g[][ALUMNOS])
{
int asig, i;
for(asig=0; asig < ASIGNAT; ++asig)
{
printf("\n\nAsignatura %d: \n", asig + 1);
for(i=0; i < ALUMNOS; ++i)
printf("%d) %d ",i+1, g[asig][i]);
__________________________________________________________________________________________________________
Estructuras Estáticas 24
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
}
getch();
}
#define FILA 3
#define COLU 4
#define PAGI 2
void ver_array( int [][COLU][PAGI], int , int , int );
void main(void)
{
int tridi[FILA][COLU][PAGI]={{{9,10},{11,12},{13,14},{15,16}},
{{17,18},{19,20},{21,22},{23,24}},
{{25,26},{27,28},{29,30},{31,32}}};
int f, c, p ;
for (p=0; p< PAGI; p++) //Muestra el poliedro por páginas
{
printf("PAGINA %d\n", p);
for (f=0; f < FILA; f++)
{
for (c=0; c < COLU ; c++ )
printf("%5d", tridi[f][c] [p]);
printf("\n");
}
}
for (p=0; p< PAGI; p++) //los bucles se pueden poner en
for (f=0; f< FILA; f++) // cualquier orden
for (c=0; c < COLU ; c++ ) tridi[f][c][p] += 5 ;
//Suma 5 a cada elemento
printf("\n\nEl array modificado es...\n");
ver_array (tridi, FILA, COLU, PAGI);
getch();
}
//*****************************************
void ver_array(int arr[][COLU][PAGI], int fil, int col, int pag )
{
int p,f,c;
for (p=0; p< pag; p++) //Muestra el poliedro por páginas
{
printf("PAGINA %d\n", p);
for (f=0; f < fil; f++)
{
for (c=0; c < col ; c++ )
printf("%5d", arr[f][c] [p]);
printf("\n");
}
}
}
Al igual que ocurre con las tablas bidimensionales, cuando se pasa una tabla
tridimensional a una función, el argumento efectivo es el nombre de la tabla y en los
argumentos formales se puede especificar una tabla en la que hay que especificar
obligatoriamente todas las dimensiones, excepto la primera.
__________________________________________________________________________________________________________
Estructuras Estáticas 25
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
Ejemplo:
En una lista de personas la información relativa al nombre, dirección, etc. se
representa, normalmente, como una estructura. En el siguiente fragmento de
código se muestra cómo declarar una estructura como una plantilla que
contenga dichos campos.
struct agenda
{
char nombre[30];
char calle[40];
char ciudad[20];
char provincia[15];
char codigo[5];
char telefono[9];
int importe;
};
__________________________________________________________________________________________________________
Estructuras Estáticas 26
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
Ejemplo:
struct mini_agenda
{
char nombre[30];
char telefono[9];
} amigos, clientes, colegas;
Es importante tener siempre presente que cuando se crea una variable de un tipo
estructura, se mantiene una copia de cada miembro de la misma. Por ejemplo, el campo
telefono de clientes está en una zona de memoria distinta y es diferente al campo
telefono de amigos. De hecho, la única relación que existe entre amigos y clientes es
que ambos son una instancia del mismo tipo de estructura. No existe ninguna otra
relación entre ambas.
Si sólo se necesita una variable de un tipo de estructura, no es necesario indicar
la etiqueta al definir la estructura. Esto significa que
struct
{
char titulo[100];
char director[50];
int precio;
} pelicula ;
declara una variable llamada pelicula del tipo de estructura que le precede.
struct etiqueta
{
tipo nombre_variable;
tipo nombre_variable;
tipo nombre_variable;
.............
} variables_de_estructura ;
Ejemplos:
strcpy (cliente_morosos.codigo, “11995");
__________________________________________________________________________________________________________
Estructuras Estáticas 27
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
nombre_de_estructura . nombre_de_miembro
• Asignaciones de estructuras.
Ejemplo:
colegas = amigos;
Esto hace que los miembros de colegas tengan los mismos valores que los
miembros de amigos.
• Tablas de estructuras.
Como ocurre con todas las variables de tipo array, los arrays de estructuras
comienzan con índice 0.
Ejemplos:
Cuando se utiliza una estructura como argumento de una función, ésta se pasa de
forma íntegra mediante el método estándar de llamada por valor. Esto significa que
cualquier modificación del contenido de la estructura que se realice dentro de la función
a la que se pasa, no afectará a la estructura utilizada como argumento.
Cuando se utilice una estructura como parámetro, el aspecto más importante a
tener en cuenta es que el tipo del argumento debe coincidir con el tipo del parámetro. La
mejor forma de conseguir esto consiste en definir una estructura global y, a
continuación, utilizar su nombre de etiqueta para declarar variables de estructura y
parámetros cuando se necesiten.
#include <stdio.h>
#include <conio.h>
#include <math.h>
#define PI 3.14159265358979
struct circulo
{
double xi, yi, xf, yf;
};
void calculos_circulo(struct circulo);
void main(void)
{
struct circulo c1;
clrscr();
printf("Coordenadas del circulo: \n");
printf(" Centro x: ");
scanf("%lf", &c1.xi);
printf(" Centro y: ");
scanf("%lf", &c1.yi);
printf("Pto. exterior x: ");
scanf("%lf", &c1.xf);
printf("Pto. exterior y: ");
scanf("%lf", &c1.yf);
calculos_circulo (c1);
getch();
}
void calculos_circulo( struct circulo circ)
__________________________________________________________________________________________________________
Estructuras Estáticas 29
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
{
double radio, area, proy_x, proy_y, circunferencia;
proy_x = (circ.xf - circ.xi);
proy_y = (circ.yf - circ.yi);
radio = sqrtl( proy_x * proy_x + proy_y * proy_y );
//sqrtl calcula la raíz cuadrada de un double
area = PI * radio * radio;
circunferencia = 2 * PI * radio;
printf("\nRadio: %.3lf\nArea : %.3lf\n", radio, area);
printf("Circunferencia: %.3lf\n", circunferencia);
}
#include <stdio.h>
#include <conio.h>
#include <string.h>
struct datosmotor
{
int cilindros;
float potencia, ccubicos;
};
struct equipamiento
{
char nombre_eq[21];
int precio_eq;
};
struct autos_venta
{
char marca[31];
char modelo[31];
struct datosmotor motor;
int precio;
struct equipamiento opciones[10];
int puertas;
};
void main(void)
{
struct autos_venta coche;
clrscr();
strcpy(coche.marca, "SEAONOSEA");
coche.motor.cilindros = 8;
coche.motor.potencia = 100.5;
strcpy(coche.opciones[0].nombre_eq, "AIRE ACONDICIONADO");
coche.opciones[0].precio_eq = 300000;
printf("Completa los datos\n\n");
printf("Marca %s Modelo: ", coche.marca);
scanf("%s", coche.modelo);
printf("Potencia %.1f Cent. cubicos: ", coche.motor.potencia);
scanf("%d", &coche.motor.ccubicos);
printf("Precio: ");
scanf("%d", &coche.precio);
printf("Tipo de extra: ");
scanf("%s", coche.opciones[1].nombre_eq);
printf("Precio extra: ");
scanf("%d", &coche.opciones[1].precio_eq);
getch();
}
__________________________________________________________________________________________________________
Estructuras Estáticas 30
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
meses == &meses[0]
meses++
Algo semejante sería intentar incrementar una constante numérica, por ejemplo,
el 5, de la forma 5++. Sin embargo, si es factible operar de la siguiente forma:
meses + 1
pt = meses;
y luego...
pt++;
__________________________________________________________________________________________________________
Estructuras Estáticas 31
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
Por tanto, para referirnos a un elemento del vector id_array deberemos usar la
expresión
*(id_array + N - 1)
#include <stdio.h>
#include <conio.h>
short int meses[]={31,28,31,30,31,30,31,31,30,31,30,31};
#define TOPE sizeof (meses) / (sizeof (short int))
void main(void)
{ // Si <indice> comenzara en 1, se emplearía la
int indice;// expresión: * ( meses + indice - 1 )
for(indice=0; indice < TOPE ; indice++)
printf("Mes %2d = %d dias.\n", indice + 1, *(meses + indice) );
getch();
}
#include <stdio.h>
#include <conio.h>
#define NUM_ALUMNOS 10
float fmedia (float * , int); // Observe la declaración de prototipo
void main(void) // especialmente, el puntero: float *
{
float notas[NUM_ALUMNOS], nota_media;
int i;
for (i=0; i < NUM_ALUMNOS; i++ )
{
printf("NOTA %d : ",i+1);
scanf("%f", notas+i); // scanf necesita la dirección
}
nota_media = fmedia (notas, NUM_ALUMNOS);
printf("Nota media = %5.2f ", nota_media );
getch();
}
float fmedia ( float *vector, int num_elem )
__________________________________________________________________________________________________________
Estructuras Estáticas 32
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
{
float totnotas;
int indice;
for (indice=0, totnotas=0.0; indice < num_elem ; indice++)
totnotas += *(vector+indice);
return ( totnotas / num_elem ) ;
}
tira1==&tira1[0]
*tira1=='L'
*(tira1+1)==tira1[1]=='e'
#include <string.h>
#include <stdio.h>
#include <conio.h>
char m3[10];
void main(void)
{
char m1[30]={'L','e','n','g','u','a','j','e',' ','C','\0'};
static char m2[11]="Lenguaje C"; // longitud lógica= 10
caracteres
printf("m3=%s Dir=%u \n\n", m3, m3 );
printf("m1=%s Dir=%u \n", m1, m1 ); // Lenguaje C 4239660
printf(" %c %c\n\n", *m1, *(m1+3) ); // L g
printf("m2=%s Dir=%u\n", m2, m2 ); // Lenguaje C
4239690
printf(" %c %c\n\n", *m2, m2[5] ); // L a
printf("\n\n Long. fisica Long. logica\n");
printf("m1=\t %d \t\t %d \n", sizeof m1, strlen(m1)); // 30 10
printf("m2=\t %d \t\t %d \n", sizeof m2, strlen(m2)); // 11 10
printf("m3=\t %d \t\t %d \n", sizeof m3, strlen(m3)); // 10 0
printf("\n\nAsignando nuevos valores:\n");
// Es ilegal m1 = "aaaa";
// Es ilegal m2 = "bbbbb";
// Es ilegal m3 = "ccccc";
// En su lugar hay que utilizar la función strcpy();
strcpy (m1, "aaaaa");
strcpy (m2, "bbbb");
strcpy (m3, "ccccc");
printf ("m1=%s \nm2=%s \nm3=%s \n ", m1, m2, m3);
getch();
}
• Punteros a char
__________________________________________________________________________________________________________
Estructuras Estáticas 33
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
............
printf("%c",pttira); // L
pttira++;
printf("%c",pttira); // e
*pttira = 'a';
printf("%s",pttira); // anguaje C
..........................
arraytira == &arraytira[0]
*(arraytira + x)
....................
*(arraytira + 9) = 'B';
printf("%s",arraytira); // Lenguaje B
......................
#include <stdio.h>
#include <conio.h>
int long_cad (char * );
void main (void)
{
int long1, long2;
char nombre[40];
char *comida="una hilera de hormigas..."; // 25 caracteres
printf("¿Cómo se llama el oso hormiguero? ");
gets(nombre); // nombre y comida actúan como punteros a
cadenas
long1 = long_cad (nombre);
long2 = long_cad (comida);
printf("%s, que mide %d, se comió ", nombre, long1);
__________________________________________________________________________________________________________
Estructuras Estáticas 34
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
puts(comida);
printf("en total %d.", long2);
getch();
}
//*****************************************************************
int long_cad (char *cadena) //esta función equivale a strlen()
{
char *ptrcad;
ptrcad = cadena;
while (*ptrcad != '\0')
ptrcad++;
return (ptrcad - cadena);
}
Supongamos la definición:
resulta que bid es el nombre de una tabla bidimensional, o sea, bid es un vector de
vectores. Dicho de otra forma: bid contiene 3 elementos, cada uno de los cuales es un
vector de 5 enteros.
4 9 0 0 0 0 0 0 0 0 3 1 0 0 0
bid[0] bid[1] bid[2]
Los punteros que apuntan a cada uno de estos 3 vectores son bid[0], bid[1] y
bid[2].
bid[1] == &bid[1][0]
bid[2] == &bid[2][0]
.....................................
No obstante, hay una diferencia:
Por ello, al sumar 1 a bid[0] obtenemos una dirección 4 bytes superior (la del
elemento siguiente), pero al sumar 1 a bid obtenemos una dirección 20 bytes superior
(la del vector siguiente).
#include <stdio.h>
#include <conio.h>
#define FILA 3
#define COLU 5
void main(void)
{
int tabla[FILA][COLU]= {{21,23,25,27,29},{42,43,44,45,46},{1,2,3,4,5}};
int f,c ;
for (f=0; f< FILA; f++) //Duplica el valor de cada elmto tabla[f][c]
for (c=0; c < COLU ; c++ )
* ( *(tabla+f) + c ) *= 2 ;
for (f=0; f < FILA; f++)
{
for (c=0; c < COLU ; c++ )
printf("%5d", * ( *(tabla+f)+c)); //printf("%5d", tabla[f][c]);
printf("\n");
}
getch();
}
Al igual que bid, la tabla bidimensional tabla del ejemplo anterior se puede
considerar un vector de vectores. Así pues, tabla + 0 apunta a tabla[0] que es un
vector de 5 enteros y que a su vez apunta a tabla[0][0];tabla + 1 apunta a tabla[1]
que es otro vector de 5 enteros y que a su vez apunta a tabla[1][0], etc.
Por último, para acceder al valor que guardan tales elementos, basta aplicar el
operador de indirección.
*( * ( tabla + f ) + c )
__________________________________________________________________________________________________________
Estructuras Estáticas 36
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
• Punteros a estructuras.
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#define DELAY 960000
struct mi_tiempo
{
int horas, minutos, segundos;
};
void actualiza (struct mi_tiempo *t), muestra (struct mi_tiempo *t);
void retraso(void);
void resetea (struct mi_tiempo *t);
int main(void)
{
struct mi_tiempo crono;
unsigned char tecla;
crono.horas = 23;
crono.minutos = 58;
crono.segundos = 55;
while(1)
{actualiza(&crono);
gotoxy(1,1);
muestra(&crono);
if(kbhit())
{
tecla = toupper(getch());
if (tecla == 'R')
resetea(&crono);
else return 0;
}
}
}
void resetea (struct mi_tiempo *t)
{
t->horas = t->minutos = t->segundos = 0;
}
void actualiza (struct mi_tiempo *t)
{
t->segundos++;
if(t->segundos==60)
{
t->segundos = 0;
t->minutos++;
}
if(t->minutos==60)
{
t->minutos = 0;
t->horas++;
}
if(t->horas==24)
t->horas = 0;
retraso();
__________________________________________________________________________________________________________
Estructuras Estáticas 37
I.E.S. Francisco Romero Vargas –Departamento de Informática - Fundamentos de Programación
__________________________________________________________________________________________________________
}
void muestra(struct mi_tiempo *t)
{
printf("%02d:%02d:%02d", t->horas, t->minutos, t->segundos);
}
void retraso(void)
{
long int t;
for(t=1; t<DELAY; ++t) ;
}
#include <stdio.h>
#include <conio.h>
#include <math.h>
#define PI 3.14159265358979
struct circulo
{
double xi, yi, radio;
};
void pidedatos_circulo( struct circulo * );
void main(void)
{
struct circulo c1;
double area, circunferencia;
clrscr;
pidedatos_circulo ( &c1);
area = PI * c1.radio * c1.radio ;
circunferencia = 2 * PI * c1.radio;
printf("\n\nCirculo (%.3lf , %.3lf) Radio=%.3lf\n\n", c1.xi, c1.yi,
c1.radio);
printf("Area: %.3lf \nCircunferencia: %.3lf \n", area, circunferencia );
getch();
}
//*************************************************************************
void pidedatos_circulo ( struct circulo *c )
{
printf("Centro x: ");
scanf("%lf", &c->xi);
printf("Centro y: ");
scanf("%lf", &c->yi);
printf(" Radio: ");
scanf("%lf", &c->radio);
}
__________________________________________________________________________________________________________
Estructuras Estáticas 38