Вы находитесь на странице: 1из 64

1.

- Caractersticas del lenguaje C


2.- Estructura de un programa en C
o 2.1.- Estructura
o 2.2.- Comentarios
o 2.3.- Palabras clave
o 2.4.- Identificadores
3.- Tipos de datos
o 3.1.- Tipos
o 3.2.- Calificadores de tipo
o 3.3.- Las variables
o 3.4.- !nde se declaran "
o 3.#.- Constantes
o 3.$.- %ecuencias de escape
o 3.&.- Inclusi!n de fic'eros
4.- Operadores aritmticos y de asignacin
o 4.1.- (peradores ar)tmeticos
o 4.2.- (peradores de asi*naci!n
o 4.3.- +erar,u)a de los operadores
5.- Salida / Entrada
o #.1.- %entencia printf-.
o #.2.- %entencia scanf-.
6.- Operadores relacionales
7.- Sentencias condicionales
o &.1.- Estructura I/...EL%E
o &.2.- Estructura %0ITC1
8.- Operadores lgicos
9.- Bucles
o 2.1.- %entencia 01ILE
o 2.2.- %entencia (...01ILE
o 2.3.- %entencia /(3
o 2.4.- %entencia 43E56
o 2.#.- %entencia C(7TI78E
10.- Funciones
o 19.1.- Tiempo de vida de los datos
o 19.2.- /unciones
o 19.3.- eclaraci!n de las funciones
o 19.4.- Paso de par:metros a una funci!n
11.- Arrays
o 11.1.- ;ectores
o 11.2.- <atrices
12.- Punteros
o 12.1.- eclaraci!n
o 12.2.- (peradores
o 12.3.- 5si*naci!n
o 12.4.- 5ritm=tica de direcciones
13.- Estructuras
o 13.1.- Concepto de estructura
o 13.2.- Estructuras > funciones
o 13.3.- 5rra>s de estructuras
o 13.4.- T>pedef
14.- Ficheros
o 14.1.- 5pertura
o 14.2.- Cierre
o 14.3.- Escritura > lectura
15.- Gestin dinmica de memoria
o 1#.1.- /unciones
o 1#.2.- Estructuras din:micas de datos
16.- Programacin grfica (Disponible el 1/04/2001)
o 1$.1.- Conceptos b:sicos
o 1$.2.- /unciones
17.- Apndice (Disponible el 15/04/2001)
o 1&.1.- Librer)a stdio.'
o 1&.2.- Librer)a stdlib.'
o 1&.3.- Librer)a conio.'
o 1&.4.- Librer)a strin*.'
o 1&.#.- Librer)a *rap'ics.'
o 1&.$.- Librer)a dir.'
o 1&.&.- /unciones interesantes
1.- CARACTERISTICAS DEL LENGUAJE C

El len*ua?e C se conoce como un len*ua?e compilado. E@isten dos tipos de
len*ua?eA interpretados > compilados. Los interpretados son a,uellos ,ue necesitan
del c!di*o fuente para funcionar -P.e?A 4asic.. Los compilados convierten el c!di*o
fuente en un fic'ero ob?eto > =ste en un fic'ero e?ecutable. Este es el caso del
len*ua?e C.
Podemos decir ,ue el len*ua?e C es un len*ua?e de nivel medioB >a ,ue combina
elementos de len*ua?e de alto nivel con la funcionalidad del len*ua?e ensamblador.
Es un len*ua?e estructuradoB >a ,ue permite crear procedimientos en blo,ues
dentro de otros procedimientos. 1a> ,ue destacar ,ue el C es un len*ua?e portableB
>a ,ue permite utiliCar el mismo c!di*o en diferentes e,uipos > sistemas
inform:ticosA el len*ua?e es independiente de la ar,uitectura de cual,uier m:,uina
en particular.
Por Dltimo solo ,ueda decir ,ue el C es un len*ua?e relativamente pe,ueEoF se
puede describir en poco espacio > aprender r:pidamente. Este es sin duda el
ob?etivo de =ste curso. 7o pretende ser un completo manual de la pro*ramaci!nB
sin! una base Dtil para ,ue cual,uiera pueda introducirse en este apasionante
mundo.
5un,ue en principio cual,uier compilador de C es v:lidoB para se*uir este curso
se recomienda utiliCar el compilador Turbo C/C++ o bien el Borland C++ 5.0.
2.- ESTRUCTURA DE UN PROGRAMA EN C

2.1.- Estructura
Todo pro*rama en C consta de una o m:s funcionesB una de las cuales se llama
main. El pro*rama comienCa en la funci!n mainB desde la cual es posible llamar a
otras funciones.
Cada funci!n estar: formada por la cabecera de la funci!nB compuesta por el
nombre de la misma > la lista de ar*umentos -si los 'ubiese.B la declaraci!n de las
variables a utiliCar > la secuencia de sentencias a e?ecutar.
E?emploA
declaraciones globales
main( ) {
variables locales
bloque
}
funcion1( ) {
variables locales
bloque
}
2.2.- Comentarios
5 la 'ora de pro*ramar es conveniente aEadir comentarios -cuantos m:s me?or.
para poder saber ,ue funci!n tiene cada parte del c!di*oB en caso de ,ue no lo
utilicemos durante al*Dn tiempo. 5dem:s facilitaremos el traba?o a otros
pro*ramadores ,ue puedan utiliCar nuestro arc'ivo fuente.
Para poner comentarios en un pro*rama escrito en C usamos los s)mbolos /* >
*/A
/* Este es un ejemplo de comentario */
/* Un comentario tambin puede
estar escrito en varias lneas */
El s)mbolo /* se coloca al principio del comentario > el s)mbolo */ al final.
El comentarioB contenido entre estos dos s)mbolosB no ser: tenido en cuenta por
el compilador.
2.3.- Palabras clave
E@isten una serie de indicadores reservadosB con una finalidad determinadaB ,ue
no podemos utiliCar como identificadores.
5 continuaci!n vemos al*unas de estas palabras claveA
c!ar int float double if
else do "!ile for
s"itc!
s!ort long e#tern static
default
continue brea$ register si%eof
t&pedef
2.4.- Identificadores
8n identificador es el nombre ,ue damos a las variables > funciones. Est:
formado por una secuencia de letras > d)*itosB aun,ue tambi=n acepta el caracter
de subra>ado _. Por contra no acepta los acentos ni la G.
El primer caracter de un identificador no puede ser un nDmeroB es decir ,ue
debe ser una letra o el s)mbolo _.
%e diferencian las ma>Dsculas de las minDsculasB as) numB Num > nuM son
distintos identificadores.
5 continuaci!n vemos al*unos e?emplos de identificadores v:lidos > no v:lidosA
'(lidos )o v(lidos
_num 1num
var1 nmero2
fecha_nac ao_nac
3.- TIPOS DE DATOS

3.1.- Tipos
En HCH e@isten b:sicamente cuatro tipos de datosB aun,ue como se ver:
despu=sB podremos definir nuestros propios tipos de datos a partir de estos cuatro.
5 continuaci!n se detalla su nombreB el tamaEo ,ue ocupa en memoria > el ran*o
de sus posibles valores.
*+,- *ama.o /ango de valores
char 1 byte -128 a 127
int 2 bytes -32768 a 32767
float 4 bytes 3'4 E-38 a 3'4 E38
!ouble 8 bytes 1'7 E-3"8 a 1'7 E3"8
3.2.- Calificadores de tipo
Los calificadores de tipo tienen la misi!n de modificar el ran*o de valores de un
determinado tipo de variable. Estos calificadores son cuatroA
signed
Le indica a la variable ,ue va a llevar si*no. Es el utiliCado por defecto.

tama.o rango de valores

signed c!ar 1 byte -128 a 127

signed int 2 bytes -32768 a 32767

unsigned
Le indica a la variable ,ue no va a llevar si*no -valor absoluto..

tama.o rango de valores

unsigned c!ar 1 byte " a 2##

unsigned int 2 bytes " a 6##3#

short
3an*o de valores en formato corto -limitado.. Es el utiliCado por defecto.

tama.o rango de valores

s!ort c!ar 1 byte -128 a 127

s!ort int 2 bytes -32768 a 32767

long
3an*o de valores en formato lar*o -ampliado..

tama.o rango de valores

long int 4 bytes -2$147$483$648 a 2$147$483$647

long double 1" bytes -3'36 E-4%32 a 1'18 E4%32

Tambi=n es posible combinar calificadores entre s)A


signed long int 0 long int 0 long
unsigned long int 0 unsigned long 1 b&tes 2 a 1345135673458 (El ma&or
entero permitido en 9:9)
3.3.- Las variables
8na variable es un tipo de datoB referenciado mediante un identificador -,ue es
el nombre de la variable.. %u contenido podr: ser modificado a lo lar*o del
pro*rama.
8na variable s!lo puede pertenecer a un tipo de dato. Para poder utiliCar una
variableB primero tiene ,ue ser declaradaA
;calificador< =tipo> =nombre>
Es posible inicialiCar > declarar m:s de una variable del mismo tipo en la misma
sentenciaA
;calificador< =tipo>
=nombre1>?=nombre4>0=valor>?=nombre@>0=valor>?=nombre1>
/* Uso de las variables */
Ainclude =stdio3!>
main() /* Buma dos valores */
{
int num101?num4?num@06C
printf(DEl valor de num1 es EdD?num1)C
printf(DFnEl valor de num@ es EdD?num@)C
num40num1Gnum@C
printf(DFnnum1 G num@ 0 EdD?num4)C
}
Hrc!ivoI variab13c
3.4.- Dnde se declaran ?
Las variables pueden ser de dos tipos se*Dn el lu*ar en ,ue las declaremosA
globales o locales.
La variable *lobal se declara antes de la main( ). Puede ser utiliCada en
cual,uier parte del pro*rama > se destru>e al finaliCar =ste.
La variable local se declara despu=s de la main( )B en la funci!n en ,ue va>a a
ser utiliCada. %!lo e@iste dentro de la funci!n en ,ue se declara > se destru>e al
finaliCar dic'a funci!n.
El identificador -nombre de la variable. no puede ser una palabra clave > los
caracteres ,ue podemos utiliCar son las letrasA a-z > A-Z -o?oI la o no est:
permitida.B los nDmerosA 0-9 > el s)mbolo de subra>ado _. 5dem:s 'a> ,ue tener
en cuenta ,ue el primer caracter no puede ser un nDmero.
/* JeclaraciKn de variables */
Ainclude =stdio3!>
int aC
main() /* Luestra dos valores */
{
int b01C
printf(Db es local & vale EdD?b)C
a08C
printf(DFna es global & vale EdD?a)C
}
Hrc!ivoI variab43c
3.5.- Constantes
5l contrario ,ue las variablesB las constantes mantienen su valor a lo lar*o de
todo el pro*rama.
Para indicar al compilador ,ue se trata de una constanteB usaremos la directiva
#defineA
Adefine =identificador> =valor>
(bserva ,ue no se indica el punto > coma de final de sentencia ni tampoco el
tipo de dato.
La directiva #define no s!lo nos permite sustituir un nombre por un valor
num=ricoB sin! tambi=n por una cadena de caracteres.
El valor de una constante no puede ser modificado de nin*una manera.
/* Uso de las constantes */
Ainclude =stdio3!>
Adefine pi @31116
Adefine escribe printf
main() /* :alcula el permetro */
{
int rC
escribe(D+ntroduce el radioI D)C
scanf(DEdD?Mr)C
escribe(DEl permetro esI EfD?4*pi*r)C
}
Hrc!ivoI constan13c
3.6.- Secuencias de escape
Ciertos caracteres no representados *r:ficamente se pueden representar
mediante lo ,ue se conoce como secuencia de escape.
5 continuaci!n vemos una tabla de las m:s si*nificativasA
\n salto de l)nea
\b retroceso
\t tabulaci!n 'oriContal
\v tabulaci!n vertical
\\ contrabarra
\f salto de p:*ina
\' ap!strofe
\" comillas dobles
\0 fin de una cadena de caracteres
/* Uso de las secuencias de escape */
Ainclude =stdio3!>
main() /* Escribe diversas sec3 de escape */
{
printf(DLe llamo FD)emoFD el grandeD)C
printf(DFnJirecciKnI :FF La&or 48D)C
printf(DFnNa salido la letra F9OF9D)C
printf(DFn/etrocesoFbD)C
printf(DFnFtEsto !a sido todoD)C
}
Hrc!ivoI secuen13c
3.7.- Inclusin de ficheros
En la pro*ramaci!n en C es posible utiliCar funciones ,ue no esten inclu)das en
el propio pro*rama. Para ello utiliCamos la directiva #includeB ,ue nos permite
aEadir librer)as o funciones ,ue se encuentran en otros fic'eros a nuestro
pro*rama.
Para indicar al compilador ,ue vamos a incluir fic'eros e@ternos podemos
'acerlo de dos maneras -siempre antes de las declaraciones..
1. Indic:ndole al compilador la ruta donde se encuentra el fic'ero.
Ainclude Dmisfunc3!D
Ainclude DcIFincludesFmisfunc3!D
2. Indicando ,ue se encuentran en el directorio por defecto del compilador.
Ainclude =misfunc3!>
4.- OPERADORES ARITMETICOS Y DE ASIGNACION

5 continuaci!n se e@plican los tipos de operadores -aritm=ticos > de asi*naci!n.
,ue permiten realiCar operaciones matem:ticas en len*ua?e C.
4.1.- Operadores aritmticos
E@isten dos tipos de operadores aritm=ticosA
Los binariosA
G &uma
P 'esta
* (ulti)licaci*n
/ +ivisi*n
E (*!ulo ,resto-
> los unariosA
GG .ncremento ,suma 1-
P P +ecremento ,resta 1-
P /ambio !e si0no
%u sinta@is esA
binarios1
=variable1>=operador>=variable4>
unarios1
=variable>=operador> y al rev2s3 =operador>=variable>3
/* Uso de los operadores aritmticos */
Ainclude =stdio3!>
main() /* /eali%a varias operaciones */
{
int a01?b04?c0@?rC
r0aGbC
printf(DEd G Ed 0 EdFnD?a?b?r)C
r0cPaC
printf(DEd P Ed 0 EdFnD?c?a?r)C
bGGC
printf(Db G 1 0 EdD?b)C
}
Hrc!ivoI operad13c
4.2.- Operadores de asignacin
La ma>or)a de los operadores aritm=ticos binarios e@plicados en el cap)tulo
anterior tienen su correspondiente operador de asi*naci!nA
0 4si0naci*n sim)le
G0 &uma
P0 'esta
*0 (ulti)licaci*n
/0 +ivisi*n
E0 (*!ulo ,resto-
Con estos operadores se pueden escribirB de forma m:s breveB e@presiones del
tipoA
n0nG@ se )ue!e escribir nG0@
$0$*(#P4) lo )o!emos sustituir )or $*0#P4
/* Uso de los operadores de asignaciKn */
Ainclude =stdio3!>
main() /* /eali%a varias operaciones */
{
int a01?b04?c0@?rC
aG08C
printf(Da G 8 0 EdFnD?a)C
cP01C
printf(Dc P 1 0 EdFnD?c)C
b*0@C
printf(Db * @ 0 EdD?b)C
}
Hrc!ivoI operad43c
4.3.- Jerarqua de los operadores
%er: importante tener en cuenta la precedencia de los operadores a la 'ora de
traba?ar con ellosA
( ) (ayor )rece!encia
GG? P P
*? /? E
G? P (enor )recen!encia
Las operaciones con ma>or precedencia se realiCan antes ,ue las de menor
precedencia.
%i en una operaci!n encontramos si*nos del mismo nivel de precedenciaB dic'a
operaci!n se realiCa de iC,uierda a derec'a. 5 continuaci!n se muestra un e?emplo
sobre elloA
a*bGc/dPe
13 a5b resulta!o 6 7
43 c8! resulta!o 6 y
@3 7y resulta!o 6 9
13 9-e
/i?arse ,ue la multiplicaci!n se resuelve antes ,ue la divisi!n >a ,ue est:
situada m:s a la iC,uierda en la operaci!n. Lo mismo ocurre con la suma > la resta.
/* Qerarqua de los operadores */
Ainclude =stdio3!>
main() /* /eali%a una operaciKn */
{
int a06?b08?c01?d04?e01?#?&?%?rC
#0a*bC
printf(DEd * Ed 0 EdFnD?a?b?#)C
&0c/dC
printf(DEd / Ed 0 EdFnD?c?d?&)C
%0#G&C
printf(DEd G Ed 0 EdFnD?#?&?%)C
r0%PeC
printf(DEd 0 EdD?r?a*bGc/dPe)C
}
Hrc!ivoI operad@3c
5.- SALIDA / ENTRADA

5.1.- Sentencia printf( )
La rutina printf permite la aparici!n de valores num=ricosB caracteres > cadenas
de te@to por pantalla.
El prototipo de la sentencia printf es el si*uienteA
printf(control?arg1?arg4333)C
En la cadena de control indicamos la forma en ,ue se mostrar:n los ar*umentos
posteriores. Tambi=n podemos introducir una cadena de te@to - sin necesidad de
ar*umentos .B o combinar ambas posibilidadesB as) como secuencias de escape.
En el caso de ,ue utilicemos ar*umentos deberemos indicar en la cadena de
control tantos modificadores como ar*umentos va>amos a presentar.
El modificador est: compuesto por el caracter % se*uido por un caracter de
conversi!nB ,ue indica de ,ue tipo de dato se trata.
/* Uso de la sentencia printf() 13 */
Ainclude =stdio3!>
main() /* Baca por pantalla una suma */
{
int a042?b012C
printf(DEl valor de a es EdFnD?a)C
printf(DEl valor de b es EdFnD?b)C
printf(D,or tanto EdGEd0EdD?a?b?aGb)C
}
Hrc!ivoI printf3c
Los modificadores m:s utiliCados sonA
Ec :n nico caracter
Ed :n entero con si0no3 en base !ecimal
Eu :n entero sin si0no3 en base !ecimal
Eo :n entero en base octal
E# :n entero en base he7a!ecimal
Ee :n nmero real en coma flotante3 con e7)onente
Ef :n nmero real en coma flotante3 sin e7)onente
Es :na ca!ena !e caracteres
Ep :n )untero o !irecci*n !e memoria
/* Uso de la sentencia printf() 43 */
Ainclude =stdio3!>
main() /* Lodificadores 1 */
{
c!ar cad;<0DEl valor deDC
int a0P18C
unsigned int b0@C
float c05@438C
printf(DEs a es EdFnD?cad?a)C
printf(DEs b es EuFnD?cad?b)C
printf(DEs c es Ee o EfD?cad?c?c)C
}
Hrc!ivoI printf43c

El formato completo de los modificadores es el si*uienteA
E ;signo< ;longitud< ;3precisiKn< ;l/O< conversiKn
SignoA indicamos si el valor se a?ustar: a la iC,uierdaB en cu>o caso utiliCaremos
el si*no menosB o a la derec'a - por defecto ..
LongitudA especifica la lon*itud m:@ima del valor ,ue aparece por pantalla. %i la
lon*itud es menor ,ue el nDmero de d)*itos del valorB =ste aparecer: a?ustado a la
iC,uierda.
PrecisinA indicamos el nDmero m:@imo de decimales ,ue tendr: el valor.
l/LA utiliCamos l cuando se trata de una variable de tipo lon* > L cuando es de
tipo double.
/* Uso de la sentencia printf() @3 */
Ainclude =stdio3!>
main() /* Lodificadores 4 */
{
c!ar cad; <0DEl valor deDC
int a0485R6C
long int b01576841C
float c05387618C
printf(DEs a es E5dFnD?cad?a)C
printf(DEs b es EldFnD?cad?b)C
printf(DEs c es E3@fD?cad?c)C
}
Hrc!ivoI printf@3c
5.2.- Sentencia scanf( )
La rutina scanf permite entrar datos en la memoria del ordenador a trav=s del
teclado.
El prototipo de la sentencia scanf es el si*uienteA
scanf(control?arg1?arg4333)C
En la cadena de control indicaremosB por re*la *eneralB los modificadores ,ue
'ar:n referencia al tipo de dato de los ar*umentos. 5l i*ual ,ue en la sentencia
printf los modificadores estar:n formados por el caracter % se*uido de un
caracter de conversi!n. Los ar*umentos indicados ser:nB nuevamenteB las
variables.
La principal caracter)stica de la sentencia scanf es ,ue necesita saber la posici!n
de la memoria del ordenador en ,ue se encuentra la variable para poder almacenar
la informaci!n obtenida. Para indicarle esta posici!n utiliCaremos el s)mbolo
ampersand - & .B ,ue colocaremos delante del nombre de cada variable. - Esto no
ser: necesario en los arra>s ..
/* Uso de la sentencia scanf()3 */
Ainclude =stdio3!>
main() /* Bolicita dos datos */
{
c!ar nombre;12<C
int edadC
printf(D+ntroduce tu nombreI D)C
scanf(DEsD?nombre)C
printf(D+ntroduce tu edadI D)C
scanf(DEdD?Medad)C
}
Hrc!ivoI scanf3c
6.- OPERADORES RELACIONALES

Los operadores relacionales se utiliCan para comparar el contenido de dos
variables.
En C e@isten seis operadores relacionales b:sicosA
> (ayor ;ue
= (enor ;ue
>0 (ayor o i0ual ;ue
=0 (enor o i0ual ;ue
00 .0ual ;ue
S0 +istinto ;ue
El resultado ,ue devuelven estos operadores es 1 para ;erdadero > 0 para
/also.
%i 'a> m:s de un operador se evalDan de iC,uierda a derec'a. 5dem:s los
operadores == > != est:n por deba?o del resto en cuanto al orden de precedencia.
/* Uso de los operadores relacionales3 */
Ainclude =stdio3!>
main() /* :ompara dos nTmeros entre ellos */
{
int a?bC
printf(D+ntroduce el valor de HI D)C
scanf(DEdD?Ma)C
printf(D+ntroduce el valor de UI D)C
scanf(DEdD?Mb)C
if(a>b)
printf(DH es ma&or que UD)C
else if(a=b)
printf(DU es ma&or que HD)C
else
printf(DH & U son igualesD)C
}
Hrc!ivoI operrel3c
7.- SENTENCIAS CONDICIONALES

Este tipo de sentencias permiten variar el flu?o del pro*rama en base a unas
determinadas condiciones.
E@isten varias estructuras diferentesA
7.1.- Estructura IF...ELSE
%inta@isA
if (condiciKn) sentenciaC
La sentencia solo se e?ecuta si se cumple la condici!n. En caso contrario el
pro*rama si*ue su curso sin e?ecutar la sentencia.
(tro formatoA
if (condiciKn) sentencia1C
else sentencia4C
%i se cumple la condici!n e?ecutar: la sentencia1B sin! e?ecutar: la
sentencia2. En cual,uier casoB el pro*rama continuar: a partir de la sentencia2.
/* Uso de la sentencia condicional +V3 */
Ainclude =stdio3!>
main() /* Bimula una clave de acceso */
{
int usuario?clave01R476C
printf(D+ntroduce tu claveI D)C
scanf(DEdD?Musuario)C
if(usuario00clave)
printf(DHcceso permitidoD)C
else
printf(DHcceso denegadoD)C
}
Hrc!ivoI if13c

(tro formatoA
if (condiciKn) sentencia1C
else if (condiciKn) sentencia4C
else if (condiciKn) sentencia@C
else sentencia1C
Con este formato el flu?o del pro*rama Dnicamente entra en una de las
condiciones. %i una de ellas se cumpleB se e?ecuta la sentencia correspondiente >
salta 'asta el final de la estructura para continuar con el pro*rama.
E@iste la posibilidad de utiliCar llaves para e?ecutar m:s de una sentencia dentro
de la misma condici!n.
/* Uso de la sentencia condicional EOBE333+V3 */
Ainclude =stdio3!>
main() /* Escribe beb? ni.o o adulto */
{
int edadC
printf(D+ntroduce tu edadI D)C
scanf(DEdD?Medad)C
if (edad=1)
printf(DOo siento? te !as equivocado3D)C
else if (edad=@) printf(DEres un bebD)C
else if (edad=1@) printf(DEres un ni.oD)C
else printf(DEres adultoD)C
}
Hrc!ivoI elseif3c
7.2.- Estructura SWITCH
Esta estructura se suele utiliCar en los menDsB de manera ,ue se*Dn la opci!n
seleccionada se e?ecuten una serie de sentencias.
%u sinta@is esA
s"itc! (variable){
case contenidoWvariable1I
sentenciasC
brea$C
case contenidoWvariable4I
sentenciasC
brea$C
defaultI
sentenciasC
}
Cada case puede incluir una o m:s sentencias sin necesidad de ir entre llavesB
>a ,ue se e?ecutan todas 'asta ,ue se encuentra la sentencia BREAK. La variable
evaluada s!lo puede ser de tipo entero o caracter. default e?ecutar: las
sentencias ,ue inclu>aB en caso de ,ue la opci!n esco*ida no e@ista.
/* Uso de la sentencia condicional BX+*:N3 */
Ainclude =stdio3!>
main() /* Escribe el da de la semana */
{
int diaC
printf(D+ntroduce el daI D)C
scanf(DEdD?Mdia)C
s"itc!(dia){
case 1I printf(DOunesD)C brea$C
case 4I printf(DLartesD)C brea$C
case @I printf(DLircolesD)C brea$C
case 1I printf(DQuevesD)C brea$C
case 8I printf(D'iernesD)C brea$C
case 6I printf(DB(badoD)C brea$C
case 7I printf(DJomingoD)C brea$C
}
}
Hrc!ivoI s"itc!3c
8.- OPERADORES LOGICOS

Los operadores l!*icos b:sicos son tresA
MM 4<+
YY ='
S <=> ,El valor contrario-
Estos operadores actDan sobre e@presiones l!*icas. Permiten unir e@presiones
l!*icas simples formando otras m:s comple?as.
; J ;erdadero / J /also
/* Uso de los op3 lKgicos H)J?-/?)-*3 */
Ainclude =stdio3!>
main() /* :ompara un nTmero introducido */
{
int numeroC
printf(D+ntroduce un nTmeroI D)C
scanf(DEdD?Mnumero)C
if(S(numero>02))
printf(DEl nTmero es negativoD)C
else if((numero=0122)MM(numero>048))
printf(DEl nTmero est( entre 48 & 122D)C
else if((numero=48)YY(numero>122))
printf(DEl nTmero no est( entre 48 & 122D)C
}
Hrc!ivoI operlog3c
9.- BUCLES

Los bucles son estructuras ,ue permiten e?ecutar partes del c!di*o de forma
repetida mientras se cumpla una condici!n.
Esta condici!n puede ser simple o compuesta de otras condiciones unidas por
operadores l!*icos.
9.1.- Sentencia WHILE
%u sinta@is esA
"!ile (condiciKn) sentenciaC
Con esta sentencia se controla la condici!n antes de entrar en el bucle. %i =sta
no se cumpleB el pro*rama no entrar: en el bucle.
7aturalmenteB si en el interior del bucle 'a> m:s de una sentenciaB =stas
deber:n ir entre llaves para ,ue se e?ecuten como un blo,ue.
/* Uso de la sentencia XN+OE3 */
Ainclude =stdio3!>
main() /* Escribe los nTmeros del 1 al 12 */
{
int numero01C
"!ile(numero=012)
{
printf(DEdFnD?numero)C
numeroGGC
}
}
Hrc!ivoI "!ile3c
9.2.- Sentencia DO...WHILE
%u sinta@is esA
do{
sentencia1C
sentencia4C
}"!ile (condiciKn)C
Con esta sentencia se controla la condici!n al final del bucle. %i =sta se cumpleB
el pro*rama vuelve a e?ecutar las sentencias del bucle.
La Dnica diferencia entre las sentencias K'ile > do...K'ile es ,ue con la se*unda
el cuerpo del bucle se e?ecutar: por lo menos una veC.
/* Uso de la sentencia J-333XN+OE3 */
Ainclude =stdio3!>
main() /* Luestra un menT si no se pulsa 1 */
{
c!ar seleccionC
do{
printf(D13P :omen%arFnD)C
printf(D43P HbrirFnD)C
printf(D@3P ZrabarFnD)C
printf(D13P BalirFnD)C
printf(DEscoge una opciKnI D)C
seleccion0getc!ar()C
s"itc!(seleccion){
case 919Iprintf(D-pciKn 1D)C
brea$C
case 949Iprintf(D-pciKn 4D)C
brea$C
case 9@9Iprintf(D-pciKn @D)C
}
}"!ile(seleccionS0919)C
}
Hrc!ivoI do"!ile3c
9.3.- Sentencia FOR
%u sinta@is esA
for (iniciali%aciKnCcondiciKnCincremento){
sentencia1C
sentencia4C
}
La inicialiCaci!n indica una variable -variable de control. ,ue condiciona la
repetici!n del bucle. %i 'a> m:sB van separadas por comasA
for (a01?b0122CaS0bCaGG?bP P){
El flu?o del bucle FOR transcurre de la si*uiente formaA
/* Uso de la sentencia V-/3 */
Ainclude =stdio3!>
main() /* Escribe la tabla de multiplicar */
{
int num?#?resultC
printf(D+ntroduce un nTmeroI D)C
scanf(DEdD?Mnum)C
for (#02C#=012C#GG){
result0num*#C
printf(DFnEd por Ed 0 EdFnD?num?#?result)C
}
}
Hrc!ivoI for13c
9.4.- Sentencia BREAK
Esta sentencia se utiliCa para terminar la e?ecuci!n de un bucle o salir de una
sentencia SWITCH.
9.5.- Sentencia CONTINUE
%e utiliCa dentro de un bucle. Cuando el pro*rama lle*a a una sentencia
CONTINUE no e?ecuta las l)neas de c!di*o ,ue 'a> a continuaci!n > salta a la
si*uiente iteraci!n del bucle.
L a,u) termina el cap)tulo dedicado a los bucles. E@iste otra sentenciaB GOTOB
,ue permite al pro*rama saltar 'acia un punto identificado con una eti,uetaB pero
el buen pro*ramador debe prescindir de su utiliCaci!n. Es una sentencia mu> mal
vista en la pro*ramaci!n en HCH.
/* Uso de la sentencia :-)*+)UE3 */
Ainclude =stdio3!>
main() /* Escribe del 1 al 122 menos el 48 */
{
int numero01C
"!ile(numero=0122)
{
if (numero0048)
{
numeroGGC
continueC
}
printf(DEdFnD?numero)C
numeroGGC
}
}
Hrc!ivoI continue3c
9.4.- Sentencia BREAK
Esta sentencia se utiliCa para terminar la e?ecuci!n de un bucle o salir de una
sentencia SWITCH.
9.5.- Sentencia CONTINUE
%e utiliCa dentro de un bucle. Cuando el pro*rama lle*a a una sentencia
CONTINUE no e?ecuta las l)neas de c!di*o ,ue 'a> a continuaci!n > salta a la
si*uiente iteraci!n del bucle.
L a,u) termina el cap)tulo dedicado a los bucles. E@iste otra sentenciaB GOTOB
,ue permite al pro*rama saltar 'acia un punto identificado con una eti,uetaB pero
el buen pro*ramador debe prescindir de su utiliCaci!n. Es una sentencia mu> mal
vista en la pro*ramaci!n en HCH.
/* Uso de la sentencia :-)*+)UE3 */
Ainclude =stdio3!>
main() /* Escribe del 1 al 122 menos el 48 */
{
int numero01C
"!ile(numero=0122)
{
if (numero0048)
{
numeroGGC
continueC
}
printf(DEdFnD?numero)C
numeroGGC
}
}
Hrc!ivoI continue3c
1.- !UNCIONES

10.1.- Tiempo de vida de los datos
%e*Dn el lu*ar donde son declaradas puede 'aber dos tipos de variables.
lobalesA las variables permanecen activas durante todo el pro*rama. %e crean
al iniciarse =ste > se destru>en de la memoria al finaliCar. Pueden ser utiliCadas en
cual,uier funci!n.
LocalesA las variables son creadas cuando el pro*rama lle*a a la funci!n en la
,ue est:n definidas. 5l finaliCar la funci!n desaparecen de la memoria.
%i dos variablesB una *lobal > una localB tienen el mismo nombreB la local
prevalecer: sobre la *lobal dentro de la funci!n en ,ue 'a sido declarada.
os variables locales pueden tener el mismo nombre siempre ,ue est=n
declaradas en funciones diferentes.
/* 'ariables globales & locales3 */
Ainclude =stdio3!>
int num101C
main() /* Escribe dos cifras */
{
int num4012C
printf(DEdFnD?num1)C
printf(DEdFnD?num4)C
}
Hrc!ivoI funcion13c
10.2.- Funciones
Las funciones son blo,ues de c!di*o utiliCados para dividir un pro*rama en
partes m:s pe,ueEasB cada una de las cu:les tendr: una tarea determinada.
%u sinta@is esA
tipoWfunciKn nombreWfunciKn (tipo & nombre de argumentos)
{
bloque de sentencias
}
tipo!funcinA puede ser de cual,uier tipo de los ,ue conocemos. El valor
devuelto por la funci!n ser: de este tipo. Por defectoB es decirB si no indicamos el
tipoB la funci!n devolver: un valor de tipo entero - int .. %i no ,ueremos ,ue
retorne nin*Dn valor deberemos indicar el tipo vac)o - void ..
nombre!funcin" es el nombre ,ue le daremos a la funci!n.
tipo # nombre de argumentos" son los par:metros ,ue recibe la funci!n. Los
ar*umentos de una funci!n no son m:s ,ue variables locales ,ue reciben un valor.
Este valor se lo enviamos al 'acer la llamada a la funci!n. Pueden e@istir funciones
,ue no reciban ar*umentos.
blo$ue de sentencias" es el con?unto de sentencias ,ue ser:n e?ecutadas cuando
se realice la llamada a la funci!n.
Las funciones pueden ser llamadas desde la funci!n main o desde otras
funciones. 7unca se debe llamar a la funci!n main desde otro lu*ar del pro*rama.
Por Dltimo recalcar ,ue los ar*umentos de la funci!n > sus variables locales se
destruir:n al finaliCar la e?ecuci!n de la misma.
10.3.- Declaracin de las funciones
5l i*ual ,ue las variablesB las funciones tambi=n 'an de ser declaradas. Esto es
lo ,ue se conoce como prototipo de una funci!n. Para ,ue un pro*rama en C sea
compatible entre distintos compiladores es imprescindible escribir los prototipos de
las funciones.
Los prototipos de las funciones pueden escribirse antes de la funci!n main o
bi=n en otro fic'ero. En este Dltimo caso se lo indicaremos al compilador mediante
la directiva #include.
En el e?emplo ad?unto podremos ver la declaraci!n de una funci!n - prototipo ..
5l no recibir ni retornar nin*Dn valorB est: declarada como void en ambos lados.
Tambi=n vemos ,ue e@iste una variable *lobal llamada num. Esta variable es
reconocible en todas las funciones del pro*rama. La en la funci!n main
encontramos una variable local llamada num. 5l ser una variable localB =sta tendr:
preferencia sobre la *lobal. Por tanto la funci!n escribir: los nDmeros 19 > #.
/* JeclaraciKn de funciones3 */
Ainclude =stdio3!>
void funcion(void)C /* prototipo */
int num08C /* variable global */
main() /* Escribe dos nTmeros */
{
int num012C /* variable local */
printf(DEdFnD?num)C
funcion()C /* llamada */
}
void funcion(void)
{
printf(DEdFnD?num)C
}
Hrc!ivoI funcion43c
10.4.- Paso de parmetros a una funcin
Como >a 'emos vistoB las funciones pueden retornar un valor. Esto se 'ace
mediante la instrucci!n returnB ,ue finaliCa la e?ecuci!n de la funci!nB devolviendo
o no un valor.
En una misma funci!n podemos tener m:s de una instrucci!n return. La forma
de retornar un valor es la si*uienteA
return ( valor o e#presiKn )C
El valor devuelto por la funci!n debe asi*narse a una variable. e lo contrarioB
el valor se perder:.
En el e?emplo puedes ver lo ,ue ocurre si no *uardamos el valor en una
variable. /)?ate ,ue a la 'ora de mostrar el resultado de la sumaB en el printfB
tambi=n podemos llamar a la funci!n.
/* ,aso de par(metros3 */
Ainclude =stdio3!>
int suma(int?int)C /* prototipo */
main() /* /eali%a una suma */
{
int a012?b048?tC
t0suma(a?b)C /* guardamos el valor */
printf(DEd0EdD?suma(a?b)?t)C
suma(a?b)C /* el valor se pierde */
}
int suma(int a?int b)
{
return (aGb)C
}
Hrc!ivoI funcion@3c
5'ora veremos lo ,ue se conoce como paso de par:metros.
E@isten dos formas de enviar par:metros a una funci!nA
Por valor: cual,uier cambio ,ue se realice dentro de la funci!n en el ar*umento
enviadoB NO afectar: al valor ori*inal de las variables utiliCadas en la llamada. Es
como si traba?aramos con una copiaB no con el original. 7o es posible enviar por
valor arraysB deberemos 'acerlo por referencia.
Por referencia: lo ,ue 'acemos es enviar a la funci!n la direcci!n de memoria
donde se encuentra la variable o dato. Cual,uier modificaci!n SI afectar: a las
variables utiliCadas en la llamada. Traba?amos directamente con el original.
/* ,aso por valor3 */
Ainclude =stdio3!>
void intercambio(int?int)C
main() /* +ntercambio de valores */
{
int a01?b04C
printf(Da0Ed & b0EdD?a?b)C
intercambio(a?b)C /* llamada */
printf(Da0Ed & b0EdD?a?b)C
}
void intercambio (int #?int &)
{
int au#C
au#0#C
#0&C
&0au#C
printf(Da0Ed & b0EdD?#?&)C
}
Hrc!ivoI funcion13c
Para enviar un valor por referencia se utiliCa el s)mbolo & - ampersand . delante
de la variable enviada. Esto le indica al compilador ,ue la funci!n ,ue se e?ecutar:
tendra ,ue obtener la direcci!n de memoria en ,ue se encuentra la variable.
;amos a fi?arnos en los e?emplos. En el e?emplo anterior podr:s comprobar ,ue
antes > despu=s de la llamadaB las variables mantienen su valor. %olamente se
modifica en la funci!n intercambio - paso por %alor ..
En el si*uiente e?emplo podr:s ver como las variables intercambian su valor tras
la llamada de la funci!n - paso por referencia ..
Las variables con un * son conocidas como punterosB el Dnico dato en HCH ,ue
puede almacenar una direcci!n de memoria.
/* ,aso por referencia3 */
Ainclude =stdio3!>
void intercambio(int *?int *)C
main() /* +ntercambio de valores */
{
int a01?b04C
printf(Da0Ed & b0EdD?a?b)C
intercambio(Ma?Mb)C /* llamada */
printf(Da0Ed & b0EdD?a?b)C
}
void intercambio (int *#?int *&)
{
int au#C
au#0*#C
*#0*&C
*&0au#C
printf(Da0Ed & b0EdD?*#?*&)C
}
Hrc!ivoI funcion83c
.- Los argumentos de la funcin main
La 'emos visto ,ue las funciones pueden recibir ar*umentos. Pues bi=nB la
funci!n main no pod)a ser menos > tambi=n puede recibir ar*umentosB en este
caso desde el e@terior.
Los ar*umentos ,ue puede recibir sonA
argc: es un contador. %u valor es i*ual al nDmero de ar*umentos escritos en la
l)nea de comandosB contando el nombre del pro*rama ,ue es el primer ar*umento.
argv: es un puntero a un arra> de cadenas de caracteres ,ue contiene los
ar*umentosB uno por cadena.
En este e?emplo vamos a ver un pe,ueEo pro*rama ,ue escribir: un saludo por
pantalla. El pro*rama FUNCION6.EXE.
/* Hrgumentos de la main3 */
Ainclude =stdio3!>
main(int argc?c!ar *argv;<) /* argumentos */
{
printf(DFn:urso de ,rogramaciKn en : P :op&rig!t (c) 1557P4221?
Bergio ,ac!oFnD)C
printf(D,rograma de ejemplo3FnFnD)C
if (argc=4)
{
printf(D*ecleeI funcion6 suWnombreD)C
e#it(1)C /* fin */
}
printf(DNola EsD?argv;1<)C
}
Hrc!ivoI funcion63c
11.- ARRAYS

8n arra> es un identificador ,ue referencia un con?unto de datos del mismo tipo.
Ima*ina un tipo de dato intF podremos crear un con?unto de datos de ese tipo >
utiliCar uno u otro con s!lo cambiar el )ndice ,ue lo referencia. El )ndice ser: un
valor entero > positivo. En C los arra>s comienCan por la posici!n 0.
11.1.- Vectores
8n vector es un arra> unidimensionalB es decirB s!lo utiliCa un )ndice para
referenciar a cada uno de los elementos. %u declaraci!n ser:A
tipo nombre ;tama.o<C
El tipo puede ser cual,uiera de los >a conocidos > el tamaEo indica el nDmero de
elementos del vector - se debe indicar entre corc'etes [ ] .. En el e?emplo puedes
observar ,ue la variable i es utiliCada como )ndiceB el primer for sirve para rellenar
el vector > el se*undo para visualiCarlo. Como vesB las posiciones van de 0 a 9
- total 19 elementos ..
/* JeclaraciKn de un arra&3 */
Ainclude =stdio3!>
main() /* /ellenamos del 2 P 5 */
{
int vector;12<?iC
for (i02Ci=12CiGG) vector;i<0iC
for (i02Ci=12CiGG) printf(D EdD?vector;i<)C
}
Hrc!ivoI arra&s13c
Podemos iniciali&ar -asi*narle valores. un vector en el momento de declararlo.
%i lo 'acemos as) no es necesario indicar el tamaEo. %u sinta@is esA
tipo nombre ;<0{ valor 1? valor 4333}
E?emplosA
int vector;<0{1?4?@?1?8?6?7?R}C
c!ar vector;<0DprogramadorDC
c!ar vector;<0{9p9?9r9?9o9?9g9?9r9?9a9?9m9?9a9?9d9?9o9?9r9}C
8na particularidad con los vectores de tipo char -cadena de caracteres.B es ,ue
deberemos indicar en ,ue elemento se encuentra el fin de la cadena mediante el
caracter nulo -\0.. Esto no lo controla el compiladorB > tendremos ,ue ser nosotros
los ,ue insertemos este caracter al final de la cadena.
Por tantoB en un vector de 19 elementos de tipo char podremos rellenar un
m:@imo de 2B es decirB 'asta vector[8]. %i s!lo rellenamos los # primerosB 'asta
vector[4]B debemos asi*nar el caracter nulo a vector[5]. Es mu> sencilloA
vector[5]='\0'; .
5'ora veremos un e?emplo de como se rellena un vector de tipo char.
/* 'ector de tipo c!ar3 */
Ainclude =stdio3!>
main() /* /ellenamos un vector c!ar */
{
c!ar cadena;42<C
int iC
for (i02Ci=15 MM cadena;iP1<S01@CiGG)
cadena;i<0getc!e( )C
if (i0015) cadena;i<09F29C
else cadena;iP1<09F29C
printf(DFnEsD?cadena)C
}
Hrc!ivoI arra&s43c
Podemos ver ,ue en el for se encuentran dos condicionesA
1.- Mue no se 'a>an rellenado todos los elementos -i<19..
2.- Mue el usuario no 'a>a pulsado la tecla E7TE3B cu>o c!di*o 5%CII es 13.
-cadena[x-i]!=13..
Tambi=n podemos observar una nueva funci!n llamada getche( )B ,ue se
encuentra en conio.h. Esta funci!n permite la entrada de un caracter por teclado.
espu=s se encuentra un ifB ,ue comprueba si se 'a rellenado todo el vector. %i es
ciertoB coloca el caracter nulo en el elemento nN29 -cadena[19].. En caso
contrario tenemos el elseB ,ue asi*na el caracter nulo al elemento ,ue almacen! el
caracter E7TE3.
En resumenA al declarar una cadena deberemos reservar una posici!n m:s ,ue
la lon*itud ,ue ,ueremos ,ue ten*a dic'a cadena.
.- Llamadas a funciones con arrays
Como >a se coment! en el tema anteriorB los arra>s Dnicamente pueden ser
enviados a una funci!n por referencia. Para ello deberemos enviar la direcci!n de
memoria del primer elemento del arra>. Por tantoB el ar*umento de la funci!n
deber: ser un puntero.
/* Envo de un arra& a una funciKn3 */
Ainclude =stdio3!>
void visuali%ar(int ;<)C /* prototipo */
main() /* rellenamos & visuali%amos */
{
int arra&;48<?iC
for (i02Ci=48CiGG)
{
printf(DElemento n[ EdD?iG1)C
scanf(DEdD?Marra&;i<)C
}
visuali%ar(Marra&;2<)C
}
void visuali%ar(int arra&;<) /* desarrollo */
{
int iC
for (i02Ci=48CiGG) printf(DEdD?arra&;i<)C
}
Hrc!ivoI arra&s@3c
En el e?emplo se puede apreciar la forma de enviar un arra> por referencia. La
funci!n se pod)a 'aber declarado de otra maneraB aun,ue funciona e@actamente
i*ualA
declaracin o prototipo
void visuali%ar(int *)C
desarrollo de la funcin
void visuali%ar(int *arra&)
11.2.- Matrices
8na matriC es un arra> multidimensional. %e definen i*ual ,ue los vectores
e@cepto ,ue se re,uiere un )ndice por cada dimensi!n.
%u sinta@is es la si*uienteA
tipo nombre ;tama.o 1<;tama.o 4<333C
8na matriC bidimensional se podr)a representar *r:ficamente como una tabla
con filas > columnas.
La matriC tridimensional se utiliCaB por e?emploB para traba?os *r:ficos con
ob?etos 3D.
En el e?emplo puedes ver como se rellena > visualiCa una matriC bidimensional.
%e necesitan dos bucles para cada una de las operaciones. 8n bucle controla las
filas > otro las columnas.
/* Latri% bidimensional3 */
Ainclude =stdio3!>
main() /* /ellenamos una matri% */
{
int #?i?numeros;@<;1<C
/* rellenamos la matri% */
for (#02C#=@C#GG)
for (i02Ci=1CiGG)
scanf(DEdD?Mnumeros;#<;i<)C
/* visuali%amos la matri% */
for (#02C#=@C#GG)
for (i02Ci=1CiGG)
printf(DEdD?numeros;#<;i<)C
}
Hrc!ivoI arra&s13c
%i al declarar una matriC tambi=n ,ueremos inicialiCarlaB 'abr: ,ue tener
encuenta el orden en el ,ue los valores son asi*nados a los elementos de la matriC.
;eamos al*unos e?emplosA
int numeros;@<;1<0{1?4?@?1?8?6?7?R?5?12?11?14}C
,uedar)an asi*nados de la si*uiente maneraA
numeros;2<;2<01 numeros;2<;1<04 numeros;2<;4<0@ numeros;2<;@<01
numeros;1<;2<08 numeros;1<;1<06 numeros;1<;4<07 numeros;1<;@<0R
numeros;4<;2<05 numeros;4<;1<012 numeros;4<;4<011 numeros;4<;@<014
Tambi=n se pueden inicialiCar cadenas de te@toA
c!ar dias;7<
;12<0{DlunesD?DmartesD?DmircolesD?DjuevesD?DviernesD?Ds(badoD?DdomingoD}C
Para referirnos a cada palabra bastar)a con el primer )ndiceA
printf(DEsD?dias;i<)C
12.- PUNTEROS

8n puntero es una variable ,ue contiene la direcci!n de memoria de otra
variable. %e utiliCan para pasar informaci!n entre una funci!n > sus puntos de
llamada.
12.1.- Declaracin
%u sinta@is es la si*uienteA
tipo *nombreC
onde nombre esB naturalmenteB el nombre de la variableB > tipo es el tipo del
elemento cu>a direcci!n almacena el puntero.
12.2.- Operadores
E@isten dos operadores especiales para traba?ar con punterosA & > *.
El primero devuelve la direcci!n de memoria de su operando. Por e?emploB si
,ueremos *uardar en el puntero x la direcci!n de memoria de la variable numB
deberemos 'acer lo si*uienteA
#0MnumC
El se*undo devuelve el valor de la variable cu>a direcci!n es contenida por el
puntero. Este e?emplo sitDa el contenido de la variable apuntada por xB es decir
numB en la variable aA
a0*#C
12.3.- Asignacin
Los punteros se asi*nan i*ual ,ue el resto de las variables. El pro*rama e?emplo
mostrar: las direcciones contenidas en p1 > p2B ,ue ser: la misma en ambos
punteros.
/* Hsignaciones de punteros3 */
Ainclude =stdio3!>
main() /* Hsignamos direcciones */
{
int aC
int *p1?*p4C
p10MaC
p40p1C
printf(DEp EpD?p1?p4)C
}
Hrc!ivoI puntero13c
12.4.- Aritmtica de direcciones
Es posible desplaCar un puntero recorriendo posiciones de memoria. Para ello
podemos usar los operadores de sumaB restaB incremento > decremento -OB -B OOB
- -.. %i tenemos un puntero - p1 . de tipo int - 2 b#tes .B apuntando a la posici!n
39999 > 'acemosA p1=p1+5; el puntero almacenar: la posici!n 39919B por,ue
apunta # enteros por encima - 10 b#tes m's ..
13.- ESTRUCTURAS

13.1.- Concepto de estructura
8na estructura es un con?unto de una o m:s variablesB de distinto tipoB
a*rupadas ba?o un mismo nombre para ,ue su mane?o sea m:s sencillo.
%u utiliCaci!n m:s 'abitual es para la pro*ramaci!n de bases de datosB >a ,ue
est:n especialmente indicadas para el traba?o con re*istros o fic'as.
La sinta@is de su declaraci!n es la si*uienteA
struct tipoWestructura
{
tipoWvariable nombreWvariable1C
tipoWvariable nombreWvariable4C
tipoWvariable nombreWvariable@C
}C
onde tipo_estructura es el nombre del nuevo tipo de dato ,ue 'emos
creado. Por DltimoB tipo_variable > nombre_variable son las variables ,ue
forman parte de la estructura.
Para definir variables del tipo ,ue acabamos de crear lo podemos 'acer de
varias manerasB aun,ue las dos m:s utiliCadas son =stasA
:na forma !e !efinir la estructura1
struct trabajador
{
c!ar nombre;42<C
c!ar apellidos;12<C
int edadC
c!ar puesto;12<C
}C
struct trabajador fijo? temporalC
=tra forma1
struct trabajador
{
c!ar nombre;42<C
c!ar apellidos;12<C
int edadC
c!ar puesto;12<C
}fijo? temporalC
En el primer caso declaramos la estructuraB > en el momento en ,ue
necesitamos las variablesB las declaramos. En el se*undo las declaramos al mismo
tiempo ,ue la estructura. El problema del se*undo m=todo es ,ue no podremos
declarar m:s variables de este tipo a lo lar*o del pro*rama. Para poder declarar
una variable de tipo estructuraB la estructura tiene ,ue estar declarada
previamente. %e debe declarar antes de la funci!n main.
El mane?o de las estructuras es mu> sencilloB as) como el acceso a los campos
- o variables . de estas estructuras. La forma de acceder a estos campos es la
si*uienteA
variable3campoC
onde variable es el nombre de la variable de tipo estructura ,ue 'emos
creadoB > campo es el nombre de la variable ,ue forma parte de la estructura. Lo
veremos me?or con un e?emplo basado en la estructura del cap)tulo 13.1A
temporal3edad048C
Lo ,ue estamos 'aciendo es almacenar el valor 2# en el campo edad de la
variable temporal de tipo trabajador.
(tra caracter)stica interesante de las estructuras es ,ue permiten pasar el
contenido de una estructura a otraB siempre ,ue sean del mismo tipo naturalmenteA
fijo0temporalC
5l i*ual ,ue con los otros tipos de datosB tambi=n es posible inicialiCar variables
de tipo estructura en el momento de su declaraci!nA
struct trabajador fijo0{D,edroD?DNern(nde% Bu(re%D? @4? DgerenteD}C
%i uno de los campos de la estructura es un array de nDmerosB los valores de la
inicialiCaci!n deber:n ir entre llavesA
struct notas
{
c!ar nombre;@2<C
int notas;8<C
}C
struct notas alumno0{D:arlos ,re%D?{R?7?5?6?12}}C
13.2.- Estructuras y funciones
Podemos enviar una estructura a una funci!n de las dos maneras conocidasA
1.- Por valor: su declaraci!n ser)aA
void visuali%ar(struct trabajador)C
espu=s declarar)amos la variable fijo > su llamada ser)aA
visuali%ar(fijo)C
Por DltimoB el desarrollo de la funci!n ser)aA
void visuali%ar(struct trabajador datos)
/* ,aso de una estructura por valor3 */
Ainclude =stdio3!>
struct trabajador
{
c!ar nombre;42<C
c!ar apellidos;12<C
int edadC
c!ar puesto;12<C
}C
void visuali%ar(struct trabajador)C
main() /* /ellenar & visuali%ar */
{
struct trabajador fijoC
printf(D)ombreI D)C
scanf(DEsD?fijo3nombre)C
printf(DFnHpellidosI D)C
scanf(DEsD?fijo3apellidos)C
printf(DFnEdadI D)C
scanf(DEdD?Mfijo3edad)C
printf(DFn,uestoI D)C
scanf(DEsD?fijo3puesto)C
visuali%ar(fijo)C
}
void visuali%ar(struct trabajador datos)
{
printf(D)ombreI EsD?datos3nombre)C
printf(DFnHpellidosI EsD?datos3apellidos)C
printf(DFnEdadI EdD?datos3edad)C
printf(DFn,uestoI EsD?datos3puesto)C
}
Hrc!ivoI estruc13c
2.- Por referencia: su declaraci!n ser)aA
void visuali%ar(struct trabajador *)C
espu=s declararemos la variable fijo > su llamada ser:A
visuali%ar(Mfijo)C
Por DltimoB el desarrollo de la funci!n ser:A
void visuali%ar(struct trabajador *datos)
/)?ate ,ue en la funci!n visualizarB el acceso a los campos de la variable datos
se realiCa mediante el operador ->B >a ,ue tratamos con un puntero. En estos
casos siempre utiliCaremos el operador ->. %e consi*ue con el si*no menos se*uido
de ma#or $ue.
/* ,aso de una estructura por referencia3 */
Ainclude =stdio3!>
struct trabajador
{
c!ar nombre;42<C
c!ar apellidos;12<C
int edadC
c!ar puesto;12<C
}C
void visuali%ar(struct trabajador *)C
main() /* /ellenar & visuali%ar */
{
struct trabajador fijoC
printf(D)ombreI D)C
scanf(DEsD?fijo3nombre)C
printf(DFnHpellidosI D)C
scanf(DEsD?fijo3apellidos)C
printf(DFnEdadI D)C
scanf(DEdD?Mfijo3edad)C
printf(DFn,uestoI D)C
scanf(DEsD?fijo3puesto)C
visuali%ar(Mfijo)C
}
void visuali%ar(struct trabajador *datos)
{
printf(D)ombreI EsD?datosP>nombre)C
printf(DFnHpellidosI EsD?datosP>apellidos)C
printf(DFnEdadI EdD?datosP>edad)C
printf(DFn,uestoI EsD?datosP>puesto)C
}
Hrc!ivoI estruc43c
13.3.- Arrays de estructuras
Es posible a*rupar un con?unto de elementos de tipo estructura en un arra>.
Esto se conoce como arra# de estructurasA
struct trabajador
{
c!ar nombre;42<C
c!ar apellidos;12<C
int edadC
}C
struct trabajador fijo;42<C
5s) podremos almacenar los datos de 29 traba?adores. E?emplos sobre como
acceder a los campos > sus elementosA para ver el nombre del cuarto traba?adorB
fijo[3].nombre;. Para ver la tercera letra del nombre del cuarto traba?adorB
fijo[3].nombre[2];. Para inicialiCar la variable en el momento de declararla lo
'aremos de esta maneraA
struct trabajador fijo;42<0{{DQosD?DNerrero Lartne%D?45}?{DOuisD?DZarca
B(nc!e%D?16}}C
13.4.- Typedef
Es posible a*rupar un con?unto de elementos de tipo estructura en un arra>.
Esto se conoce como arra# de estructurasA El len*ua?e HCH dispone de una
declaraci!n llamada typedef ,ue permite la creaci!n de nuevos tipos de datos.
E?emplosA
t&pedef int enteroC /* acabamos de crear un tipo de dato llamado entero */
entero a? b0@C /* declaramos dos variables de este tipo */
%u empleo con estructuras est: especialmente indicado. %e puede 'acer de
varias formasA
:na forma !e hacerlo1
struct trabajador
{
c!ar nombre;42<C
c!ar apellidos;12<C
int edadC
}C
t&pedef struct trabajador datosC
datos fijo?temporalC
=tra forma1
t&pedef struct
{
c!ar nombre;42<C
c!ar apellidos;12<C
int edadC
}datosC
datos fijo?temporalC
13.3.- Arrays de estructuras
Es posible a*rupar un con?unto de elementos de tipo estructura en un arra>.
Esto se conoce como arra# de estructurasA
struct trabajador
{
c!ar nombre;42<C
c!ar apellidos;12<C
int edadC
}C
struct trabajador fijo;42<C
5s) podremos almacenar los datos de 29 traba?adores. E?emplos sobre como
acceder a los campos > sus elementosA para ver el nombre del cuarto traba?adorB
fijo[3].nombre;. Para ver la tercera letra del nombre del cuarto traba?adorB
fijo[3].nombre[2];. Para inicialiCar la variable en el momento de declararla lo
'aremos de esta maneraA
struct trabajador fijo;42<0{{DQosD?DNerrero Lartne%D?45}?{DOuisD?DZarca
B(nc!e%D?16}}C
13.4.- Typedef
Es posible a*rupar un con?unto de elementos de tipo estructura en un arra>.
Esto se conoce como arra# de estructurasA El len*ua?e HCH dispone de una
declaraci!n llamada typedef ,ue permite la creaci!n de nuevos tipos de datos.
E?emplosA
t&pedef int enteroC /* acabamos de crear un tipo de dato llamado entero */
entero a? b0@C /* declaramos dos variables de este tipo */
%u empleo con estructuras est: especialmente indicado. %e puede 'acer de
varias formasA
:na forma !e hacerlo1
struct trabajador
{
c!ar nombre;42<C
c!ar apellidos;12<C
int edadC
}C
t&pedef struct trabajador datosC
datos fijo?temporalC
=tra forma1
t&pedef struct
{
c!ar nombre;42<C
c!ar apellidos;12<C
int edadC
}datosC
datos fijo?temporalC
14.- !IC"EROS

5'ora veremos la forma de almacenar datos ,ue podremos recuperar cuando
deseemos. Estudiaremos los distintos modos en ,ue podemos abrir un fic'eroB as)
como las funciones para leer > escribir en =l.
14.1.- Apertura
5ntes de abrir un fic'ero necesitamos declarar un puntero de tipo FILEB con el
,ue traba?aremos durante todo el proceso. Para abrir el fic'ero utiliCaremos la
funci!n fopen( ).
%u sinta@is esA
V+OE *punteroC
puntero 0 fopen ( nombre del fic!ero? Dmodo de aperturaD )C
donde puntero es la variable de tipo FILEB nombre del fichero es el nombre
,ue daremos al fic'ero ,ue ,ueremos crear o abrir. Este nombre debe ir encerrado
entre comillas. Tambi=n podemos especificar la ruta donde se encuentra o utiliCar
un arra> ,ue conten*a el nombre del arc'ivo - en este caso no se pondr:n las
comillas .. 5l*unos e?emplosA
puntero0fopen(DJH*-B3JH*D?DrD)C
puntero0fopen(D:IFF*\*FFBHOUJ-3*\*D?D"D)C
8n arc'ivo puede ser abierto en dos modos diferentesB en modo te@to o en
modo binario. 5 continuaci!n lo veremos con m:s detalle.
Modo texto
" crea un fichero !e escritura$ &i ya e7iste lo crea !e nuevo$
"G crea un fichero !e lectura y escritura$ &i ya e7iste lo crea !e nuevo$
a abre o crea un fichero )ara aa!ir !atos al final !el mismo$
aG abre o crea un fichero )ara leer y aa!ir !atos al final !el mismo$
r abre un fichero !e lectura$
rG abre un fichero !e lectura y escritura$
Modo binario
"b crea un fichero !e escritura$ &i ya e7iste lo crea !e nuevo$
"Gb crea un fichero !e lectura y escritura$ &i ya e7iste lo crea !e nuevo$
ab abre o crea un fichero )ara aa!ir !atos al final !el mismo$
aGb abre o crea un fichero )ara leer y aa!ir !atos al final !el mismo$
rb abre un fichero !e lectura$
rGb abre un fichero !e lectura y escritura$
La funci!n fopen devuelveB como >a 'emos vistoB un puntero de tipo FILE. %i al
intentar abrir el fic'ero se produ?ese un error - por e?emplo si no e@iste > lo
estamos abriendo en modo lectura .B la funci!n fopen devolver)a NULL. Por esta
raC!n es me?or controlar las posibles causas de error a la 'ora de pro*ramar. 8n
e?emploA
V+OE *pfC
pf0fopen(Ddatos3t#tD?DrD)C
if (pf 00 )UOO) printf(DError al abrir el fic!eroD)C
freopen( )
Esta funci!n cierra el fic'ero apuntado por el puntero > reasi*na este puntero a
un fic'ero ,ue ser: abierto. %u sinta@is esA
freopen(nombre del fic!ero?Dmodo de aperturaD?puntero)C
donde nombre del fichero es el nombre del nuevo fic'ero ,ue ,ueremos abrirB
lue*o el modo de aperturaB > finalmente el puntero ,ue va a ser reasi*nado.
14.2.- Cierre
8na veC ,ue 'emos acabado nuestro traba?o con un fic'ero es recomendable
cerrarlo. Los fic'eros se cierran al finaliCar el pro*rama pero el nDmero de estos
,ue pueden estar abiertos es limitado. Para cerrar los fic'eros utiliCaremos la
funci!n fclose( );.
Esta funci!n cierra el fic'eroB cu>o puntero le indicamos como par:metro. %i el
fic'ero se cierra con =@ito devuelve 0.
fclose(puntero)C
8n e?emplo ilustrativo aun,ue de poca utilidadA
V+OE *pfC
pf0fopen(DHZE)JH3JH*D?DrbD)C
if ( pf 00 )UOO ) printf (DError al abrir el fic!eroD)C
else fclose(pf)C
14.3.- Escritura y lectura
5 continuaci!n veremos las funciones ,ue se podr:n utiliCar dependiendo del
dato ,ue ,ueramos escribir >Go leer en el fic'ero.
Un caracter
fputc( variableWcaracter ? punteroWfic!ero )C
Escribimos un caracter en un fic'ero - abierto en modo escritura .. 8n e?emploA
V+OE *pfC
c!ar letra09a9C
if (S(pf0fopen(Ddatos3t#tD?D"D))) /* otra forma de controlar si se produce un error
*/
{
printf(DError al abrir el fic!eroD)C
e#it(2)C /* abandonamos el programa */
}
else fputc(letra?pf)C
fclose(pf)C]b
fgetc( punteroWfic!ero )C
Lee un caracter de un fic'ero - abierto en modo lectura .. eberemos *uardarlo
en una variable. 8n e?emploA
V+OE *pfC
c!ar letraC
if (S(pf0fopen(Ddatos3t#tD?DrD))) /* controlamos si se produce un error */
{
printf(DError al abrir el fic!eroD)C
e#it(2)C /* abandonamos el programa */
}
else
{
letra0fgetc(pf)C
printf(DEcD?letra)C
fclose(pf)C
}
Un nmero entero
put"( variableWentera? punteroWfic!ero )C
Escribe un nDmero entero en formato binario en el fic'ero. E?emploA
V+OE *pfC
int num0@C
if (S(pf0fopen(Ddatos3t#tD?D"bD))) /* controlamos si se produce un error */
{
printf(DError al abrir el fic!eroD)C
e#it(2)C /* abandonamos el programa */
}
else
{
fput"(num?pf)C /* tambin podamos !aber !ec!o directamenteI
fput"(@?pf)C */
fclose(pf)C
}
get"( punteroWfic!ero )C
Lee un nDmero entero de un fic'eroB avanCando dos b>tes despu=s de cada
lectura. 8n e?emploA
V+OE *pfC
int numC
if (S(pf0fopen(Ddatos3t#tD?DrbD))) /* controlamos si se produce un error */
{
printf(DError al abrir el fic!eroD)C
e#it(2)C /* abandonamos el programa */
}
else
{
num0get"(pf)C
printf(DEdD?num)C
fclose(pf)C
}
Una cadena de caracteres
fputs( variableWarra&? punteroWfic!ero )C
Escribe una cadena de caracteres en el fic'ero. E?emploA
V+OE *pfC
c!ar cad0DLe llamo 'icenteDC
if (S(pf0fopen(Ddatos3t#tD?D"D))) /* controlamos si se produce un error */
{
printf(DError al abrir el fic!eroD)C
e#it(2)C /* abandonamos el programa */
}
else
{
fputs(cad?pf)C /* o tambin asI fputs(DLe llamo 'icenteD?pf)C */
fclose(pf)C
}
fgets( variableWarra&? variableWentera? punteroWfic!ero )C
Lee una cadena de caracteres del fic'ero > la almacena en variableParra>. La
variablePentera indica la lon*itud m:@ima de caracteres ,ue puede leer. 8n
e?emploA
V+OE *pfC
c!ar cad;R2<C
if (S(pf0fopen(Ddatos3t#tD?DrbD))) /* controlamos si se produce un error */
{
printf(DError al abrir el fic!eroD)C
e#it(2)C /* abandonamos el programa */
}
else
{
fgets(cad?R2?pf)C
printf(DEsD?cad)C
fclose(pf)C
}
Con formato
fprintf( punteroWfic!ero? formato? argumentos)C
/unciona i*ual ,ue un printf pero *uarda la salida en un fic'ero. E?emploA
V+OE *pfC
c!ar nombre;42<0DBantiagoDC
int edad0@1C
if (S(pf0fopen(Ddatos3t#tD?D"D))) /* controlamos si se produce un error */
{
printf(DError al abrir el fic!eroD)C
e#it(2)C /* abandonamos el programa */
}
else
{
fprintf(pf?DE42sE4dFnD?nombre?edad)C
fclose(pf)C
}
fscanf( punteroWfic!ero? formato? argumentos )C
Lee los ar*umentos del fic'ero. 5l i*ual ,ue con un scanfB deberemos indicar la
direcci!n de memoria de los ar*umentos con el s)mbolo & - ampersand .. 8n
e?emploA
V+OE *pfC
c!ar nombre;42<C
int edadC
if (S(pf0fopen(Ddatos3t#tD?DrbD))) /* controlamos si se produce un error */
{
printf(DError al abrir el fic!eroD)C
e#it(2)C /* abandonamos el programa */
}
else
{
fscanf(pf?DE42sE4dFD?nombre?Medad)C
printf(D)ombreI Es EdadI EdD?nombre?edad)C
fclose(pf)C
}
Estructuras
f"rite( *buffer? tama.o? n[ de veces? punteroWfic!ero )C
%e utiliCa para escribir blo,ues de te@to o de datosB estructurasB en un fic'ero.
En esta funci!nB *buffer ser: la direcci!n de memoria de la cu:l se reco*er:n los
datosF tamaoB el tamaEo en b>tes ,ue ocupan esos datos > n de vecesB ser: el
nDmero de elementos del tamaEo indicado ,ue se escribir:n.
fread( *buffer? tama.o? n[ de veces? punteroWfic!ero )C
%e utiliCa para leer blo,ues de te@to o de datos de un fic'ero. En esta funci!nB
*buffer es la direcci!n de memoria en la ,ue se almacenan los datosF tamaoB el
tamaEo en b>tes ,ue ocupan esos datos > n de vecesB ser: el nDmero de
elementos del tamaEo indicado ,ue se leer:n.
Puedes encontrar e?emplos sobre la apertura > cierre de fic'erosB as) como de la
lectura > escritura de datosB en el arc'ivo IMAGECAT.C. %e trata de un pro*rama
,ue crea un cat:lo*o en formato 1T<L a partir de las im:*enes ,ue se encuentran
en un directorio determinado.
Otras funciones para ficheros
re"ind( punteroWfic!ero )C
%itDa el puntero al principio del arc'ivo.
fsee$( punteroWfic!ero? long posicion? int origen )C
%itDa el puntero en la posicion ,ue le indi,uemos. Como origen podremos
ponerA
2 o BEE^WBE*3 el )rinci)io !el fichero
1 o BEE^W:U/3 la )osici*n actual
4 o BEE^WE)J3 el final !el fichero
rename( nombre1? nombre4 )C
%u funci!n es e@actamente la misma ,ue la ,ue conocemos en MS-DOS.
Cambia el nombre del fic'ero nombre1 por un nuevo nombreB nombre2.
remove( nombre )C
Como la funci!n del (% delB podremos eliminar el arc'ivo indicado en
nombre.
Deteccin de final de fichero
feof( punteroWfic!ero )C
%iempre deberemos controlar si 'emos lle*ado al final de fic'ero cuando
estemos le>endoB de lo contrario podr)an producirse errores de lectura no
deseados. Para este fin disponemos de la funci!n feof( ). Esta funci!n retorna 0 si
no 'a lle*ado al finalB > un valor diferente de 0 si lo 'a alcanCado.
Pues con esto lle*amos al final del tema. Espero ,ue no 'a>a sido mu> pesado.
7o es necesario ,ue te aprendas todas las funciones de memoria. C=ntrate sobre
todo en las funciones fputs( )B fgets( )B fprintf( )B fwrite( ) > fread( ). Con
estas cinco se pueden *estionar los fic'eros perfectamente.
15.- GESTION DINAMICA DE MEMORIA

15.1.- Funciones
Como veremos despu=sB la *esti!n din:mica memoria se realiCa mediante
estructuras din:micas de datos. /)?ate ,ue se repite la palabra dinmica. Estas
estructuras se diferencian de las estticas - arra>s > estructuras .B en ,ue no
tienen un tamaEo fi?oB es decirB no tenemos ,ue indicar su tamaEo al declararlasB
sino ,ue podremos aumentarlo o disminuirlo en tiempo de ejecucinB cuando se
est= e?ecutando la aplicaci!n. Como puedes verB las estructuras din:micas son de
*ran utilidad. 5 continuaci!n veremos las funciones ,ue se encar*an de reservar >
liberar memoria durante la e?ecuci!nB ,ue se encuentran en la librer)a alloc.hA
malloc( tamao );
Esta funci!n reserva en memoria una Cona de tamao b>tesB > devuelve un
puntero al inicio de esa Cona. %i no 'ubiera suficiente memoria retornar)a NULL.
<:s adelante veremos al*unos e?emplos.
free( puntero );
Esta funci!n libera de la memoria la Cona ,ue 'ab)amos reservado
anteriormente con la funci!n malloc. Tambi=n podremos ver al*Dn e?emplo en la
p:*ina si*uiente.
15.2.- Estructuras dinmicas de datos
En funci!n de la forma en ,ue se relacionan e@isten varios tipos de estructuras
de datos. Este tipo de estructuras son autorreferenciadasB es decirB contienen entre
sus campos un puntero de su mismo tipo. Las m:s utiliCadas sonA
P pilas
P colas
P listas
Las pilas
Este tipo de estructuras se caracteriCa por,ue todas las operaciones se realiCan
en el mismo lado. Es de tipo LIFO - Last In First Out .B el Dltimo elemento en
entrar es el primero en salir.
/* Ejemplo de una pila3 */
Ainclude =stdio3!>
Ainclude =conio3!>
Ainclude =stdlib3!>
Ainclude =alloc3!>
void insertar(void)C
void e#traer(void)C
void visuali%ar(void)C
struct pila
{
c!ar nombre;42<C
struct pila *antC
}*:HU0)UOO?*HU\0)UOOC
main() /* /ellenar? e#traer & visuali%ar */
{
c!ar opcC
do
{
clrscr()C /* borramos la pantalla */
goto#&(@2?R)C /* columna @2? fila R */
printf(D13P +nsertarD)C
goto#&(@2?12)C
printf(D43P E#traerD)C
goto#&(@2?14)C
printf(D@3P 'isuali%ar la pilaD)C
goto#&(@2?11)C
printf(D13P BalirD)C
opc0getc!( )C
s"itc!(opc)
{
case 919I
insertar( )C
brea$C
case 949I
e#traer( )C
brea$C
case 9@9I
visuali%ar( )C
}
}"!ile (opcS0919)C
}
void insertar(void)
{
HU\0(struct pila *)malloc(si%eof(struct pila))C
clrscr()C
printf(D)ombreI D)C
gets(HU\P>nombre)C
if (:HU00)UOO)
{
:HU0HU\C
HU\P>ant0)UOOC
}
else
{
HU\P>ant0:HUC
:HU0HU\C
}
}
void e#traer(void)
{
if (:HU00)UOO) returnC
HU\0:HUC
:HU0:HUP>antC
free(HU\)C
}
void visuali%ar(void)
{
if (:HU00)UOO) returnC
clrscr()C
HU\0:HUC
"!ile (HU\S0)UOO)
{
printf(D)ombreI EsFnD?HU\P>nombre)C
HU\0HU\P>antC
}
getc!( )C
}
Hrc!ivoI pila3c
La estructura tipo ,ue utiliCaremos ser: =staA
struct pila
{
tipo variablesC
struct pila *antC
}*:HU0)UOO?*HU\0)UOOC
donde tipo variables ser:n las diferentes variables ,ue *uardaremos en la
estructuraB struct pila *ant es un puntero ,ue apunta al elemento de tipo pila
introducido anteriormenteB *CAB ser: donde *uardaremos el Dltimo elemento
insertado en la pila > *AUX nos servir: para *uardar elementos temporalmente >
para recorrer la pila al visualiCarla.
5ntes de insertar un elementoB deberemos comprobar si la pila est: vac)a o no.
%i lo estuviera deberemos insertar el primer elementoA
:HU0HU\C
:HUP>ant0)UOOC
%i >a 'ubiera al*Dn elemento crearemos uno nuevo apuntado por AUX >
'aremos ,ue AUX->ant apunte a CABB ,ue en este momento contiene la direcci!n
del elemento insertado anteriormente. Tras esto 'aremos ,ue CAB apunte al Dltimo
elemento insertadoB ,ue ser: la nueva cabeCa de la pilaA
HU\P>ant0:HUC
:HU0HU\C
Para e@traer un elemento de la pila deberemos 'acer ,ue AUX apunte a la
misma direcci!n ,ue CABB despu=s 'aremos ,ue CAB apunte a CAB->antB con lo
,ue el elemento anterior pasar: a ser la cabeCa de la pila. Tras estoB solo ,ueda
liberar la memoria de la Cona apuntada por AUX. 7o olvides controlar si e@iste
al*Dn elemento - si CAB es i*ual a NULL la pila est: vac)a .A
if (:HU00)UOO) returnC
HU\0:HUC
:HU0:HUP>antC
free(HU\)C
Por DltimoB para visualiCar los elementos de la pilaB 'aremos ,ue el puntero
au@iliar AUX apunte a la cabeCa de la pilaB o seaB a CAB. Tras esto iremos
visualiCando el contenido de la pilaB 'aciendo ,ue AUX tome la direcci!n de AUX-
>antB mientras AUX sea distinto de NULL. Tambi=n es importante controlar ,ue la
pila no est= vac)a.
if (:HU00)UOO) returnC
HU\0:HUC
"!ile (HU\S0)UOO)
{
printf(DEsD?HU\P>nombre)C
HU\0HU\P>antC
}C
Estructura *r:fica de una pilaA
Las colas
Este tipo de estructuras se caracteriCa por,ue insertamos los elementos por un
lado > los e@traemos por el otro lado. Es de tipo FIFO - First In First Out .B el
primer elemento en entrar es el primero en salir. Para *estionar la cola utiliCaremos
3 punteros - para la pila solo eran necesarios 2 ..
/* Ejemplo de una cola3 */
Ainclude =stdio3!>
Ainclude =conio3!>
Ainclude =stdlib3!>
Ainclude =alloc3!>
void insertar(void)C
void e#traer(void)C
void visuali%ar(void)C
struct cola
{
c!ar nombre;42<C
struct cola *sigC
}*:HU0)UOO?*HU\0)UOO?*V+)0)UOOC
main() /* /ellenar? e#traer & visuali%ar */
{
c!ar opcC
do
{
clrscr()C
goto#&(@2?R)C
printf(D13P +nsertarD)C
goto#&(@2?12)C
printf(D43P E#traerD)C
goto#&(@2?14)C
printf(D@3P 'isuali%ar la colaD)C
goto#&(@2?11)C
printf(D13P BalirD)C
opc0getc!( )C
s"itc!(opc)
{
case 919I
insertar( )C
brea$C
case 949I
e#traer( )C
brea$C
case 9@9I
visuali%ar( )C
}
}"!ile (opcS0919)C
}
void insertar(void)
{
HU\0(struct cola *)malloc(si%eof(struct cola))C
clrscr()C
printf(D)ombreI D)C
gets(HU\P>nombre)C
HU\P>sig0)UOOC
if (V+)00)UOO)
V+)0:HU0HU\C
else
{
V+)P>sig0HU\C
V+)0HU\C
}
}
void e#traer(void)
{
if (:HU00)UOO) returnC
HU\0:HUC
:HU0:HUP>sigC
free(HU\)C
}
void visuali%ar(void)
{
if (:HU00)UOO) returnC
clrscr()C
HU\0:HUC
"!ile (HU\S0)UOO)
{
printf(D)ombreI EsFnD?HU\P>nombre)C
HU\0HU\P>sigC
}
getc!()C
}
Hrc!ivoI cola3c
La estructura ,ue utiliCaremos ser:A
struct cola
{
tipo variablesC
struct cola *sigC
}*:HU0)UOO?*HU\0)UOO?*V+)0)UOOC
donde tipo variables ser:n las diferentes variables ,ue *uardaremos en la
estructuraB struct cola *sig es un puntero ,ue apunta al elemento de tipo cola
introducido a continuaci!nB *CAB ser: donde *uardaremos el primer elemento
insertado en la colaB *AUX nos servir: para *uardar elementos temporalmente >
para recorrer la cola al visualiCarla > *FIN tomar: la direcci!n del Dltimo elemento
insertado.
5ntes de insertar un elementoB deberemos comprobar si la cola est: vac)a o no.
%i lo est: deberemos insertar el primer elementoA
if (V+)00)UOO)
:HU0V+)0HU\C
%i >a e@istiera al*Dn elemento 'aremos ,ue FIN->sig apunte al elemento de
AUX > a continuaci!n 'aremos ,ue FIN tome la direcci!n de AUXB con lo ,ue FIN
apuntar: al Dltimo elemento insertado.
V+)P>sig0HU\C
V+)0HU\C
Para e@traer un elemento de la cola 'aremos ,ue el puntero au@iliar AUX tome
la direcci!n del primer elemento insertadoB ,ue 'emos *uardado en CAB. Tras esto
'aremos ,ue CAB apunte a CAB->sigB es decirB ,ue tome la direcci!n del se*undo
elemento insertadoB ,ue a'ora pasar: a ser el primero. Lue*o liberaremos la Cona
de memoria apuntada por AUXA
HU\0:HUC /* Jeberemos controlar que no est vacaI if (:HU00)UOO) returnC */
:HU0:HUP>sigC
free(HU\)C
Para visualiCar la cola comprobaremos ,ue e@istan elementosB esto esB ,ue FIN
sea distinto de NULL. 1ec'o esto asi*naremos a AUX la direcci!n de CAB e iremos
recorriendo la cola 'asta ,ue AUX sea i*ual a NULL.
HU\0:HUC /* Jeberemos controlar que no est vacaI if (:HU00)UOO) returnC */
"!ile(HU\S0)UOO)
{
printf(DEsD?HU\P>nombre)C
HU\0HU\P>sigC
}
Estructura *r:fica de una colaA
Las listas
Este tipo de estructuras se caracteriCa por,ue los elementos est:n enlaCados
entre s)B de manera ,ue adem:s de las acciones 'abituales de insertarB e@traer >
visualiCar tambi=n podremos buscar un elemento. Para *estionar la lista
utiliCaremos 4 punteros.
/* Ejemplo de una lista3 */
Ainclude =stdio3!>
Ainclude =conio3!>
Ainclude =stdlib3!>
Ainclude =alloc3!>
void insertar(void)C
void e#traer(void)C
void visuali%ar(void)C
struct lista
{
int numC
struct lista *sigC
}*:HU0)UOO?*HU\0)UOO?*V0)UOO?*,0)UOOC
main() /* /ellenar? e#traer & visuali%ar */
{
c!ar opcC
do
{
clrscr( )C
goto#&(@2?R)C
printf(D13P +nsertarD)C
goto#&(@2?12)C
printf(D43P E#traerD)C
goto#&(@2?14)C
printf(D@3P 'isuali%ar la listaD)C
goto#&(@2?11)C
printf(D13P BalirD)C
opc0getc!( )C
s"itc!(opc)
{
case 919I
insertar( )C
brea$C
case 949I
e#traer( )C
brea$C
case 9@9I
visuali%ar( )C
}
}"!ile (opcS0919)C
}
/* H continuaciKn insertaremos el elemento que
vamos a crear en la posiciKn que le corresponda?
teniendo en cuenta que la lista deber( quedar
ordenada de menor a ma&or3 El puntero , comprueba
si el campo num de un elemento es menor que el
campo num del elemento introducido3 El puntero
V se quedar( apuntando al elemento de la posiciKn
anterior al elemento que !emos insertado */
void insertar(void)
{
HU\0(struct lista *)malloc(si%eof(struct lista))C
clrscr( )C
printf(D+ntroduce un nTmeroI D)C
scanf(DEdD?MHU\P>num)C
HU\P>sig0)UOOC
if (:HU00)UOO)
:HU0HU\C
else if (:HUP>num > HU\P>num)
{
HU\P>sig0:HUC
:HU0HU\C
}
else
{
,0V0:HUC
"!ile (,P>num = HU\P>num MM ,S0)UOO)
{
if (,00:HU) ,0,P>sigC
else
{
,0,P>sigC
V0VP>sigC
}
}
HU\P>sig0VP>sigC
VP>sig0HU\C
}
}
void e#traer(void)
{
int varC
if (:HU00)UOO) returnC
clrscr( )C
printf(D+ntroduce el nTmero a e#traerI D)C
scanf(DEdD?Mvar)C
if (:HUP>num00var)
{
,0:HUC
:HU0:HUP>sigC
free(,)C
}
else
{
,0V0:HUC
"!ile (,P>num S0 var MM ,S0)UOO)
{
if (,00:HU) ,0,P>sigC
else
{
,0,P>sigC
V0VP>sigC
}
}
if (,00)UOO) returnC
VP>sig0,P>sigC
free(,)C
}
}
void visuali%ar(void)
{
if (:HU00)UOO) returnC
clrscr( )C
HU\0:HUC
"!ile (HU\S0)UOO)
{
printf(D)TmeroI EdFnD?HU\P>num)C
HU\0HU\P>sigC
}
getc!( )C
}
Hrc!ivoI lista3c
La estructura ,ue utiliCaremos ser:A
struct lista
{
tipo variablesC
struct lista *sigC
}*:HU0)UOO?*HU\0)UOO?*V0)UOO?*,0)UOOC
donde tipo variables ser:n las variables ,ue *uardaremos en la estructuraB
struct lista *sig es un puntero ,ue apunta al elemento de tipo lista introducido a
continuaci!nB *CAB ser: donde *uardaremos el primer elemento de la listaB *AUX
nos servir: para *uardar elementos temporalmente > para recorrer la lista al
visualiCarlaB *P para comparar los valores introducidos > ordenarlosB > *FB ,ue
apuntar: al elemento anterior al Dltimo introducido.
5ntes de insertar un elementoB deberemos comprobar si la lista est: vac)a o no.
%i lo est: deberemos insertar el primer elementoA
if (:HU00)UOO) :HU0HU\C
%i >a e@istiera al*Dn elemento 'aremos ,ue P > F apunten al primero de la lista.
%i el elemento introducido fuera menor ,ue el primero de la listaB 'ar)amos ,ue el
nuevo elemento pasara a ser el primeroB > el ,ue 'asta a'ora era el primeroB
pasar)a a ser el se*undo.
if (HU\P>num = :HUP>num){
HU\P>sig0:HUC
:HU0HU\C
}
Para e@traer un elemento de la lista solicitaremos un nDmeroB si el nDmero
introducido se corresponde con el campo num de uno de los elementosB =ste ser:
e@tra)do de la lista. eberemos controlar ,ue la lista no est= vac)a > ,ue el
elemento con el nDmero solicitado e@ista.
/)?ate en el e?emploB en la funci!n e@traer. %i CAB es i*ual a NULLB ser: ,ue la
lista est: vac)aB > si P es i*ual a NULL al salir del while si*nificar: ,ue no se 'a
encontrado nin*Dn elemento ,ue conten*a el nDmero introducido.
Para visualiCar la lista comprobaremos ,ue e@istan elementosB es decirB ,ue
CAB sea distinto de NULL. 1ec'o esto asi*naremos a AUX la direcci!n de CAB e
iremos recorriendo la lista mientras AUX sea distinto de NULL.
if (:HU00)UOO) returnC
HU\0:HUC
"!ile(HU\S0)UOO)
{
printf(DEdD?HU\P>num)C
HU\0HU\P>sigC
}
Estructura *r:fica de una listaA
5,u) finaliCa el tema de la *esti!n din:mica de memoria. Es un tema al*o
comple?o 'asta ,ue se asimila el concepto > funcionamiento de las diferentes
estructurasB pero tras conse*uirlo >a no tiene nin*Dn secreto. %i al*una veC no
recuerdas su funcionamiento siempre es una buena soluci!n co*er papel > l:piCB
dibu?ar una pilaB cola o lista *r:ficamente > simular la introducci!n de elementosB
escribiendo la situaci!n de los punteros en cada momento.
E@isten otras estructurasB como las listas doblemente enlazadas. La Dnica
diferencia con la lista ,ue conocemos es ,ue en las primeras cada elemento *uarda
la direcci!n del anterior > del posterior. %er)a una estructura como estaA
struct listaWdoble
{
c!ar nombre;42<C
struct listaWdoble *antC
struct listaWdoble *sigC
}C
%u funcionamiento es mu> similar al de una lista normal. Puedes intentar 'acerla tu
mismo.
(tras estructurasB como los rboles son m:s comple?as > menos utiliCadas.

Вам также может понравиться