Apuntadores, cadenas y estructuras

Post on 05-Jul-2015

325 views 4 download

Transcript of Apuntadores, cadenas y estructuras

P t

Contenido

(apuntador)

a punteros a constantes

defunciones

… Punteros a punteros

… Direcciones en memoria … Aritmética de punteros… Concepto de puntero … Punteros constantes frente

… Puntero null y void … Punteros como argumento

… Punteros a Arrays … Punteros a funciones

… Arrays de punteros … Punteros a estructuras

… Punteros a cadenas …

Dirección

de memoria

†Int n;

†Asocia al nombre n, el tipoint

y la dirección dealgunaposición de memoria donde se almacena el valor de

n

… Cuando una variable se declara, se asociantres atributos fundamentales con la misma: sunombre, su tipo y su dirección de memoria

P i tf % )

Cont…

†Printf (“%d”,n);

… A la dirección de la variable se accede por mediodeloperador

dedirección &.

Por

ejemplo,

se

puedeimprimir la dirección de n

conla sentencia:†Printf (“%p”,&n);

… Al valor de la variable se accede por medio desu nombre. Por ejemplo, se puede imprimir elvalor de n con la sentencia;

l d

{

Ejemplo 10.1… Obtener el valor y la dirección de una variable

† #include <stdio.h>

† #include <stdlib.h>

† int main ()

† {

† int n=75;

† printf("n=%d\n",n);

† printf("&n=%p\n",&n);

† system("pause");

† return 0;

† }

En posición almacenan datos los apunta puntero

Concepto de puntero (apuntador)… El tipo de variable que almacena una dirección se denomina puntero

… Los punteros se rigen por estas reglas básicas:†Un puntero es una variable como cualquier otra;

enmemoria

†Una variable puntero contiene una dirección que apunta a otraposición

†En esa posición se almacenan los datos a los que apunta el puntero

†Un puntero apunta a una variable de memoria

… Un puntero es una variable que contiene una dirección de memoria

i l d dlib h

i

("& % " &

}

Ejemplo 10.2… #include <stdio.h>

… #include <stdlib.h>

… int main ()

… {

… int n=75;

… int*p=&n;

… printf("n=%d, &n=%p, p=%p\n",n,&n,p);

… printf("&p=%p\n",&p);

… system("PAUSE");

… return 0;

… }

asterisco

Fl t

Declaración de punteros

compilador el tipo de dato alque

apunta elpuntero;para ello s

ehace

preceder

a su

nombre

con

unasterisco

(*)… <tipo de dato apuntado>*<identificador de puntero>

… Float*f;

… Al igual que cualquier variable, las variablespunteros han de ser declaradas antes deutilizarlas. La declaración de una variablepuntero debe indicar al

Inicialización depunteros

dirección del

dato correspondiente.

Para asignar

unadirección de memoria a un puntero se utiliza el

operador de referencia &.

†Int *p;

†P=&i; /*asigna la dirección de i a p*/

†*p=50; /*asigna un valor a la dirección de memoria*/

… &valor†Int i;

… La inicialización de un puntero proporciona a ese punterola

}

Indireccion de punteros… El uso de un puntero

para obtener elvalor

… #include <stdlib.h>

char*pc;

for(c='A';c<='Z';c++)…

printf("\n");…

return0;

… #include <stdio.h>

charc;

… int main()

al que apunta, es decir, … {

su dato apuntado se … pc=&c;

denomina indireccionar …

printf("%c",*pc);

el puntero …

system("pause");

… }

lid

Punteros null y void

valido enmemoria

†Int *ptr=0;

… Los punteros nulos se utilizan confrecuencia punteros

en programas con arraysde

… En C se puede declarar un puntero de modo que apunte acualquier tipo de dato, es decir, no se asigna a un tipo de datoespecifico. El método es declarar el puntero como puntero void*denominado puntero genérico

†Void *prt

… Un puntero nulo no apunta a ninguna parte, no direcciona ningúndato

†#define NULL 0

… Otra forma de declarar un puntero nulo es asignar un valor de 0

Punteros a punteros… Un puntero puede apuntar a otra variable puntero.

Este

concepto se utiliza con mucha frecuencia enprogramas

complejos de C. para declarar un puntero a unpuntero

se hace preceder a la variable con dos asteriscos(**)

†Int valor_e=100;

†Int *ptr1=&valor_e;

†Int **ptr5=&ptr1;

ú i d

Punteros y Arrays

arrays, implica quesede datos enelementos

pueden almacenarcadenasde arrays. Sin punteroseso

no es

posible, yaque

noexiste

el tipo de datocadena

en C. no existen

variables

de cadena,únicamente constantes de cadena

… Se pueden direccionar arrays como sifueran punteros y punteros como si fueranarrays. La posibilidad de almacenar yacceder a punteros y

0

Nombres de arrays como

punteros

Supongamos

que se

tiene

la siguiente

declaración

de unarray:

… In lista[5]={10,20,30,40,50}

visualizar *lista. Como un nombre de un array es unpuntero,

primer elemento del array, se debe indireccionar elpuntero

… Si se manda a visualizar lista[0] se vera 10 y si se mandaa

también se vera 10

… Dado que un nombre de un array contiene ladirección del

para obtener el valor del elemento

… Un nombre de un array es simplemente un puntero.

siguiente un de variables a

Arrays de punteros

contiene

como elementos

punteros,

cada uno

de loscuale

sapunta

a untipo

de datoespecifico.

La lineasiguiente reserva un array de diez variablespuntero aenteros:

… Int *ptr[10];

… Si se necesita reservar muchos punteros amuchos valores diferentes, se puede declara unarray de punteros. Un array de punteros esun array que

* [12]={“ ” ”f b ” ” ” ”

b ” ” i b ” ”di i b ”}

Inicialización de un array de punteros a cadenas… La inicialización de un array de punteros acadenasse puede realizar con una declaración

similar a

esta;

… Char

*nombres_meses[12]={“enero”,”febrero”,”marzo”,”

abril”,”mayo”,”junio”,”julio”,”agosto”,”septiembre”,”

octubre”,”noviembre”,”diciembre”};

Punteros de cadenas

alfabeto;

… Char alfabeto[27]=“ABCDE….z”;… P=&alfabeto[0]

Printf(“%c\n”,*p);

… Los punteros se pueden utilizar en lugar deíndices de arrays. Considérese la siguientedeclaración de un array de caracteres quecontiene las letras del

d t d

A puntero le sumar restar entero ; hace apunte

Aritmética de punteros

se puede modificar, un puntero es una variable que se puedemodificar.

sobre punteros

n posiciones adelante, o atrás del actual. Las operaciones novalidas son;

… Al contrario que un nombre de un array, que es un puntero constante yno

Como consecuencia, se pueden realizar ciertas operacionesaritméticas

… A un puntero se le puede sumar o restar un entero n; esto hace

que apunte suma, multiplicación o división entre dos punteros

†Float m[20];

†Float *r;

†r=m;

†r++

Punteros constantes frente a punteros a constantes… Un puntero constante es un puntero que no sepuedecambiar, pero que los datos apuntados por el

puntero pueden ser cambiados. Por otra parte,un

puntero a una constante se puede modificarpara

apuntar a una constante diferente, pero losdatos

apuntados por el puntero no se puedencambiar

Punteros constantes

se debe utilizar el siguiente formato:†<Tipo de dato>*const<nombre puntero>=<dirección

de variable>;

†p1=&y , no es legal ya que se cambia el valor del puntero

†Int x;

†Int y;

†Int *const p1=&x;

†*p1=y, es legal ya que se cambia el contenido de memoria

… Para crear un puntero constante diferente de un array,

* 1 15 d il ió

Punteros a constantes

†Const

†Const

†Const

int

int

int

x=25;

y=50;

*p1=&x;

†P1=&y, p1 apunta a otra constante†*p1=15, crea un error de compilación

… El formato para definir un puntero a una constante es;

†Const<tipo de dato elemento>*<nombre puntero>=<dirección de constante>;

Punteros constantes a constantes

a constantes utilizando el formatosiguiente;†Const <tipo de dato elemento

>*const

<nombrepuntero>=<direccion de

constante>;

entera

x, cualquier

intento

de modificar

p1 o bien *p1

†Const int x=25;

†Const int *const p1=&x;

†P1 es un entero constante que apunta a una constante

producirá un error

… El ultimo caso a considerar es crear punterosconstantes

6 7

Punteros como argum

ntos de f

nciones

no se puede cambiar el valor de esa variable. Sinembargo,si se pasa un puntero a una variable a una función(paso por dirección) se puede cambiar el valor de la variable†Void func1 (int *s, int t) int i, j;

†{ i=5;

†*s=6; j=7;

†t=25; func1 (&i, j);

†}

… Cuando se pasa una variable a una función (paso porvalor)

Caracteres Valor entero representado como caracter entre comillas simples. Por ejemplo: 'z' representa al

valor entero de z

Internamente se representa como un tipo de dato enumerado usando el código ASCII (código estándar americano para el intercambio de información).

Cadenas Es un arreglo de caracteres que:

Puede incluir letras, dígitos y caracteres especiales (*, /, $)

Tiene un puntero al primer caracter

Cuyo valor de la cadena es la dirección de memoria del primer elemento.

1. Los códigos para los caracteres que representan dígitos del 0 al 9 son consecutivos.

2. Las letras en el alfabeto están divididos en dos rangos: uno para las mayúsculas (A-Z) y otro para las minúsculas (a-z). Sin embargo dentro de cada rango los valores ASCII son consecutivos.

Es un estándar para referirse a un carácter específico en C.

Para referirse al código ASCII de la letra A, se especifica ‘A’, el cual es el 65.

Para referirse al código del carácter 9, de forma similar, ‘9’.

CUIDADO: El referirse al carácter, no es lo mismo que referirse al valor

entero. El 9 es diferente del ‘9’.

Se puede:

Sumar un entero a un carácter

Restar un entero de un caracter

Restar un caracter de otro

Comparar dos caracteres entre sí

CUIDADO: Al sumar o restar el resultado no debe salirse del rango

de representación ASCII

Definición Como un arreglo de caracteres o una variable de tipo char *

char color[] = "blue";char *colorPtr = "blue";

Recuerde que una cadena se representa como un arreglo de caracteres y termina con '\0' color tiene 5 elementos

Lectura Utilizando scanf

scanf("%s", cadena); Copia la entrada en el arreglo cadena[] No se necesita el & (porque una cadena es un puntero)

Recuerde dejar espacio en el arreglo para el fin de cadena'\0‘

Escritura Utilizando printf

printf(“%s”,cadena);

char RandomLetra(void){

return (RandomInteger (‘A’, ‘Z’));}

bool esMayuscula (char ch) {

return (ch >= ‘A’ && ch <=‘Z’);}

bool esDigito (char ch)

{

return (ch >= ‘0’ && ch <=‘9’);

}

bool esMinuscula (char ch)

{

return (ch >= ‘a’ && ch <=‘z’);

}

Contiene un gran número de funciones para determinar el tipo de carácter, entre las principales tenemos:

islower(ch) retorna TRUE si el carácter ch es minúscula

isupper(ch) retorna TRUE si el carácter ch es mayúscula

isalpha(ch) retorna TRUE si ch es un valor alfabético

isdigit(ch) retorna TRUE si ch es un dígito

isalnum(ch) retorna TRUE si ch es un valor alfanumérico

ispunct(ch) retorna TRUE si ch es un símbolo de puntuación

isspace(ch) retorna TRUE si ch es un carácter en blanco

Prototype Description

int isdigit( int c ); Returns true if c is a digit and false otherwise.

int isalpha( int c ); Returns true if c is a letter and false otherwise.

int isalnum( int c ); Returns true if c is a digit or a letter and false otherwise.

int isxdigit( int c ); Returns true if c is a hexadecimal digit character and false otherwise.

int islower( int c ); Returns true if c is a lowercase letter and false otherwise.

int isupper( int c ); Returns true if c is an uppercase letter; false otherwise.

int tolower( int c ); If c is an uppercase letter, tolower returns c as a lowercase letter. Otherwise, tolower

returns the argument unchanged. int toupper( int c );

If c is a lowercase letter, toupper returns c as an uppercase letter. Otherwise, toupper

returns the argument unchanged. int isspace( int c );

Returns true if c is a white-space character—newline ('\n'), space (' '), form feed

('\f'), carriage return ('\r'), horizontal tab ('\t'), or vertical tab ('\v')—and false

otherwise int iscntrl( int c );

Returns true if c is a control character and false otherwise. int ispunct( int c );

Returns true if c is a printing character other than a space, a digit, or a letter and false

otherwise. int isprint( int c );

Returns true value if c is a printing character including space (' ') and false otherwise.

int isgraph( int c ); Returns true if c is a printing character other than space (' ') and false otherwise.

Convierte cadenas de dígitos a enteros y valores de punto flotante.

Function prototype Function description double atof( const char *nPtr ); Converts the string nPtr to double.

int atoi( const char *nPtr ); Converts the string nPtr to int.

long atol( const char *nPtr ); Converts the string nPtr to long int.

double strtod( const char *nPtr, char **endPtr );

Converts the string nPtr to double.

long strtol( const char *nPtr, char **endPtr, int base );

Converts the string nPtr to long.

unsigned long strtoul( const char *nPtr, char **endPtr, int base );

Converts the string nPtr to unsigned long.

Function prototype Function description int getchar( void ); Inputs the next character from the standard input and re-

turns it as an integer.

char *gets( char *s ); Inputs characters from the standard input into the array s

until a newline or end-of-file character is encountered. A

terminating null character is appended to the array. int putchar( int c ); Prints the character stored in c. int puts( const char *s ); Prints the string s followed by a newline character. int sprintf( char *s, const char *format, ... );

Equivalent to printf, except the output is stored in the

array s instead of printing it on the screen. int sscanf( char *s, const char *format, ... );

Equivalent to scanf, except the input is read from the array

s instead of reading it from the keyboard.

Incluye funciones para: Manipular cadenas

Búsqueda en cadenas

Manejo de tokens

Determine la longitud de cadenas

Function prototype Function description char *strcpy( char *s1, const char *s2 )

Copies string s2 into array s1. The value of s1 is returned.

char *strncpy( char *s1, const char *s2, size_t n )

Copies at most n characters of string s2 into array s1. The value of s1

is returned.

char *strcat( char *s1, const char *s2 )

Appends string s2 to array s1. The first character of s2 overwrites the

terminating null character of s1. The value of s1 is returned. char *strncat( char *s1, const char *s2, size_t n )

Appends at most n characters of string s2 to array s1. The first

character of s2 overwrites the terminating null character of s1. The

value of s1 is returned.

int strcmp( const char *s1, const char *s2 );

Compara string s1 con s2 Retorna:

Un número negativo si s1 < s2

Cero,si s1 == s2

Un número positivo si s1 > s2

int strncmp(const char *s1,const char *s2,size_t n);

Compara n caracteres de s1 en s2 Retorna valores como los anteriores

Function prototype Function description

char *strchr( const char *s, int c );

Locates the first occurrence of character c in string s. If c is found, a

pointer to c in s is returned. Otherwise, a NULL pointer is returned.

size_t strcspn( const char *s1, const char *s2 );

Determines and returns the length of the initial segment of string s1

consisting of characters not contained in string s2.

size_t strspn( const char *s1, const char *s2 );

Determines and returns the length of the initial segment of string s1

consisting only of characters contained in string s2.

char *strpbrk( const char *s1, const char *s2 );

Locates the first occurrence in string s1 of any character in string s2.

If a character from string s2 is found, a pointer to the character in

string s1 is returned. Otherwise, a NULL pointer is returned.

char *strrchr( const char *s, int c );

Locates the last occurrence of c in string s. If c is found, a pointer to c

in string s is returned. Otherwise, a NULL pointer is returned.

char *strstr( const char *s1, const char *s2 );

Locates the first occurrence in string s1 of string s2. If the string is

found, a pointer to the string in s1 is returned. Otherwise, a NULL

pointer is returned.

char *strtok( char *s1, const char *s2 );

A sequence of calls to strtok breaks string s1 into “tokens”—logical

pieces such as words in a line of text—separated by characters

contained in string s2. The first call contains s1 as the first argument,

and subsequent calls to continue tokenizing the same string contain

NULL as the first argument. A pointer to the current token is returned

by each call. If there are no more tokens when the function is called,

NULL is returned.

Una estructura (también llamada registro) es un tipo de datos que agrupa

varios datos de tipo simple en un solo objeto.

Las estructuras se declaran con la palabra reservada struct.

struct nombre{

campos;

};

Cada campo esta formado por la declaración de una o más variables de algún

otro tipo. Ejemplo:

struct persona{

char nombre[30];

int edad;

};

nombre (cadena) edad (int)

persona

Campos

Una vez definida la estructura se pueden declarar variables de ese tipo:

struct persona{

char nombre[30];

int edad;

};

persona juan, maria; o

struct persona juan, maria;

La asignación se hace mediante el operador “.”

gets(juan.nombre);

juan.edad = 23;

gets(maria.nombre);

maria.edad = 17;

TAMBIEN

struct persona{

char nombre[30];

int edad;

}juan, maria;

#include <stdio.h>

#include <conio.h>

#include <string.h>

struct persona{

char nombre[30];

int edad;

};

main(){

persona per1,per2;

strcpy(per1.nombre,"pedro");

strcpy(per2.nombre,"maria");

per1.edad = 23;

per2.edad = 17;

printf("nombre: %s\nedad: %d\n",per1.nombre,per1.edad);

printf("nombre: %s\nedad: %d\n",per2.nombre,per2.edad);

getch();

}

struct carta{

int numero;

char palo;

}

numero palo

Carta de baraja

struct libro{

char titulo[40];

char autor[30];

char editorial[20];

int anyo;

}

titulo autor

Libro

editorial anyo

struct poligono{

char nombre[20];

int lados;

float longitudLado,

area;

}

nombre lados

Polígono regular

longitudLado

area

struct carta c1;

c1.numero = 3;

c1.palo = ‘D’;

struct libro L1;

strcpy(L1.titulo,”Piensa en C”);

strcpy(L1.autor,”Osvaldo Cairó”);

strcpy(L1.editorial,”Pearson”);

L.anyo = 2006;

struct poligono p;

strcpy(p.nombre,”hexagono”);

p.lados = 6;

p.longitudLado = 5;

p.area = p.lados*p.longitudLado*p.longitudLado/2.0/

tan(PI/p.lados);

struct alumno{

int matricula;

char nombre[20];

char carrera[20];

float promedio;

char direccion[20];

};

matricula nombre carrera direccionpromedio

alumno

main(){

struct alumno a1={120,"Maria","Contabilidad",8.9,"Queretaro"},a2;

printf("\nIngrese la matricula del alumno 2:");

scanf("%d",&a2.matricula);

fflush(stdin);

printf("\nIngrese el nombre del alumno 2:");

gets(a2.nombre);

printf("\nIngrese la carrera del alumno 2:");

gets(a2.carrera);

printf("\nIngrese el promedio del alumno 2:");

scanf("%f",&a2.promedio);

fflush(stdin);

printf("\nIngrese la direccion del alumno 2:");

gets(a2.direccion);

printf("\nDatos del alumno 1\n");

printf("%d\n",a1.matricula);

puts(a1.nombre);

puts(a1.carrera);

printf("%.2f\n",a1.promedio);

puts(a1.direccion);

printf("\nDatos del alumno 2\n");

printf("%d\n",a2.matricula);

puts(a2.nombre);

puts(a2.carrera);

printf("%.2f\n",a2.promedio);

puts(a2.direccion);

getch();

}

CURP marca modelo anyo placa

Defina estructuras para los siguientes datos y escriba un ejemplo de inicialización

de una variable con llaves y campo por campo.

Registro de automóviles

Cliente de videoclub

nombre direccion telefono

Licencia de manejo

nombres apellidoPaterno apellidoMaterno fechaDesde fechaVencimiento

nacionalidad grupoSanguineo CURPoRFC restricciones donaOrganos

clave direccion

adeuda

Tarjeta de crédito

nombre fechaVencimiento numeroTarjeta saldo limite

El operador = se puede utilizar para asignar todos los campos de una estructura

a otra.

Ejemplo:

struct libro{

char titulo[30], autor[30], editorial[15];

int anyo,edicion;

};

main(){

libro a = {“El Quijote”,”Cervantes”,”Limusa”,1987,2},b;

b = a;//copia todos los datos de a en b

}

Para acceder a una estructura mediante un apuntador se utiliza la siguiente notación:

(*estructura).campo o estructura->campo

Es necesario crear mediante new la estructura antes de usarla.

Ejemplo:struct alumno{

int matricula;

char nombre[20];

char carrera[20];

float promedio;

char direccion[20];

};

main(){

alumno *a;

a = new(struct alumno);

(*a).matricula = 234; a->matricula = 234;

strcpy((*a).nombre,"Juan Perez"); strcpy(a->nombre,"Juan Perez");

strcpy((*a).carrera,"Mate"); strcpy(a->carrera,"Mate");

(*a).promedio = 6.7; a->promedio = 6.7;

strcpy((*a).direccion,"Lomas 34"); strcpy(a->direccion,"Lomas 34");

}

#include <stdio.h>

#include <conio.h>

#include <string.h>

struct dir{

char calle[20];

int numero;

char colonia[20];

int cp;

};

dir dameDir(){

dir a={"alamo",43,"lomas",78000};

return a;

}

main(){

dir b;

b = dameDir();

printf("calle: %s %d\n",b.calle,b.numero);

printf("colonia: %s\n",b.colonia);

printf("CP: %d\n",b.cp);

getch();

}

Una función puede regresar una

estructura

Las estructuras se pasan como parámetros a las funciones de la

misma forma que las variables de tipo simple.

Función para escribir datos de un alumno:

void escribeAlumno(struct alumno a){

printf("\nDatos del alumno\n");

printf("%d\n",a.matricula);

puts(a.nombre);

puts(a.carrera);

printf("%.2f\n",a.promedio);

puts(a.direccion);

}

Función para leer un alumno:

void lectura(struct alumno *a){

printf("\nIngrese la matricula del alumno:");

scanf("%d",&(*a).matricula);

fflush(stdin);

printf("\nIngrese el nombre del alumno:");

gets(a->nombre);

printf("\nIngrese la carrera del alumno:");

gets((*a).carrera);

printf("\nIngrese el promedio del alumno:");

scanf("%f",&a->promedio);

fflush(stdin);

printf("\nIngrese la direccion del alumno:");

gets(a->direccion);

}

(*estructura).campo estructura->campo

Un número racional se define como el cociente de dos enteros, por ejemplo:

3/4, 5/6, 32/40, 7=7/1, etc.

Podemos representarlos mediante una estructura como sigue:

struct racional{

int num,den;

};

Note que no basta con comparar numerador y denominador para determinar

la igualdad de dos racionales. Es decir, 4/6 es igual a 2/3, pero 4 2 y 6 3.

Para establecer la igualdad de dos racionales debemos asegurar que estén

en su forma reducida. Es decir, que numerador y denominador sean primos

entre sí.

El algoritmo de Euclides permite reducir un número racional.

1. Sea a el mayor y b el menor entre numerador y denominador.

2. Divídase a entre b y sea q el cociente y r el residuo.

3. Hágase a = b y b = r

4. Repítase desde el paso 2 hasta que b sea 0.

5. Divídase numerador y denominador entre a.

a b q r

340 45 7 25

45 25 1 20

25 20 1 5

20 5 4 0

5 0

num=340, den=45

num=340/5 = 68

den=45/5 = 9

num=140, den=26 num=380, den=44 num=830, den=675

void reduce(racional *r){

int a,b,t;

if(r->num>r->den){

a = r->num;

b = r->den;

}else{

a = r->num;

b = r->den;

}

while(b){

t = a % b;

a = b;

b = t;

}

r->num = r->num/a;

r->den = r->den/a;

}

bd

cbad

d

c

b

a

racional suma(racional a, racional b){

racional c;

c.num = (a.num*b.den+b.num*a.den);

c.den = a.den*b.den;

reduce(&c);

return c;

}

void imprime(racional a){

printf("%d/%d\n",a.num,a.den);

}

Las estructuras pueden contener a otras estructuras como

componentes.

Una estructura que tiene componentes de tipo estructura se llama

estructura anidada.

Ejemplo de estructuras anidadas

struct fecha{

int dia,mes,anyo;

};

struct persona{

char nombre[20];

char apellido[20];

fecha nacimiento;

int edad;

int sexo;

char CURP[19];

char telefono[20];

};

nombre apellido nacimiento edad sexo CURP telefono

dia mes anyo

void despliegaFecha(fecha f){

printf("%d de ",f.dia);

switch(f.mes){

case 1:printf("ene");break;

case 2:printf("feb");break;

case 3:printf("mar");break;

case 4:printf("abr");break;

case 5:printf("may");break;

case 6:printf("jun");break;

case 7:printf("jul");break;

case 8:printf("ago");break;

case 9:printf("sep");break;

case 10:printf("oct");break;

case 11:printf("nov");break;

case 12:printf("dic");break;

}

printf(" de %d\n",f.anyo);

}

void despliegaPersona(persona p){

printf("Nombre: %s\n",p.nombre);

printf("Apellidos: %s\n",p.apellido);

printf("Fecha de nacimiento: ");

despliegaFecha(p.nacimiento);

printf("Edad: %d\n",p.edad);

if(p.sexo)

printf("Sexo: masculino\n");

else

printf("Sexo: femenino\n");

printf("CURP: %s\n",p.CURP);

printf("Telefono: %s\n",p.telefono);

}

void leerFecha(fecha *f){

printf("Dia? ");

scanf("%d",&(f->dia));

printf("Mes? ");

scanf("%d",&(f->mes));

printf("Anyo? ");

scanf("%d",&(f->anyo));

}

void leerPersona(persona *p){

fflush(stdin);

printf("Nombre? ");

gets(p->nombre);

printf("Apellidos? ");

gets(p->apellido);

printf("Fecha de nacimiento:\n");

leerFecha(&p->nacimiento);

printf("Edad? ");

scanf("%d",&p->edad);

printf("Sexo (1-Hombre, 0-Mujer)? ");

scanf("%d",&p->sexo);

fflush(stdin);

printf("CURP? ");

gets(p->CURP);

printf("Telefono? ");

gets(p->telefono);

}

Se puede acceder a los campos de una estructura anidada mediante el

operador “.”. Por ejemplo:

persona per,*per2;

per.nacimiento.dia = 5;

per.nacimiento.mes = 7;

per.nacimiento.anyo = 1998;

per2->nacimiento.dia = 1;

per2->nacimiento.mes = 8;

per2->nacimiento.anyo = 2005;

Note que el campo anidado se accede mediante el operador “.” y el no

anidado mediante “->”.

struct fecha{

int dia,mes,anyo;

};

struct direccionStruct{

char

calle[30],colonia[20],ciudad[30],estado[15],pais[20];

int numero,cp;

};

struct nombreStruct{

char nombre[20],apellidos[20];

};

struct nomdir{

nombreStruct nom;

direccionStruct dir;

};

struct posicion{

char depto[5];

char trabajo[20];

};

struct empleado{

nomdir nombreDireccion;

posicion trabajo;

float salario;

int numDepto;

fecha fechaIngreso;

};

struct estudiante{

nomdir nombreDireccion;

char carrera[20];

float promedio;

int creditos;

};

dia mes anyo

calle colonia ciudad estado pais num cp

nombre apellidos

dirnom

nombre apellidos calle colonia ciudad estado pais num cp

fecha

direccionStruct

nombreStruct

nomdir

depto trabajo

posicion

empleado

dirnom

nombre apellidos calle colonia ciudad estado pais num cp

nombredireccion

depto trabajo

trabajo salario numDepto fechaIngreso

dia mesanyo

estudiante

dirnom

nombre apellidos calle colonia ciudad estado pais num cp

nombredireccion carrera promedio creditos

main(){

nomdir per = {{"juan","perez lopez"},

{"olmo","lomas","SLP","SLP","Mexico",32,78000}};

estudiante est = {{},"fisica",7.5,210};

empleado emp = {{},{"dep1","afanador"},30000,2,{5,5,2003}};

est.nombreDireccion = per;

emp.nombreDireccion = per;

printf("nombre: %s\n",per.nom.nombre);

printf("apellidos: %s\n",per.nom.apellidos);

printf("nombre: %s\n",est.nombreDireccion.nom.nombre);

printf("apellidos: %s\n",est.nombreDireccion.nom.apellidos);

printf("nombre: %s\n",emp.nombreDireccion.nom.nombre);

printf("apellidos: %s\n",emp.nombreDireccion.nom.apellidos);

printf("Fecha ingreso: %d/%d/%d\n", emp.fechaIngreso.dia,

emp.fechaIngreso.mes, emp.fechaIngreso.anyo);

getch();

}